HELP: Automating React Native App and Chrome authentication web page

Hi,

as a beginner this has me somewhat confused as to how to solve:

Environment: Mac OS X
Appium Version: 1.14.0
WDIO: 5.11.11
Testing against an Android 8.1 simulator

Packages used:

“devDependencies”: {
@babel/cli”: “^7.4.3”,
@babel/core”: “^7.4.3”,
@babel/preset-env”: “^7.4.3”,
@babel/register”: “^7.4.0”,
@babel/traverse”: “^7.4.3”,
@babel/types”: “^7.4.0”,
@wdio/appium-service”: “^5.11.4”,
@wdio/cli”: “^5.11.6”,
@wdio/cucumber-framework”: “^5.11.12”,
@wdio/jasmine-framework”: “^5.7.8”,
@wdio/local-runner”: “^5.11.6”,
@wdio/sauce-service”: “^5.11.1”,
@wdio/spec-reporter”: “^5.11.6”,
@wdio/sync”: “^5.7.9”,
“babel-eslint”: “^10.0.1”,
“chai”: “^4.2.0”,
“eslint”: “^5.16.0”,
“eslint-config-standard”: “^12.0.0”,
“eslint-plugin-import”: “^2.14.0”,
“eslint-plugin-node”: “^7.0.1”,
“eslint-plugin-promise”: “^4.1.1”,
“eslint-plugin-standard”: “^4.0.0”,
“eslint-plugin-wdio”: “^5.7.8”,
“node-fetch”: “^2.3.0”,
“webdriverio”: “^5.7.12”
}

I’ve been using the Appium-boilerplate repository to determine rewrite some the tests using cucumber JS (they were in Jasmine form) so that I can get used to writing things that way.

Now I am starting on our company’s mobile application which is implemented using React Native. The majority of user interaction is through the native app but a login is implemented as a Chrome/Safari window for Android and iOS respectively. So at the start of our native app the Welcome screen has a couple of buttons which open a login URL or register URL on the Chrome/Safari browser. When the username and password are submitted the native app gets an authorisation token posted back to it that allows it to carry on (and dismisses the Chrome browser app at the same time).

If I call driver.getContexts() I see something like [‘NATIVE_APP’, ‘WEBVIEW_chrome’, ‘WEBVIEW_com.blahfoo.blahbar’] but if I subsequently try and driver.setContext() with either of the web views then the automation code just sits at this point and times out. It does not always show these three contexts returned; sometimes WEBVIEW_chrome or WEBVIEW_com.blahfoo.blahbar only but most of the time both are returned in addition to NATIVE_APP.

If I don’t driver.setContext() but instead attempt to interact with the Chrome page directly (which is the app that has focus now) I can see that driver.getCurrentActivity() returns org.chromium.chrome.browser.customtabs.CustomTabActivity but when I try and interact with the browser page in an attempt to interact with the Email ID on the Chrome browser login page using:

const user = browser.findElement(‘xpath’, ‘/html/body/div/div/div[2]/div/div[2]/div/div/form/div[1]/div/input’);

I get the following error:

[0-0] 2019-08-09T01:49:18.545Z INFO webdriver: COMMAND findElement(“xpath”, “/html/body/div/div/div[2]/div/div[2]/div/div/form/div[1]/div/input”)
[0-0] 2019-08-09T01:49:18.545Z INFO webdriver: [POST] http://127.0.0.1:4723/wd/hub/session/34e7b3fe-ba3f-49e3-b5f1-5d8883f6b933/element
[0-0] 2019-08-09T01:49:18.546Z INFO webdriver: DATA { using: ‘xpath’,
value:
‘/html/body/div/div/div[2]/div/div[2]/div/div/form/div[1]/div/input’ }
[0-0] 2019-08-09T01:49:19.085Z INFO webdriver: RESULT { error: ‘no such element’,
message:
‘An element could not be located on the page using the given search parameters.’,
stacktrace:
‘NoSuchElementError: An element could not be located on the page using the given search parameters.\n at AndroidUiautomator2Driver.helpers.findElOrEls (/usr/local/lib/node_modules/appium/node_modules/appium-android-driver/lib/commands/find.js:75:11)’ }

What is the accepted approach to automating this kind of behaviour? It doesn’t appear to behave as a webview that is embedded in an app so it doesn’t sound like switching from native to web to native context is the way to do it.

What am I missing here?

Thanks for any hints or insights.

Derek Wong.

PS - for the same React Native app this will eventually need to work on iOS as well although I’d be keen just to get this going on Android right now.

Some further details from the Appium server logs - as I mentioned previously the call to driver.getContexts() returns all available NATIVE and WEBVIEW contexts correctly but at the point where I invoke a driver.switchContext(‘WEBVIEW_com.foo.bar’) it times out after 60 seconds of trying:

2019-08-13 22:54:52:102 [HTTP] --> GET /wd/hub/session/8397000f-2d9f-4469-b17a-c092e0370d19/contexts
2019-08-13 22:54:52:102 [HTTP] {}
2019-08-13 22:54:52:105 [W3C (8397000f)] Calling AppiumDriver.getContexts() with args: [“8397000f-2d9f-4469-b17a-c092e0370d19”]
2019-08-13 22:54:52:106 [AndroidDriver] Getting a list of available webviews
2019-08-13 22:54:52:107 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell cat /proc/net/unix’
2019-08-13 22:54:52:132 [AndroidDriver] WEBVIEW_15345 mapped to pid 15345
2019-08-13 22:54:52:135 [AndroidDriver] Getting process name for webview
2019-08-13 22:54:52:135 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell ps’
2019-08-13 22:54:52:187 [AndroidDriver] Parsed pid: ‘15345’ pkg: ‘com.foo.bar’ from
2019-08-13 22:54:52:188 [AndroidDriver] USER PID PPID VSZ RSS WCHAN ADDR S NAME
2019-08-13 22:54:52:188 [AndroidDriver] u0_a81 15345 1511 1710524 251420 SyS_epoll_wait 0 S com.foo.bar
2019-08-13 22:54:52:191 [AndroidDriver] Returning process name: ‘com.foo.bar’
2019-08-13 22:54:52:191 [AndroidDriver] Found webviews: [“WEBVIEW_chrome”,“WEBVIEW_com.foo.bar”]
2019-08-13 22:54:52:191 [AndroidDriver] Available contexts: [“NATIVE_APP”,“WEBVIEW_chrome”,“WEBVIEW_com.foo.bar”]
2019-08-13 22:54:52:192 [W3C (8397000f)] Responding to client with driver.getContexts() result: [“NATIVE_APP”,“WEBVIEW_chrome”,“WEBVIEW_com.foo.bar”]
2019-08-13 22:54:52:193 [HTTP] <-- GET /wd/hub/session/8397000f-2d9f-4469-b17a-c092e0370d19/contexts 200 91 ms - 69
2019-08-13 22:54:52:193 [HTTP]
2019-08-13 22:54:52:195 [HTTP] --> POST /wd/hub/session/8397000f-2d9f-4469-b17a-c092e0370d19/context
2019-08-13 22:54:52:195 [HTTP] {“name”:“WEBVIEW_com.foo.bar”}
2019-08-13 22:54:52:196 [W3C (8397000f)] Calling AppiumDriver.setContext() with args: [“WEBVIEW_com.foo.bar”,“8397000f-2d9f-4469-b17a-c092e0370d19”]
2019-08-13 22:54:52:197 [AndroidDriver] Getting a list of available webviews
2019-08-13 22:54:52:197 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell cat /proc/net/unix’
2019-08-13 22:54:52:218 [AndroidDriver] WEBVIEW_15345 mapped to pid 15345
2019-08-13 22:54:52:218 [AndroidDriver] Getting process name for webview
2019-08-13 22:54:52:218 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell ps’
2019-08-13 22:54:52:261 [AndroidDriver] Parsed pid: ‘15345’ pkg: ‘com.foo.bar’ from
2019-08-13 22:54:52:261 [AndroidDriver] USER PID PPID VSZ RSS WCHAN ADDR S NAME
2019-08-13 22:54:52:261 [AndroidDriver] u0_a81 15345 1511 1710524 251420 SyS_epoll_wait 0 S com.foo.bar
2019-08-13 22:54:52:261 [AndroidDriver] Returning process name: ‘com.foo.bar’
2019-08-13 22:54:52:261 [AndroidDriver] Found webviews: [“WEBVIEW_chrome”,“WEBVIEW_com.foo.bar”]
2019-08-13 22:54:52:261 [AndroidDriver] Available contexts: [“NATIVE_APP”,“WEBVIEW_chrome”,“WEBVIEW_com.foo.bar”]
2019-08-13 22:54:52:262 [AndroidDriver] Connecting to chrome-backed webview context ‘WEBVIEW_com.foo.bar’
2019-08-13 22:54:52:269 [AndroidDriver] A port was not given, using random port: 8002
2019-08-13 22:54:52:270 [Chromedriver] Changed state to ‘starting’
2019-08-13 22:54:52:271 [Chromedriver] Set chromedriver binary as: /Users/derekwong/Downloads/chromedriver
2019-08-13 22:54:52:271 [Chromedriver] Killing any old chromedrivers, running: pkill -15 -f “/Users/derekwong/Downloads/chromedriver.*–port=8002”
2019-08-13 22:54:52:304 [Chromedriver] No old chromedrivers seemed to exist
2019-08-13 22:54:52:305 [Chromedriver] Cleaning any old adb forwarded port socket connections
2019-08-13 22:54:52:305 [ADB] List forwarding ports
2019-08-13 22:54:52:305 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 forward --list’
2019-08-13 22:54:52:314 [ADB] Removing forwarded port socket connection: 12033
2019-08-13 22:54:52:314 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 forward --remove tcp:12033’
2019-08-13 22:54:52:322 [ADB] Removing forwarded port socket connection: 12399
2019-08-13 22:54:52:322 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 forward --remove tcp:12399’
2019-08-13 22:54:52:329 [Chromedriver] Spawning chromedriver with: /Users/derekwong/Downloads/chromedriver --url-base=wd/hub --port=8002 --adb-port=5037 --verbose
2019-08-13 22:54:52:354 [Chromedriver] Chromedriver version: ‘2.34.522932’
2019-08-13 22:54:52:355 [WD Proxy] Matched ‘/status’ to command name ‘getStatus’
2019-08-13 22:54:52:355 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8002/wd/hub/status] with no body
2019-08-13 22:54:52:359 [WD Proxy] Got an unexpected response: {“errno”:“ECONNREFUSED”,“code”:“ECONNREFUSED”,“syscall”:“connect”,“address”:“127.0.0.1”,“port”:8002}
2019-08-13 22:54:52:560 [WD Proxy] Matched ‘/status’ to command name ‘getStatus’
2019-08-13 22:54:52:560 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8002/wd/hub/status] with no body
2019-08-13 22:54:52:566 [WD Proxy] Got response with status 200: “{“sessionId”:”",“status”:0,“value”:{“build”:{“version”:“alpha”},“os”:{“arch”:“x86_64”,“name”:“Mac OS X”,“version”:“10.14.6”}}}"
2019-08-13 22:54:52:567 [WD Proxy] Matched ‘/session’ to command name ‘createSession’
2019-08-13 22:54:52:567 [WD Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8002/wd/hub/session] with body: {“desiredCapabilities”:{“chromeOptions”:{“androidPackage”:“com.foo.bar”,“androidUseRunningApp”:true,“androidDeviceSerial”:“emulator-5554”}}}
2019-08-13 22:54:52:875 [Chromedriver] Webview version: ‘Chrome/61.0.3163.98’
2019-08-13 22:55:52:885 [WD Proxy] Got response with status 200: {“sessionId”:“c500d4869f03de506877639be88b09ed”,“status”:13,“value”:{“message”:“unknown error: unable to discover open pages\n (Driver info: chromedriver=2.34.522932 (4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.14.6 x86_64)”}}
2019-08-13 22:55:52:885 [WD Proxy] Got an unexpected response: {“sessionId”:“c500d4869f03de506877639be88b09ed”,“status”:13,“value”:{“message”:“unknown error: unable to discover open pages\n (Driver info: chromedriver=2.34.522932 (4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.14.6 x86_64)”}}
2019-08-13 22:55:52:886 [MJSONWP] Matched JSONWP error code 13 to UnknownError
2019-08-13 22:55:52:903 [Chromedriver] Error: Failed to start Chromedriver session: An unknown server-side error occurred while processing the command. Original error: unknown error: unable to discover open pages
2019-08-13 22:55:52:904 [Chromedriver] (Driver info: chromedriver=2.34.522932 (4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.14.6 x86_64)
2019-08-13 22:55:52:904 [Chromedriver] at Object.wrappedLogger.errorAndThrow (/usr/local/lib/node_modules/appium/node_modules/appium-support/lib/logging.js:78:13)
2019-08-13 22:55:52:904 [Chromedriver] at /usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/lib/chromedriver.js:478:13
2019-08-13 22:55:53:109 [WD Proxy] Matched ‘/session’ to command name ‘createSession’
2019-08-13 22:55:53:111 [WD Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8002/wd/hub/session] with body: {“desiredCapabilities”:{“chromeOptions”:{“androidPackage”:“com.foo.bar”,“androidUseRunningApp”:true,“androidDeviceSerial”:“emulator-5554”}}}
2019-08-13 22:55:53:406 [Chromedriver] Webview version: ‘Chrome/61.0.3163.98’
2019-08-13 22:56:08:982 [HTTP] --> DELETE /wd/hub/session/8397000f-2d9f-4469-b17a-c092e0370d19
2019-08-13 22:56:08:982 [HTTP] {}
2019-08-13 22:56:08:983 [W3C (8397000f)] Calling AppiumDriver.deleteSession() with args: [“8397000f-2d9f-4469-b17a-c092e0370d19”]
2019-08-13 22:56:08:983 [BaseDriver] Event ‘quitSessionRequested’ logged at 1565736968983 (10:56:08 GMT+1200 (New Zealand Standard Time))
2019-08-13 22:56:08:983 [Appium] Removing session 8397000f-2d9f-4469-b17a-c092e0370d19 from our master session list
2019-08-13 22:56:08:984 [UiAutomator2] Deleting UiAutomator2 session
2019-08-13 22:56:08:985 [UiAutomator2] Deleting UiAutomator2 server session
2019-08-13 22:56:08:985 [WD Proxy] Matched ‘/’ to command name ‘deleteSession’
2019-08-13 22:56:08:985 [WD Proxy] Proxying [DELETE /] to [DELETE http://localhost:8200/wd/hub/session/b2631220-e6f7-48ae-a3d7-8c9ffa7806a6] with no body
2019-08-13 22:56:09:000 [WD Proxy] Got response with status 200: “{“sessionId”:“b2631220-e6f7-48ae-a3d7-8c9ffa7806a6”,“status”:0,“value”:“Session deleted”}”
2019-08-13 22:56:09:001 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 shell am force-stop com.foo.bar’
2019-08-13 22:56:09:057 [Logcat] Stopping logcat capture
2019-08-13 22:56:09:060 [ADB] Removing forwarded port socket connection: 8200
2019-08-13 22:56:09:060 [ADB] Running ‘/Users/derekwong/Library/Android/sdk/platform-tools/adb -P 5037 -s emulator-5554 forward --remove tcp:8200’
2019-08-13 22:56:09:073 [BaseDriver] Event ‘quitSessionFinished’ logged at 1565736969072 (10:56:09 GMT+1200 (New Zealand Standard Time))
2019-08-13 22:56:09:073 [W3C (8397000f)] Received response: null
2019-08-13 22:56:09:074 [W3C (8397000f)] But deleting session, so not returning
2019-08-13 22:56:09:074 [W3C (8397000f)] Responding to client with driver.deleteSession() result: null
2019-08-13 22:56:09:075 [HTTP] <-- DELETE /wd/hub/session/8397000f-2d9f-4469-b17a-c092e0370d19 200 93 ms - 14
2019-08-13 22:56:09:075 [HTTP]
2019-08-13 22:56:09:202 [HTTP] <-- POST /wd/hub/session/8397000f-2d9f-4469-b17a-c092e0370d19/context - - ms - -
2019-08-13 22:56:09:203 [HTTP]
2019-08-13 22:56:09:419 [Instrumentation] .
2019-08-13 22:56:10:151 [Instrumentation] Time: 95.104
2019-08-13 22:56:10:151 [Instrumentation]
2019-08-13 22:56:10:151 [Instrumentation] OK (1 test)
2019-08-13 22:56:10:163 [Instrumentation] The process has exited with code 0
2019-08-13 22:56:53:434 [WD Proxy] Got response with status 200: {“sessionId”:“e3b56d8d1f200a46aad8834cd0b01455”,“status”:13,“value”:{“message”:“unknown error: unable to discover open pages\n (Driver info: chromedriver=2.34.522932 (4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.14.6 x86_64)”}}
2019-08-13 22:56:53:434 [WD Proxy] Got an unexpected response: {“sessionId”:“e3b56d8d1f200a46aad8834cd0b01455”,“status”:13,“value”:{“message”:“unknown error: unable to discover open pages\n (Driver info: chromedriver=2.34.522932 (4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.14.6 x86_64)”}}
2019-08-13 22:56:53:434 [MJSONWP] Matched JSONWP error code 13 to UnknownError
2019-08-13 22:56:53:435 [Chromedriver] Error: Failed to start Chromedriver session: An unknown server-side error occurred while processing the command. Original error: unknown error: unable to discover open pages
2019-08-13 22:56:53:435 [Chromedriver] (Driver info: chromedriver=2.34.522932 (4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.14.6 x86_64)
2019-08-13 22:56:53:435 [Chromedriver] at Object.wrappedLogger.errorAndThrow (/usr/local/lib/node_modules/appium/node_modules/appium-support/lib/logging.js:78:13)
2019-08-13 22:56:53:435 [Chromedriver] at /usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/lib/chromedriver.js:478:13
2019-08-13 22:56:53:638 [WD Proxy] Matched ‘/session’ to command name ‘createSession’
2019-08-13 22:56:53:638 [WD Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8002/wd/hub/session] with body: {“desiredCapabilities”:{“chromeOptions”:{“androidPackage”:“com.foo.bar”,“androidUseRunningApp”:true,“androidDeviceSerial”:“emulator-5554”}}}
2019-08-13 22:57:44:527 [Appium] Received SIGINT - shutting down
2019-08-13 22:57:44:530 [WD Proxy] Got an unexpected response: {“code”:“ECONNRESET”}
2019-08-13 22:57:44:530 [Chromedriver] Error: Failed to start Chromedriver session: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to remote server. Original error: Error: socket hang up
2019-08-13 22:57:44:530 [Chromedriver] at Object.wrappedLogger.errorAndThrow (/usr/local/lib/node_modules/appium/node_modules/appium-support/lib/logging.js:78:13)
2019-08-13 22:57:44:530 [Chromedriver] at /usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/lib/chromedriver.js:478:13
2019-08-13 22:57:44:531 [Chromedriver] Chromedriver exited unexpectedly with code null, signal SIGINT
2019-08-13 22:57:44:531 [Chromedriver] Changed state to ‘stopped’
2019-08-13 22:57:44:734 [WD Proxy] Matched ‘/session’ to command name ‘createSession’
2019-08-13 22:57:44:734 [WD Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8002/wd/hub/session] with body: {“desiredCapabilities”:{“chromeOptions”:{“androidPackage”:“com.foo.bar”,“androidUseRunningApp”:true,“androidDeviceSerial”:“emulator-5554”}}}
2019-08-13 22:57:44:736 [WD Proxy] Got an unexpected response: {“errno”:“ECONNREFUSED”,“code”:“ECONNREFUSED”,“syscall”:“connect”,“address”:“127.0.0.1”,“port”:8002}
2019-08-13 22:57:44:736 [Chromedriver] Error: Failed to start Chromedriver session: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8002
2019-08-13 22:57:44:736 [Chromedriver] at Object.wrappedLogger.errorAndThrow (/usr/local/lib/node_modules/appium/node_modules/appium-support/lib/logging.js:78:13)
2019-08-13 22:57:44:737 [Chromedriver] at /usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/lib/chromedriver.js:478:13
2019-08-13 22:57:44:737 [Chromedriver] Error: Failed to start Chromedriver session: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8002
2019-08-13 22:57:44:737 [Chromedriver] at Object.wrappedLogger.errorAndThrow (/usr/local/lib/node_modules/appium/node_modules/appium-support/lib/logging.js:78:13)
2019-08-13 22:57:44:737 [Chromedriver] at Chromedriver.start (/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/lib/chromedriver.js:426:11)
2019-08-13 22:57:44:738 [W3C (8397000f)] Encountered internal error running command: Error: Failed to start Chromedriver session: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8002
2019-08-13 22:57:44:738 [W3C (8397000f)] at Object.wrappedLogger.errorAndThrow (/usr/local/lib/node_modules/appium/node_modules/appium-support/lib/logging.js:78:13)
2019-08-13 22:57:44:738 [W3C (8397000f)] at Chromedriver.start (/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/lib/chromedriver.js:426:11)

So why doesn’t the ChromeDriver session start? What settings in the Appium server or in the simulator am I missing?

Like I said initially, the test examples in the appium-boilerplate for the example React Native app appear to switch context correctly for the embedded web view (which also needs to establish a ChromeDriver session to interact with the embedded web view).

Takers anyone?

So reading still further; maybe the URL opened in our native app is not opening on an embedded Webview but in a Chrome window (native app) instead. According to this link https://stackoverflow.com/questions/39243603/switching-to-browser-from-a-native-android-app-with-appium I have to close the Appium app driver session and then create a new Appium session with capabilities that can automate a browser on the simulator or device instead before automating on the browser page and then doing the same in reverse to get back and automate the native app once again.

Has anyone got a code snippet (in Javascript would be nice but anything will do) that can demonstrate to me how this is done? Going from native app A to Chrome native app (browser) and back sounds like a pattern that would be often used in Appium when testing link content scenarios where a button in the native app takes you to an external web page where you might verify contents.

Thanks for any help here.