我正在使用Selenium来测试我的用户界面。
我正在尝试使用@ FindBy-Annotation。以下代码可以正常工作:
@FindBy(how=How.XPATH, xpath ="//input[contains(@id,'idOfInputField')]")
private WebElement someWebElement;
private void someMethod(){
WebElement a = someWebElement.findElement(By.xpath("//a[contains(@class, 'ui-spinner-up')][1]"));
WebElement span1 = a.findElement(By.xpath("//a[contains(@class, 'ui-spinner-up')][1]"));
WebElement span2 = span1.findElement(By.xpath("//span[contains(@class, 'ui-button-text')][1]"));
WebElement b = span2.findElement(By.xpath("//span[contains(@class,'ui-icon ui-icon-triangle-1-n')]"));
b.click();
}
我想使用以下代码,因为它是基于注释的,但它不起作用,虽然我认为它完全相同:
@FindBy(how=How.XPATH, xpath ="//input[contains(@id,'idOfInputField')]"
+ "//a[contains(@class, 'ui-spinner-up')][1]"
+ "//a[contains(@class, 'ui-spinner-up')][1]"
+ "//span[contains(@class, 'ui-button-text')][1]"
+ "//span[contains(@class,'ui-icon ui-icon-triangle-1-n')]")
private WebElement someWebElement;
pivate void someMethod(){
someWebElement.click();
}
我得到的是以下例外:
java.lang.RuntimeException: Cannot invoke click on element null. Cannot find it.
Cause: org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"//input[contains(@id,'idOfInputField')]//a[contains(@class, 'ui-spinner-up')][1]//span[contains(@class, 'ui-button-text')][1]//span[contains(@class,'ui-icon ui-icon-triangle-1-n')]"}
Command duration or timeout: 14 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.32.0', revision: '6c40c187d01409a5dc3b7f8251859150c8af0bcb', time: '2013-04-09 10:39:28'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '3.5.0-28-generic', java.version: '1.7.0_21'
Session ID: 92f605a1-0a63-4ba0-b290-ca724b3c6386
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{platform=LINUX, databaseEnabled=true, cssSelectorsEnabled=true, javascriptEnabled=true, acceptSslCerts=true, handlesAlerts=true, browserName=firefox, browserConnectionEnabled=true, nativeEvents=false, webStorageEnabled=true, rotatable=false, locationContextEnabled=true, applicationCacheEnabled=true, takesScreenshot=true, version=20.0}]
at path.to.package.utils.StaleReferenceAwareFieldDecorator$StaleReferenceAwareElementLocator.in
voke(StaleReferenceAwareFieldDecorator.java:86)
at com.sun.proxy.$Proxy9.click(Unknown Source)
at
....
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
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)
有些机构可以解释这种行为的原因,或者这两段代码之间是否存在差异?
答案 0 :(得分:3)
首先,你不能使用这样一个错综复杂的xpath,它会破坏页面对象的可读性。您的选择器应尽可能简洁。其次,您不应该使用XPATH并使用CSS选择器。现在回到你的问题,
@FindBy(css="span[class*='ui-icon-triangle-1-n']")
WebElement b;
或尝试
@FindBy(css="span[class*='ui-button-text']>span[class*='ui-icon-triangle-1-n']")
WebElement b;
答案 1 :(得分:1)
//a[contains(@class, 'ui-spinner-up')][1]
的XPath选择器,但在你的第二个例子中只有一个...可能会导致你的问题。
答案 2 :(得分:0)
PageFactory类通过.initObjects方法使用@FindBy注释来加载注释。如果我的页面对象通过扩展LoadableComponent来实现LoadableComponent接口,那么我会使用这个方法。 (注意:当然,通过扩展LoadableComponent,您不能通过页面对象扩展另一个类,但如果在实现的接口中使用静态方法,JDK8功能,那么您可以获得类似于扩展多个类的功能,或者像traits / mixins 。)
答案 3 :(得分:0)
页面对象需要装饰对象。我认为你得到这个错误,因为你没有装饰所需的类。使用方法initElements(yourdriverobject,classToBeDecorated)。这应该可以解决问题。如果您需要任何帮助,请告诉我。