not able to click radio button element by xpath in selenium using python - xpath

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.

Related

What are the methods to pass Springboot/Thyleaf objects to Modal forms?

I'm confused. I've thought it's possible to pass SpringBoot/Thymeleaf objects from the html page to the Modal form. I've come across many examples using ajax to pull data from the REST endpoint instead.
Is using ajax to pull in objects into Modals, the only method?
Thymeleaf is a server side templating language... the concept of a modal form usually means showing/hiding a window opens and closes on the client side (meaning JavaScript that runs when a user clicks a link or a button ). If you don't want to use an API to pull that data (which I think makes the most sense), then you have to create a hidden modal for every row on your page. For example:
<div th:each="item, i: ${items}">
<a href="#"
onClick="openModal(this.getAttribute('data-modal'))"
th:data-modal="|#modal${i.index}|">
Edit modal #<span th:text="${i.index}" />
</a>
<div th:id="|modal${i.index}|" style="display: none;">
<p>I am a modal form for element <span th:text="${i.index}" />!</p>
<input type="text" th:value="${item.value}" />
</div>
</div>
You can see how this works... creating a hidden div/modal form for every row (so you don't have to call an API to get the form values), but it comes with a lot of extra HTML.

identifying xpath from Ext JS application

I'm trying to automated a application designed in Ext Js, xpath identification is become complex. Please help in getting the xpath for the below scenario.
For a dropdown having a set of names, need to select a name from the list available.
I'm using a mouse action to locate the drop down name and then moveToElement particular element in the List of menu present.
For example If the menu is containing a list of names like, Abi, Ashwini Asha, Ashwini, Diva.
Using parameterizing I'm able to select the names from the menu.
But when I need to select Ashwini from the menu ,since Ashwini Asha is already present in the menu , Ashwini Asha object gets clicked.
contains() is not working here. Which function should I use?
The below is the code which am using :
html :
<div id="combo-1023-inputWrap" class="x-form-text-wrap x-form- text-wrap-default" role="presentation" data-ref="inputWrap">
<input id="combo-1023-inputEl" class="x-form-field x-form-text x-form-text-default " type="text" autocomplete="off" aria-autocomplete="list" aria-expanded="false" aria-haspopup="true" aria-required="false" aria-invalid="false" aria-readonly="false" aria-disabled="false" aria-hidden="false" role="combobox" value="Triton" name="selectedName" size="1" data-ref="inputEl" data-componentid="combo-1023">
......
<li>------------ Ashwini Asha</li>
<li>------------ Ashwini</li>
</div>
to click on the menu :
action.moveToElement(driver.findElement(By.xpath("//input[#name='selectedName']"))).click().perform();
to load the data in the menu :
wait.until(ExpectedConditions.visibiltyOfElementLocated(By.xpath("//li[contains(text(),'"+NameParameter+"')]")));
click the object :
action.moveToElement(driver.findElement(By.xpath("//li[contains(text(),'"+NameParameter+"')]"))).click().perform();
Let me know how to select the name Ashwini alone?
Thanks
No need to use contains in your xpath. Go for exact match of the name.
By.xpath("//li[text()='"+NameParameter+"']")
or
By.xpath("//li[.='"+NameParameter+"']")
If I'm understanding this correctly, you could use:
Driver.Instance.findElements(...
This would return an array in which you could just iterate and perform actions on based on the .text of the element.

Having trouble hovering and clicking button using Capybara and Xpath

I'm trying to click a button using Capybara. I've tried all combinations I can think of but no luck. Trying to click on the 'delete' link. The delete link only shows up when you hover over the row in the table.
This is the HTML:
<tbody>
<tr class="even" id="informal_6">
<td class="columnOrganizationNameColumnValue" id="informal_7">
<div>
<a id="showLink_0" title="Organization Details" class="viewLink">
Institution / Automation
</a>
</div>
<div class="gridMenuDescription">
</div>
<div class="gridMenu">
<a id="gridMenuDirectLink_1" title="Edit Organization" class="gridMenuItem">
edit
</a>
<a id="gridMenuDirectLink_2" class="gridMenuItem delete">
delete
</a>
</div>
</td>
</tbody>
I'd like to note, that the "gridMenu" div, when you hover over it using Firebug it turns to:
<div class="gridMenu hover gridMenuShow">
Some things I've tried, but no luck:
find(:xpath, '//*[(#id = "gridMenuDirectLink_2")]').click
find("#informal_6").find("#informal_7").find(".gridMenu.hover.gridMenuShow").find(".gridMenuItem.delete").click
Suggestions?
After a crazy amount of attempts trying different things I was able to get it to work with this code:
find('#informal_6').hover.find('.gridMenu').hover.find('.gridMenuItem.delete').click
Try the below code to hover over the row.
page.driver.browser.mouse.move_to(page.driver.browser.find_element(:id=>"locator"))
I have a calendar interface where AJAX edit & delete links appear only when you hover over each calendar entry. It's nice and compact, but I had trouble getting Capybara to click on those dynamically displayed elements, and using .hover on the parent element didn't seem to make a difference. So I tried a brute-force approach that is working nicely so far:
# Use Jquery to force display a hidden element. Useful for getting at links
# that are dynamically displayed.
# Call it like: js_show(".entry.scheduled[data-id=\"#{#da3.id}\"] .actions")
def js_show(selector)
page.execute_script(" $('#{selector}').show(); ")
end
def js_hide(selector)
page.execute_script(" $('#{selector}').hide(); ")
end
Now, when I need to click on an element that's only displayed on hover etc., I can call js_show(".whatever.container.selector") to force the links to display, then page.find(...).click works.

Finding an element by XPath in Selenium

I am trying to use Selenium to navigate a webpage. There is a button I am trying to get to via its xpath. For other buttons on the site, it works fine. But for this particular one, I keep getting the error that the element can't be located. Firebug is just giving me the xpath in this format: //*[#id="continueButton"].
I notice that the button has wrappers around it. They are structured like
<div class = "cButtonWrapper">
<div class = "cButtonHolder">
<input type="image" id="continueButton" name="Continue" alt="Continue" src="/store/images/btn_continue.gif" value="Continue">
</div>
</div>
Could the wrappers around the button have anything to do with not being able to locate it?
Maybe the <input> element cannot be properly located by XPath because you are using invalid HTML. Try using <input id="continueButton"/> or <input id="continueButton"></input> in your page source.

click button in jruby + celerity

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.

Resources