我们是否有任何通用function来检查页面是否已在Selenium中完全加载
我试图在selenium中检查网页是否已加载完成(即检查是否已加载所有控件)。
我尝试下面的代码:
new WebDriverWait(firefoxDriver, pageLoadTimeout).until( webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
但即使页面加载上面的代码也不会等待。
我知道我可以检查特定元素以检查它是否可见/可点击等,但我正在寻找一些通用的解决方案
正如您所提到的,如果有任何通用function来检查页面是否已在Selenium中完全加载,则答案为否 。
首先让我们看一下您的代码试用,如下所示:
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
上面一行代码中的参数pageLoadTimeout并不真正与实际的pageLoadTimeout()
相似。
在这里,您可以找到Selenium中pageLoadTimeout的详细讨论
现在,当您的用例与完全加载的页面相关时,您可以使用DesiredCapabilities类或ChromeOptions类的实例将pageLoadStrategy()
设置为normal
[支持的值为none , eager或normal ],如下所示:
-
使用DesiredCapabilities类:
import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxOptions; import org.openqa.selenium.remote.DesiredCapabilities; public class myDemo2 { public static void main(String[] args) throws Exception { System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe"); DesiredCapabilities dcap = new DesiredCapabilities(); dcap.setCapability("pageLoadStrategy", "normal"); FirefoxOptions opt = new FirefoxOptions(); opt.merge(dcap); WebDriver driver = new FirefoxDriver(opt); driver.get("https://www.google.com/"); System.out.println(driver.getTitle()); driver.quit(); } }
-
使用ChromeOptions类:
import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxOptions; import org.openqa.selenium.PageLoadStrategy; public class myDemo1 { public static void main(String[] args) throws Exception { System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe"); FirefoxOptions opt = new FirefoxOptions(); opt.setPageLoadStrategy(PageLoadStrategy.NORMAL); WebDriver driver = new FirefoxDriver(opt); driver.get("https://www.google.com/"); System.out.println(driver.getTitle()); driver.quit(); } }
您可以在Page load strategy for Chrome driver (Updated till Selenium v3.12.0)
找到详细讨论Page load strategy for Chrome driver (Updated till Selenium v3.12.0)
现在将PageLoadStrategy设置为NORMAL
并且您的代码试用版都确保浏览器客户端 (即Web浏览器 )已达到'document.readyState'
等于"complete"
。 一旦满足此条件,Selenium将执行下一行代码。
您可以在Selenium IE WebDriver only works while debugging
找到详细的讨论Selenium IE WebDriver only works while debugging
但是,实现'document.readyState'
等于"complete"
的浏览器客户端仍然不能保证所有JavaScript和Ajax调用都已完成。
要等待所有JavaScript和Ajax调用完成,您可以编写如下函数:
public void WaitForAjax2Complete() throws InterruptedException { while (true) { if ((Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")){ break; } Thread.sleep(100); } }
您可以在Wait for ajax request to complete - selenium webdriver
找到详细讨论Wait for ajax request to complete - selenium webdriver
现在,通过PageLoadStrategy和“return jQuery.active == 0”的上述两种方法看起来都在等待无限期事件。 因此,对于一个明确的等待,您可以引导WebDriverWait与设置为titleContains()
方法的ExpectedConditions
,这将确保页面标题 (即网页 )可见并假设所有元素也可见如下:
driver.get("https://www.google.com/"); new WebDriverWait(driver, 10).until(ExpectedConditions.titleContains("partial_title_of_application_under_test")); System.out.println(driver.getTitle()); driver.quit();
现在,有时页面标题可能与您的应用程序标题匹配,但您想要交互的所需元素仍未完成加载。 因此,更细粒度的方法是将WebDriverWait与ExpectedConditions
设置为visibilityOfElementLocated()
方法联系起来,这将使您的程序等待所需元素可见 ,如下所示:
driver.get("https://www.google.com/"); WebElement ele = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("xpath_of_the_desired_element"))); System.out.println(ele.getText()); driver.quit();
我也使用selenium,我遇到了同样的问题,修复我只是等待jQuery加载。
所以如果你有同样的问题,也试试这个
((Long) ((JavascriptExecutor) browser).executeScript("return jQuery.active") == 0);
您可以将两个函数包装在一个方法中并检查,直到加载了页面和jQuery
实现这一点,它为包括我在内的许多人工作。 它包括JavaScript页面等待,Angular,JQuery,如果它在那里。
如果您的应用程序包含Javascript和JQuery,您只能编写代码,
通过单一方法定义它,您可以在任何地方调用它:
// Wait for jQuery to load { ExpectedCondition jQueryLoad = driver -> ((Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active") == 0); boolean jqueryReady = (Boolean) js.executeScript("return jQuery.active==0"); if (!jqueryReady) { // System.out.println("JQuery is NOT Ready!"); wait.until(jQueryLoad); } wait.until(jQueryLoad); } // Wait for ANGULAR to load { String angularReadyScript = "return angular.element(document).injector().get('$http').pendingRequests.length === 0"; ExpectedCondition angularLoad = driver -> Boolean.valueOf(((JavascriptExecutor) driver).executeScript(angularReadyScript).toString()); boolean angularReady = Boolean.valueOf(js.executeScript(angularReadyScript).toString()); if (!angularReady) { // System.out.println("ANGULAR is NOT Ready!"); wait.until(angularLoad); } } // Wait for Javascript to load { ExpectedCondition jsLoad = driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").toString() .equals("complete"); boolean jsReady = (Boolean) js.executeScript("return document.readyState").toString().equals("complete"); // Wait Javascript until it is Ready! if (!jsReady) { // System.out.println("JS in NOT Ready!"); wait.until(jsLoad); } }
单击此处查看参考链接
如果您坚持执行,请告诉我。
它克服了Thread或Explicit Wait的使用。
public static void waitForPageToLoad(long timeOutInSeconds) { ExpectedCondition expectation = new ExpectedCondition () { public Boolean apply(WebDriver driver) { return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"); } }; try { System.out.println("Waiting for page to load..."); WebDriverWait wait = new WebDriverWait(Driver.getDriver(), timeOutInSeconds); wait.until(expectation); } catch (Throwable error) { System.out.println( "Timeout waiting for Page Load Request to complete after " + timeOutInSeconds + " seconds"); } }
试试这个方法