等待Selenium中的页面加载

xeos 发布于 2018-11-11 java 最后更新 2018-11-11 13:32 100 浏览

你如何让Selenium 2.0等待页面加载?

已邀请:

pporro

赞同来自:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
通过以上行,您的问题将得到解决。

riure

赞同来自:

我不认为隐含的等待是你想要的。尝试这个: driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS); documentation中的更多信息

oqui

赞同来自:

使用以下代码,页面加载非常简单。

 public void PageLoad(IWebDriver driver, By by)
        {
            try
            {
                Console.WriteLine("PageLoad" + by);
                WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
                wait.Until(ExpectedConditions.ElementIsVisible(by));
                wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); // 30 seconds wait until element not found. 
                wait.Until(ExpectedConditions.ElementToBeClickable(by));
}
            catch (Exception ex)
            {
Console.WriteLine(ex.Message);
                Assert.Fail("Element not found!")
            }
        }
我希望这可以帮助你。

dsit

赞同来自:

我很惊讶谓词并不是第一选择,因为你通常知道下一个要在你等待加载的页面上与之交互的元素。我的方法一直是构建像waitForElementByID(String id)waitForElemetVisibleByClass(String className)等谓词/函数,然后在我需要的地方使用和重用它们,无论是页面加载还是页面内容更改,我都在等待。 例如, 在我的测试类中:

driverWait.until(textIsPresent("expectedText");
在我的测试类父级中:
protected Predicate<WebDriver> textIsPresent(String text){
    final String t = text;
    return new Predicate<WebDriver>(){
        public boolean apply(WebDriver driver){
            return isTextPresent(t);
        }
    };
}
protected boolean isTextPresent(String text){
    return driver.getPageSource().contains(text);
}
虽然这看起来很多,但它会为您重复检查 并且可以设置检查频率的间隔以及最终 超时前等待时间。此外,您将重用此类方法。 在此示例中,父类定义并启动了WebDriver driverWebDriverWait driverWait。 我希望这有帮助。

cut

赞同来自:

隐含和明确的等待更好。 但是如果您在Java中处理异常,那么您可以使用它来等待页面重新加载:

Thead.sleep(1000);

ut_est

赞同来自:

使用此功能

public void waitForPageLoad(ChromeDriver d){
        String s="";
        while(!s.equals("complete")){
        s=(String) d.executeScript("return document.readyState");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
}

nquae

赞同来自:

您还可以使用类:ExpectedConditions显式等待元素显示在网页上,然后您可以采取任何操作进一步操作 您可以使用ExpectedConditions类来确定元素是否可见:

WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));
有关您可以检查的所有条件的列表,请参阅ExpectedConditions class Javadoc

nquas

赞同来自:

通常,使用Selenium 2.0时,Web驱动程序只应在确定页面已加载后才将控制权返回给调用代码。如果没有,您可以调用waitforelemement,它循环调用findelement直到找到或超时(可以设置超时)。

cea

赞同来自:

您可以使用此代码段来加载页面:

    IWait wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver,TimeSpan.FromSeconds(30.00));
    wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
或者你可以使用服务员来加载任何元素并在该页面上变得可见/可点击,最有可能在加载结束时加载,如:
    Wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpathOfElement));
    var element = GlobalDriver.FindElement(By.XPath(xpathOfElement));
    var isSucceededed = element != null;

adicta

赞同来自:

你可以使用等待。在硒中基本上有两种等待

  • 隐含等待
  • 明确等待
- 隐瞒等待 这很简单请看下面的语法:
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
- 明确等待 在此等待中明确等待或有条件等待,直到发生给定条件。
WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
您可以使用其他属性,如visblityOf()visblityOfElement()

jsed

赞同来自:

在此等待中明确等待或有条件等待直到给定条件。

 WebDriverWait wait = new WebDriverWait(wb, 60);
 wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));
这将等待每个web元素60秒。 隐式使用等待页面上每个元素的等待直到给定时间。
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
这将等待每个web元素60秒。 两者都很好。但我个人最喜欢的是明确等待,因为它更稳定

prem

赞同来自:

  1. WebDriver driver = new ff / chrome / anyDriverYouWish(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 等待最多10秒。
  2. WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(WebElement element));
  3. FluentWait<Driver> fluentWait; fluentWait = new FluentWait<>(driver).withTimeout(30, TimeUnit.SECONDS) .pollingEvery(200, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class);
