Selenium (java) can't get text from nested element without printing it - java

I try to get text from title of modal pop-up window. On the page there are many such windows - each with uniqe id. In each such modal window all elements have the same class names so first I need to point to the correct window and then look for particular element.
So I do it with this code:
public String getRFRTitle(String rfrNumber) {
return driver.findElement(By.id("rfr-details-dialog-"+rfrNumber)).
findElement(By.className("modal-title")).getText();
}
But it's not displaying for me anything.
What I have found is that when I print this title text before, this function works correctly.
I added this before returning value from the function:
System.out.println("tite: "+ driver.findElement(By.id("rfr-details-dialog-"+rfrNumber)).
findElement(By.className("modal-title")).getText());
I tried with initialisation of variables before returning text but without luck.
I can go with my workaround but I'm curious is this Java or Selenium issue.

This will most likely be a timeout issue. The following might work for you and if it doesn't, the stacktrace will give you more feedback.
By locator = By.cssSelector("#rfr-details-dialog-" + rfrNumber + " .modal-title");
int timeoutInSeconds = 10;
WebElement foundElement = new WebDriverWait(webdriver, timeoutInSeconds).until(ExpectedConditions.visibilityOfElementLocated(locator));
System.out.println("tite: " + foundElement.getText());

Related

JxBrowser How to get value from a html node within java

Hello guys I am trying out the jxBrowser component and I am unable to the value of selected html component...
List<DOMElement> paragraphs = divRoot.findElements(By.cssSelector("p"));
for (DOMElement paragraph : paragraphs) {
System.out.println("paragraph.getNodeValue() = " +
paragraph.getNodeValue());
}
I am able to find paragraphs.. But can't get their node's value.. or simply <p>I cant get this value<p/> The code must be okay because its just a pure copy of their own sample code: here
So my question is... What have I done wrong? It seems properly imported.. I am using library version 6.19.1 on a macbook. ( And I even tried it on a windows 10 with same result.. )
Or if there is other java browser solution with similar functions.. What I need is to load a page, get some values out of some divs and then simulate click.
DOMElement.getNodeValue() returns the value of this node, depending on its DOMNodeType. The text you are trying to get is a children node for the node, so you need to get it with the following code paragraph.getChildren().get(0).
So, the final code will look like the following:
for (DOMElement paragraph : paragraphs) {
System.out.println("paragraph.getNodeValue() = " +
paragraph.getChildren().get(0).getNodeValue());
}

WebElement getText() doesn't work on Winium-Desktop

I'm trying to execute getText() on a WebElement instance but for some reason it doesn't work: pcresultsList.get(0).getText()
Maybe Winium doesn't support this method?
My code is:
public void monitorBasic() throws InterruptedException {
monitorFrame = driver.findElement(By.name("BEAM Monitor"));
WebElement resultsFrame = monitorFrame.findElement(By.id("ReportListBox"));
List<WebElement> pcresultsList = resultsFrame.findElements(By.className("TextBlock"));
System.out.println(pcresultsList.get(0).getText());
}
sorry for not posting the error I'm getting - the site tells me that my code is not indent and when i'm trying to present it as code the site tells i have too much code. :)
Have you tried using:
System.out.println(pcresultsList.get(0).getAttribute("Value"));
Also try to get other properties of the element to confirm you can get info.
The code below works for me:
element = Window.findElement(By.xpath("//*[contains(#ControlType,'ControlType.DataItem') and contains(#Name,'G15')]"));
System.out.println("Cell text: " + element.getText()); //writes Shipments
Let us know if this helps.
As far as I understand you are trying to get some text from an element which is inside a frame. In that case you need to switch to the frame first then acquire the text of any of the element within the frame.
You need to do:
Apply ImplicitlyWait for 2/3 seconds.
driver.switchTo().frame("BEAM Monitor"); // assuming that's the frame name.
Then click on a element inside the frame :
driver.findElement(By.id("ReportListBox")).click();
Create a list to get all the elements in a list:
List<WebElement> pcresultsList = driver.findElements(By.className("TextBlock"));
Create a for loop to iterate through the elements to get the text:
for(WebElement pcresult : pcresultsList)
{
System.out.println(pcresult.getText());
}
Let me know if this helps you.
I've found that with Winium, you need to get the Name attribute because getText() does not work correctly.

Choosing random WebElement from drop down using Selenium with Java

