I'm trying to verify that a column in a table on a webpage displays the term 'Regular' in all of it's rows. Below is the code I’m trying to execute. when I run the code below in IntelliJ I get a failure of Condition not Satisfied. Changing the == to equals doesn't resolve the issue. What am I doing wrong here?
List‹WebElement› tdCollection = driver. findElements(By.xpath("//table[#class='jsgrid-table']"))
for (WebElement element : tdCollection) {
element.getText()=="Regular"
}
If this xpath
//table[#class='jsgrid-table']
represent all the Regular term in rows, then the below code should work for you.
Also, you can put OR condition to have a check for Regular or regular.
Also, if you are using TestNG with integration to Selenium, you can use below assert.
List<WebElement> tdCollection = driver.findElements(By.xpath("//table[#class='jsgrid-table']"));
for (WebElement element : tdCollection) {
if (element.getText().equals("Regular") || element.getText().equals("regular")) {
System.out.println("Regular or regular is present");
Assert.assertTrue(true);
}
}
I have the following HTML code:
I need to refer to the span element (last element in the tree) in order to check if it exists.
The problem is, I can't find the right XPath to it and was not able to find any question already concerning this specific issue.
I tried:
"//span[#data-highlighted='true']"
and also further successional XPaths referring to its previous nodes but was not able to actually get a working Xpath. The difficulty for me is that it has no id or title so I tried to get it through its "data-highlighted" but that does not seem to work.
Just for the sake of completeness:
I have written the following Java method which is meant to get an Xpath as its input:
public Boolean webelementIsPresent (String inputXpath) throws InterruptedException {
return driver.findElements(By.xpath(inputXpath)).size()>0;
}
Then in a test class I perform an assertTrue wether the webelement exists (the method returns a True) or wether it doesn't.
I'm open for any help, thanks in advance! :)
To identify the element "//span[#data-highlighted='true']" you can use the following xpath :
"//table[#class='GJBYOXIDAQ']/tbody//tr/td/div[#class='GJBYOXIDPL' and #id='descriptionZoom']/table/tbody/tr/td/div[#class='GJBYOXIDIN zoomable highlight' and #id='description']/div[#class='gwt-HTML' and #id='description']//span[#data-highlighted='true']"
You can get element by text
driver.findElement(By.xpath("//span[contains(text(), 'Willkommen')]"));
Or find div with id and based on that, find span element. There are 2 options to do that:
driver.findElement(By.xpath("//div[#id='description']//span"));
OR
WebElement descriptionDiv = driver.findElement(By.id("description"));
descriptionDiv.findElement(By.tagName("span"));
OR
driver.findElement(By.cssSelector("#description span"));
Your XPath looks fine, my guess is that it's a timing issue and you need a brief wait. It could also be that the page was in a certain state when you captured the HTML and it's not always in that state when you reach the page.
There are other locators that should work here.
XPath
//span[contains(., 'Willkommen')]
CSS selectors (These may or may not work based on your current XPath results)
span[data-highlighted='true']
#description span[data-highlighted='true']
For your function, I would suggest a change. Replace the String parameter with a By for more flexibility. You can then locate an element using any method and not be restricted to just XPath.
public Boolean webElementIsPresent(By locator)
{
return driver.findElements(locator).size() > 0;
}
or if you want to add a wait,
public Boolean webElementIsPresent(By locator)
{
try
{
new WebDriverWait(driver, 5).until(ExpectedConditions.presenceOfElementLocated(locator));
return true;
}
catch (TimeoutException e)
{
return false;
}
}
OS: Windows 10
Selenium Version: 3.4
#FINDALL annotation is supposed to match at least one of the given criteria.
Here is the OR :
URL for WebPage : http://store.demoqa.com/
WebElement : -
#FINDALL ({
#findby(xpath = "//input[#name='s']"),
#findby(xpath = "//a[contains(.,'Magic Mouse')]")
})
public WebElement Header__txtSearch;
I am trying to verify element on page with multiple locators.
When I give 2 correct values of XPath, then the driver identifies it quickly on the webpage and returns normally. But when I give the first one as Correct and second one as Incorrect , then it still returns true that element is found but it waits for the object timeout that was provided while initializing the driver(implicit wait).
Isn't there a way where if it finds the first element then it immediately returns us as true instead of going to match the next locator, So that no more time is taken for the test execution to move forward.
How can it be stopped after finding the correct locater info ??
Or is there a workaround for this in which I can use multiple locators for one element so that driver return true as soon as it matches the one locator correctly?
did you try to combine selectors into one by "|"? like:
#findby(xpath = "//input[#name='s']|//a[contains(.,'Magic Mouse')]")
public WebElement Header__txtSearch;
You can use or in the to get the first matching locator.
#findby(xpath = "//input[#name='s'] or //a[contains(.,'Magic Mouse')]")
public WebElement Header__txtSearch;
So having a WebElement in Selenium, I am trying to get all of its direct childs by XPath including text nodes. I already tried the XPath "*" which works but doesn't give me any text node (if there is any). According to XPath's documentation I then tried many things:
"child::node()" gives me InvalidSelectorException.
Tried to get all the nodes with "*" and then trying to get all the text nodes with "text()": gives me InvalidSelectorException on the "text()" query.
I tried these XPaths with the XPathHelper extension on Chrome and it works as intented but it doesn't seem to work with Selenium (Chrome WebDriver and PhantomJS).
This is my loop that I thought should work:
for(WebElement child : node.findElements(new By.ByXPath("child::node()"))) {
//Do something with child
}
Where could be the problem?
This is what I use.
public String getHiddenText(WebDriver driver, WebElement aWebElement) {
return (String) ((JavascriptExecutor) driver).executeScript("return arguments[0].textContent;", aWebElement);
}
Addressing crawljax comment,
public String getHiddenText(EmbeddedBrowser browser, WebElement aWebElement) {
WebDriver driver = browser.getDriver();
return (String) ((JavascriptExecutor) driver).executeScript("return arguments[0].textContent;", aWebElement);
}
I find that the best way to learn a new tool is to go to its github repository and search the automated tests for examples of how to use it. Just saying. :-)
I have a curious case where the selenium chrome driver getText() method (java) returns an empty string for some elements, even though it returns a non-empty string for other elements with the same xpath. Here is a bit of the page.
<div __gwt_cell="cell-gwt-uid-223" style="outline-style:none;">
<div>Text_1</div>
<div>Text_2</div>
<div>Text_3</div>
<div>Text_4</div>
<div>Text_5</div>
<div>Text_6</div>
</div>
for each of the inner tags, I can get valid return values for getTagName(), getLocation(), isEnabled(), and isDisplayed(). However, getText() returns an empty string for some of the divs.
Further, I notice that if I use the mac chrome driver, it is consistently the ‘Text_5’ for which getText() returns an empty string. If I use the windows chrome driver, it is , it is consistently the ‘Text_2’ for which getText() returns an empty string. If I use the firefox driver, getText() returns the expected text from all the divs.
Has anyone else had this difficulty?
In my code, I use something like this…
ArrayList<WebElement> list = (ArrayList<WebElement>) driver.findElements(By.xpath(“my xPath here”));
for (WebElement e: list) System.out.println(e.getText());
As suggested below, here is the actual xPath I am using. The page snippet above deals with the last two divs.
//*[#class='gwt-DialogBox']//tr[contains(#class,'data-grid-table-row')]//td[contains(#class,'lms-assignment-selection-wizard-cell')]/div/div
Update: The textContent attribute is a better option and supported across the majority of browsers. The differences are explained in detail at this blog post: innerText vs. textContent
As an alternative, the innerText attribute will return the text content of an element which exists in the DOM.
element.getAttribute("innerText")
The isDisplayed() method can sometimes trip over when the element is not really hidden but outside the viewport; getText() returns an empty string for such an element.
You can also bring the element into the viewport by scrolling to it using javascript, as follows:
((JavaScriptExecutor)driver).executeScript("arguments[0].scrollIntoView(true);", element);
and then getText() should return the correct value.
Details on the isDisplayed() method can be found in this SO question:
How does Selenium WebDriver's isDisplayed() method work
WebElement.getAttribute("value") should help you !!
This is not a solution, so I don't know if it belongs in an answer, but it's too long for a comment and includes links, so I'm putting it an answer.
I have had this issue as well. After doing some digging, it seems that the problem arises when trying to get the text of an element that is not visible on the screen.(As #Faiz comments above.)This can happen if the element is not scrolled to, or if you scroll down and the element is near the top of the document and no longer visible after the scroll. I see you have a FindElements() call that gets a list of elements. At least some are probably not visible; you can check this by trying boolean b = webElement.isDisplayed(); on each element in the list and checking the result. (See here for a very long discussion of this issue that's a year old and still no resolution.)
Apparently, this is a deliberate design decision (see here ); gettext on invisible elements is supposed to return empty. Why they are so firm about this, I don't know. Various workarounds have been suggested, including clicking on the element before getting its text or scrolling to it. (See above link for example code for the latter.) I can't vouch for these because I haven't tried them, but they're just trying to bring the element into visiblity so the text will be available. Not sure how practical that is for your application; it wasn't for mine. For some reason, FirefoxDriver does not have this issue, so that's what I use.
I'm sorry I can't give you a better answer - perhaps if you submit a bug report on the issues page they'll see that many people find it to be a bug rather than a feature and they'll change the functionality.
Good luck!
bsg
EDIT
See this question for a possible workaround. You won't be able to use it exactly as given if isDisplayed returns true, but if you know which element is causing the issue, or if the text is not normally blank and you can set an 'if string is empty' condition to catch it when it happens, you can still try it. It doesn't work for everyone, unfortunately.
NEW UPDATE
I just tried the answer given below and it worked for me. So thanks, Faiz!
for (int count=0;count<=sizeofdd;count++)
{
String GetInnerHTML=getddvalue.get(count).getAttribute("innerHTML");
}
where,
1. getddvalue is the WebElement
2. sizeofdd is the size of getddvalue
element.getAttribute("innerText") worked for me, when getText() was returning empty.
I encountered a similar issue recently.
I had to check that the menu tab "LIFE EVENTS" was present in the scroll box. The problem is that there are many menu tabs and you are required to scroll down to see the rest of the menu tabs. So my initial solution worked fine with the visible menu tabs but not the ones that were out of sight.
I used the xpath below to point selenium to the parent element of the entire scroll box.
#FindBy(xpath = "//div[contains(#class, 'menu-tree')]")
protected WebElement menuTree;
I then created a list of WebElements that I could increment through.
The solution worked if the menu tab was visible, and returned a true. But if the menu tab was out of sight, it returned false
public boolean menuTabPresent(String theMenuTab) {
List<WebElement> menuTabs = new ArrayList<WebElement>();
menuTabs = menuTree.findElements(By.xpath("//i/following-sibling::span"));
for(WebElement e: menuTabs) {
System.out.println(e.getText());
if(e.getText().contains(theMenuTab)) {
return true;
}
}
return false;
}
I found 2 solutions to the problem which both work equally well.
for(WebElement e: menuTabs) {
scrollElementIntoView(e); //Solution 1
System.out.println(e.getAttribute("textContent")); //Solution 2
if(e.getAttribute("textContent").contains(theMenuTab)) {
return true;
}
}
return false;
Solution 1 calls the method below. It results in the scroll box to physically move down while selenium is running.
protected void scrollElementIntoView(WebElement element) {
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true)", element);
}
Solution 2 gets the text content (even for the menu tabs not currently visible) of the attribute that you are pointing to. Thus doing the job properly that .getText() was not able to do in this situation.
Mine is python, but the core logic is similar:
webElement.text
webElement.get_attribute("innerText")
webElement.get_attribute("textContent")
Full code:
def getText(curElement):
"""
Get Selenium element text
Args:
curElement (WebElement): selenium web element
Returns:
str
Raises:
"""
# # for debug
# elementHtml = curElement.get_attribute("innerHTML")
# print("elementHtml=%s" % elementHtml)
elementText = curElement.text # sometime NOT work
if not elementText:
elementText = curElement.get_attribute("innerText")
if not elementText:
elementText = curElement.get_attribute("textContent")
# print("elementText=%s" % elementText)
return elementText
Calll it:
curTitle = getText(h2AElement)
hope is useful for you.
if you don't care about isDisplayed or scrolling position, you can also write
String text = ((JavaScriptExecutor)driver).executeScript("return $(arguments[0]).text();", element);
or without jquery
String text = ((JavaScriptExecutor)driver).executeScript("return arguments[0].innerText;", element);
Related to getText() I have also an issue and I resolved so:
WebElement errMsg;
errMsg = driver.findElement(By.xpath("//div[#id='mbr-login-error']"));
WebElement parent = driver.findElement(By.xpath("//form[#id='mbr-login-form']"));
List<WebElement> children = parent.findElements(By.tagName("div"));
System.out.println("Size is: "+children.size());
//((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView(true);", children);
for(int i = 0;i<children.size();i++)
{
System.out.println(i + " " + children.get(i).getText());
}
int indexErr = children.indexOf(errMsg);
System.out.println("index " + indexErr);
Assert.assertEquals(expected, children.get(indexErr).getText());
None of the above solutions worked for me.
Worked for me:
add as a predicate of xpath the length of string greater than 0:
String text = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//span[string-length(text()) > 0]"))).getText();