Selenium - 等待 Javascript 函数执行后再继续

发布于 2025-01-05 07:18:27 字数 1293 浏览 4 评论 0原文

我目前正在使用 Selenium 创建一些测试用例,但遇到了一个问题。

在我的测试用例中,我尝试浏览的网站有一个小表单和一个搜索按钮。填写表格并单击按钮没有问题。一旦点击问题,问题就来了。

一旦单击按钮,就会调用此函数:

function muestraEspera(){
document.getElementById("divCargando").style.display = "";
}

基本上,这会使包含“正在加载”图像的 DIV 可见,因此访问者只能看到该图像,并且在完成之前无法实际看到网站正在加载内容(内容是加载ajax)。

加载内容后,就会执行此函数:

function escondeEspera(){
document.getElementById("divCargando").style.display = "none";
}

这基本上隐藏了“正在加载”DIV,以便访问者可以看到结果。

现在,我无法使用 SLEEPS,因为加载可能需要或多或少的时间,而且我需要网站的实际执行时间。有什么方法(使用 java - junit4)让 selenium 等到第二个函数执行后再继续下一步?

编辑:我确实使用 Selenium RC。要启动我使用的驱动程序:

public void setUp() throws Exception {
        selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "website-url");
        selenium.start();
    }

最后,Pavel Janicek 给出的最适合我的解决方案是:

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;
          }      
     }

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;
          }      
     }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半枫 2025-01-12 07:18:27

您可以使用 waitForCondition
如果您使用 WebDriver,则可以尝试 WebDriverBackedSelenium 或 FluentWait。
我认为此链接会有所帮助。

You can use waitForCondition
And if you're using WebDriver, you can try WebDriverBackedSelenium or FluentWait.
I think this link will help.

醉南桥 2025-01-12 07:18:27

你应该尝试这个。它会等待,直到指定的超时时间。它等待的内容在 FluentWait 对象中指定。它会等到布尔值变为真。因此,如果您的元素不再可见,布尔值将变为 true 并且该方法将停止等待。这样做的好处是,它只每 1 秒询问一次元素是否可见,而不是尽可能快地询问,这是没有意义的。

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

编辑:正如您在评论和编辑中所写的那样,您似乎使用了 Selenium 1。WebDriver 是 Selenium 2 的一部分。所以只需像这样获取包装的驱动程序:

Selenium selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "website-url");
CommandExecutor executor = new SeleneseCommandExecutor(selenium); 
WebDriver driver = new RemoteWebDriver(executor, new DesiredCapabilities());

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());
墨洒年华 2025-01-12 07:18:27

** 编辑 3**

所以我们有:

DefaultSelenium selenium = new DefaultSelenium("localhost",4444,"*iexplore", "websiteURL");

您仍然可以像这样使用命令 isVisible

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;
      }      
}

希望您不会陷入无限循环。

我从未使用过 DefaultSelenium,因此请像使用 click() 一样使用 isVisible() 函数。

** 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文