Selenium says invalid xpath locator - java

I am trying to get value of HREF attribute but always it says incorrect Xpath.
Html Code :
I am trying code :
WebElement Link = driver.findElement(By.xpath("//table[contains(#class,'display')]/thead/tbody/tr/td/a"));
System.out.println(Link.getAttribute("href"));
I tried many xpath but none of them worked.

This should work:
WebElement Link = driver.findElement(By.xpath("//table[contains(#class,'display')]/tbody/tr/td/a"));
Explanation: tbody is not nested in thead.
Note that a path expression like this can return a set of several nodes, in document order. The findElement method only returns the first result node. So: if the a element you are looking for is no longer the first one in this table, the path expression breaks.
If the the href is unique, something like this would be less error-prone:
WebElement Link = driver.findElement(By.xpath("//table[contains(#class,'display')]//a[#href='/admin/client/product_overrides/edit/242625']"));

Related

How to find xpath for first searched product

How to find XPath for the first searched element on given page
https://www.amazon.com/b/?encoding=UTF8&node=2346727011&bbn=7141123011&ref_=Oct_d_odnav_1040660&pd_rd_w=WJf7p&pf_rd_p=72459b27-e231-4837-b61c-b057ff0c50ac&pf_rd_r=YMKJ7M0AMXW5GER3MMRQ&pd_rd_r=eba15a0a-f59c-4dfd-a693-7c2f7f3416cf&pd_rd_wg=LRrkE
I tried the below XPath..on html page its showing the element but when putting on selenium code it's showing the error invalid selector: Unable to locate an element with the xpath expression
//div[#id='CardInstance1wPgwM8pHmoJmdnyjYOeWg']//child::div[2]//div[1]//div[1]//div[1]//div[2]//div[#class='a-section a-spacing-none a-spacing-top-small s-title-instructions-style']//span
Please help me to find xpath for first searched product.
Thanks in Advance.
You can directly use
//li[starts-with(#class,'octopus-pc-item')]
this does have 26 entries and is not unique in HTML, however, findElement will return the first matching node.
Furthermore, you can do indexing like below
(//li[starts-with(#class,'octopus-pc-item')])[1]
and [2] for the second product and so on... for other products
Perform click like below
Using ExplicitWaits
wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//li[starts-with(#class,'octopus-pc-item')]"))).click();
Using findElement
Thread.sleep(3000);
driver.findElement(By.xpath("(//li[starts-with(#class,'octopus-pc-item')])[1]")).click();

How to find the xpath of element of a web page that located by it's class name | Java selenuim

I have a table on a web page that its xpath differs from time to time but its class name doesn't. so I can handle it by its class name but my code needs the xpath of that element so how to get the xpath of that element?
OR how to deal with such elements that its xpath differs from time to time?
String xpath = "here sould be the xpath of that element";
wait_page_loading(By.xpath(table_xpath)); //this other function in my class wait the page loading
WebElement Webtable = driver.findElement(By.xpath(table_xpath));
List<WebElement> totalRowCount = Webtable.findElements(By.xpath(table_xpath + "/tbody/tr"));
if(totalRowCount.size() <= 1) {
throw new Exception("Can't find results in the problem page");
}
return totalRowCount.get(0).findElements(By.xpath("td")).get(6).getText();
Thanks a lot in advance.
I see a div and then we have a child table, please use the below xpath :
//div[#class='table-responsive']/table
Below xPath returns all the row values of the table.
//div[#class='table-responsive']/table/tbody/tr
how to deal with such elements that its xpath differs from time to
time?
If a xPath value partially dynamic I would suggest you to us contains method. For an example,
<input class = "User1235">
In above xPath the value 1235 is dynamic in this case you can create a xPath with contains
//input[contains(#class,'User')]

Unable to click on a "text" link in google search page

I am trying to click on News link on google search page the HTML structure looks like this
I tried following xpaths but none worked
//a/child::span[1][contains(.,'News')]
The following xpath resulted in invalid selector: The result of the xpath expression "//a/child::span/following-sibling::text()[contains(.,'News')]" is: [object Text]. It should be an element.
//a/child::span/following-sibling::text()[contains(.,'News')]
Thanks
//a[contains(.,'News')] might return this link, but may result in a list of more than one element that you'd need to handle and select the right element from.
You can use Selenium's SearchContext to specify a container element, or solve it using an xpath one-liner like: //div[#role='navigation']//a[contains(.,'News')] (Effectively searching for a link that contains 'News' somewhere in it's html-tree, somewhere inside a div that has a role attribute with value 'navigation').
You simply need
//a[contains(., "News")]
Note that "News" is not a part of span, but a, so your 1st XPath won't work

Use Selenium Java to get string text from HTML

