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

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!

Related

How do I select pseudo-elements in python with Selenium?

These two elements have the exact same attributes except for the text in the pseudo-element. Is there anyway I can click on the "Practical" element. I've tried the following to no avail:
driver.find_element(By.XPATH, "//div[contains(text(),'Practical')]").click()
driver.find_element(By.XPATH, "//div[#class='v-tab']")[1].click()
Pseudo elements are not elements. So, that ::before seems to be just a kind of text content of div element.
I can't give you tested answer since you didn't share a link to the page you are working on, but I can suggest.
I'd try this:
driver.find_element(By.XPATH, "//div[#class='v-tab'][contains(.,'Practical')]")].click()
In case v-tab class name and Practical text content are unique enough it should work. Otherwise you will need to find nore unique locator.

Element not found when using webdriver with Selenium in Python

got a problem with my code and I need your help. What I'm trying to do is the following:
1- access a website;
2- fill the registration form: name, email, password, etc.
Step 1 works; after clicking the sign up button, the form will pop up in a new tab.
Step 2; when trying to find the elements, by, id or name, I get the error "selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element"
My code is the following:
driver.find_element_by_link_text('Sign Up').click()
time.sleep(3)
driver.find_element_by_id("signup_title").send_keys(signup_tile)
driver.find_element_by_id("signup_name").send_keys(signup_name)
Attached you can find the html. Thank you in advance, much appreciated your help.
Note
In console I tried to find the element searching the id using
$x("//*[#id='signup_title']") and it was found: [input#signup_title.sc-AxirZ.kzqQJb.invalid]. Also the element is loaded.
HTML
Try using:
driver.find_element_by_xpath("<XPath>")
It seems to work better. To get the XPath of an element, find the element in the inspector, right-click it then Copy -> Copy XPath. If that doesn't work, select Copy Full XPath instead
The problem was related to the second tab; because the form opens in another tab, the window must be switched in the code.
I used the following:
driver.switch_to.window(driver.window_handles['Nr']), Nr being the index for the tab- if there are 2, the main one, and the second one-in my case with the form, the index will pe 1-counting starts from zero.

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'))

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()

find submit button in selenium without id

I have a button
<input type="submit" class="button button_main" style="margin-left: 1.5rem;" value="something">
I cannot find it by id or name and need to submit a form.
I tried doing this:
Alternatively, WebDriver has the convenience method “submit” on every element. If you call this on an element within a form, WebDriver will walk up the DOM until it finds the enclosing form and then calls submit on that. If the element isn’t in a form, then the NoSuchElementException will be raised:
element.submit()
http://selenium-python.readthedocs.org/navigating.html
But that cannot find the submit selector either.
ideas?
There are many options here, to name a few:
If class alone is unique, you can use
driver.find_element_by_css_selector(".button_main").click()
If class + value combo is unique, you can use:
driver.find_element_by_css_selector(".button_main[value='something']").click()
You can also use xpath:
driver.find_element_by_xpath("//input[#type='submit' and #value='something']").click()
If none of those work (i.e. they are not identifying button uniquely), look at the elements above the button (for example <form) and provide the xpath in format:
driver.find_element_by_xpath("//unique_parent//input[#type="submit" and #value='something']").click()
i recommend xpath chrome extension, with it you will be able to get the path by running the extension and shift-clicking on the element you want this chrome extension https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl
You could try to find the element with an XPath expression or a CSS selector like input[type="button"], and then just click the element.

Categories

Resources