最后一个选项的优点是您可以包含预期的异常,以便继续执行。

nsunt

赞同来自:

public static int counter = 0;
public void stepGeneralWait() {
boolean breakIt = true;
while (true) {
        breakIt = true;
        try {
do{
                // here put e.g. your spinner ID
                Controller.driver.findElement(By.xpath("//*[@id='static']/div[8]/img")).click();
                Thread.sleep(10000);
counter++;
if (counter > 3){
                    breakIt = false;
}
            }
            while (breakIt);
} catch (Exception e) {
            if (e.getMessage().contains("element is not attached")) {
                breakIt = false;
            }
        }
        if (breakIt) {
            break;
        }
}
try {
        Thread.sleep(12000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

icum

赞同来自:

如果要等待加载特定元素,可以在RenderedWebElement上使用isDisplayed()方法:

// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
    // Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
    RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));
// If results have been returned, the results are displayed in a drop down.
    if (resultsDiv.isDisplayed()) {
      break;
    }
}
(来自The 5 Minute Getting Started Guide的示例)

rsequi

赞同来自:

我使用node + selenium-webdriver(现在版本是3.5.0)。我为此做的是:

var webdriver = require('selenium-webdriver'),
    driver = new webdriver.Builder().forBrowser('chrome').build();
;
driver.wait(driver.executeScript("return document.readyState").then(state => {
  return state === 'complete';
}))

aet

赞同来自:

最简单的方法是等待一些元素出现在加载的页面上。 如果您想在页面加载后单击某个按钮,可以使用等待并单击:

await().until().at.most(20, TimeUnit.Seconds).some_element.isDisplayed(); // or another condition
getDriver().find(some_element).click;

uet

赞同来自:

您可以使用以下现有方法设置pageeLoadTimeout的时间 在下面的示例中,如果页面加载时间超过20秒,则会引发页面重新加载的异常

 WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS)

fet

赞同来自:

我见过的最好方法是利用stalenessOf ExpectedCondition,等待旧页面变得陈旧。 例:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));
它会等待十秒钟,旧的HTML标记变得陈旧,然后如果没有发生则抛出异常。

ea_qui

赞同来自:

private static void checkPageIsReady(WebDriver driver) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
// Initially bellow given if condition will check ready state of page.
        if (js.executeScript("return document.readyState").toString().equals("complete")) {
            System.out.println("Page Is loaded.");
            return;
        }
// This loop will rotate for 25 times to check If page Is ready after
        // every 1 second.
        // You can replace your value with 25 If you wants to Increase or
        // decrease wait time.
        for (int i = 0; i < 25; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            // To check page ready state.
            if (js.executeScript("return document.readyState").toString().equals("complete")) {
                break;
            }
        }
    }

reos

赞同来自:

我的简单方法:

long timeOut = 5000;
    long end = System.currentTimeMillis() + timeOut;
while (System.currentTimeMillis() < end) {
if (String.valueOf(
                    ((JavascriptExecutor) driver)
                            .executeScript("return document.readyState"))
                    .equals("complete")) {
                break;
            }
        }

mnatus

赞同来自:

这似乎是WebDriver的严重限制。显然等待一个元素并不意味着页面被加载,特别是DOM可以完全构建(onready状态),JS仍在执行,CSS和图像仍在加载。 我相信最简单的解决方案是在初始化所有内容后在onload事件上设置一个JS变量,并在Selenium中检查并等待这个JS变量。

xqui

赞同来自:

Ruby实现:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
    @driver.execute_script("return document.readyState;") == "complete" 
}

wsed

赞同来自:

您可以删除System.out行。它是为了调试目的而添加的。

WebDriver driver_;
public void waitForPageLoad() {
Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            System.out.println("Current Window State       : "
                + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
            return String
                .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
                .equals("complete");
        }
    });
}

dsit

赞同来自:

如果您设置驱动程序的隐式等待,然后对您希望在加载页面上的元素调用findElement方法,WebDriver将轮询该元素,直到找到该元素或达到超时值。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
来源:implicit-waits

phic

赞同来自:

driver.asserts().assertElementFound("Page was not loaded",
By.xpath("//div[@id='actionsContainer']"),Constants.LOOKUP_TIMEOUT);

prerum

赞同来自:

Imran的回答重新针对Java 7:

    WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver wdriver) {
            return ((JavascriptExecutor) driver).executeScript(
                "return document.readyState"
            ).equals("complete");
        }
    });

ut_et

赞同来自:

