how can i handle dynamically changing ids on my webpage using selenium? - selenium

Here is my code
<mat-error class="mat-error" role="alert" id="mat-error-0"> </mat-error>
<mat-error class="mat-error" role="alert" id="mat-error-1"> </mat-error>
Here mat-error-0 will change to mat-error-1 on page refresh and mat-error-1 will change to mat-error-2 and so on..
There is no unique class or role attribute here that i can take here.
Please advise.

Use the following xpath
//mat-error[text()='Please enter a valid To date']
//mat-error[text()='Please enter a valid From date']

As long as innerHTML stays consistent after refreshing the page, you can use Xpath to find the element. e.g. the following Xpath can locate To date webElement.
//mat-error[contains(.,'valid To date')]

Use Following Xpath for dynamically changing id.
//mat-error[starts-with(#id,'mat-error')]

As per the HTML you have shared, as the id keeps changing so you have to construct dynamic xpath to identify both the elements as follows :
Element with text as Please enter a valid To date :
//mat-error[#class='mat-error' and starts-with(#id,'mat-error') and contains(.,'To')]
Element with text as Please enter a valid From date :
//mat-error[#class='mat-error' and starts-with(#id,'mat-error') and contains(.,'From')]

Related

Can't find unique xpath for clickable element

I'm trying to get an xpath so I can click a link as per href below:
<div id="viewIFL" style="">
<div class="moneycentrallink">
Track your cash in one place with
Money Central
</div>
</div>
When I use the below in ChroPath:
//a[contains(text(),'Money Central')]
It returns 2 elements matching for xpath="1" and xpath="2".
I then tried:
//a[contains(text(),'Money Central') and #xpath='2']
and at first it resolved to just 1 element found but when I tried searching again it returned 0 elements found. Also this does not work via Selenium either (returns unable to find element).
Any ideas what's going on and how I can find the unique xpath to clickable element? Thanks
Don't use xpath attribute in your xpath as ChroPath adds the xpath attribute in element to tell the user what is matching occurrence of that element. For example- If ChroPath added xpath=5 i.e. this element is the 5th for the corresponding xpath.
For your scenario, please inspect the element and see what ChroPath gives the relative xpath.
Also you can try //div[contains(text(),'Track your cash')]//a[contains(text(),'Money Central')]
Your problem is badly formulated.
There is always a unique path to an element of the form *[1]/*[4]/*[1]/*[2]. The problem is that this path isn't very useful because it only works if you know exactly what is in the document, and if you knew exactly what was in the document, you wouldn't need XPath to find it.
So you're actually looking for an XPath that will work on a set of possible documents in which some parts are known (fixed) and others are unknown (variable). To find an XPath that works on every document in that set, you need to define what is known and what is unknown. Looking at one sample document isn't going to tell you that.

Xpath finder for selenium using python -automation

I am trying to find an unique xpath for the below element, please advice if there are any better xpaths to make it for general text as I have currently given for that specific name.
<td tabindex="4" style="text-align: left;" title="name" class="">Name</td>
xpath i am using: //td[#title='name']
here if the name is changed with something else in the code, this wouldn't work, could someone help me identify unique xpath which works in general for any text. Thanks!
You can concatenate (using and / or) multiple attributes of element to find the element precisely .
By.xpath("//td[#title= 'name' and contains(text(), 'Name')]")
However we need to see more details of the code and your DOM of page to find element.
There will always be some element which will never change in the page(like name of table) using that as a relative point ,we can refer to the row of the table.
the simplest way to find the XPath of any element is to go to the developer options and select the markup of the element you want XPath of.
Right Click -> Copy -> XPath
I believe this is the simplest way. And you will also where you are doing wrong.
Screenshot attached for your reference.
I have used the general syntax - "//td[text()='{}']" and passing the name parameter when i define a method so that it won't be specific to one and others can test using the same locator with their name changed when someone else uses the testcase.
Thanks everyone for your response!

Unable to locate an element using text attribute in XPath

I am trying to locate element using relative XPath. I have attached HTML schema of the element. Below is the XPath I am using:
//a[contains(text(),"Sales")].
If you want to locate link by text you might need to use search by link text instead of XPath:
Java:
driver.findElement(By.linkText("Sales")).click();
Python:
driver.find_element_by_link_text("Sales").click()
Note that you should use exact value as it appears on rendered page in browser:
if it appears as SALES:
driver.find_element_by_link_text("SALES")
if it appears as "Sales":
driver.find_element_by_link_text("\"Sales\"")
In case some extra text is added by ::before pseudo-element, you can also use search by partial link text:
driver.find_element_by_partial_link_text("Sales")
//*[#class='**your class name**']//*[text()='Sales']
Hope above XPath helps you!

How to get value from an attribute in selenium RC in java?

I have this code for xpath and html:
<a class="WatchButton inicon" rel="nofollow" data-productid="111124">
xpath=/html/body/div[2]/div[2]/div/div[2]/div[1]/div[1]/div[2]/div[8]/a
How can I get the data-productid value?
Just add #data-productid to the xpath expression:
/html/body/div[2]/div[2]/div/div[2]/div[1]/div[1]/div[2]/div[8]/a/#data-productid
Note that the xpath expression you have is very fragile since it depends on a bunch of elements and their relevant positions. Try to rely on the element's attributes or one of it's containers - look for id and class attributes. For example:
//a[contains(#class, "WatchButton")]/#data-productid
This gets the first link anywhere on a page that contains WatchButton class and retrieves it's data-productid attribute value.
* Sharing the link to the web page or showing the complete HTML could help to provide you with a more reliable xpath expression.

how to click on element using WebDriver

i need to click on dat element:
<span id="act_action9" class="" onclick="openDialog('export', event)">
text
</span>
i cant click on id,because it is dynamic. After a click i am getting window with some settings.
You should use xpath in order to click this element, so you could add an expression that unequivocally identify this element.
Could you please include more HTML code, because just with the code included is not enough to create a xpath expression.
I recommend this tutorial to start doing good xpath expressions:
http://www.w3schools.com/xpath/
See example for dynamic xpath
By.xpath("//span[#id [contains(.,'act_action')]]")
Great xpath cheatsheets: http://extract-web-data.com/5-best-xpath-cheat-sheets-and-quick-references/
You can also use xpath like following(assuming only digit is dynamic):
".//span[contains(#id, 'act_action')]"
As ID is dynamic, you can use xpath for text which is inside span.
driver.findElement(By.xpath("//span[text()='text']").click();
Or if part of ID remain common, then you can use
//span[contains(#id,'act')]