Selenium - Wait for Javascript function to execute before continuing
Solution 1
** EDIT 3**
So we have:
DefaultSelenium selenium = new DefaultSelenium("localhost",4444,"*iexplore", "websiteURL");
Still you can use the command isVisible
like this:
boolean doTheLoop = true;
int i = 0;
while (doTheLoop){
i = i+200;
Thread.sleep(200);
if (i>30000){
doTheLoop = false;
}
if (!selenium.isVisible("id=the ID Of element")){
doTheLoop = false;
}
}
Hope you will not end up in infinite loop.
I never worked with DefaultSelenium, so use please the isVisible()
function the same way as you are using the click()
for example.
Solution 2
You can use waitForCondition
And if you're using WebDriver, you can try WebDriverBackedSelenium or FluentWait.
I think this link will help.
Solution 3
You should try this. It waits until the specified timeout. And what it waits for is specified in the FluentWait-object. It waits until the Boolean gets true. So if your element is not visible any more, the Boolean gets true and the method stops waiting. The nice thing about this is that it only asks every 1 second if your element is visible instead of asking as fast as it can which makes no sense.
public static void wait(WebDriver driver, int timeout, final By locator){
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(timeout, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class)
wait.until(new Function<WebDriver, Boolean>() {
public Boolean apply(WebDriver driver) {
WebElement element = driver.findElement(locator);
return !element.isDisplayed();
}
});
}
EDIT: As you wrote in your comments and in your edit, it seems that you use Selenium 1. WebDriver is part of Selenium 2. So just get the wrapped driver like this:
Selenium selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "website-url");
CommandExecutor executor = new SeleneseCommandExecutor(selenium);
WebDriver driver = new RemoteWebDriver(executor, new DesiredCapabilities());
Kevin Maschke
Updated on July 09, 2022Comments
-
Kevin Maschke almost 2 years
I'm currently creating some test cases with Selenium and I've come across a problem.
In my test case, the website I'm trying to walk through has a small form and a button to search. No problem filling the form and clicking the button. The problem comes once clicking the problem.
Once clicked the button, this function is called:
function muestraEspera(){ document.getElementById("divCargando").style.display = ""; }
Basically, this makes visible a DIV which contains an "loading" image so the visitor do just see the image and wont be able to actually see the website loading the content until finished (the content is loaded with ajax).
Once the content is loaded, this function is executed:
function escondeEspera(){ document.getElementById("divCargando").style.display = "none"; }
Which basically hides the "loading" DIV so the visitor can see the results.
Now, I can't use SLEEPS because loading can take more or less, and because I need the real execution time of the website. Is there any way (using java - junit4) to make selenium wait until the second function is executed before continuing with the next steps?
EDIT: I do use Selenium RC. To start the driver I use:
public void setUp() throws Exception { selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "website-url"); selenium.start(); }
At the end, the solution that worked perfectly for me, given by Pavel Janicek is:
boolean doTheLoop = true; int i = 0; while (doTheLoop){ i= i+200; Thread.sleep(1000); if (i>30000){ doTheLoop = false; } if (!selenium.isVisible("id=divCargando")){ doTheLoop = false; } if (selenium.isVisible("id=divCargando")){ doTheLoop = true; } }
-
Kevin Maschke about 12 yearsUsing ----- FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(200, TimeUnit.SECONDS) .pollingEvery(1, TimeUnit.SECONDS) .ignoring(NoSuchElementException.class); wait.until(new Function<WebDriver, Boolean>() { public Boolean apply(WebDriver driver) { WebElement element = driver.findElement(divCargando); return !element.isDisplayed(); } }); ----- I do get this error: "Driver cannot be resolved to a variable"
-
Kevin Maschke about 12 yearsBoth methods give me these errors: "driver cannot be resolved" and "The method isVisible() is undefined for the type WebElement"..
-
Kevin Maschke about 12 yearsHow would you use it? I tried it with waitForCondition and I could not get it to work... :(
-
Pavel Janicek about 12 yearsI forgot to mention - the
driver
is instance of WebDriver. I will update the answer a little. -
Pavel Janicek about 12 yearsThe waitForCondition seems to be Selenium-IDE related. Will not work if you use WebDriver approach.
-
tester about 12 yearsCan you provide a stack trace? driver is an WebDriver instance, like FirefoxDiver or RemoteWebDriver.
-
Kevin Maschke about 12 yearsThe thing is that I use selenium RC: selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "website-url");
-
Pavel Janicek about 12 yearsOr more generally - can you provide how do you initialize the WebDriver?
-
Kevin Maschke about 12 yearsI do use: selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "website-url"); To start the driver. Selenium RC.
-
Pavel Janicek about 12 yearsEditing once more. I will provide the quickest solution found:
WebDriver driver = selenium.getWrappedDriver();
-
tester about 12 yearsYou use Selenium 1. Just add the following after your DefaultSelenium: CommandExecutor executor = new SeleneseCommandExecutor(selenium); WebDriver driver = new RemoteWebDriver(executor, new DesiredCapabilities());
-
Kevin Maschke about 12 yearsJust one problem using this solution: "The method getWrappedDriver() is undefined for the type Selenium"
-
Kevin Maschke about 12 yearsHere I do get: "RemoteWebDriver cannot be resolved to a type"
-
tester about 12 yearsare you sure you imported org.openqa.selenium.remote.RemoteWebDriver ?
-
Pavel Janicek about 12 yearsDarn! I provided you the answer for WebDriverBackedSelenium class, which I am using sometimes. Never worked with DefaultSelenium class. Will have to look...
-
Kevin Maschke about 12 yearsSORRY!! I missed that one. I imported it and that error disappeared. Now the only error left is: "The type Function is not generic; it cannot be parameterized with arguments <WebDriver, Boolean>".
-
tester about 12 yearsSure it can. the code which I posted works. Are you sure we are talking about the same Function-class? It is com.google.common.base.Function. And furthermore this thread is gonna turn into a Java-coding problem than the original problem with selenium. I tested the code I posted and it works and solves your problem.
-
Kevin Maschke about 12 yearsThanks a lot for your help! But at the end the solution provided by Pavel Janicek worked like a charm. Thanks a lot :D I would give you a PLUS vote, but I haven't got enough rep.. :(
-
Kevin Maschke about 12 yearsThanks a lot! This worked great! I just added: if (selenium.isVisible("id=divCargando")){ doTheLoop = true;} This way once the div is hidden, next step is done like a charm! Thank you very much!
-
Kevin Maschke about 12 yearsCan't mark two answers as solution. And the other one worked perfectly for me.
-
Pavel Janicek about 12 yearsUff! At least something :) Happy testing to you ;)
-
tester about 12 yearsThats what I meant. Mark HIS answer as solution. not mine.