Handle elements that have changing ids all the time through Selenium Webdriver - selenium

I am running the script to automate test cases and having this unique problem.
I have detected and used IDs of the elements for click etc. purpose. However, all of a sudden these ids have changed and the script works no more.
Another weird thing is those IDs are same as in script when inspected in Chrome but different in Firefox driver browser.
Firebug for test driver: -
<p class="description" onclick="selectElementTextListForIE(this,'tile29', 'tile19');selectElementTextList(this,'tile29', '')" id="tile29_span_0_0">
Platinum
</p>
Chrome inspector for same element: -
<p class="description" onclick="selectElementTextListForIE(this,'tile20', 'tile19');selectElementTextList(this,'tile20', '')" id="tile20_span_0_0">
Platinum
</p>
Also, what could be the best strategy for detecting such elements whose IDs are generated on run.
I even tried using XPATH but that too contains id's reference
eg. #id="tile276_input
Any help will be appreciated.
Thanks.
Abhishek

You can utilize CSS for this. For your element, looks like its:
<* id="tile276_input" />
What you need to do is find out what is changing about it. I assume it's the number inbetween. If it is, then your selector would look something like:
By.cssSelector("*[id^='tile'][id$='input']")
This will look for anything that has an ID that "starts with tile" and "ends with input. In our case, "tile276_input" matches that.
See this article if you want more information

You also can try contains and starts-with() for such things
driver.findElement(By.xpath("//*[contains(#id,'title')]"))
or
driver.findElement(By.xpath("//* [start-with(#id,'title')]"))

WebElement element = driver.getElement(By.cssSelector("[id^='title']);
Or
WebElement element = driver.getElement(By.cssSelector("id:contains('title')"));
You Can use this element to do desired actions.

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!

selenium webdriver find element in region

Working with automated testing, I have come across the following issue quite a lot of time: I want to find an element on the page, but the element has to be at a specific region of the page.
Take the following as an example:
I have a searchfield with type-ahead on the site. In my sidebar, I have the element I am seraching for (lets call it "Selenium"), but that is not the element I am interested in, I want to see if my type-ahead search is delivering the expected result when searching for "Selenium".
<body>
<header>
<searchfield>
<searchresults>
<a .... >Selenium</a>
<searchresults>
</searchfield>
</header>
<aside>
...
<a .... >Selenium</a>
...
</aside>
</body>
If I in selenium webdriver search for the linktext "Selenium" it will find both entries, the one in the sidebar aswell as the one in the searchfield.
Furthermore am I not able to wait for the searchresult with the WaitForVisible command on the linkText as Selenium will find the element in the sidebar and conclude that the element is preset.
So my question is:
"With selenium webdriver, how do I search for an element within a specific region?"
Poking around with this issue, I came across the use of Xpath. With this I could create "areas" where I want to search for an element. As an example, I went from
html/body/div/aside/div[2]/ul/li
to
//div[contains(#class,'coworkerwidget')]/ul/li
Now the code is MUCH more dynamic, and less prone to errors if our frontend guys edit something in the future.
Regarding the search, I could now set up something like the following code
//div[contains(#class, 'searchfield')]//div[contains(#title, 'searchfield') and contains(., '" + searchword + "')]"
First we specify that we want to look in the searchfield area:
//div[contains(#class, 'searchfield')]
I can then set some more criteria for the result I want to find:
//div[contains(#class, 'title') and contains(., '" + searchword + "')]
Some litterature on the subjects for further reading.
http://www.qaautomation.net/?p=388
http://www.w3schools.com/xsl/xpath_syntax.asp
Click a button with XPath containing partial id and title in Selenium IDE
Retrieve an xpath text contains using text()

locating html elements with selenese in a test

while writing some acceptance tests for my webapp (playframework based),I got confused by the usage of some selenium commands.
In my html page,I have a submit button like this
<input type="submit" id="removecartitem" value="remove"/>
to locate this,I used
assertElementPresent(id='removecartitem')
however,this fails,
assertElementPresent id='removecartitem' false
The selenium documentation says
id=id: Select the element with the specified #id attribute.
but,if i simply put
assertElementPresent('removecartitem')
Then,the test is executed correctly.This is the source for confusion, since the default way is to select the element whose name attribute is 'removecartitem' ,and I haven't mentioned any name attribute in my html
Any idea why this happens?
It looks like you need to remove the single quotes according to the documentation you provided...e.g:
assertElementPresent(id=removecartitem)

CSS locator for corresponding xpath for selenium

The some part of the html of the webpage which I'm testing looks like this
<div id="twoWideCallouts">
<div class="callout">
<a target="_blank" href="http://facebook.com">Facebook</a>
</div>
<div class="callout last">
<a target="_blank" href="http://youtube.com">Youtube</a>
</div>
I've to check using selenium that when I click on text, the URL opened is the same that is given in href and not error page.
Using Xpath I've written the following command
//i is iterator
selenium.getAttribute("//div[contains(#class, 'callout')]["+i+"]/a/#href")
However, this is very slow and for some of the links doesn't work. By reading many answers and comments on this site I've come to know that CSS loactors are faster and cleaner to maintain so I wrote it again as
css = div:contains(callout)
Firstly, I'm not able to reach to the anchor tag.
Secondly, This page can have any number of div where id = callout. Using xpathcount i can get the count of this, and I'll be iterating on that count and performing the href check. How can something similar be done using CSS locator?
Any help would be appreciated.
EDIT
I can click on the link using the locator css=div.callout a, but when I try to read the href value using String str = "css=div.callout a[href]";
selenium.getAttribute(str);. I get the Error - element not found. Console description is given below.
19:12:33.968 INFO - Command request: getAttribute[css=div.callout a[href], ] on session
19:12:33.993 INFO - Got result: ERROR: Element css=div.callout a[href not found on session
I tried to get the href attribute using xpath like this
"xpath=(//div[contains(#class, 'callout')])["+1+"]/a/#href" and it worked fine.
Please tell me what should be the corresponding CSS locator for this.
It should be -
css = div:contains(callout)
Did you notice ":" instead of "." you used?
For CSSCount this might help -
http://www.eviltester.com/index.php/2010/03/13/a-simple-getcsscount-helper-method-for-use-with-selenium-rc/
#
On a different note, did you see proposal of new selenium site on area 51 - http://area51.stackexchange.com/proposals/4693/selenium.
#
To read the sttribute I used css=div.callout a#href and it worked. The problem was with use of square brackets around attribute name.
For the first part of your question, anchor your identifier on the hyperlink:
css=a[href=http://youtube.com]
For achieving a count of elements in the DOM, based on CSS selectors, here's an excellent article.