我在Java使用WebDriver,我有一个自定义的方法来等待DOM事件(通过JQuery):
public void waitForJQuery(WebDriver driver) {
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
JavascriptExecutor js = (JavascriptExecutor) d;
return (Boolean) js.executeScript("return jQuery.active == 0");
}
});
}
当测试命中此方法并抛出错误时:
org.openqa.selenium.WebDriverException: jQuery is not defined
Build info: version: '2.37.0', revision: 'a7c61cb', time: '2013-10-18 17:14:00'
System info: host: 'WMWIN70089', ip: '10.68.44.231', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0'
Driver info: driver.version: unknown
Command duration or timeout: 190 milliseconds
Build info: version: '2.37.0', revision: 'a7c61cb', time: '2013-10-18 17:15:02'
System info: host: 'LMWIN70038', ip: '10.86.44.35', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_17'
Session ID: 2cf19cb9-edcd-463e-b77e-0121eb05e246
Driver info: org.openqa.selenium.remote.RemoteWebDriver
Capabilities [{platform=XP, acceptSslCerts=true, javascriptEnabled=true, browserName=firefox, rotatable=false, locationContextEnabled=true, webdriver.remote.sessionid=2cf19cb9-edcd-463e-b77e-0121eb05e246, version=25.0.1, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, browserConnectionEnabled=true, nativeEvents=true, webStorageEnabled=true, applicationCacheEnabled=true, takesScreenshot=true}]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:193)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:554)
at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:463)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.openqa.selenium.remote.Augmenter$CompoundHandler.intercept(Augmenter.java:280)
at org.openqa.selenium.remote.RemoteWebDriver$$EnhancerByCGLIB$$13369d6d.executeScript(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.openqa.selenium.support.events.EventFiringWebDriver$2.invoke(EventFiringWebDriver.java:101)
at com.sun.proxy.$Proxy10.executeScript(Unknown Source)
at org.openqa.selenium.support.events.EventFiringWebDriver.executeScript(EventFiringWebDriver.java:209)
at driver.core.web.core.WebDriverMaster$2.apply(WebDriverMaster.java:186)
at driver.core.web.core.WebDriverMaster$2.apply(WebDriverMaster.java:1)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:208)
at driver.core.web.core.WebDriverMaster.waitForJQuery(WebDriverMaster.java:183)
at driver.services.web.ib4b.template.CreateTemplateDetails.searchItemBy(CreateTemplateDetails.java:364)
at driver.services.web.csu.regression.testSearchAndSort.testSearchByAllFields(testSearchAndSort.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
你能帮我解决这个问题吗?
谢谢。
您可以添加一个检查以查看jQuery
是否首先定义,这样它就不会抛出异常:
public void waitForJQuery(WebDriver driver) {
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
JavascriptExecutor js = (JavascriptExecutor) d;
return (Boolean) js.executeScript("return !!window.jQuery && window.jQuery.active == 0");
}
});
}
这就是我最终让它工作的方式(带有一些用于调试的打印输出)。
从这里改编:
http://pastebin.com/3uMWQ5L0
private static void waitForPageLoad(WebDriver driver) {
System.out.println("Wating for ready state complete");
(new WebDriverWait(driver, 5)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
JavascriptExecutor js = (JavascriptExecutor) d;
String readyState = js.executeScript("return document.readyState").toString();
System.out.println("Ready State: " + readyState);
return (Boolean) readyState.equals("complete");
}
});
}
调试输出:
Wating for ready state complete
Ready State: interactive
Ready State: interactive
Ready State: complete
对于JQuery,只需将"返回文档. readyState"
替换为"返回!!window.jQuery
这里是没有调试信息的JQuery代码(我希望不那么混乱)。
private static void waitForJQuery(PhantomJSDriver driver) {
(new WebDriverWait(driver, 5)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
JavascriptExecutor js = (JavascriptExecutor) d;
return (Boolean) js.executeScript("return !!window.jQuery && window.jQuery.active == 0");
}
});
}