Click a tab button on website - c#

I want to click tab buttons on website which runs on web browser with code below. I put "step2Tab" and "group1step2" as parameter but getting NullReferenceException error. How can i click these buttons?
webBrowser1.Document.GetElementById("step2Tab").InvokeMember("click");
Here is the html code
Step 3
Step 2
<a class="currentTab" href="javascript:donothing()" onclick="showTab(this,1,'step1')" id="group1step1">Step 1</a>
<div id="step1Tab" style="display: block;"></div>
<div id="step2Tab" style="display: block;"></div>
<div id="step3Tab" style="display: block;"></div>

I'm not familiar with the environment you're working in, you may need to be more specific but looking at other people having this issue (link, link) it appears you need to get elements by tag:
webBrowser1.Document.GetElementByTagName("step2Tab");
This will return an array of elements with that tag. You will then need to compare by the an attribute of the element:
GetAttribute("attribute")
I hope this is useful.

Related

Is it possible to give name to Quasar Uploader in <form>

I have a <form> where I am using Vue.js and Quasar, and submits in as a HTML form in asp .net core 3.1
The problem is when I am using Quasar Uploader (https://quasar.dev/vue-components/uploader).
The functionality works fine, but when I submit the form (post i C# and .net core).
I cant get the the file in the controller.
As you can see from this example: https://codepen.io/cbrown___/pen/GRZwpxw
When the Uploader is rendered it does not have the attribute name. From the example above you have this input:
<input tabindex="-1" type="file" title="" class="q-uploader__input overflow-hidden absolute-full">.
I guess that is why I cant get it from my Controller. How can I solve this when I am using .net Core 3.1 to submit this form?
And I see no good solutinos in letting people upload files through my API before the record is created.
Is it a option here I do not see?
EDIT:
The <input> is on the plus-icon. So by using inspect elements you should be able to see that no name occurs.
EXAMPLE CODE:
HTML
<div id="q-app">
<div class="q-pa-md">
<div class="q-gutter-sm row items-start">
<q-uploader
url="http://localhost:4444/upload"
style="max-width: 300px"
></q-uploader>
<q-uploader
url="http://localhost:4444/upload"
color="teal"
flat
bordered
style="max-width: 300px"
></q-uploader>
<q-uploader
url="http://localhost:4444/upload"
label="Upload files"
color="purple"
square
flat
bordered
style="max-width: 300px"
></q-uploader>
<q-uploader
url="http://localhost:4444/upload"
label="No thumbnails"
color="amber"
text-color="black"
no-thumbnails
style="max-width: 300px"
></q-uploader>
</div>
</div>
</div>
JS:
new Vue({
el: '#q-app'
})
If any body else need this I ended up with using this:
:name="'file_description[' + index + ']'"
That way each one got one name...and from another array I knew how many file_description it would be.

C# Access asp control from Parent page

I have a parent page containing an iframe, an ASP label and a button.
When the user click on the parent button, it will display some table results inside the iframe.
Now i would like to display the parent label with different text and color depending on the results of the iframe.
So i m trying in the code behind (C#) of the iframe to retrieve the label from the parent and assign it a CssClass. But no matter what i do it always come back with a null reference when trying to find the control from the parent.
Can someone please help?
Parent page code:
<div class="search-row">
<div class="search">
<button id="btnSearch" type="submit" class="button button-block">Search</button>
</div>
<div class="search" style="padding-top: 20px;">
<asp:Label ID="wrapperResponse" CssClass="resp" runat="server">TEST</asp:Label>
</div>
</div>
<div id="iframeDiv">
<iframe name="my_frame" width="100%" height="350px" src="Results.aspx" scrolling="no" frameborder="0"></iframe>
</div>`
The Results.aspx will display a table with some html build dynamically.
Now let s say if resulting Table has one row, i would like Label WrapperReponse to be in Green and says "1 row" but if 2 rows then i would like it to be in Red and says "2 Rows"
In my Results.aspx.cs i tried
String test= String.Format("{0}", Request.Form["wrapperResponse"]);
Label statusResponse = (Label)this.FindControl("wrapperResponse");
Label statusResponse2 = (Label)Parent.FindControl("wrapperResponse");
Any ideas are welcome!
thanks
Well, just a couple of points needed mentioning here. Food for thought.
In order to access the asp label control, you need to do it on the parent page instead of on the results page.
I would suggest you reconsider the design of the page. Do you really have to use the iframe here? Why not place your button and label controls on the results.page directly? Or perhaps make results.aspx as an ASCX user control, so you can embed it on the parent page.
Hope it helps

"Element is not currently visible and so may not be interacted with" but another is?

I've created another question which I think is the cause for this error: Why does the Selenium Firefox Driver consider my modal not displayed when the parent has overflow:hidden?
Selenium version 2.33.0
Firefox driver
The code that causes the error:
System.Threading.Thread.Sleep(5000);
var dimentions = driver.Manage().Window.Size;
var field = driver.FindElement(By.Id("addEmployees-password")); //displayed is true
field.Click(); //works fine
var element = driver.FindElement(By.Id(buttonName)); //displayed is false
element.Click(); //errors out
The button that its trying to click:
<div id="addEmployees" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="addEmployeesLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>Add Employee</h3>
</div>
<div class="modal-body">
<p class="alert alert-info">
<input name="addEmployees-username" id="addEmployees-username" />
<input name="addEmployees-password" id="addEmployees-password" type="password" />
<input name="addEmployees-employee" id="addEmployees-employee" />
</p>
</div>
<div class="modal-footer">
<button name="addEmployees-add" id="addEmployees-add" type="button" class="btn" data-ng-click="submit()">Add</button>
</div>
</div>
If I change the call to FindElements then I get ONE element, so there isn't anything else on the page.
If I FindElement on a field that occurs right before the button, say addEmployees-employee, then addEmployees-employee is displayed
In the browser itself, it shows up fine, all i need to do is actually click the button and the desired behavior executes, but the webdriver refuses to consider the element displayed
How is it that one field can be considered displayed and the other is not?
The modal with the add button in the bottom right, all the other elements are displayed = true
The window size is 1200x645 per driver.Manage().Window.Size;
The element location is: 800x355y per driver.FindElement(By.Id(buttonName)).Location
The element dimentions are: 51x30 per driver.FindElement(By.Id(buttonName)).Size
The password element location is: 552x233y per driver.FindElement(By.Id("addEmployees-password")).Size
Brian's response was right: use an explicit wait versus Thread.Sleep(). Sleep() is generally brittle, you're losing five seconds needlessly, and moreover it's just a really rotten practice for automated testing. (It took me a long, LONG time to learn that, so you're not alone there.)
Avoid implicit waits. They generally work for new items being added to the DOM, not for transitions for things like a modal to become active.
Explicit waits have a great set of ExpectedConditions (detailed in the Javadox) which can get you past these problems. Use the ExpectedCondition which matches the state you need for your next action.
Also, see Ian Rose's great blogpost on the topic, too.
Selenium WebDriver does not just check for opacity != 0, visibility = true, height > 0 and display != none on the current element in question, but it also searches up the DOM's ancestor chain to ensure that there are no parent elements that also match these checkers.
(UPDATE After looking at the JSON wire code that all the bindings refer back to, SWD also requires overflow != hidden, as well as a few other cases.)
I would do two things before restructuring the code as #Brian suggests.
Ensure that the "div.modal_footer" element does not have any reason for SWD to consider it to not be visible.
Inject some Javascript to highlight the element in question in your browser so you know absolutely you have selected the right element. You can use this gist as a starting point. If the button is highlighted in a yellow border, then you know you have the right element selected. If not, it means that the element selected is located elsewhere in the DOM. If this is the case, you probably don't have unique IDs as you would expect, which makes manipulation of the DOM very confusing.
If I had to guess, I would say that number two is what you are running into. This has happened to me as well, where a Dev reused an element ID, causing contention in which element you're supposed to find.
After discussing this with you in chat, I think the best solution (for now, at least) is to move the button out of the footer for your modal and into the body of it.
This is what you want (for now):
<div class="modal-body">
<p class="alert alert-info">
<input name="addEmployees-username" id="addEmployees-username" />
<input name="addEmployees-password" id="addEmployees-password" type="password" />
<input name="addEmployees-employee" id="addEmployees-employee" />
<button name="addEmployees-add" id="addEmployees-add" type="button" class="btn" data-ng-click="submit()">Add</button>
</p>
</div>
And not this:
<div class="modal-body">
<p class="alert alert-info">
<input name="addEmployees-username" id="addEmployees-username" />
<input name="addEmployees-password" id="addEmployees-password" type="password" />
<input name="addEmployees-employee" id="addEmployees-employee" />
</p>
</div>
<div class="modal-footer">
<button name="addEmployees-add" id="addEmployees-add" type="button" class="btn" data-ng-click="submit()">Add</button>
</div>
I had the same issue of element not visible so cannot be interacted with. it just got solved. i updated my selenium stand alone server. previous version was 2.33.0 and now it is 2.35.0
In my case the element was already present in the page but it was disabled,
so this didn't work (python):
wait.until(lambda driver: driver.find_element_by_id("myBtn"))
driver.find_element_by_id("myBtn").click()
it failed with error:
“Element is not currently visible and so may not be interacted with"
To solve my problem, I had to wait a couple of seconds ( time.sleep(5) ) until the element became visible.
You can also enable the element using JavaScript, a python example:
driver.execute_script("document.getElementById('myBtn').disabled='' ")
driver.execute_script("document.getElementById('myBtn').click() ")

navigation using <a> </a> tag in code behind

I am currently using <a> tag to click and navaigate as mentioned in below code.I want to navigate the below code in c# tag in page_prerender event based on id selected.could any one help on this?
<li>Category 1</li>
<li>Category 2</li>
<div id="cat1">
Content goes here
</div>
<div id="cat2">
Content goes here
</div>
something like if url doesn't contain '#' then
Response.Redirect("www.yoururl.com/Default.aspx#Cat2");
is that what you're looking for?
clicking on the <a> in html is really the same as just adding #Cat2 to the end of the URL , the browser knows what to do from there
I believe you need a url rewriting layer for how you have it. The <a> links are simply going to be a GET request with no further information. And even then you would need the links to be href="cat1" or href="#cat1".
The simplest alternative would be using <asp:linkbutton /> which can have server-side onclick events.
You might also look into AJAX requests, or use javascript to hide and display the sections, if the content is dynamic based on the request AJAX would be required there.

Javascript Back Button Behavior

I have a site I'm building where one of my pages contains several tab-panes. Whenever the user clicks on one of these tab-panes it updates the browser's history and thus affects the browser's back button functionality in an undesirable way. I've searched around on this site, but everything I found was people wanting the browser to take the user back to the previous tab, which isn't what I want. I want the browser to take the user back to the previous page, not the previous tab on the same page, if that makes sense.
I assume there should be a simple way to do this, but I just can't find it. Seems like I'm kind of alone in this want of mine.
The site is built with aspx and visual studios mvc framework.
here is a small code sample.
<ul class="nav nav-tabs">
<li class="active">Tab1</li>
<li>Tab2</li>
<li>Tab3</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
</div>
<div class="tab-pane" id="tab2">
</div>
<div class="tab-pane" id="tab3">
</div>
</div>
this is a know issue
you will need to use the javsacript method window.location.replace(url);
using window.location.replace() the current page will not be saved in session history

Categories

Resources