Python Selenium webdriver get XPATH and select dropdown - python

I've found the word 'Burger' in HTML table with this code
findRow = driver.find_element(By.XPATH, "//*[contains(text(),'Burger')]").value_of_css_property('#name')
how do I can get XPATH 'Burger'?
how do I can select the column beside it (example select 'Fish' beside column 'Burger') and then submit button?
HTML code
<tbody>
<tr>
<td>..</td>
<td>.....</td>
</tr>
<tr>
<td>Burger</td>
<td>
<select class="form-control input-sm" id="sel222" name="sel222" type="68" group="433" onchange="count(this)">
<option value="1">Vegetables</option>
<option value="2">Fish</option>
<option value="3">Beef</option>
</select>
</td>
</tr>
</tbody>
</table>
<button type="button" class="btn btn-primary" id="submit"><span class="fa fa-save"></span> Save</button>

Based on the HTML posted, the simplest XPath to find "Burger" would be,
//td[text()='Burger']
The XPath to find the SELECT in the cell to the right of the "Burger" cell would be,
//td[text()='Burger']/following-sibling::td/select
^ the XPath to find the TD that contains "Burger", from above
^ then find the sibling TD
^ then the SELECT child of the sibling
Putting this all together to select "Fish" from the SELECT element next to the "Burger" cell and click Submit,
from selenium.webdriver.support.ui import Select
select = Select(driver.find_element(By.XPATH, "//td[text()='Burger']/following-sibling::td/select"))
select.select_by_visible_text("Fish")
driver.find_element(By.ID, "submit").click()

In this scenario, you can identify the select list box using xpath following technique. Use the below xpath to identify select object
//td[contains(.,'Burger')]/following::select

You can select the option Burger using the below XPath:
.//td[text()='Burger']
You can select the options inside select tag using the below XPath:
.//td[text()='Burger']//parent::tr//select/option

Related

Selenium find and Click button based on other tags

The below html consist of 1 of many rows.
Below is a sample row I need to click on the href. The href link is dependent on DataScience td tag and the Finance td tag they are fixed tags they dont change. The tag that I am looping that changes is SomeCategory each category will have a different number instead of the 328 for this particular link.
<tr>
<th class=\"align-middle\" scope=\"row\">
<span class=\"badge bg-primary position-relative py-2\">SomeCategory
<span class=\"position-absolute top-0 start-100 translate-middle badge rounded-pill bg-secondary\">P3
</span>
</span>
</th>
<td class=\"align-middle small\">DataScience</td>
<td class=\"align-middle small\">Finance</td>
<td class=\"align-middle small\">
<div class=\"btn-group\" role=\"group\">
<span data-bs-placement=\"left\" data-bs-toggle=\"tooltip\" title=\"\" data-bs-original-title=\"Show Application\" aria-label=\"Show Application\">
<a class=\"btn btn-sm btn-outline-primary\" href=\"/repo/applications/328\">
<svg class=\"bi flex-shrink-0\" height=\"18\" role=\"img\" width=\"18\">
<use href=\"#icon_eye\"></use>
</svg>
</a>
</span>
</div>
</td>
</tr>
My objective is to find the href link by changing "SomeCategory" value so that I may go to that page. The other 2 values stay the same. By changing "SomeCategory" value the number would change creating a new link. How would I find this href based on the category change while other filter tags remain the same so i can return the href value and create the link for that category like the one below and use driver to go to that page
https://mybooks.topics.com/repo/applications/328
(This link wont work its only for sample purpose)
You can find the parent tr element based on the SomeCategory value and then find the a element containing the href inside it.
Something like this:
//tr[.//span[contains(.,'SomeCategory')]]//a
UPD
Let's say you have categories, a list of values you want to use with SomeCategory.
You can format the XPath expression string with SomeCategory variable values as following:
xpath_template = '//tr[.//span[contains(.,"{0}")]]//a'
for category in categories:
xpath = xpath_template.format(category)
Now you can use the xpath above getting the correspondingly href links / elements.
To click() on the desired element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
With respect to the element with text DataScience:
text = "DataScience"
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, f"//td[text()='{text}']//following-sibling::td[2]//a[#class='btn btn-sm btn-outline-primary']"))).click()
With respect to the element with text Finance:
text = "Finance"
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, f"//td[text()='{text}']//following::td[1]//a[#class='btn btn-sm btn-outline-primary']"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Python / Selenium - access not interactive element

