Wait to perform two actions - selenium/ java - selenium

I'm trying to use Fluent wait to perform two actions as below:
Click on search button
Check the result for the element
Right now I'm trying with the below code and it doesn't seem to work:
public SendMailPage waitForSometime() throws Exception {
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofMinutes(2))
.pollingEvery(Duration.ofSeconds(10))
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
driver.findElement(By.xpath("//BUTTON[#type='submit'][text()='Search']")).click();
driver.findElement(By.xpath("xpath of the element i'm waiting to find"));
return driver.findElement(By.xpath("xpath of the element i'm waiting to find"));
}
});
element.isDisplayed();
return new SendMailPage();
}
Can someone guide me on how to fix this?
***UPDATED CODE: where waiting for a single element also doesn't work :
public SendMailPage assertMailSubject() throws Exception {
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofMinutes(2))
.pollingEvery(Duration.ofSeconds(30))
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("the element that i am waiting for"));
}
}
);
return new SendMailPage();
}

I fixed both the problems:
The code was not working as the NoSuchElementException was from Java util instead of Selenium.
And for performing two actions, I just added by Search key action before the return statement.

Related

How to wait untill a page is dim after clicking a button?

How to wait until a page is dim(loading) after clicking a button? I tried following options but not succeeded yet. I have to capture transaction timings.
1) Implicit Wait
(driver.manage().timeouts().implicitlyWait(20L, TimeUnit.SECONDS);)
2) Explicit Wait
(wait = new WebDriverWait(driver, 200);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(//a[#ardbn='z3Btn_TDS_Next']/div/img)[position()<3]")));)
3) One of my own function
public void waitForPageLoaded() {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete"); } };
Wait<WebDriver> wait = new WebDriverWait(driver,30); try { wait.until(expectation); } catch(Throwable error) { fail("Timeout waiting for Page Load Request to complete."); } }
Wait till invisibility of Loading box.
Suppose locator/id/xpath of Loading box is id = loader, Then
By locator = By.id("loader");
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(timeOutInSeconds, TimeUnit.SECONDS)
.pollingEvery(pollingIntervalInSeconds, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
wait.until(ExpectedConditions.invisibilityOfElementLocated(locator));

How to use clickandwait in Selenium Webdriver using Java?

I am trying to click on the object, to show the list of value pop-up.
I used the following script, but unable to populate the list value pop-up.
Driver.findElement(By.xpath(OR.getProperty(Object))).click();
Thread.sleep(1000L);
Is there any other way to click and wait for the object?
Driver.findElement(By.xpath(OR.getProperty(Object))).click();
WebDriverWait wait = new WebDriverWait(Driver, timeoutInSeconds);
wait.until(ExpectedConditions.elementToBeClickable(By.id("yourId")));
There are other conditions like visibilityOf so choose the one which suits you most - documentation here.
String mainWindowHandle = driver.getWindowHandle();
System.out.println(mainWindowHandle);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(OR.getProperty(Object)));
Driver.findElement(By.xpath(OR.getProperty(Object))).click();
PageUtil.sleep(3000);
Set<String> s1 = driver.getWindowHandles();
Iterator<String> ite = s1.iterator();
while (ite.hasNext()) {
String popupHandle = ite.next().toString();
System.out.println(popupHandle + " Present Pop Up window name");
if (!popupHandle.contains(mainWindowHandle)) {
driver.switchTo().window(popupHandle);
}
}
WebDriverWait wait = new WebDriverWait(Driver, timeoutInSeconds);
wait.until(ExpectedConditions.elementToBeClickable(By.id("yourId")));
Driver.findElement(By.id("yourId")).click();
driver.switchTo().window(mainWindowHandle);
After clicking you can wait using FluentWait,
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("foo"));
}
});
refer this for more info
I'm not quite familiar with java syntax, but I'll give you php code and you can write similar. The idea is to find HTML element by tag and get it's id BEFORE YOU CLICK. Then AFTER THE CLICK wait for the id to change.
It looks like this:
class MySeleniumCondition extends WebDriverExpectedCondition{
public static function htmlElementIdIsNot($htmlElementId) {
return new WebDriverExpectedCondition(
function ($driver) use ($htmlElementId) {
$htmlElement = $driver->findElement(WebDriverBy::tagName('html'));
return $htmlElementId != $htmlElement->getId();
}
);
}
}
// .............. somehere in a class:
public function waitForNewPage($oldHtmlElementId, $time = 10){
try{
$this->driver->wait($time)->until(
MySeleniumCondition::htmlElementIdIsNot(
$oldHtmlElementId
)
);
return true;
}catch(TimeOutException $e){
return false;
}
}
// use this only when you are sure the page will reload
public function clickAndWait(WebDriverBy $locator, $time = 10){
$webElement = $this->driver->findElement($locator);
$oldHtmlElement = $driver->findElement(WebDriverBy::tagName('html'));
$oldHtmlElementId = $oldHtmlElement->getId();
$webElement->click();
$this->waitForNewPage($oldHtmlElementId, $time);
return true;
}

