Selenium - multiple tags - python

I am writing a script for a friend to automate her workflow a little bit and I am using selenium with python.
On a website, I have a radiobutton section which looks like this :
<br/>
<input id="orgtype" name="orgtype" value="euk" onclick="setvalue('orgtype','euk'); setvalue('Dcut-noTM',Dcut_noTM()); setvalue('Dcut-TM',Dcut_TM());" checked="" type="radio"/>
Eukaryotes
<br/>
<input id="orgtype" name="orgtype" value="gram-" onclick="setvalue('orgtype','gram-'); setvalue('Dcut-noTM',Dcut_noTM()); setvalue('Dcut-TM',Dcut_TM());" type="radio"/>
Gram-negative bacteria
<br/>
<input id="orgtype" name="orgtype" value="gram+" onclick="setvalue('orgtype','gram+'); setvalue('Dcut-noTM',Dcut_noTM()); setvalue('Dcut-TM',Dcut_TM());" type="radio"/>
Gram-positive bacteria
<br/>
I am trying to select the middle option which has a value of "gram-". I was wondering if anyone could help me with ( or pointing to a very simple tutorial on how to ) finding the right element by xpath? overall I know you can write ( for example :
user = browser.find_element_by_css_selector('#email')
but I am not sure on how to go about finding elements with multiple tags.
Thank you :)

As #Stack said in the comments, you should use find_element_by_xpath. If you are unsure as to how to write an xpath, Chrome has a handy option to show the XPath of a selected element. If you open the Developer Tools (Ctrl + Shift + I) and locate the element in the source, you can right click, Copy, Copy XPath.
This is just a quick fix. You should consider learning how XPath works.

