Question

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>
Was it helpful?

Solution

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.

OTHER TIPS

You should try the android inspector that comes with the sdk. It can give you not only the id of the exact element in the tree but numerous other details. It doesnt have xPath so you might need to still use the appium inspector depending on what you want to do. Look for it at

./path-to-sdk/android-sdk-macosx/tools/uiautomatorviewer

Inspect the element after entering the text, and make sure that the ID is not changing after entering

Put some thread sleep. This is occurs because you app activity need some time to launch. Before that UI automator cannot able to find the element. You can put a Thread sleep before sending the keys

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top