Keep on refreshing the page until certain element to appear?

I have a scenario like, i want to keep on refreshing the page until some element to appear in the page. Can anyone please help me on the same?
I am using the below code for the same but the page is not refreshing after five second
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
Thanks
Sudhansu
Try using the FluentWait class.
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("foo"));
}
});
In that way Selenium will just wait for a certain period of time until certain elements have been loaded.
I hope that will solve your problem so you don't have to refresh the page.
Edited:
As MrTi so friendly points out, the above code will not refresh your page. It will only wait for a certain period of time until certain elements have been loaded. I just thought it might solve the problem, without you having to refresh the page. If that does not solve your problem and you still need to refresh your page, then you need to add driver.navigate().refresh() before the return, like this:
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
driver.navigate().refresh()
return driver.findElement(By.id("foo"));
}
});
Thank you EmilC for your proposal.
It's also posible to declare the Function using java lambda's syntax the following way.
Wait<WebDriver> wait = new FluentWait<WebDriver>(ctx.driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
wait.until((webDriver) -> {
webDriver.navigate().refresh();
return driver.findElement(by);
});
if $all_loaded = true > do something > else > refresh page

Selenium refresh

I am working on project where everything is saved in events so it took some time for server to respond for new data. I am using Fluent wait for pages using ajax, but this one doesn't use any ajax. So I want to refresh page check if new item is there if not refresh again. How this is achieved in Selenium 2?
I did this :
def accountsAfterCreating = 0
while (accountsAfterCreating <= existingAccounts) {
driver.navigate().refresh()
WebElement table = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.className("table"))
}
})
accountsAfterCreating = table.findElements(By.className("amount")).size()
}
Is it correct way?
Use Explicit wait like this In try catch block
try{
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
}
catch()
{
driver.navigate().refresh()
}
I usually use this method to wait for any html tag. We can also specify the wait time.
public boolean waitForElement(WebElement ele, String xpath, int seconds) throws InterruptedException{
//returns true if the element appears within the time
//false when timed out
int t=0;
while(t<seconds*10){
if(ele.findElements(By.xpath(xpath)).size()>0)
return true;
else{
Thread.sleep(100);
t++;
continue;
}
}
System.out.println("waited for "+seconds+"seconds. But couldn't find "+xpath+ " in the element specified");
return false;
}
I came up with answer like this. This will work only on groovy because it is using closure
private boolean refreshUntil(Closure<Boolean> condition) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(8, TimeUnit.SECONDS)
.pollingEvery(200, TimeUnit.MILLISECONDS)
.ignoring(NoSuchElementException)
wait.until(new Predicate<WebDriver>() {
boolean apply(WebDriver driver) {
driver.navigate().refresh()
if (condition()) {
return true
}
return false
}
})
return true
}
and calling this method
refreshUntil {
accountsBeforeCreation + 1 == driver.findElements(By.tagName("tr"))).size()
}

Selenium RC : Page is not loading compeletelly

When I run my selenium rc script page is not loading completely because of change in the urls.
Earlier it was working fine when url was something link this
https://testersworld.com/
But now it changed to (updated the URL in the script before run)
https://testersworld.com/#login
Because of which when I run the script browser launches with specified url but fails to displayed login popup.
How to handle this https://testersworld.com/#login which gives login pop after page load. I used all methods of wait.
try this:
driver.manage().deleteAllCookies();
driver.get("https://testersworld.com/");
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
or
driver.manage().deleteAllCookies();
driver.get("https://testersworld.com/");
Thread.sleep(1000);
or
select locator on login page (e.g. input login(e-mail ) field):
String cssLocator=..blablabla...;
and use fluentWait mechanism:
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo; } ;
fluentWait(By.cssSelector(cssLocator));