I'm automating our application using Selenium 2.0 and Java. I would like to get a clearer understanding how can I overcome the problem with generating random ID for my WebElement and then click on it.
I have a list of elements in my drop down that all differs only in endings:
driver.findElement(By.id(""uxMiniFinderVoyageSelect_chzn_o_1")
driver.findElement(By.id(""uxMiniFinderVoyageSelect_chzn_o_2")
driver.findElement(By.id(""uxMiniFinderVoyageSelect_chzn_o_3")
driver.findElement(By.id(""uxMiniFinderVoyageSelect_chzn_o_4")
and so on till 250.
What I did is I called Random class where I declared a random variable within the range 1 to 250
Random random = new Random();
int x = random.nextInt(250) + 1;
Now I'm searching for my element this way
private WebElement cruiseSailing = driver.findElement(By.id("uxMiniFinderVoyageSelect_chzn_o_" + x));
That's all OK and is working as expected. The problem I'm facing is sometimes error message appears after selecting some of those elements from drop down. According to my test case, I need to catch this error, capture the screenshot and choose another element from the drop down. But once I set up cruiseSailing element, it chooses the same element over and over.Please see code example below:
private WebElement cruiseSailingDropDown = driver.findElement(By.id(Some ID));
private WebElement errorMessage = driver.findElement(By.xpath("some xpath expression"));
private WebElement cruiseSailing = driver.findElement(By.id("uxMiniFinderVoyageSelect_chzn_o_" + x));
cruiseSailingDropDown.click();
cruiseSailing.click();
Thread.sleep(2000);
if(errorMessage .isDisplayed){
System.out.printLn("Error message is displayed")
cruiseSailingDropDown.click();
cruiseSailing.click();
}else{
proceed further to the next step
Please advise how can I generate another ID for my cruiseSailing webelement.
The reason why it is choosing the same element again in case of failure is you are not reassigning the cruiseSailing value to new one .
There are 2 ways which i can think of :
Assign a new value to cruiseSailing inside the "If" block. You can do something as below inside "If" block.
cruiseSailing = driver.findElement(By.id("uxMiniFinderVoyageSelect_chzn_o_" + x));
Call the Orignial method again which sets cruiseSailing value to new value.
Note: You might want to remove below lines from If block if you are going on with 2nd approach.
cruiseSailingDropDown.click();
cruiseSailing.click();
For Taking screenshot you can create a method and call it inside If block.
Code for taking screenshot
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\error\\screenshot.png"));
Please vote up if this helped you. Thanks :)

getText() method of selenium chrome driver sometimes returns an empty string

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();

Selenium WebDriver: I want to overwrite value in field instead of appending to it with sendKeys using Java

In WebDriver, if I use sendKeys it will append my string to the value that already exists in the field. I can't clear it by using clear() method because the second I do that, the webpage will throw an error saying that it has to be between 10 and 100. So I can't clear it or an error will be thrown before I can put in the new value using sendKeys, and if I sendKeys it just appends it to the value already there.
Is there anything in WebDriver that lets you overwrite the value in the field?
You can also clear the field before sending it keys.
element.clear()
element.sendKeys("Some text here")
I think you can try to firstly select all the text in the field and then send the new sequence:
from selenium.webdriver.common.keys import Keys
element.sendKeys(Keys.chord(Keys.CONTROL, "a"), "55");
Okay, it is a few days ago...
In my current case, the answer from ZloiAdun does not work for me, but brings me very close to my solution...
Instead of:
element.sendKeys(Keys.chord(Keys.CONTROL, "a"), "55");
the following code makes me happy:
element.sendKeys(Keys.HOME, Keys.chord(Keys.SHIFT, Keys.END), "55");
So I hope that helps somebody!
In case it helps anyone, the C# equivalent of ZloiAdun's answer is:
element.SendKeys(Keys.Control + "a");
element.SendKeys("55");
This worked for me.
mElement.sendKeys(Keys.HOME,Keys.chord(Keys.SHIFT,Keys.END),MY_VALUE);
Use this one, it is trusted solution and works well for all browsers:
protected void clearInput(WebElement webElement) {
// isIE() - just checks is it IE or not - use your own implementation
if (isIE() && "file".equals(webElement.getAttribute("type"))) {
// workaround
// if IE and input's type is file - do not try to clear it.
// If you send:
// - empty string - it will find file by empty path
// - backspace char - it will process like a non-visible char
// In both cases it will throw a bug.
//
// Just replace it with new value when it is need to.
} else {
// if you have no StringUtils in project, check value still empty yet
while (!StringUtils.isEmpty(webElement.getAttribute("value"))) {
// "\u0008" - is backspace char
webElement.sendKeys("\u0008");
}
}
}
If input has type="file" - do not clear it for IE. It will try to find file by empty path and will throw a bug.
More details you could find on my blog
Had issues using most of the mentioned methods since textfield had not accepted keyboard input, and the mouse solution seem not complete.
This worked for to simulate a click in the field, selecting the content and replacing it with new.
Actions actionList = new Actions(driver);
actionList.clickAndHold(WebElement).sendKeys(newTextFieldString).
release().build().perform();
Use the following:
driver.findElement(By.id("id")).sendKeys(Keys.chord(Keys.CONTROL, "a", Keys.DELETE), "Your Value");
This is something easy to do and it worked for me:
//Create a Javascript executor
JavascriptExecutor jst= (JavascriptExecutor) driver;
jst.executeScript("arguments[1].value = arguments[0]; ", 55, driver.findElement(By.id("id")));
55 = value assigned
The original question says clear() cannot be used. This does not apply to that situation. I'm adding my working example here as this SO post was one of the first Google results for clearing an input before entering a value.
For input where here is no additional restriction I'm including a browser agnostic method for Selenium using NodeJS. This snippet is part of a common library I import with var test = require( 'common' ); in my test scripts. It is for a standard node module.exports definition.
when_id_exists_type : function( id, value ) {
driver.wait( webdriver.until.elementLocated( webdriver.By.id( id ) ) , 3000 )
.then( function() {
var el = driver.findElement( webdriver.By.id( id ) );
el.click();
el.clear();
el.sendKeys( value );
});
},
Find the element, click it, clear it, then send the keys.
This page has a complete code sample and article that may help.
This solved my problem when I had to deal with HTML page with embedded JavaScript
WebElement empSalary = driver.findElement(By.xpath(PayComponentAmount));
Actions mouse2 = new Actions(driver);
mouse2.clickAndHold(empSalary).sendKeys(Keys.chord(Keys.CONTROL, "a"), "1234").build().perform();
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].onchange()", empSalary);
WebElement p= driver.findElement(By.id("your id name"));
p.sendKeys(Keys.chord(Keys.CONTROL, "a"), "55");

Categories

Resources