使用“@AndroidFindBy()”定位元素时获取 "NoSuchElementException"
Getting "NoSuchElementException" when using "@AndroidFindBy()" to locate an element
设置如下:
Android 模拟器版本:Nexus 5X API 27、Android 8.1(Google 播放)和浏览器:Google Chrome
我的声明如下:
@AndroidFindBy(id = "user_login")
WebElement user_login;
@AndroidFindBy(id = "user_pass")
WebElement user_pass;
@AndroidFindBy(id = "wp-submit")
WebElement wp_submit;
String url = "http://demosite.center/wordpress/wp-login.php";
HTML:
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="Log In">
使用 WebElements 的方法
public void enter(String usr, String pwd) {
try {
user_login.sendKeys(usr);
System.out.println("entered username");
Thread.sleep(2000);
user_pass.sendKeys(pwd);
System.out.println("entered password");
Thread.sleep(2000);
wp_submit.click();
System.out.println("clicked login button");
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
我得到的异常是:
[RemoteTestNG] detected TestNG version 6.14.3
May 08, 2019 11:31:22 AM io.appium.java_client.remote.AppiumCommandExecutor lambda[=14=]
INFO: Detected dialect: OSS
entered username
entered password
org.openqa.selenium.NoSuchElementException: Can't locate an element by this strategy: by id or name "wp_submit"
at io.appium.java_client.pagefactory.AppiumElementLocator.findElement(AppiumElementLocator.java:126)
at io.appium.java_client.pagefactory.interceptors.InterceptorOfASingleElement.intercept(InterceptorOfASingleElement.java:60)
at io.appium.java_client.android.AndroidElement$$EnhancerByCGLIB$$b598166c.click(<generated>)
at com.pages.DemoSiteWpLoginPage.enter(DemoSiteWpLoginPage.java:41)
at com.tests.LoginTest.demoAutTest(LoginTest.java:44)
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.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Caused by: org.openqa.selenium.TimeoutException: Expected condition failed: waiting for io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction@3e2059ae (tried for 1 second(s) with 500 milliseconds interval)
at org.openqa.selenium.support.ui.FluentWait.timeoutException(FluentWait.java:315)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:283)
at io.appium.java_client.pagefactory.AppiumElementLocator.waitFor(AppiumElementLocator.java:99)
at io.appium.java_client.pagefactory.AppiumElementLocator.findElement(AppiumElementLocator.java:119)
... 29 more
Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"name","selector":"wp_submit"}
(Session info: chrome=61.0.3163.98)
(Driver info: chromedriver=2.30.477700 (0057494ad8732195794a7b32078424f92a5fce41),platform=Windows NT 10.0.17763 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z'
System info: host: 'M5-D-BZCJQM2', ip: '10.222.46.14', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_201'
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities {browserName: Chrome, databaseEnabled: false, desired: {browserName: Chrome, deviceName: emulator-5554, newCommandTimeout: 100, platformName: Android, platformVersion: 8.1}, deviceManufacturer: Google, deviceModel: Android SDK built for x86, deviceName: emulator-5554, deviceScreenSize: 1080x1920, deviceUDID: emulator-5554, javascriptEnabled: true, locationContextEnabled: false, networkConnectionEnabled: true, newCommandTimeout: 100, platform: LINUX, platformName: Android, platformVersion: 8.1.0, takesScreenshot: true, warnings: {}, webStorageEnabled: false}
Session ID: fb0e8048-7572-4f4d-bc07-b5ac0a219c08
*** Element info: {Using=name, value=wp_submit}
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:214)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166)
at org.openqa.selenium.remote.http.JsonHttpResponseCodec.reconstructValue(JsonHttpResponseCodec.java:40)
at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:80)
at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:44)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:231)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:42)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:322)
at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:62)
at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElement(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.findElementByName(RemoteWebDriver.java:400)
at io.appium.java_client.DefaultGenericMobileDriver.findElementByName(DefaultGenericMobileDriver.java:118)
at io.appium.java_client.AppiumDriver.findElementByName(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElementByName(AndroidDriver.java:1)
at org.openqa.selenium.By$ByName.findElement(By.java:284)
at org.openqa.selenium.support.ByIdOrName.findElement(ByIdOrName.java:50)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:314)
at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:58)
at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElement(AndroidDriver.java:1)
at io.appium.java_client.pagefactory.bys.ContentMappedBy.findElement(ContentMappedBy.java:50)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:314)
at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:58)
at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElement(AndroidDriver.java:1)
at io.appium.java_client.pagefactory.AppiumElementLocator.lambda[=14=](AppiumElementLocator.java:120)
at io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction.apply(AppiumElementLocator.java:172)
at io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction.apply(AppiumElementLocator.java:1)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:260)
... 31 more
PASSED: demoAutTest
===============================================
Default test
Tests run: 1, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
我的假设:脚本使用 WebElement 的变量名来定位 UI 上的元素,而不是我在 @AndroidFindBy 中传递的定位器。
如果需要我提供更多信息,请告诉我。
编辑 1:
@AndroidFindBy(id = "user_login")
WebElement userName;
以上内容无效
@AndroidFindBy(id = "user_login")
WebElement user_login;
将变量名更改为 id 的名称后,上面的工作正常
在此处发布问题之前,我已经 google 并参考了以下参考资料,但它们对 @AndroidFindBy 的实现略有不同,或者没有使用过这种方法。
https://discuss.appium.io/t/nosuchelementexception-when-element-is-actually-present/18711/30
根据@AndroidFindBy
annotation documentation
Used to mark a field on a Page Object to indicate an alternative mechanism for locating the element or a list of elements. Used in conjunction with PageFactory this allows users to quickly and easily create PageObjects. using Android UI selectors, accessibility, id, name, class name, tag and xpath
这意味着您可以使用此注释来访问 Android UI 元素,例如浏览器 "Back" 和 "Reload" 按钮
鉴于您在 Chrome 浏览器中自动化网页,您应该将所有出现的 @AndroidFindBy
替换为 @FindBy
from org.openqa.selenium.support package
更多信息:
设置如下: Android 模拟器版本:Nexus 5X API 27、Android 8.1(Google 播放)和浏览器:Google Chrome
我的声明如下:
@AndroidFindBy(id = "user_login")
WebElement user_login;
@AndroidFindBy(id = "user_pass")
WebElement user_pass;
@AndroidFindBy(id = "wp-submit")
WebElement wp_submit;
String url = "http://demosite.center/wordpress/wp-login.php";
HTML:
<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="Log In">
使用 WebElements 的方法
public void enter(String usr, String pwd) {
try {
user_login.sendKeys(usr);
System.out.println("entered username");
Thread.sleep(2000);
user_pass.sendKeys(pwd);
System.out.println("entered password");
Thread.sleep(2000);
wp_submit.click();
System.out.println("clicked login button");
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
我得到的异常是:
[RemoteTestNG] detected TestNG version 6.14.3
May 08, 2019 11:31:22 AM io.appium.java_client.remote.AppiumCommandExecutor lambda[=14=]
INFO: Detected dialect: OSS
entered username
entered password
org.openqa.selenium.NoSuchElementException: Can't locate an element by this strategy: by id or name "wp_submit"
at io.appium.java_client.pagefactory.AppiumElementLocator.findElement(AppiumElementLocator.java:126)
at io.appium.java_client.pagefactory.interceptors.InterceptorOfASingleElement.intercept(InterceptorOfASingleElement.java:60)
at io.appium.java_client.android.AndroidElement$$EnhancerByCGLIB$$b598166c.click(<generated>)
at com.pages.DemoSiteWpLoginPage.enter(DemoSiteWpLoginPage.java:41)
at com.tests.LoginTest.demoAutTest(LoginTest.java:44)
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.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Caused by: org.openqa.selenium.TimeoutException: Expected condition failed: waiting for io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction@3e2059ae (tried for 1 second(s) with 500 milliseconds interval)
at org.openqa.selenium.support.ui.FluentWait.timeoutException(FluentWait.java:315)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:283)
at io.appium.java_client.pagefactory.AppiumElementLocator.waitFor(AppiumElementLocator.java:99)
at io.appium.java_client.pagefactory.AppiumElementLocator.findElement(AppiumElementLocator.java:119)
... 29 more
Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"name","selector":"wp_submit"}
(Session info: chrome=61.0.3163.98)
(Driver info: chromedriver=2.30.477700 (0057494ad8732195794a7b32078424f92a5fce41),platform=Windows NT 10.0.17763 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z'
System info: host: 'M5-D-BZCJQM2', ip: '10.222.46.14', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_201'
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities {browserName: Chrome, databaseEnabled: false, desired: {browserName: Chrome, deviceName: emulator-5554, newCommandTimeout: 100, platformName: Android, platformVersion: 8.1}, deviceManufacturer: Google, deviceModel: Android SDK built for x86, deviceName: emulator-5554, deviceScreenSize: 1080x1920, deviceUDID: emulator-5554, javascriptEnabled: true, locationContextEnabled: false, networkConnectionEnabled: true, newCommandTimeout: 100, platform: LINUX, platformName: Android, platformVersion: 8.1.0, takesScreenshot: true, warnings: {}, webStorageEnabled: false}
Session ID: fb0e8048-7572-4f4d-bc07-b5ac0a219c08
*** Element info: {Using=name, value=wp_submit}
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:214)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166)
at org.openqa.selenium.remote.http.JsonHttpResponseCodec.reconstructValue(JsonHttpResponseCodec.java:40)
at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:80)
at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:44)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:231)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:42)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:322)
at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:62)
at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElement(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.findElementByName(RemoteWebDriver.java:400)
at io.appium.java_client.DefaultGenericMobileDriver.findElementByName(DefaultGenericMobileDriver.java:118)
at io.appium.java_client.AppiumDriver.findElementByName(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElementByName(AndroidDriver.java:1)
at org.openqa.selenium.By$ByName.findElement(By.java:284)
at org.openqa.selenium.support.ByIdOrName.findElement(ByIdOrName.java:50)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:314)
at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:58)
at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElement(AndroidDriver.java:1)
at io.appium.java_client.pagefactory.bys.ContentMappedBy.findElement(ContentMappedBy.java:50)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:314)
at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:58)
at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElement(AndroidDriver.java:1)
at io.appium.java_client.pagefactory.AppiumElementLocator.lambda[=14=](AppiumElementLocator.java:120)
at io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction.apply(AppiumElementLocator.java:172)
at io.appium.java_client.pagefactory.AppiumElementLocator$WaitingFunction.apply(AppiumElementLocator.java:1)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:260)
... 31 more
PASSED: demoAutTest
===============================================
Default test
Tests run: 1, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
我的假设:脚本使用 WebElement 的变量名来定位 UI 上的元素,而不是我在 @AndroidFindBy 中传递的定位器。
如果需要我提供更多信息,请告诉我。
编辑 1:
@AndroidFindBy(id = "user_login")
WebElement userName;
以上内容无效
@AndroidFindBy(id = "user_login")
WebElement user_login;
将变量名更改为 id 的名称后,上面的工作正常
在此处发布问题之前,我已经 google 并参考了以下参考资料,但它们对 @AndroidFindBy 的实现略有不同,或者没有使用过这种方法。
https://discuss.appium.io/t/nosuchelementexception-when-element-is-actually-present/18711/30
根据@AndroidFindBy
annotation documentation
Used to mark a field on a Page Object to indicate an alternative mechanism for locating the element or a list of elements. Used in conjunction with PageFactory this allows users to quickly and easily create PageObjects. using Android UI selectors, accessibility, id, name, class name, tag and xpath
这意味着您可以使用此注释来访问 Android UI 元素,例如浏览器 "Back" 和 "Reload" 按钮
鉴于您在 Chrome 浏览器中自动化网页,您应该将所有出现的 @AndroidFindBy
替换为 @FindBy
from org.openqa.selenium.support package
更多信息: