How to handle dynamic id from xpath - selenium

I am trying to explore IDE with this site http://www.barnesandnoble.com/, by just recording and play back.
1.In the search box just enter any text to search,
2.Ten click on All Products, select Books.
When i record its xpath is as below
/html/body[#id='CDS']/div[#id='navContainer']/div[#id='bnnav2011']/div[#id='yui_3_3_0_1_1355746621091_93']/div[#id='bn-global-header']/div[#id='yui_3_3_0_1_1355746621091_92']/div[#id='yui_3_3_0_1_1355746621091_91']/form[#id='qs']/div[#id='yui_3_3_0_1_1355746621091_90']/div[#id='yui_3_3_0_1_1355746621091_89']/ul[#id='yui_3_3_0_1_1355746621091_88']/li[#id='yui_3_3_0_1_1355746621091_99']
But when we play ti again it gives error,[error] locator not found:
Wehn i search for its xpath , its chnaged and is as below
/html/body[#id='CDS']/div[#id='navContainer']/div[#id='bnnav2011']/div[#id='yui_3_3_0_1_1355748592221_91']/div[#id='bn-global-header']/div[#id='yui_3_3_0_1_1355748592221_97']/div[#id='yui_3_3_0_1_1355748592221_96']/form[#id='qs']/div[#id='yui_3_3_0_1_1355748592221_95']/div[#id='yui_3_3_0_1_1355748592221_94']/ul[#id='yui_3_3_0_1_1355748592221_93']/li[#id='yui_3_3_0_1_1355748592221_98']
Observe that, its ID's are changing.
Can any one tell me how to handle this ?

The IDE is not very smart at generating XPath queries, in fact, there isn't an automated tool out there that will calculate a reliable XPath query. Why? The reason is because to generate the XPath query, it will walk down the tree from the top (at the html element), down to the element you are interacting with.
Whilst this is fine for a lot of things, if you have elements that have dynamic values (dynamic text/ID/name/classes or even if it changes position), it's never going to work.
You'll need to look at a different way to get it, so you'll have to override what the IDE is giving you.
Looking at the source, they give whatever is selected a class value of ui-selectmenu-selected. So when the page loads, the 'All Products' list item (li) will have that class, when you change the item the new item will have that class.
So you could use this XPath:
//li[#class='ui-selectmenu-selected']
Or, this CSS selector:
li.ui-selectmenu-selected
Or, use this XPath to get the 'All Products' item specifically. It will start one level up, using the actual menu, then go down and find the item:
//ul[#class='ui-selectmenu']/li[text()='All Products' and not(#class='ui-selectmenu-hidden')]

You can try using xpath: Position. It seems that the IDs are changing all the time.

As an answer to your question you should move away from id's and try using xpath or css selectors where you can select the nth child of the parent.
Since you are new to selenium I would like to point to my notes here at.-
http://selenium-testing-notes.blogspot.in/
it will help you through a lot of other pitfalls I fell in.
The best way I found to help with selectors is to work with firebug with firepath installed. This setup can help you verifying your xpath and css selectors.

I saw your question based on that answer is first you need to add on fire-path in Firefox .Using firepath you can find the xpath locator. it is very simple to you
Example:
driver.find_element_by_xpath("see![image which i have attached in this question][1] the xpath path locator details").click()

Hi Arran i am able to click the All Products button using the xpath you have given ( xpath= //ul[#class='ui-selectmenu']/li[text()='All Products' and not(#class='ui-selectmenu-hidden')]
and also get the list available. But then not able to click the Books item from the Menu.

Related

How to identify an element without using xpath when id name is not available in selenium

There are few elements in an UI page without ID. I will download a particular version and then save all the current element tags and give to script as input, since few elements are not having id, this is causing script failures.
How can I locate the element without using Xpath.
Is there any simple way when there is no fixed id.
The short answer is "no." Sorry. All of the usual ways (by id, class, etc.) are relying on the same css information to locate elements. Xpath just shows all the ugly plumbing out in public. I don't think xpath has ever been described as "simple" but there is usually a way, using xpath, to find any element.
Xpath can be intimidating. Start with a plugin that will generate the xpath for you, once you click on an element. Usually the xpath generated will be extremely long and inefficient, but with practice you can see what can be trimmed and what is crucial. And to do that, also use a plugin that will "check" your xpath to see if it can find the element. Once you can find it (and ONLY the element you want) try trimming it to see if you can still find it with the abbreviated xpath locator.
reference ImageDon't be afraid of Xpaths. It's relatively easy to grab an Xpath using the Google Chrome browser. Navigate to your page and open Developer tools. Right-click on the particular tag for which you need an Xpath. Copy -> Xpath

Locate Tweet 'like' button using xPath (Selenium, Python)

I am trying to locate a tweet like button using xPath.
If I go to https://twitter.com/BillGates and use Chrome developer tools, I can see:
That the like button for the first tweet is located at:
/html/body/div[2]/div/div/div[2]/main/div/div/div/div[1]/div/div[2]/div/div/div[2]/section/div/div/div[1]/div/div/div/div/article/div/div[2]/div[2]/div[2]/div[3]/div[3]/div/div/div[1]/svg/g/path
That the first tweet like button has:
< path d="M12 [lots of numbers]">
I tried to use both Python + Selenium and XPath Helper Chrome extension but with both approaches I cannot find the button.
I have tried without success using the full xPath and also the query below:
.find_element_by_xpath("//path[starts-with(#d, 'M')]").click()
Actually, I cannot get anything past the last div. //svg, //g and //path all get zero results. //div on the other hand, gets me 900+ results...
Appreciate if anyone can help to point me in the right direction.
Thanks!
I highly recommend not using Twitter to practice automation.
Anyways, i've seen that the likes buttons has data-testid attribute which it's value is unique to that element you are looking for, so we can easily get all the likes buttons elements like this:
//div[#data-testid="like"]
Or with css selector like this:
div[data-testid="like"]
Assuming you are writing in Python, Then we can use find_elements method to get all the elements in a list.
like_buttons = driver.find_elements_by_xpath("//div[#data-testid="like"]")
And easily click any tweet's like button you'd by index,
like_buttons[0].click() # 0 Is the first tweet, 1 is the 2nd etc...
Note that you might need to perform a hover on this element and then click it,
So if the driver find the element, but it's not clickable, it must be it.

writing xpath locator for a link element using xpath axes

I am trying to learn Selenium and am trying to write the xpath locator for the "About Us" link on the web page - www.hdfc.com
I can do it with link as:
link=About Us
I have tried the following and it works fine:
xpath=//a[text()='About Us']
but I wanted to write the locator using xpath axes so that its flexible enough. Can someone please point me in the right direction?
In the case you have put forward the best selector you could use is ID, this is because IDs (much like classnames etc) are not dependent on the structure of the document at all but more about the content or purpose of the element. in this case you would want something like:
driver.findElements(By.Id("ic-aboutUs");
Another thing you should be aware of in general is that xpath expressions are considered a worse way to identify your elements than the use of CSS selectors, especially if you are testing in IE as the xpath implementation there is not native and is very slow. I suggest reading over http://saucelabs.com/resources/selenium/css-selectors for a brief look at some examples and also maybe have aread of http://saucelabs.com/resources/selenium/selenium-xpath-marks-the-spot in order to see some of the negatives of using xpath.
Use the below xpaths to detect 'About Us'link in your web page
Below xpath was written by refering the immediate parent node
//li[#class='expanded']/child::span[text()='About Us']
This xpath was written by using the parent node of Menu bar(parent of whole menu items)
//ul[#class='menu hdfc-investor']/child::li[contains(.,'About Us')]

Finding clickon Element using Selenium. (JAVA)

I spend hours already trying to find the way to find the Element using Selenium WebDriver. I assume I need to use driver.findElement(By.xpath("")), but I am not quite sure how.
I somehow need to find and click on "clickon" element. The problem is that part of that element is changing (see screenshot) I need to pick up from the file and putted into the xpath.
I would appreciate any help.
We have been rigorously searching for automated functional testing solutions recently, and we began with Selenium. The entire reason we decided to search for other solutions was that our application also has dynamic IDs with no other obvious XPath mechanism to identify them. Selenium is unable to identify these elements on the page without some additional knowledge, just as you would be unable to identify these elements on the page if you didn't already know what they are.
If you are controlling the DOM creation, consider adding a unique ID or class to this element.
We recently came across eggPlant from testPlant, and it is an interesting approach to functional testing. It's essentially image based. Other viable solutions are Ranorex or HP's QTP or SmartBear's TestComplete.
You can use xpath. If the div class is constant, you can use something like:
driver.findElement(By.xpath("list-row field-item")).click();
To view the xpath, you can install firefox plugin called 'xpath checker' found here and right click on the dom element and click 'View Xpath' option to get the xpath of the element and then you can use that xpath in your code.
Or you can even use regex in the xpath which is suitable for the similar problems. Xpath with regex is really powerful.
It seems that you want to click the div that has the on click attribute that contains certain text that doesn't change, ignoring the part that does. In that case, use an xpath like this:
//div[contains(#onclick, '/challenge/index/rfp_id/')]
This will select the first div with an onclick attribute with a value containing /challenge/index/rfp_id.

Verifying text is present within certain element

When creating selenium tests using the #{selenium} tag, how do you use complex XPath locators? I've got some simpler examples that work but I'd really like to avoid having to give every element an id just to facilitate testing.
I've tried variations like these:
#{selenium 'Sitemap'}
...
// These work:
assertTitle('Site Map')
verifyTextPresent('Site Map')
verifyTextPresent('Login')
verifyText('id=test', 'Login')
verifyText('//ul', 'Login')
verifyText('//ul[2]', 'Login')
// this one results in "Element //ul[#class=sitemap] not found"
verifyText('Login','//ul[#class=sitemap]')
#{/selenium}
Has anyone gotten the more complex versions working? It looks like it should work according to the selenium docs. Also, is the creation of selenium tests in the context of Play documented anywhere? The only mention of it that I can find are these trivial examples.
I disagree to a degree. Badly constructed xpaths that search through the entire DOM will slow down tests but well constructed xpaths should have minimal effect on speed (unless you are using IE which has a horrific JavaScript rendering engine).
Ideally you want to key your xpath to an ID as close to the area of the DOM you want to search as possible, this will ensure you are only searching a specific area of the DOM rather than using an xpath like the one shown above that will search through the entire DOM even it it does find a matching element quickly.
I'll provide some examples of what I would call good xpaths using http://www.lazeryattack.com as an example. If you have anything specific in mind shout and I'll see what I can do to help:
The Voice Comms link: //ul[#id='leftMenu']/li/a[.='Voice Comms']
H3 element that contains a span element with the text "January VAT Increase": //div[#id='news']/h3[span[.='January VAT Increase']]
The first paragraph of text under the above element: //div[#id='news']/h3[span[.='January VAT Increase']]/following-sibling::p[1]
The second paragraph of text under the above element: //div[#id='news']/h3[span[.='January VAT Increase']]/following-sibling::p[2]
Start searching from the featuredNews div and drop down to the h2 element with the text "New Look And Feel": //div[#id='featuredNews']/descendant::h2[.='New Look And Feel']
I would suggect using FireFox with the FireBug and FirePath extensions to help you work out xpaths, this is my personal favourite combination.
Did you try
//ul[#class='sitemap']
Notice the single quote around sitemap.
XPath would make your tests slow and id, name are better option to use.