I need help in JAVA Selenium. I could not get the web driver to find the element I want in a while loop. I tried to do it without while loop, it would work. However without the while loop, I could not make the web driver to reload the page while waiting for the element to load. I would really appreciate if anyone could assist me in this.
The problem with my code is it will not exit the loop since elementProgress is forever FALSE because the web driver is not detecting the button thus not updating the elementProgress boolean value.
//check if progress button exist
boolean elementProgress;
elementProgress = driver.findElements(By.cssSelector("tr:nth-child(1) .iconLabel")).size() != 0;
//auto reload page to prevent webpage timeout
while (!elementProgress) {
TimeUnit.SECONDS.sleep(15);
driver.navigate().refresh();
boolean check_dl_queue = driver.findElements(By.cssSelector(".cell > .table .total_records")).size() != 0;
if (!check_dl_queue) {
driver.navigate().refresh();
}
Thread.sleep(1500);
driver.navigate().refresh();
elementProgress = driver.findElements(By.cssSelector("tr:nth-child(1) .iconLabel")).size() != 0;
System.out.println("P2:" + elementProgress); //to printout element status
}
I had found a solution to that, haven't got time to post it here. Below are the the solution.
//boo stat for while loop
boolean elementProgress = true;
boolean elementProgress2 = true;
//setup new web driver wait
WebDriverWait dl_wait = new WebDriverWait(driver, 15);
//auto reload page to prevent webpage timeout
while (elementProgress) {
driver.navigate().refresh();
//start button click
try {
//phase 1: wait for button 1, if exceed wait time goto exception
dl_wait.until(presenceOfElementLocated(By.cssSelector("tr:nth-child(1) .iconLabel")));
retryingFindClick(By.cssSelector("tr:nth-child(1) .iconLabel"));
//phase 2: refresh page after button successfully clicked
driver.navigate().refresh();
//phase 3: wait for button 2, if exceed wait time goto exception
while(elementProgress2) {
try {
dl_wait.until(presenceOfElementLocated(By.cssSelector("tr:nth-child(1) .icon-cancel")));
retryingFindClick(By.cssSelector("tr:nth-child(1) .icon-cancel"));
//exit elementProgress2 while loop
elementProgress2 = false;
} catch(Exception ex) {
//refresh page to counter false positive element not found exception
driver.navigate().refresh();
}
}
//exit elementProgress while loop
elementProgress = false;
} catch(Exception ex) {
//refresh page to counter false positive element not found exception
driver.navigate().refresh();
}
}
public boolean retryingFindClick(By by) {
boolean result = false;
int attempts = 0;
while(attempts < 2) {
try {
driver.findElement(by).click();
result = true;
break;
} catch(StaleElementReferenceException e) {
}
attempts++;
}
return result;
}
Related
I am able to swipe till element is found but then I am getting NoSuchElementException.
I have written following code.
int startX=(int) (dimension.width*0.5);
int startY=(int) (dimension.height*0.8);
int endX=(int) (dimension.width*0.2);
int endY=(int) (dimension.width*0.2);
TouchAction touch=new TouchAction(driver);
boolean b=false;
while (true) {
touch.press(PointOption.point(startX, startY)).waitAction(WaitOptions.waitOptions(Duration.ofSeconds(2)))
.moveTo(PointOption.point(endX, endY)).release().perform();
Thread.sleep(5000);
try {
b=driver.findElement(By.xpath("//android.widget.TextView[#content-desc='Sweep']")).isDisplayed();
if(b) {
b=true;
break;
}
else {
continue;
}
}catch (Exception ex) {
ex.printStackTrace();
}
}
driver.findElement(By.xpath("//android.widget.TextView[#content-desc='Sweep']")).click();
Please help. Thanks
It would be more reliable to use UIAutomator-based locator, cause you obviously have a scrollable view:
MobileElement element = (MobileElement) driver.findElement(MobileBy.AndroidUIAutomator(
"new UiScrollable(new UiSelector().scrollable(true))" +
".scrollIntoView(new UiSelector().textContains(\"Sweep\"))"));
It will not only scroll to element, but make sure it is within view port area and able for interations.
This is my first time first day working on selenium and I have no hands on experience on Web Technologies in depth either.
Working around, I have been facing StaleElementException while i try to access a particular object on the DOM.
Following Method handles all the task:
private void extract(WebDriver driver) {
try {
List<WebElement> rows = driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr"));
for (WebElement row : rows) {
WebElement columns = row.findElement(By.xpath("./td[1]/a"));
if (assertAndVerifyElement(By.xpath("//*[#id='gvSearchResults']/tbody/tr/td[1]/a"))) {
columns.click();
}
List<WebElement> elements = driver
.findElements(By.xpath("//*[#id='ctl00_MainContent_pnlDetailsInd']/table/tbody/tr"));
for (WebElement element : elements) {
WebElement values = element.findElement(By.xpath("./td[1]"));
System.out.print(values.getText() + " ");
WebElement values2 = element.findElement(By.xpath("./td[2]"));
System.out.println(values2.getText());
}
if(assertAndVerifyElement(By.xpath("//*[#id='ctl00_MainContent_btnBack']")))
driver.findElement(By.xpath("//*[#id='ctl00_MainContent_btnBack']")).click();
}
} catch (Exception e) {
e.printStackTrace();
}
}
The Assertion logic goes here:
public boolean assertAndVerifyElement(By element) throws InterruptedException {
boolean isPresent = false;
for (int i = 0; i < 5; i++) {
try {
if (driver.findElement(element) != null) {
isPresent = true;
break;
}
} catch (Exception e) {
// System.out.println(e.getLocalizedMessage());
Thread.sleep(1000);
}
}
Assert.assertTrue("\"" + element + "\" is not present.", isPresent);
return isPresent;
}
I have tried few solutions asking me to use wait until expected conditions, but none of them worked.
Also, It would be appreciated if you point out any bad design practices I might be using in the above sample.
I can give you the idea to overcome staleness.
Generally we will be getting the Stale Exception if the element attributes or something is changed after initiating the webelement. For example, in some cases if user tries to click on the same element on the same page but after page refresh, gets staleelement exception.
To overcome this, we can create the fresh webelement in case if the page is changed or refreshed. Below code can give you some idea.
Example:
webElement element = driver.findElement(by.xpath("//*[#id='StackOverflow']"));
element.click();
//page is refreshed
element.click();//This will obviously throw stale exception
To overcome this, we can store the xpath in some string and use it create a fresh webelement as we go.
String xpath = "//*[#id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.findElement(by.xpath(xpath)).click(); //This works
Another example:
for(int i = 0; i<5; i++)
{
String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
System.out.println(value);
}
Hope this helps you. Thanks
The StaleElementException occurs when the webelement in question is changed on the dom and the initial reference to that webelement is lost.
You can search for the webelement again
try this
try:
element = self.find_element_by_class('')
element.click()
except StaleElementReferenceException:
element = self.find_element_by_class('')
element.click()
I am making a script using selenium and at one step it shows loading icon in center of webpage.The loading icon appears after 1st line is executed
test.driver.findElement(By.id("oaapprove")).click();
test.driver.findElement(By.xpath("//*[text()='DATA EXPLORER']")).click();
The 2nd element is still there in DOM but its not clickable so i get error as not clickable
i tried this:
Boolean isPresent=test.driver.findElements(By.xpath("//div[#class='spinner-container']")).size() > 0;
if(isPresent)
{
System.out.println("Target element found");
}
while(test.driver.findElements(By.xpath("//div[#class='spinner-container']")).size() > 0)
{
try {
System.out.println("inside");
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(!(test.driver.findElements(By.xpath("//div[#class='spinner-container']")).size() > 0))
{
System.out.println("Target element not found");
}
It is printing "inside" till the loading icon is visible but but after icon disappears it does not print "inside" but it waits for 7-8 secs and then executes next statements.
What is the cause of waiting?
Can u please tell how to i solve this.
try actions class if it's showing using fluentwait that element is clickable:
WebElement yourElement = test.driver.findElement(By.xpath("//*[text()='DATA EXPLORER']"));
Actions act = new Actions(test.driver);
act.moveToElement(yourElement).click().build().perform();
I got the solution and i used stalenessOf
new WebDriverWait(driver, 10).until(ExpectedConditions.stalenessOf(findElement(By.xpath("element_path"))));
I am new to Selenium. Getting
org.openqa.selenium.StaleElementReferenceException: Element is no longer valid (WARNING: The server did not provide any stacktrace information)
error while running the below the code.
Expectation: while loop should resume once the method "changdrawer" returned true. Please help me if any correction is needed in my code.
public class ManageTaskList {
public void CheckRequestType() throws InterruptedException
{
//Switching the driver to TaskList frame
LaunchBrowser.driver.switchTo().frame("taskList");
boolean dateFlag=false;
String date = "06/12";
WebElement table = LaunchBrowser.driver.findElement(By.id("dataTable"));
List<WebElement> rows = table.findElements(By.tagName("tr"));
Iterator<WebElement> i = rows.iterator();
System.out.println("Table has following content");
while(i.hasNext())
{
WebElement row=i.next();
List<WebElement> columns= row.findElements(By.tagName("td"));
Iterator<WebElement> j = columns.iterator();
while(j.hasNext())
{
WebElement column = j.next();
String ColumnValues=column.getText();
//System.out.println("ColumnValues" + ColumnValues);
if (ColumnValues.contains(date))
{
System.out.println("Date confirmed" +ColumnValues );
dateFlag = true;
}
if (ColumnValues.contentEquals("Issue Change Drawer") && dateFlag==true)
{
System.out.println("Found Change Drawer");
dateFlag=false;
column.click();
ChangeDrawer();
Thread.sleep(100);
}
}
}
public boolean ChangeDrawer()
{
// Issue Change Drawer
LaunchBrowser.driver.findElement(By.xpath(".//*[#id='content']/div[3]/form/table/tbody/tr[2]/td/table/tbody/tr/td[1]/input")).click();
LaunchBrowser.driver.switchTo().defaultContent();
return true;
}
}
If the changeDrawer method (that is, a click on the element) causes the page to refresh, or even the table elements to change, even if you end up having a WebElement that still matches your selector (in this case, rows), you are still holding a reference to the "old" object, which doesn't exist anymore in the page.
You would need to call the findElement/s method again to refresh the WebElement if that is the case.
i have list of Hyperlinks in one page, when i click the links , they are redirecting to the new tab. how do i find out whether the page is loaded or not. i have used the do while loop for find out the element is enabled or not. but i am getting "no such element" only. could you please help on this.. Below is the piece of code. i have tried with Explicit wait also . but getting the same issue.
WebElement element7 = driver.findElement(By.id("MenuControlBNY_MenuNavBar_MenuControlBNY_MenuNavBar_p11__Tree_item_2_cell"));
if (element7.isEnabled())
{
element7.click();
System.out.println(" Report is selected");
}
boolean element8 = false;
int count = 0 ;
do
{
element8 = driver.findElement(By.id("working")).isEnabled();
System.out.println("Report is loaded");
count = count+1;
if(count == 1000)
{
break;
}
}while(element8 == true);
I use the following, its fairly self explanatory.
private static WebDriverWait wait = new WebDriverWait(driver, 60);
private static JavascriptExecutor js = (JavascriptExecutor) driver;
public static void waitForPageLoaded() {
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
Boolean res = (js.executeScript("return document.readyState").equals("complete"));
System.out.println("[DEBUG] waitForPageLoaded: " + res);
return res;
}
});
}
EDIT: This will return true when the page is in a ready state ie the page is loaded. So you would call the above method prior to searching for your element.
You can set an implicit wait which will wait for the elements when finding them for a 15 seconds
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
or explicitly:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("working")));
From the information you have provided, I am assuming you have clicked the link and the page is opened in a new tab and then you are getting nu such elment exception.
In this case you need to switch to the new tab using window handles and use explict wait for element.here is sample code
String parentWindow= driver().getWindowHandle();
element7.click();
Set<String> myset = driver().getWindowHandles();
myset.remove(parentWindow);
driver().switchTo().window((String)myset.toArray()[0]);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(locator)));