Quick Solution:
Use browser.find_element_by_xpath("//input[#value='gram-']").
Explanation:
// - select element anywhere in the document starting from the current node (the root of the document).
//input - select all input elements anywhere in the document.
[#value='gram-'] - select element where value ist set to gram-.
//input[#value='gram-'] - select every input element anywhere in the document with value="gram-".
XPath Tutorials:
XPath Tutorial on W3Schools
XPath Syntax Overview

By css selector:
#orgtype[value='gram-']
Or by xPath
//input[#value= 'gram-']
To find by text containingGram-negative:
//text()[contains(.,'Gram-negative')]/preceding-sibling::input[1]

Related

selenium exact match based on text

If I have some HTML:
<span class="select2-selection__rendered" id="select2-plotResults-container" role="textbox" aria-readonly="true" title="50">50</span>
And I want to find it using something like:
driver.find_element_by_xpath('//*[contains(text(), "50")]')
The problem is that there is 500 somewhere before on the webpage and it's picking up on that, is there way to search for a perfect match to 50?
Instead of contains, search for a specific text value:
driver.find_element_by_xpath('//*[text()="50"]')
And if you know it will be a span element, you can be a little more specific:
driver.find_element_by_xpath('//span[text()="50"]')
Note that your question asks how to find an element by its text value. If possible and would apply to your situation, you should look for a specific class or id, if known and consistent.
You can search for it by its absolute Xpath. For that, inspect the page and find the element. Then right-click it and copy its Xpath or full Xpath.
Otherwise you can use the id:
driver.find_element_by_id("select2-plotResults-container")
Here is more on locating elements.
use something like this
msg_box=driver.find_element_by_class_name('_3u328') and driver.find_element_by_xpath('//div[#data-tab = "{}"]'.format('1'))

how to resolve changes in Element's id in html?

After deployement id of elements are changed. So that can not select those element by id in selenium using python.
Suppose I want to find the below element in HTML.
<input class="o_form_input c_field-65 o_form_field o_form_required" id="o_field_input_22" type="text">
I can not use the element's class because there will be elements with the same class.
I would like to find element without using Xpath because if new fields are added in the development side then Xpath will be changed.
In that case you should not be locating your element by id (since it not steady).
For example you can use Xpath (other locators may also work):
login_form = driver.find_element_by_xpath("//form[#id='loginForm']")
or
username = driver.find_element_by_xpath("//form[#id='loginForm']/input[1]")
Now the only thing that you can't copy from this, is the xpath it self. That is specific to your website/html/DOM.
An easy way of getting a correct xpath is by inspecting elements using f12 and then right click on the element, go to copy and select [copy xpath]. You can than paste it into your code.
Let me know it this was helpfull!

Xpath clicking not working at all

Quick info: I'm using Mac OS, Python 3.
I have like 800 links that need to be clicked on a page (and many more pages to go so need automation).
They were hidden because you only see those links when you hover over.
I fixed that by injecting CSS rule (just saying in case its the reason it's not working).
When I try to find elements by xpath it does not want to click the links afterwards and it also doesn't find all of them always just 4 (even when more are displayed in view).
HTML:
Display
When i click ok copy xpath in inspect it gives me:
//*[#id="tiles"]/li[3]/div[2]/ul/li[2]/a
But it doesn't work when I use it like this:
driver.find_elements_by_xpath('//*[#id="tiles"]/li[3]/div[2]/ul/li[2]/a')
So two questions:
How do I get them all?
How do I get it to click on each of them?
The pattern in the XPath is the same, with the /li[3] being the only number that changes, for this I created a for loop to create them all based on the count on page which I did successfully.
So if it can be done with the XPaths generated by myself that are corresponding to when I copy XPath in inspector then I only need question 2 answered.
PS.: this is HTML of parent of that first HTML:
<li onclick="openPopup(event, 'collect', {item_id: 165214})" class="collect" data-item-id="165214">Display</li>
This XPath,
//a[.="Display"]
will select all a links with anchor text equal to "Display".
As per your question, the HTML you have shared and your code attempts there is no necessity to get the <li> tags. Instead we will get the <a> tags in a list. So to answer your first question How do I get them all you can use the following line of code :
all_Display = driver.find_elements_by_xpath("//*[#id='tiles']//li/div[2]/ul/li[#class='collect']/a[#title='Display']")
Next to click on each of them you have to create a loop to iterate through all the <a> tag as follows :
all_Display = driver.find_elements_by_xpath("//*[#id='tiles']//li/div[2]/ul/li[#class='collect']/a[#title='Display']")
for each_Display in all_Display :
each_Display.click()
Using an XPath with elements by position is not ideal. Instead use a CSS selector to match the attributes for the targeted elements.
Something like:
all_Display = driver.find_elements_by_css_selector("#tiles li[onclick][data-item-id] a[title]")
You can then click them in a loop if none of them is loading a new page:
for element in all_Display:
element.click()

Python - Salesforce: How to find an object with no definitive class name and verify the text?

So, currently I'm using Python 3 and the selenium webdriver with Salesforce to automate admin verifications.
I've been pretty successful (even though I'm not that proficient with programming). However, I've run into an issue... I can't seem to figure out how to find an element on the page so that I can verify the text contained within is accurately being displayed.
This is what it looks like on the user's end:
The highlighted element displays as this
But whenever I search for "GlobalHeaderCommunitySwitcher", it spits back an error that it can't find it.
So I try searching for the other elements in the block of code:
<b class="zen-selectArrow"></b>PVT GBI Internal
<b class="zen-selectArrow"></b>
"PVT GBI Internal"
I've come up empty each time by searching by:
browser.find_element_by_id("globalHeaderCommunitySwitcher")
browser.find_element_by_class_name & used "zen-trigger" and "zen-selectArrow"
browser.find_element_by_xpath("//div[#class='zen-trigger'and text()='PVT GBI Internal']")
This also results in nothing being returned..
Essentially, how do I locate the element in the screenshot via the above code and then have the script verify that the text within that element ("PVT GBI INTERNAL") is present and correct?
you can use //tag[text()="value"] or //tag[contains(attribute,‘value’)]
example : browser.find_element_by_xpath("//a[#class='zen-trigger']//*[‌​text()='PVT GBI Internal']")
//a[#class='zen-trigger']//*[contains(text(),'PVT GBI Internal')]
//a[#class='zen-trigger']//*[contains(#class="zen-selectArrow")and
contains(text(),'PVT GBI Internal')]
Open the page using the google chrome browser
Move the mouse over the element that you want to find and right-click it
Left click Inspect (at the bottom of the selection list)
Your element will be hi-lighted in the Developers tools
Right click the hi-lighted element and select Copy
Click either copy Selector or XPath depending on your preference
Paste that into your selenium find_element_by_xpath() or find_element_by_css_selector() statement as appropriate.
Say xpath
element = browser.find_element_by_xpath("your pasted xpath")
assert element.text == 'Your expected text'

Python - Issues with selenium button click using XPath

I'm using the following code to click a button on a page but the XPath keeps changing so the code keeps breaking:
mydriver.find_element_by_xpath("html/body/div[2]/div[3]/div[1]/div/div[2]/div[2]/div[4]/div/form[2]/span/span/input").click()
Is there a better way I should be doing this? Here is the code for the button I am trying to click:
<input class="a-button-input" type="submit" title="Button 2" name="submit.button2-click.x" value="Button 2 Click"/>
XPath is really intelligent. You could do a much more simple search for that:
mydriver.find_element_by_xpath("//input[#name='submit.button2-click.x']")
which tells: search all input elements whose name equals to 'submit.button2-click.x' which will be the element of your choice.
Don't forget to try Firefix XPath Checker add-on before going to code.
I'd use findelement(by.name(" submit.button2-click.x")).click() or use find element(by.cssSelector("selector ")).click()

Categories

Resources