且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Appium +的Andr​​oid +的webdriver findElement():找不到的SendKeys后元素()?

更新时间:2022-10-15 09:58:27

用于不应该是edit_message而是融为一体的ID。 company.app:id/edit_message

基本上,如果你layout.xml文件使用为您的UI元素的ID机器人:ID =@ + ID /富(和你的应用程序是com.company 。应用程序),然后在您的测试,你应该使用com.company.app:id/foo而不仅仅是foo的$ C的$ C>。

仅仅使用foo的可允许UI元素被发现,但它一个互动之后,你将无法找到在UI东西。不知道这是为什么,但是它混淆的问题。

I have a simulated Android device and Appium. My test successfully launches the right Activity and types in a particular text field. But when I try to find the same text field in order to check the text in it, I get "An element could not be located on the page using the given search parameters." Even if I try to re-use the element instead of searching for it a second time, it still fails with the same message. What should I do differently? Maybe the context for the second findElement() is wrong -- I can't find the button next to the text field either.

Here's a git repo that contains an app and a test project. The failed JUnit test demonstrates the issue: https://github.com/achengs/an-appium-question

Details below (code and Appium log interleaved)

Here's the first findElement which succeeds. The layout xml file for the Activity has this attribute for the text field that I'm looking for: android:id="@+id/edit_message"

public static final String MESSAGE_TO_SEND = "edit_message";
...
WebElement e = driver.findElement(By.id(MESSAGE_TO_SEND));

First findElement succeeds:

debug: Appium request initiated at /wd/hub/session/0ec259be-87e0-47f6-9279-da577fe29a07/element
debug: Request received with params: {"using":"id","value":"edit_message"}
info: Pushing command to appium work queue: ["find",{"strategy":"id","selector":"edit_message","context":"","multiple":false}]
info: [BOOTSTRAP] [info] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"edit_message","context":"","multiple":false}}
info: [BOOTSTRAP] [info] Got command of type ACTION
info: [BOOTSTRAP] [debug] Got command action: find
info: [BOOTSTRAP] [debug] Finding edit_message using ID with the contextId: 
info: [BOOTSTRAP] [info] Returning result: {"value":{"ELEMENT":"1"},"status":0}
info: Responding to client with success: {"status":0,"value":{"ELEMENT":"1"},"sessionId":"0ec259be-87e0-47f6-9279-da577fe29a07"}
POST /wd/hub/session/0ec259be-87e0-47f6-9279-da577fe29a07/element 200 5656ms - 109b

Saying hello!

String text = "hello!";
e.sendKeys(text);

That succeeds:

debug: Appium request initiated at /wd/hub/session/0ec259be-87e0-47f6-9279-da577fe29a07/element/1/value
debug: Request received with params: {"id":"1","value":["hello!"]}
info: Pushing command to appium work queue: ["element:setText",{"elementId":"1","text":"hello!"}]
info: [BOOTSTRAP] [info] Got data from client: {"cmd":"action","action":"element:setText","params":{"elementId":"1","text":"hello!"}}
info: [BOOTSTRAP] [info] Got command of type ACTION
info: [BOOTSTRAP] [debug] Got command action: setText
info: [BOOTSTRAP] [info] Returning result: {"value":true,"status":0}
info: Responding to client with success: {"status":0,"value":true,"sessionId":"0ec259be-87e0-47f6-9279-da577fe29a07"}
POST /wd/hub/session/0ec259be-87e0-47f6-9279-da577fe29a07/element/1/value 200 4215ms - 89b

Here's the second findElement which fails. (If I skip this findElement and re-use the original one -- or if I try to find the Send button next to the text field instead, I still get a similar failure)

WebElement f = driver.findElement(By.id(MESSAGE_TO_SEND));

Here's the log for the failure:

debug: Appium request initiated at /wd/hub/session/0ec259be-87e0-47f6-9279-da577fe29a07/element
debug: Request received with params: {"using":"id","value":"edit_message"}
info: Pushing command to appium work queue: ["find",{"strategy":"id","selector":"edit_message","context":"","multiple":false}]
info: [BOOTSTRAP] [info] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"edit_message","context":"","multiple":false}}
info: [BOOTSTRAP] [info] Got command of type ACTION
info: [BOOTSTRAP] [debug] Got command action: find
info: [BOOTSTRAP] [debug] Finding edit_message using ID with the contextId: 
info: [BOOTSTRAP] [info] Returning result: {"value":"No element found","status":7}
info: Responding to client with error: {"status":7,"value":{"message":"An element could not be located on the page using the given search parameters.","origValue":"No element found"},"sessionId":"0ec259be-87e0-47f6-9279-da577fe29a07"}
POST /wd/hub/session/0ec259be-87e0-47f6-9279-da577fe29a07/element 500 874ms - 223b

There was a request for the HTML. I'm testing a native Android app. Here's the layout xml for the current Activity under test. If there's something else I should include here, please do let me know.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText android:id="@+id/edit_message"
    android:layout_weight="1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:hint="@string/edit_message" />
<Button
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="@string/button_send"
   android:onClick="sendMessage" android:id="@+id/send"/>
</LinearLayout>

The ID used should not be "edit_message" but rather "com.company.app:id/edit_message".

Basically if your layout.xml file specifies an ID for your UI element with android:id="@+id/foo" (and your app is com.company.app) then in your test you should use "com.company.app:id/foo" instead of just "foo".

Using just "foo" may allow the UI element to be found but after a single interaction with it you will be unable to find anything in the UI. Not sure why this is, but it confuses matters.