What I need:
Select one of the options from the drop-down list
Only BUTTON element is visible (SELECT element is not visible)
This is html code:
<td data-bind="css: { 'cell-error': applicantNames.hasError }, attr: { title: applicantNames.message }" title="">
<select data-bind="options: $parent.applicants, multivalue: applicantNames" multiple="multiple" style="display: none;">
<option value="ABC">ABC</option>
<option value="XYZ">XYZ</option>
</select>
<button type="button" class="ui-multiselect ui-widget ui-state-default ui-corner-all" aria-haspopup="true" style="width: 236px;"><span class="ui-icon ui-icon-triangle-2-n-s"></span><span>Please select...</span></button>
</td>
This is how it looks like:
The problem is that I would like to select one of these options by using Selenium, but because the SELECT element is not interactable/not visible ... not sure what to do...
If you will choose an option from the drop-down the BUTTON element will be updated like this
<button type="button" class="ui-multiselect ui-widget ui-state-default ui-corner-all ui-state-active" aria-haspopup="true" style="width: 236px;">
<span class="ui-icon ui-icon-triangle-2-n-s"></span><span>ABC, XYZ</span>
</button>
Even if I will update the BUTTON section manually, it will still not update the element visually..... so I'm a bit stuck to find a way how to interact with these elements by using Selenium...
P.S. I'm looking for ANY headless methods, e.g. Selenium / JavaScript execution through selenium and e.t.c...
See the problem is that "This is not built using Select - option tag", so one can not directly make use of Select class from Selenium support package.
Instead you can try to click on that menu using Selenium .click()
in your case something like this
driver.find_element_by_xpath("//span[contains(text(), 'Please select')]").click()
and then store all the visible option in a list of web elements using find_elements and then iterate the list :
for option in list_of_options:
if option.text == "your desired option"
option.click()

Selenium selecting from Dropdown Python

I'm using selenium in python and I'm looking to select the option Male from the below:
<div class="formelementcontent">
<select aria-disabled="false" class="Width150" id="ctl00_Gender" name="ctl00$Gender" onchange="javascript: return doSearch();" style="display: none;">
<option selected="selected" title="" value="">
</option>
<option title="Male" value="MALE">
Male
</option>
<option title="Female" value="FEM">
Female
</option>
</select>
Before selecting from the dropdown, I need to switch to iframe
driver.switch_to.frame(iframe)
I've tried many options and searched extensively. This gets me most of the way.
driver.find_element_by_id("ctl00_Gender-button").click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "ctl00_Gender")))
select=Select(driver.find_element_by_id("ctl00_Gender"))
check=select.select_by_visible_text('Male')
If I use WebDriverWait it times out.
I've tried selecting by visible text and index, both give:
ElementNotInteractableException: Element could not be scrolled into view
As per the HTML you have shared the <select> tag is having the value of style attribute set as display: none;. So using Selenium it would be tough interacting with this WebElement.
If you access the DOM Tree of the webpage through google-chrome-devtools, presumably you will find a couple of <li> nodes equivalent to the <option> nodes within an <ul> node. You may be required to interact with those.
You can find find a couple of relevant detailed discussions in:
select kendo dropdown using selenium python
How to test non-standard drop down lists through a crawler using Selenium and Python
How to select an option from a dropdown of non select tag?
Try below solutions:
Solution 1:
select = Select(driver.find_element_by_id('ctl00_Gender'))
select.select_by_value('MALE')
Note add below imports to your solution :
from selenium.webdriver.support.ui import Select
Solution 2:
driver.find_element_by_xpath("//select[#id='ctl00_Gender']/option[text()='Male']").click()

How to select a drop-down menu value wihtout an id with Selenium using Python?

