如你所提到的,如果有任何通用函数可以通过Selenium检查页面是否完全加载,答案是没有。
首先让我们看一下你的代码试验,它是这样的:
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
上述代码中的参数
pageLoadTimeout
并不真正类似于实际的
pageLoadTimeout()。
在这里,您可以找到有关
Selenium中pageLoadTimeout不起作用的详细讨论。
现在,由于您的用例涉及页面完全加载,您可以使用
pageLoadStrategy()设置为
normal
[支持的值为
none,
eager或
normal],通过
DesiredCapabilities类或
ChromeOptions类的实例来实现:
Using DesiredCapabilities Class :
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 myDemo
{
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();
}
}
Using ChromeOptions Class :
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.PageLoadStrategy;
public class myDemo
{
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();
}
}
您可以在
Chrome驱动程序页面加载策略(更新至Selenium v3.12.0)中找到详细讨论。
现在将
PageLoadStrategy设置为
NORMAL,您的代码试验都确保了
浏览器客户端已经达到了
'document.readyState'
等于
"complete"
。一旦满足这个条件,Selenium就会执行下一行代码。
您可以在
Selenium IE WebDriver仅在调试时有效中找到详细讨论。
但是,
浏览器客户端达到
'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);
}
}
你可以在等待Ajax请求完成 - Selenium WebDriver中找到详细的讨论。
现在,通过PageLoadStrategy和"return jQuery.active == 0"
这两种方法似乎正在等待无限事件。因此,为了确切地等待,您可以引入WebDriverWait结合ExpectedConditions设置为titleContains()方法,这将确保页面标题(即网页)可见并假定所有元素也可见,如下所示:
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();
有时候,尽管页面标题(Page Title)与您的应用程序标题(Application Title)相匹配,但是您想要交互的目标元素尚未加载完成。因此,一种更加细致的方法是结合ExpectedConditions设置为visibilityOfElementLocated()方法,使用WebDriverWait使程序等待所需的元素可见,如下所示:
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();
参考资料
您可以在以下几个讨论中找到一些相关的详细讨论: