Unable to locate locate element in Android phone with method findelementbyxpath

Hi I am trying to locate a switch box with method like this:
driver.findElementByXPath(“//android.widget.Switch[contains(@bounds=‘[860,311][1000,392]’)]”).click();
so that I can make the switch box to be set as “ON”.

but the log file shows that failed to find this element. anyone who can help me for this issue?

here is the log file:
info: [debug] Responding to client with success: {“status”:0,“value”:true,“sessionId”:“6521cb85-8c9b-45fe-8ebd-2a6ee664f49e”}

info: ← POST /wd/hub/session/6521cb85-8c9b-45fe-8ebd-2a6ee664f49e/touch/perform 200 325.011 ms - 76 {“status”:0,“value”:true,“sessionId”:“6521cb85-8c9b-45fe-8ebd-2a6ee664f49e”}
info: → POST /wd/hub/session/6521cb85-8c9b-45fe-8ebd-2a6ee664f49e/element {“using”:“xpath”,“value”:“//android.widget.ImageButton[@bounds=‘[860,311][1000,392]’]”}
info: [debug] Waiting up to 0ms for condition
info: [debug] Pushing command to appium work queue: [“find”,{“strategy”:“xpath”,“selector”:“//android.widget.ImageButton[@bounds=‘[860,311][1000,392]’]”,“context”:“”,“multiple”:false}]
info: [debug] [BOOTSTRAP] [debug] Got data from client: {“cmd”:“action”,“action”:“find”,“params”:{“strategy”:“xpath”,“selector”:“//android.widget.ImageButton[@bounds=‘[860,311][1000,392]’]”,“context”:“”,“multiple”:false}}
info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
info: [debug] [BOOTSTRAP] [debug] Got command action: find
info: [debug] [BOOTSTRAP] [debug] Finding //android.widget.ImageButton[@bounds=‘[860,311][1000,392]’] using XPATH with the contextId: multiple: false
info: [debug] [BOOTSTRAP] [debug] Returning result: {“value”:"Could not find an element using supplied strategy. ",“status”:7}
info: [debug] Condition unmet after 151ms. Timing out.
info: [debug] Responding to client with error: {“status”:7,“value”:{“message”:“An element could not be located on the page using the given search parameters.”,“origValue”:"Could not find an element using supplied strategy. "},“sessionId”:“6521cb85-8c9b-45fe-8ebd-2a6ee664f49e”}
info: ← POST /wd/hub/session/6521cb85-8c9b-45fe-8ebd-2a6ee664f49e/element 500 151.120 ms - 230
info: → DELETE /wd/hub/session/6521cb85-8c9b-45fe-8ebd-2a6ee664f49e {}
info: Shutting down appium session
info: [debug] Pressing the HOME button
info: [debug] executing cmd: C:\Android\AndroidSDK\platform-tools\adb.exe -s 022SSE146M005259 shell “input keyevent 3”
info: [debug] Stopping logcat capture
info: [debug] Logcat terminated with code null, signal SIGTERM
info: [debug] [BOOTSTRAP] [debug] Got data from client: {“cmd”:“shutdown”}
info: [debug] [BOOTSTRAP] [debug] Got command of type SHUTDOWN
info: [debug] [BOOTSTRAP] [debug] Returning result: {“value”:“OK, shutting down”,“status”:0}
info: [debug] [BOOTSTRAP] [debug] Closed client connection
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: numtests=1
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream=.
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: test=testRunServer
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: current=1
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: 0
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream=
info: [debug] [UIAUTOMATOR STDOUT] Test results for WatcherResultPrinter=.
info: [debug] [UIAUTOMATOR STDOUT] Time: 22.664
info: [debug] [UIAUTOMATOR STDOUT] OK (1 test)
info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: -1
info: [debug] Sent shutdown command, waiting for UiAutomator to stop…
info: [debug] UiAutomator shut down normally
info: [debug] Cleaning up android objects
info: [debug] Cleaning up appium session
info: [debug] Responding to client with success: {“status”:0,“value”:null,“sessionId”:“6521cb85-8c9b-45fe-8ebd-2a6ee664f49e”}
info: ← DELETE /wd/hub/session/6521cb85-8c9b-45fe-8ebd-2a6ee664f49e 200 682.365 ms - 76 {“status”:0,“value”:null,“sessionId”:“6521cb85-8c9b-45fe-8ebd-2a6ee664f49e”}

here is the screenshot with info.

You can use a lot of other ways to find…
Using the bounds is not recommended because it is based on position… so if you use another emulator or device with different screen size you’ll get and ElementNotFound.

  • Way 1: if you know that this item is always the first element to click you can find all the switch by id and get the first one
    driver.findElements(By.id("android:id/checkbox")).get(0).click();

  • Way 2: you can find the title ‘Message readout’ and navigate to the checkbox thought XPATH
    In this case you need to find the text by @text=‘Message readout’ and continue to navigate in the elements
    If you find this element and post the screenshot of the elements inside I can help you to find the checkbox.

Regards!

Hi Dear Elias
thanks very much for your solutions both way1 and way2.
I would like to try way1 which a totally new for me and it is good reference to locate other elements.
thanks again so much for your help, Elias.

BR
Peng

hi Elias
it seems something not so good here.
way-1 does not work from my side.



according to picture above, if I use the method:
driver.findElements(By.id(“android:id/checkbox”)).get(0).click();
it will not work as expected, two checkbox elements parameters are the same.

and from eclipse IDE, I did not see the .click() available for the last step of this method.

what happens for

driver.findElements(By.className(“android.widget.Switch”)).get(0).click();

Additional ideas:

  • Show these same screenshots to your development team so they understand that all of the switches have the same attributes and none are unique. Perhaps they can assign a unique identifier to each switch. This is a good discussion in general as it makes them aware of ways to help support the automation.
  • In this specific screen you can leverage xpath axes. It should let you use xpath that finds the switch element that is related to its text label element. Your switch looks to be a sibling of the text label.
  • In general, try to avoid using hardcoded indexes in your locators as they are the most brittle way to code your locators. switch[1] today might be switch[2] tomorrow.

Hi Satyajit
thanks so much.
but this method seems does not work.
when it goes to :
driver.findElements(By.className(“android.widget.Switch”)).get(0).
there is no click() available after the get(0).

but thanks so much for your effort to help me.

Br
Sean

Hi Christopher
1-I will try to let the developers know this.
2-I could use Xpath to achieve the target now, I just would like to try some different ways of locate elements but not the only xpath, byid,etc.
3-just like you mentioned, it is better to avuid using the [][] to locate elment. it can be dangerous.

thanks so much for your ideas, I am appreciated.

Br
Sean