I need to select an element/item from a drop-down menu that doesn't have an id element using Python and Selenium.
The piece of HTML code:
<mbo-transaction-mode-select mode="filters.mode" class="ng-isolate-scope">
<select class="form-control input-sm ng-pristine ng-untouched ng-valid ng-empty" ng-model="mode" ng-options="value for (key,value) in vm.modes">
<option value="" class="" selected="selected"></option>
<option label="LIVE" value="string:LIVE">LIVE</option>
<option label="TEST" value="string:TEST">TEST</option>
</select>
The current option I found on Stackoverflow or Google used the Select method, but that option used find_element_by_id which I unfortunately don't have.
I tried to use:
select = Select(browser.find_element_by_xpath("//input[#ng-model='mode']"))
select.select_by_visible_text('LIVE')
But this gave the error:
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //input[#ng-model='mode']
Is there another way for me the select the dropdown and one of its options?
You need to fix your xpath, as here:
element = browser.find_element_by_xpath("//select[#ng-model='mode']")
driver.execute_script("arguments[0].scrollIntoView();", element)
select = Select(element)
select.select_by_visible_text('LIVE')

Selenium: How do I get a text within a <td> tag and then click the Javascript link of it's sibling?

I have a list of forms that I need to edit one by one wherein I have to identify the form title first and then click the JavaScript link to open it's editing template.
In the sample code below, I need to identify the text Another Custom Form (Mobile) which is the form title and then click the a href link whose onclick value is editProjectFormType. It is the second sibling of form title. I am trying to perform this task in Python.
<tr class="trbg2">
<td width="10%" align="left" nowrap="nowrap">
<div align="center">
<input type="checkbox" name="selectedFormType" value="2192454$$rmymiK" checked="checked">
</div>
</td>
<td width="10%" align="left" nowrap="nowrap"><img src="https://dmsak.qa.asite.com/images/dots.gif" width="6" height="15">!!!!!!!!!!!!!!!!!!!!!!!!!!!!Ashish_test!!!!!!!!!!</td>
<td width="10%" align="left">Custom forms</td>
<td width="10%" align="center">ACFM</td>
<td width="24%">Another Custom Form (Mobile)</td>
<td width="20%">Custom</td>
<td align="center" width="15%">
<a href="javascript:void(0);" onclick="editProjectFormType('2192454$$rmymiK');">
<img src="https://dmsak.qa.asite.com/images/i_editfgt.gif" width="16" height="20" border="0">
</a>
</td>
<td align="center" width="15%">
<a href="javascript:void(0);" onclick="downloadFormTemplate('2192454$$rmymiK');">
<img src="https://dmsak.qa.asite.com/images/f_dow_tmple.gif" width="22" height="22" border="0" alt="Click here to Download Template" title="Click here to Download Template">
</a>
</td>
</tr>
I have used the following incomplete code so far and not sure what do I do next
button = browser.find_elements_by_tag_name('td')
for txt in button:
if txt == "Another Custom Form (Mobile)":
You can perform click on link with following single xPath where you can provide text Another Custom Form (Mobile) to identify their following-sibling and get that link as as below :-
link = browser.find_element_by_xpath("//td[contains(text(),'Another Custom Form (Mobile)')]/following-sibling::td/a[contains(#onclick, 'editProjectFormType')]")
link.click()
Edited..
Implement WebDriverWait to get the element as below :-
link = WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.XPATH, "//td[contains(text(),'Another Custom Form (Mobile)')]/following-sibling::td/a[contains(#onclick, 'editProjectFormType')]")))
link.click()
Note:- if target element is inside a frame. you need to switch to that frame first as browser.switch_to_frame("frame name or id") then go to find the target element as above.
Hope it will help you...:)
I would approach this by:
creating a class to represent a row in this table, say "MyRow", which has method to interact with each column as a field in the class.
using Selenium to find all of the rows in the table, returning a list of instances of this class.
loop thru the list looking for the row that matches the target name :
for (MyRow myRow : allRows) {
if (myRow.name.equals("Another Custom Form (Mobile)")) {
return myRow;
}
}
click on the link in the target row's column. myRow.editProjectForm()
The first one worked for me with some modification.
I have 3 buttons in single td, with other 4 td have texts. I have to click on specific button based on the one td value (e.g customer_name). Below is working the code.
self.driver.find_element_by_xpath(
"//td[contains(text(),'" + customer_name + "')]/following-sibling::td/button[text()='Accept']"
).click()

Categories

Resources