使用WebDriver的Java绑定时等待页面加载的最佳方法是使用PageFart设计模式和PageFactory。这允许您使用AjaxElementLocatorFactory,它只是作为所有元素的全局等待。它对诸如下拉框或复杂的javascript转换等元素有限制,但它会大大减少所需的代码量并加快测试时间。在这篇博文中可以找到一个很好的例子。假设对Core Java有基本的了解。 http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html

sest

赞同来自:

您还可以使用JavascriptExecutor接口及其executeAsyncScript()方法。例如,下面的命令等待4秒。

js.executeAsyncScript("window.setTimeout(arguments[arguments.length - 1], 4000);");
您可以在此链接中找到示例:http://www.swtestacademy.com/selenium-11-javascriptexecutor/

ysunt

赞同来自:

隐式使用等待页面上每个元素的等待直到给定时间。

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
这等待页面上的每个元素持续30秒。 另一个等待是在此等待中显式等待或有条件等待,直到给定条件。
WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
在id中,只要加载页面,就会在页面上显着地显示静态元素id。

equia

赞同来自:

对于隐式等待,您可以使用以下内容:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)
为了使网页等待特定对象可见或某些条件为真。您可以使用Web驱动程序的等待羽毛。
//120 is maximum number of seconds to wait.
WebDriverWait wait = new WebDriverWait(driver,120);  
wait.until(ExpectedConditions.elementToBeClickable("CONDITITON"));
在Java中,另一种选择是将线程休眠特定时间。
Thread.sleep(numberOfSeconds*1000); 
//This line will cause thread to sleep for seconds as variable
我创建了一个简化thread.sleep方法的方法
public static void wait_time(int seconds){
        try {
            Thread.sleep(seconds*1000);
            }catch (InterruptedException e) {
            // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
将该方法用作wait_time(10);线程将睡眠10秒钟。

qea

赞同来自:

在python中,您可以简单地使用:

driver.implicitly_wait(30)

tet

赞同来自:

您可以尝试使用此代码让页面完全加载,直到找到元素。

public void waitForBrowserToLoadCompletely() {
    String state = null;
    String oldstate = null;
    try {
        System.out.print("Waiting for browser loading to complete");
int i = 0;
        while (i < 5) {
            Thread.sleep(1000);
            state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
            System.out.print("." + Character.toUpperCase(state.charAt(0)) + ".");
            if (state.equals("interactive") || state.equals("loading"))
                break;
            /*
             * If browser in 'complete' state since last X seconds. Return.
             */
if (i == 1 && state.equals("complete")) {
                System.out.println();
                return;
            }
            i++;
        }
        i = 0;
        oldstate = null;
        Thread.sleep(2000);
/*
         * Now wait for state to become complete
         */
        while (true) {
            state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
            System.out.print("." + state.charAt(0) + ".");
            if (state.equals("complete"))
                break;
if (state.equals(oldstate))
                i++;
            else
                i = 0;
            /*
             * If browser state is same (loading/interactive) since last 60
             * secs. Refresh the page.
             */
            if (i == 15 && state.equals("loading")) {
                System.out.println("\nBrowser in " + state + " state since last 60 secs. So refreshing browser.");
                driver.navigate().refresh();
                System.out.print("Waiting for browser loading to complete");
                i = 0;
            } else if (i == 6 && state.equals("interactive")) {
                System.out.println(
                        "\nBrowser in " + state + " state since last 30 secs. So starting with execution.");
                return;
            }
Thread.sleep(4000);
            oldstate = state;
}
        System.out.println();
} catch (InterruptedException ie) {
        ie.printStackTrace();
    }
}

lut

赞同来自:

所有这些解决方案都适用于特定情况,但它们至少会遇到以下几个问题之一:

  1. 它们不够通用 - 它们希望您提前知道某些特定情况对于您要访问的页面是否正确(例如,某些元素将会显示)
  2. 他们对竞争条件持开放态度,您可以使用旧页面上实际存在的元素以及新页面。
这是我尝试避免这个问题的通用解决方案(在Python中): 首先,一个通用的“等待”函数(如果你愿意,可以使用WebDriverWait,我发现它们很难看):
def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))
接下来,该解决方案依赖于selenium为页面上的所有元素记录(内部)id号的事实,包括顶级<html>元素。当页面刷新或加载时,它会获得一个带有新ID的新html元素。 因此,假设您要单击带有文本“我的链接”的链接,例如:
old_page = browser.find_element_by_tag_name('html')
browser.find_element_by_link_text('my link').click()
def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id
wait_for(page_has_loaded)
对于更多Pythonic,可重用的通用助手,您可以创建一个上下文管理器:
from contextlib import contextmanager
@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')
yield
def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id
wait_for(page_has_loaded)
然后你可以在任何硒交互中使用它:
with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()
我认为那是防弹的!你怎么看? blog post about it here中的更多信息

