I'm having some trouble finding an element in a table. The Site is finance.yahoo.com/q/ks?s=GOOG
I'm trying to find that element named "Market Cap (Intraday)" It does have an ID, but I need the other elements in the table as well and they do not. I've traced the xPath I think to this
//table[#id='yfncsumtab']/tbody/tr[2]/td[1]/table[2]/tbody/tr/td/table/tbody/td[1]/td[2]/span
However, it's not spitting out the amount. I'm getting the no_such_element exception (It's not finding it)
Is my xPath correct? Or is there a more streamlined way to find the element?
I can't technically go by class names because they can change with the Stock
You got a typo. The correct xpath is:
//table[#id='yfncsumtab']/tbody/tr[2]/td[1]/table[2]/tbody/tr/td/table/tbody/tr[1]/td[2]/span
Your last part had a td that should have been a tr.
An easy way to debug this is using Chrome developer tools, see Is there a way to get the xpath in google chrome?
Instead of writing such a lengthy xpath, you can write simple xpath as following:
//td[text()='Market Cap (intraday)']
which looks for td for which text is Market Cap (intraday). Similarly, you can do for other cells from the table.
Related
I am testing a web app using selenium and java. I've always avoided xpath like it was a disease. Unfortunately, I got stuck on a stubborn web element buried deep inside a table unfortunately with no id or class. I tried everything and even invited my great great grand parents but nay...nothing worked, except xpath...see below.
I tried: className, name, cssSelector e.t.c. with e.g.
driver.findElement(By.className("kujes")).click();
This is what worked.
driver.findElement(By.xpath("/html/body/div[7]/div[3]/div/div[2]/div[1]/div[2]/div/div/div/div/div[2]/div/div[1]/div/div/div[6]/div/div[2]/div[2]/div/table/tbody/tr[1]/td[3]")).click();
I do not want anything less than professional in my work.
So, my questions are is xpath reliable and a good practice?
Is it professional to use xpath?
driver.findElement(By.xpath("/html/body/div[7]/div[3]/div/div[2]/div[1]/div[2]/div/div/div/div/div[2]/div/div[1]/div/div/div[6]/div/div[2]/div[2]/div/table/tbody/tr[1]/td[3]")).click();
The above approach is very very bad practice.
Never use indexes in your xpath. It becomes very fragile and will break every single time even when there is a small change in the target application. Try to ask the developers to add ID to that object.
It depends on the cases. Ultimate goal is to find selector which is unique and never changing until big change happens.
First you can try with id or class name which are unique.
Then we can play with css selector to find,
Element with attribute, classname , id and combination.
Element which is child of another element,
Element which is next sibling of another element.
You are using absolute xpath, which is unreadable and changing one. Using absolute xpath is completely unprofessional.
driver.findElement(By.xpath("/html/body/div[7]/div[3]/div/div[2]/div[1]/div[2]/div/div/div/div/div[2]/div/div[1]/div/div/div[6]/div/div[2]/div[2]/div/table/tbody/tr[1]/td[3]")).click()
You can use relative xpath
driver.findElement(By.xpath("//table[#id='somevalue']//td[text() = 'Name']]/preceding-sibling::td")).click()
There are few cases which are possible only with XPath in selenium
Finding parent element of an element
Finding preceding sibling of an element
Finding an element with innerText
Finding nth element of the locator
The above cases are not possible with css selector and xpath is the only straight forward way to find those element.You can also achieve these indirectly with jquery selector and javascript executor.
I have one issue which I can't resolve...
I'm trying to write automated tests with Appium...
We don't have unique elements in our application except Text.
As example we have some element which i want to click. This element has not uniquely id "elements" (many of others elements on this page have the same id) but this element has as unique text "Track"...
As I know one chance for me it's find this element by Xpath but unfortunately I can't do this and when I run my tests i get one by one exceptions...(
My xpath is:
//*[#id='elements' and contains(text(),'Track']
What I should change in my xpath? how to build it correctly?
Thx in advance.
Seems like you have a few mistakes in your XPath, This should work:
//*[#resource-id='elements' and contains(#text,'Track')]
before you go any further with your automation project, visit this site:
http://www.software-testing-tutorials-automation.com/2015/10/ui-automator-viewer-get-android-app.html
driver.findElement(By.xpath("//*[#id='elements' and contains(text(),'Track')]")).clear();
I am currently working on the Robot Framework and using Selenium2Libraries to work on a Web Application. I'm working on a Form and I'm dealing with a dynamic elements which is an editable text area and drop down list..
I really hope someone would be able to guide me on how I can do this. An example of what I am doing is,
[Example element code]
input id="textfield-1237-inputEl" class="x-form-field x-form-text x-form-text-default x-form-focus x-field-form-focus x-field-default-form-focus"
data-ref="inputEl" size="1" name="textfield-1237-inputEl"
maxlength="200" role="textbox" aria-hidden="false" aria-disabled="false"
aria-readonly="false" aria-invalid="false" aria-required="false" autocomplete="off" data-componentid="textfield-1237" type="text"
Any information on this would be much appreciated. Thanks!
There are many types of Identifiers are available.you can search,If the values are dynamic you can use Xpath Identifier to find the locator.Id can be used only for the static values.
In the above case you can use Xpath as
xpath=.//*[contains(type(),'text')]
because text is static.It wont be change.
When trying to handle dynamic IDs, and elements which dont have easy UIDs about them, the best way to go around this is using Xpath.
Xpaths are basically the location of the element within the HTML. This is kind of the best way to get around the problem of not having ID readily available (My work has no IDs anywhere I can use, thus I have no choice but to use Xpaths)
Xpaths are really powerful, if used correctly. If not they are really brittle and can be a nightmare to maintain. Ill give you an example of potential Xpaths you may have to use:
Select From List By Label xpath=(//select)[2] DropDownItem1
You said that you have a drop down. Here is a potenital "look-a-like" you would see. The Xpath here is basically saying, find the 2nd drop down you find, anywhere on the entire HTML page.
Xpaths will take a while to get your head round, esspecially if you have had the luxurary of using IDs. The tools I use in order to locate and debug Xpaths are:
FireBug
Selenium IDE
I mainly use Selenium IDE now, as it is a nice tool which basically lets you "Select" an element within the HTML and it will spurt out its ID, CSS Path, Xpath, DOM, etc... Not only that, when you come to discover more complex Xpaths, there is a "Find" tools which shows you visually, where your Xpath is pointing to (or isnt, if its wrong)
Something which really helped me was This. It is really usful and has a lot of examples for you to work against.
If you have any problems, just reply and ill try to help
More Examples:
Click Element //span[contains(text(), 'Submit')]
Input Text xpath=(//textarea)[3] Some Random Text!
As with the other answers, I propose that you use Xpath.
Using Xpath can point you to the element by identifying the relationship of that element with the other elements around it. So my suggestion is to find a static element that you could use as your starting point.
For example:
starting point has static id:
xpath=//td[#id='startingPoint']/following-sibling::select[1]
starting point has no id but has static text (usually the label of the field):
xpath=//td[contains(text(),'Field Label')]/following-sibling::select[1]
If you could give us an idea of what the element is..we could provide you better examples..
What I did was alter the Xpath for example:
//*[#id="cec9efb093e14182b361766c26fd1919"]/section/div[1]/ticket/div/div/input
And took out the Id what was being generated dynamically cec9efb093e14182b361766c26fd1919 to switch for an autoId I set to the parent element where the Id was being generated. It's a cheap fix but it works if only one of the parent element is being generated.
So the parent element has the attribute autoid=container added to it and I referenced it as [#autoid="container"]/section/div[1]/ticket/div/div/input in the robot code
I have one doubt. Whenever I copy xpath from Firebug and try to use it in my selenium script, the functionality does not work. Or I get this error that unable to locate the element. But, certainly when I try to write expression and execute the same code snippet, it works fine. Why is it so, is there some problem with Firebug which is one of the popular tool.
suggestions welcomed.
There could be multiple reasons for the firebug generated XPath not to work in selenium.
Most common are two:
an element you are trying to find is not yet present in the DOM - this could happen when the page is not completely loaded, or is loaded asynchronously
there are iframe elements on a page. If you need to find and element inside an iframe, you need to switch to it first
Also, don't blindly trust the XPath generated by Firebug - most of the time it would not be the most reliable expression. If possible, operate id and class attributes and don't start your XPath expression from the root HTML element - make it relative (using //).
The issue here is not with the Xpath you are using,
First check where your element is located,
The reason here is your element is not visible to the driver,
The question here is why the element is not visible,
Work on this,
And Do provide the html code in your question so that it will be more helpful to resolve the issue quickly,
so I am using HTML Unit to click an item on a webpage. I usually use Xpath to select my items, but this page gives every element a randomly generated ID and class. I usually use Google Chrome to get the Xpath of elements, but it gives me something like this: //*[#id=":og"] where :og is the randomly generated ID. I know that sometimes chrome gives me Xpath without any ID's or Classes, like this: /html/body/table/tbody/tr[2]/td/table/tbody/tr[3]/td/form/table[2]/tbody/tr/td/input[2] Is it possable to get an Xpath that does not rely on IDs or Classes in a case like this?
Thanks.
In order to construct shorter xpaths or alternative ones based on tags only you can use plugins that will let you do just that. Particularly I favor the Selenium IDE in firefox, but in Chrome you can use things like Xpath Helper. There are others you can explore by searching the chrome web store.