I want to get Selenium with Chromedriver to recognize and import a line of html text into a Webelement variable.
Given this HTML:
<li id="password_rules">
<strong>Password Rules</strong>
<p>The database password rules conform with...:</p>
<ul>
<li>The password can not be the same as the user id.</li>
<li>Password length must be between 8 and 25 characters.</li>
</ul>
</li>
I want to grab the text in the last list element ("Password length must be between 8 and 25 characters.").
This is the java code I'm attempting to use:
WebElement passwordCriteria = driver.findElement(By.xpath("//*[#id = 'password_rules']//*[contains(text(), 'Password length must be between ')]"));
String lineText = passwordCriteria.getText();
When that Java executes, it returns an error saying the element cannot be found:
Exception in thread "main"
org.openqa.selenium.InvalidSelectorException: invalid selector: Unable
to locate an element with the xpath expression //[contains((text(),
'Password length must be between ')] because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string
'//[contains((text(), 'Password length must be between ')]' is not a
valid XPath expression.
Any insight is much appreciated.
If you are grabbing a WebElement by it's id, then you don't need your extra specific xPath. id is supposed to be unique by convention. If you have other html elements with the same id, consider changing them to a class.
You should be able to grab the element like this:
WebElement passwordCriteria = driver.findElement(By.id("password_rules"));
If you're committed to finding the element by the id containing some text then the way you should do it is as follows:
WebElement passwordCriteria = driver.findElement(By.xpath("//*[contains((text(),'Password length must be between')]"));
Also, sometimes Selenium will complain if elements are not visible on the page when you try and reference them. Sometimes you need to wait, other times you need to perform some other action to make the text visible before referencing it, like hovering the mouse over a dropdown, etc.
For example
Suppose the html you pasted here is an error message. This error message does not start out as being 'visible', but instead it is shown after the user types their password in incorrectly. In such an instance, Selenium won't let you reference the text from an element inside this div, since it's not currently view-able. Instead, what you would have to do is use Selenium to input the incorrect password in the fields, wait for the error message to be displayed, and then finally reference the WebElement, only after it is able to be seen.
EDIT:
I misread OP's intention. The element that OP is trying to reference is NOT the element with the id, but rather a child of that element. Instead of rewriting my answer, I will point out that #Grasshopper answer has both css and xPath solutions.
You can try these locators if the concerned li is always the last child.
Css - "li[id='password_rules'] > ul > li:last-child"
xpath - "//li[#id='password_rules']/ul/li[last()]"
As per your question as the desired text is within Password Rules you have to induce WebDriverWait with ExpectedConditions as textToBePresentInElementLocated and then retrieve the text as follows :
new WebDriverWait(driver, 20).until(ExpectedConditions.textToBePresentInElementLocated(By.xpath("//li[#id='password_rules']//ul//li"), "Password length"));
String lineText = driver.findElement(By.xpath("//li[#id='password_rules']//ul//li[contains(.,'Password length')]")).getAttribute("innerHTML");
Thank you for the help everyone. I finally got it using the following:
new WebDriverWait(driver, 20).until(ExpectedConditions.textToBePresentInElementLocated(By.xpath("//li[#id = 'password_rules']"), "Password length must be between "));
WebElement passwordCriteria = driver.findElement(By.xpath("//li[#id = 'password_rules']/ul/li[2]);
String lineText = passwordCriteria.getText();
Your original example had // which should only be used at the beginning of an xpath.

NoSuchElementException when using By.Xpath

Edit :
The element was inside an iframe, this is how it finally worked:
WebDriverWait wait = new WebDriverWait(_driver, 60);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By
.xpath("//*[#class='IFrameID']")));
WebElement element_t = _driver.findElement(
By.xpath("//*[#myattribute='mytest']"));
Edit :
My problem seems to be the structure of the page. i tried different things, and i only was able to get the body by id, ever other element i tried to get by id or any other attribute couldnt be found...
I am trying to get an element by using the By.xpath method, the xpath itself works just fine when used in firebug/firepath, but when used in the java application i am getting an Exception:
org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":".//*[#myattribute='mytest']"}
The attribute i am trying to access is not a standard html one, but generated from a framework so the field looks like this :
<input id="F_19" class="FIELDInputEdit" type="text" style=" width:100%;" maxlength="40" myattribute="mytest" name="CC">
The javacode itself looks like this :
WebElement element_t = _driver.findElement(
By.xpath(".//*[#myattribute='mytest']"));
Since the only known attribute is this one, i have no ohter way to access the input field.
I am using Firefox 17.0.11
good practice (imho) before using xpath in webdriver test it using selenium ide (http://docs.seleniumhq.org/download/)
Error might be because of «.» before «//». Try to remove it.
Read this: http://www.w3schools.com/xpath/xpath_syntax.asp
.//*[#myattribute='mytest']
«.» = Selects the current node
«//» = Selects nodes in the document from the current node that match the selection no matter where they are
«*» = Matches any element node
«[#myattribute='mytest']» ( = [#myattribute = \"mytest\"]) = Node, that contains attribute "myattribute", which value is "mytest"
Now, _driver.findElement(By.xpath("//*[#myattribute='mytest']")) = search whole page for first node with attribute «myattribute» with value «mytest»
_driver.findElement(By.xpath("//input[#myattribute='mytest']"))
= search whole page for first input with «myattribute» = «mytest»
_driver.findElement(By.xpath("//input[#myattribute='mytest']")).then(By.path("./*[#comeAtr]")) = in input with «myattribute» = «mytest» find any node with atribute = «
Have you tried to use CSS selectors instead?
By.cssSelector("input[myattribute=\"mytest\"]")
The element was inside an iframe, this is how it finally worked:
WebDriverWait wait = new WebDriverWait(_driver, 60);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By
.xpath("//*[#class='IFrameID']")));
WebElement element_t = _driver.findElement(
By.xpath("//*[#myattribute='mytest']"));

Categories

Resources