snihil

赞同来自:

SeleniumWaiter:

import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
public class SeleniumWaiter {
private WebDriver driver;
public SeleniumWaiter(WebDriver driver) {
           this.driver = driver;
      }
public WebElement waitForMe(By locatorname, int timeout){
           WebDriverWait wait = new WebDriverWait(driver, timeout);
           return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
      }
public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
            // TODO Auto-generated method stub
            return new Function<WebDriver, WebElement>() {
                 @Override
                 public WebElement apply(WebDriver driver) {
                      return driver.findElement(locator);
                 }
            };
      }
 }
并且你使用它:
_waiter = new SeleniumWaiter(_driver);
try {
   _waiter.waitForMe(By.xpath("//..."), 10);
} 
catch (Exception e) {
   // Error
}

ncum

赞同来自:

How to get Selenium to wait for page load after a click提供以下有趣的方法:

  1. 从旧页面存储对WebElement的引用。
  2. 点击链接。
  3. 继续调用WebElement上的操作,直到抛出StaleElementReferenceException
示例代码:
WebElement link = ...;
link.click();
new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) ->
{
    try
    {
        link.isDisplayed();
        return false;
    }
    catch (StaleElementReferenceException unused)
    {
        return true;
    }
});

phic

赞同来自:

使用:

driver.manage().timeOuts().implicitlyWait(10, TimeUnit.SECONDS);
这意味着在网页上搜索元素可能需要一些时间来加载。在抛出异常之前设置了implicitlyWaitTimeUnit显示您想要等待的方式(秒,分钟,小时和天)。

et_id

赞同来自:

使用if条件和任何存在的元素

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

ciste

赞同来自:

此代码将等待,直到页面上的所有元素都加载到DOM中。

WebDriver driver = new WebDriver();
WebDriverWait wait = new WebDriverWait(driver, timeout);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*")));

znon

赞同来自:

您还可以使用以下代码检查pageloaded

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

vet

赞同来自:

使用WebDriverWait类 另请参阅here 你可以期待展示一些元素。像C#中的东西:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));
_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));

zquam

赞同来自:

Webdriver / Selenium 2软件测试工具中有两种类型的等待。其中一个是隐式等待,另一个是显式等待。两者(隐式等待和显式等待)对于在WebDriver中等待非常有用。使用等待,我们告诉WebDriver在进入下一步之前等待一段时间。您可以使用隐式等待页面加载等待。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

oillo

赞同来自:

NodeJS解决方案: 在Nodejs中,您可以通过承诺获得它... 如果您编写此代码,则可以确保在到达当时页面已完全加载...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));
如果您编写此代码,您将导航,selenium将等待3秒......
driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...
来自Selenium文档: this.get(url)→那么 安排命令导航到给定的URL。 返回在文档加载完成后将解析的promise。 Selenium Documentation (Nodejs)

bsequi

赞同来自:

您可以显式等待元素显示在网页上,然后才能执行任何操作(如element.click())

driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(new ExpectedCondition<WebElement>(){
        @Override
        public WebElement apply(WebDriver d) {
        return d.findElement(By.id("myDynamicElement"));
}});
这是我用于类似场景的工作,它工作正常。

daut

赞同来自:

/**
 * Call this method before an event that will change the page.
 */
private void beforePageLoad() {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("document.mpPageReloaded='notYet';");
}
/**
 * Call this method after an event that will change the page.
 * 
 * @see #beforePageLoad
 * 
 *      Waits for the previous page to disappear.
 */
private void afterPageLoad() throws Exception {
    (new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() {
@Override
        public boolean apply(WebDriver driver) {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            Object obj = js.executeScript("return document.mpPageReloaded;");
            if (obj == null) {
                return true;
            }
            String str = (String) obj;
            if (!str.equals("notYet")) {
                return true;
            }
            return false;
        }
    });
}
在仅更改文档的一部分的情况下,您可以从文档更改为元素。 这项技术的灵感来自于自上而下的答案。

要回复问题请先登录注册