This is a dropdown which I am not able to click through xpath or CSS selector.
My HTML code:-
<button class="userInfo dropdown-toggle btn btn-default" data-reactid=".0.0.0.1:$=11:$1.1" type="button"> <span class="sr-only" data-reactid=".0.0.0.1:$=11:$1.1.0">Toggle dropdown</span> <span class="caret" data-reactid=".0.0.0.1:$=11:$1.1.1"/> <span data-reactid=".0.0.0.1:$=11:$1.1.2" style="letter-spacing:-.3em;"/>
Code I have tried:-
driver.findElement(By.xpath(".//*[#data-reactid='.0.0.0.1:$=11:$1.1']")).click();
but I am getting error says:-
it can not find such xpath
There may be a possiblity of iframe:-
driver.switchTo().frame("provide frame name or location");
Refer below for more info regarding switch on frame:-
http://toolsqa.com/selenium-webdriver/handling-iframes-using-selenium-webdriver/
OR
There is a possiblity that your xpath is not fine or returning more than 1 element to selenium. In this condition selenium will be confuse that on which element selenium should click . so check your xpath again
Hope it will help you :)
Related
Below is my HTML
<div id="slectrole" class="collapse in" role="tabpanel" aria-labelledby="selectrole">
<div class="panel-body">
<div class="dropdown">
<input class="search-control jsSayt jsRolesFreeText" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Eg: Delivery, BPO, Driver'" placeholder="Eg: Delivery, BPO, Driver" value="" aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" type="text">
<ul class="jsSaytList jsRolesFilter">
<li id="jsFilter_subRole_1" class="checkbox-inline jsFilterSubRole jsRoleValue_1" data-value="Accountant">
<input id="Accountant" class="radio-custom jsFilterRadio jsRole" value="Accountant" name="Role" data-roleid="1" type="radio">
<label class="radio-custom-label" for="Accountant">Accountant</label>
Below is the code I am using to click the radio button:
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[#id='slectrole']/descendant::li[#data-value='Accountant']/label[#for='Accountant']")))
driver.find_element_by_xpath("//div[#id='slectrole']/descendant::li[#data-value='Accountant']/label[#for='Accountant']").click()
The code runs ok but it does not select the radio button.
OK, so I can understand your frustration, I tried your code and wasn't able to .click() (select) the element when located via xpath. See bellow print-screen:
As you can see, it was only clicking the radio-button when issuing a .click() via a CSS-located element.
Question No.1: Are you bound to the xpath locator strategy in one way or another?
If NOT, then just use a regulat CSS selector: 'input[id="Accountant"]'.
Else, you have to figure out what is wrong with the website you are testing, or switch to another WebElement locator strategy. (e.g.: ID, Class, CSS, LinkText, etc.)
If you would opt to go with the CSS locator-strategy, then your code would look like this:
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "label[for='Accountant']")))
driver.find_element_by_css("input[id='Accountant']").click()
Alternatively, you can try to click on the <label> tag attached to the radio-button, which in my console works the same way:
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "label[for='Accountant']")))
driver.find_element_by_css("label[for='Accountant']").click()
Explanation: In a real-life scenario, you can select the radio-button both via the actual radio-button, or via its label. That's why your solution worked.
Question No.2: Why are you using such a long xpath selector?
In order to have a optimal selector, you should ALWAYS go with the shortest, combination of tags/attributes that will UNIQUELY identify your target element. Else you will be susceptible to website changes, flaky test cases, etc.
You can perform the click on the drop down and then wait for the radio button to appear, before clicking it. Hence, try following:
driver.find_element_by_xpath("//div[#id='slectrole']/div/div[#class='dropdown']/input[1]")).click()
wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located((By.XPATH, '//div[#id='slectrole']/descendant::li[#data-value='Accountant']/input[1]')))
driver.find_element_by_xpath("//div[#id='slectrole']/descendant::li[#data-value='Accountant']/input[1]").click()
Let me know, if above code works for you.
I just updated Firefox to 48.0.1 from 48.0 and now I'm seeing an issue with the Bootstrap tooltip. Looking at the HTML in Firebug, it appears that Firefox is adding a new <div> at the bottom of the page that is not in the .jsp:
<div id="tooltip404721" class="tooltip fade top in" role="tooltip" style="top: 162.4px; left: 1220.5px; display: block;">
<div class="tooltip-arrow" style="left: 50%;"></div>
<div class="tooltip-inner">Delete</div>
</div>
This only happens if the tooltip is attached to a button - links are not affected. The links and buttons are column elements in a jQuery DataTables table. The tooltip portion of the code for link vs. button is identical.
Link:
<td><a class="btn btn-info btn-xs" href="<c:url value='/recipe/viewRecipe/${recipe.id}'/>"
data-toggle="tooltip" data-placement="top" title="<spring:message code="tooltip.view"></spring:message>">
<span class="glyphicon glyphicon-list-alt"></span></a>
Button:
<td><button class="btn btn-danger btn-xs" type="button" id="delete${recipe.id}" onclick="deleteRecipe(${recipe.id},
'<spring:escapeBody javaScriptEscape="true">${recipe.name}</spring:escapeBody>')"
data-toggle="tooltip" data-placement="top" title="<spring:message code="tooltip.delete"></spring:message>">
<span class="glyphicon glyphicon-remove"></span></button>
This DataTables-specific setting is in a .js file included on the page:
$('[data-toggle="tooltip"]').tooltip({
container : 'body'
});
Removing the above gets rid of the extra <div> but then the tooltip no longer appears with Bootstrap formatting. Adding data-container="body" to the button itself didn't work either.
Any ideas?
EDIT:
Although I just recently noticed the issue I downgraded to 47.0.1 and still see the problem. I will keep downgrading to find out which version this starting appearing in. I don't think it's my code because the production version has the same problem as my dev version. Also, this does not happen in Chrome but it does in Edge.
I found the problem. I have a function that's applied to all pages that sets the input focus for form pages to the first form control. This is because the menu contains a search input and button, which would otherwise get the focus instead of the first form input.
function setInputFocus() {$(':input:visible:enabled:eq(2)').focus();}
For some reason that I don't remember now I moved the code to toggle the tooltip (see question) above this focus code. That meant that the first button in the first row of the datatable ended up getting the focus, hence the tooltip being visible when the page was displayed. Moving the tooltip toggle after this focus code fixed the problem.
Obviously, I should be more careful about site-wide code that is specific to a particular issue but ends up being applied to all pages...
Can some one help me to locate an element (without using xpath) which is displayed using : <i id="ext-gen759" class="icon-tool"></i> under a <div> tag. The HTML is as follows:
<div id="ext-comp-1089" class=" MiniTbar">
<a href="javascript:void(0);" id="ext-gen760" class=" active">
<i id="ext-gen759" class="icon-tool"></i> -->> need to locate this.
</a>
</div>
I don't want to use:
By.Id --> id is dynamic
By.XPath --> not stable
I have tried the following without getting a result:
By.className("icon-tool") -- > not working
By.partialLinkText("icon-tool") --> not working
Any solution?
You can rely on the part of the id using, for example, starts-with():
//div[starts-with(#id, "ext-comp-")]/a[starts-with(#id, "ext-gen")]/i[#class="icon-tool"]
Or a CSS selector:
div[id^=ext-comp-] a.active[id^=ext-gen] i.icon-tool[id^=ext-gen]
using xpath should do this. You may need to make sure that's the only element i with same criteria on the page
//i[contains(#id,'ext-gen')]
Give a chance to the find element by css selector ?
driver.find_element_by_css_selector('i.icon-tool')
The python documentation is here http://selenium-python.readthedocs.org/en/latest/locating-elements.html
You can find it using css selector:
driver.findElement(By.cssSelector("i[class='icon-tool']"));
I have following html code. And I want to using Ruby Mechanize select dropdown element wit specific text (I want to click on it). Example Chinese. My question is how to do this? I am new in Mechanize.
<form class="form-inline search search-large" action="/translate" method="get">
<input id="q" name="q" type="text" placeholder="Search" class="input-large" value="" autofocus="autofocus" data-pons-redirect-input="true" data-pons-autofocus="true" autocomplete="off">
<div class="btn-group source open" data-pons-lang="de">
<button class="btn btn-large dropdown-toggle" data-toggle="dropdown">
<span class="text">Chinese</span>
<i class="icon-angle-down"></i>
</button>
<ul class="dropdown-menu">
<li>
<a href="#" class="language">
<span class="text">Chinese</span>
<span class="flag flag_zh"></span>
</a>
</li>
<li>
<a href="#" class="language">
<span class="text">Elvish</span>
<span class="flag flag_lb"></span>
</a>
</li>
</ul>
</div>
</form>
Bad News
As far as I see, your example page is too involved to let mechanize interface it with e.g. a .click method. Actually it will be able to follow the links (""), but I guess this will not help you much, because it seems there is some javascript or other black magic involved.
You can try first to see if the page will work nicely (not guaranteed) with mechanize by disabling JavaScript in your browser.
Good News
Anyway, at the end you will want mechanize to do certain kinds of HTTP requests - triggered by JS or not does not matter. That you will be able to do with mechanize (although it might not necessarily be the best choice for all scenarios).
Tips
I encourage you to use your browsers developer thing (often fired up by pressing F12) and see what is really happening, e.g. which form gets submitted with which values. And don't forget to check if its the same when used with and without javascript (mechanize will not execute JavaScript as far as i know).
Also, when developing your mechanize code, use irb or another repl like pry to try your code live. Your mechanize agent or page will have a method save or save_as or similar with which you can always save the current page and review it in your browser or favorite text editor. And remember _ in irb gives you your last return value.
I'm trying to do some screen scraping, and I've gotten down to this last step. I'm trying to download a file, which is accessed via a button from the following html:
<button class="pdf ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button" aria-disabled="false">
<span class="ui-button-text">
<span class="icon-32 pdf-32"></span>
<span class="btn-txt"> PDF file </span>
I'm used to clicking buttons with the following ruby code:
browser.button(:value, "Sign In").click
But with this .. there doesn't seem to be any value I can use. Can anyone help me out?
I can think of a couple possibilities. One is that you can do a regular expression match on the value. Try:
browser.button(:value, /PDF file/).click
But you don't have to use the value, you can use a uniquely identifying attribute. In this case, you may be able to use the class, e.g.
browser.button(:class, "pdf").click
If the pdf class is not unique, you can add an :index to identify which one of the matches to click.