NightwatchJS for Mobile Browser testing

Daniel Maioni
10 min readJul 31, 2023

Preparing environment for Mobile Browser test automation

Requirements

  1. Install Appium V2

Add appium to your dev project

npm i appium --save-dev
appium -v
2.5.1

Note: As Appium is officially version 2, we do not need anymore to use appium@next

2. Install Drivers

npx appium driver list

npx appium driver install uiautomator2

✔ Installing 'uiautomator2' using NPM install spec 'appium-uiautomator2-driver'
ℹ Driver uiautomator2@2.29.2 successfully installed
- automationName: UiAutomator2
- platformNames: ["Android"]

OR

npx appium driver install xcuitest

✔ Installing 'xcuitest' using NPM install spec 'appium-xcuitest-driver'
ℹ Driver xcuitest@4.32.21 successfully installed
- automationName: XCUITest
- platformNames: ["iOS","tvOS"]

To update use:

appium driver update uiautomator2
OR
appium driver update xcuitest

3. Create a NightwatchJS project for browser at mobile:

  • npm init nightwatch@latest <project-directory>
npm init nightwatch@latest nightwatch-appium-mobile-browser

Need to install the following packages:
create-nightwatch@3.0.1
Ok to proceed? (y) y

// End-2-End, Component or Mobile App
? Select testing type to setup for your project
> End-to-End testing
? Select language + test runner variant
> JavaScript / default
? Select target browsers
> Chrome (or Firefox or Edge or Safari for Mac)
? Enter source folder where test files are stored
> test
? Enter the base_url of the project
> http://localhost
? Select where to run Nightwatch tests
> Both (localhost and remote/cloude service)
? (Remote) Select cloud provider:
> BrowserStack (or Sauce Labs or Other provider / remote selenium-server)
? Allow Nightwatch to collect completely anonymous usage metrics?
> No
? Setup testing on Mobile devices as well?
> Yes
? Select target mobile platform(s):
> Both (Real Adnroid and Android emulator, iOS is only available for Macs)
cd <project-directory>
npx @nightwatch/mobile-helper android
npx @nightwatch/mobile-helper ios
Once setup is complete...
▶ To run an example test on Real Android device
* Make sure your device is connected with USB Debugging turned on.
* Make sure required browsers are installed.
For mobile web tests, run:
npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.real.chrome
▶ To run an example test on Android Emulator
For mobile web tests, run:
npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.emulator.chrome

NPM will install nightwatch, chrome and firefox webdrivers for hybrid apps, missing android binaries: avd, android emulator image (PIs Intel x86_6) and others.

4. Verify the environment with mobile-helper (Optional):

cd nightwatch-appium-mobile-browser

npx @nightwatch/mobile-helper android --appium
OR
npx @nightwatch/mobile-helper ios --appium

? Select language + test runner variant:
> JavaScript / default
? Select target mobile platform(s):
> Android (iOS is only available for Macs)
? Enter source folder where test files are stored:
> test
? Select where to run Nightwatch tests:
> On localhost
? Allow Nightwatch to collect completely anonymous usage metrics?:
> No
? Select target device(s):
> Both (Android and iOS)
[Emulator] Select browser(s) to set up on Emulator:
> Both (Google Chrome and Mozilla Firefox)
? Do you wish to setup the missing requirements for Appium?
Yes

Checking the value of ANDROID_HOME environment variable...
✔ ANDROID_HOME is set to '/home/popos/Android/Sdk'

? Select target device(s): Both
? [Emulator] Select browser(s) to set up on Emulator: Both

Verifying the setup requirements for real devices/emulator...
✔ adb binary is present at '/home/popos/Android/Sdk/platform-tools/adb'
✔ avdmanager binary is present at '/home/popos/Android/Sdk/cmdline-tools/latest/bin/avdmanager'
✔ emulator binary is present at '/home/popos/Android/Sdk/emulator/emulator'

✔ platforms subdirectory is present at '/home/popos/Android/Sdk/platforms'

✔ nightwatch-android-11 AVD is present and ready to be used.

Making sure adb is running...
Success! adb server is running.

Verifying if browser(s) are installed...

Checking if AVD is already running...
! 'nightwatch-android-11' AVD not found running!

Launching emulator with 'nightwatch-android-11' AVD...
✔ 'nightwatch-android-11' AVD launched!

Waiting for emulator to boot up...
✔ Boot up complete!

Making sure adb has root permissions...
✔ adb is running with root permissions!

Verifying if Firefox is installed...
✔ Firefox browser is installed in the AVD.

Checking the version of installed Firefox browser...
✔ Your Firefox browser is up-to-date.

Verifying if Chrome is installed...
✔ Chrome browser is installed in the AVD.

Checking the version of installed Chrome browser...
Version: 83.0.4103.106

Note: Automatic upgrade of Chrome browser is not supported yet.

Checking if chromedriver is already downloaded...
✖ chromedriver not found at '/home/popos/Projetos/nightwatch-appium-mobile-browser/chromedriver-mobile/chromedriver'

? Do you wish to setup the missing requirements for Chrome browser? Yes

Downloading chromedriver to work with the factory version of Chrome browser...
[████████████████████████████████████████] 100% | ETA: 0s
Done! chromedriver downloaded at '/home/popos/Projetos/nightwatch-appium-mobile-browser/chromedriver-mobile/chromedriver'

You can run your tests now on your Android Emulator's Chrome browser.

Closing emulator...
Emulator will close shortly. If not, please close it manually.

Success! All requirements are set.
You can go ahead and run your tests now on an Android device/emulator.

Note: Please make sure you have required browsers installed on your real-device before running tests.

Great! All the requirements are being met.
You can go ahead and run your tests now on an Android device/emulator.

5. Setup environment

Update the nightwatch.conf.js file:

Disable parallel test execution, change test_workers to false:

test_workers: {
enabled: false
},

Enable w3c to true at chrome desiredCapabilities:

chrome: {
desiredCapabilities: {
browserName: 'chrome',
'goog:chromeOptions': {
// More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
//
// w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
w3c: true,
args: [
//'--no-sandbox',
//'--ignore-certificate-errors',
//'--allow-insecure-localhost',
//'--headless'
]
}
},

The Nightwatch.conf.js file will be create with pre-configured environment profiles:

  • android.emulator.chrome — to connect to browser at your android emulator
  • android.real.chrome — to connect to browser at your real android device
  • ios emulator — to connect to browser at your ios emulator
  • ios real — to connect to browser at your real ios device
// environment to run tests on browser at your Android emulator
'android.emulator.chrome': {
desiredCapabilities: {
real_mobile: false,
avd: 'nightwatch-android-11',
browserName: 'chrome',
'goog:chromeOptions': {
// More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
//
// w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
w3c: true,
args: [
//'--no-sandbox',
//'--ignore-certificate-errors',
//'--allow-insecure-localhost',
//'--headless'
],
androidPackage: 'com.android.chrome',
// add the device serial to run tests on, if multiple devices are online
// Run command: `$ANDROID_HOME/platform-tools/adb devices`
// androidDeviceSerial: ''
},
},

webdriver: {
start_process: true,
// path to chromedriver executable which can work with the factory
// version of Chrome mobile browser on the emulator (version 83).
server_path: 'chromedriver-mobile/chromedriver',
cli_args: [
// --verbose
]
}
},

The Chrome Browser will be used at the device due to the capabilities:

androidPackage: 'com.android.chrome'

New environments can be created, here are some for Browser Stack:

browserstack: {
selenium: {
host: 'hub.browserstack.com',
port: 443
},
// More info on configuring capabilities can be found on:
// https://www.browserstack.com/automate/capabilities?tag=selenium-4
desiredCapabilities: {
'bstack:options': {
userName: '${BROWSERSTACK_USERNAME}',
accessKey: '${BROWSERSTACK_ACCESS_KEY}'
}
},

disable_error_log: true,
webdriver: {
timeout_options: {
timeout: 15000,
retry_attempts: 3
},
keep_alive: true,
start_process: false
}
},

'browserstack.local': {
extends: 'browserstack',
desiredCapabilities: {
'browserstack.local': true
}
},

'browserstack.chrome': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'chrome',
'goog:chromeOptions': {
w3c: true
}
}
},

'browserstack.local_chrome': {
extends: 'browserstack.local',
desiredCapabilities: {
browserName: 'chrome'
}
},

'browserstack.android.chrome': {
extends: 'browserstack',
desiredCapabilities: {
'bstack:options' : {
osVersion: '12.0',
deviceName: 'Samsung Galaxy S22'
},
browserName: 'chrome',
'goog:chromeOptions': {
// w3c: false
}
}
},

'browserstack.ios.safari': {
extends: 'browserstack',
desiredCapabilities: {
browserName: 'safari',
'bstack:options' : {
osVersion: "15.5",
deviceName: "iPhone 13"
},
browserName: 'safari'
}
},

6. Running a sample test case

npx nightwatch <test case path/test.js> — env <environment available at config file>

For Real Android device:

  • Make sure your device is connected with USB Debugging turned on.
  • Make sure required browsers are installed.
# to run one single test
npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.real.chrome

OR

# to tun all test cases
npx nightwatch ./nightwatch/examples/basic/ --env android.real.chrome

For Android Emulator device:

# to run one single test
npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.emulator.chrome

OR

# to tun all test cases
npx nightwatch ./nightwatch/examples/basic/ --env android.emulator.chrome

Note: Let`s gonna fix the test case to make sure the first result will be the nightwatch js webpage, change the line (/nightwatch-appium-mobile-browser/nightwatch/examples/basic/ecosia.js)

from

.setValue('input[type=search]', 'nightwatch')

to

.setValue('input[type=search]', 'nightwatch js')

ecosia.js test case

describe('Ecosia.org Demo', function() {
before(browser => browser.navigateTo('https://www.ecosia.org/'));

it('Demo test ecosia.org', function(browser) {
browser
.waitForElementVisible('body')
.assert.titleContains('Ecosia')
.assert.visible('input[type=search]')
.setValue('input[type=search]', 'nightwatch js')
.assert.visible('button[type=submit]')
.click('button[type=submit]')
.assert.textContains('.layout__content', 'Nightwatch.js');
});

after(browser => browser.end());
});

Execute the test case at android emulator:

npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.emulator.chrome

Checking if AVD is already running...
! 'nightwatch-android-11' AVD not found running!

Launching emulator with 'nightwatch-android-11' AVD...
✔ 'nightwatch-android-11' AVD launched!

Waiting for emulator to boot up...
✔ Boot up complete!



[Ecosia.org Demo] Test Suite
────────────────────────────────────────────────────────
ℹ Connected to ChromeDriver on port 9515 (24635ms).
Using: chrome (83.0.4103.106) on ANDROID.


Running Demo test ecosia.org:
───────────────────────────────────────────────────────────────────────────────────────────────────
✔ Element <body> was visible after 99 milliseconds.
✔ Testing if the page title contains 'Ecosia' (37ms)
✔ Testing if element <input[type=search]> is visible (112ms)
✔ Testing if element <button[type=submit]> is visible (53ms)
✔ Testing if element <.layout__content> contains text 'Nightwatch.js' (1295ms)

✨ PASSED. 5 assertions. (3.418s)
Wrote HTML report file to: /home/popos/Projetos/nightwatch-appium-mobile-browser/tests_output/nightwatch-html-report/index.html

The sample test case wil start your android emulator device, open the chrome browser, and navigate to the ecosia.org website, search for nightwatch js, and verify that Nightwatch.js is available at results

It will also register a test report at /tests_output/nightwatch-html-report/index.html

Test Output Report

7. Inspect web elements

Add a break point into the test case with .debug()

ecosia.js test case

describe('Ecosia.org Demo', function() {
before(browser => browser.navigateTo('https://www.ecosia.org/'));

it('Demo test ecosia.org', function(browser) {
browser
.waitForElementVisible('body')
.assert.titleContains('Ecosia')
.debug()
.assert.visible('input[type=search]')
.setValue('input[type=search]', 'nightwatch js')
.assert.visible('button[type=submit]')
.click('button[type=submit]')
.assert.textContains('.layout__content', 'Nightwatch.js');
});

after(browser => browser.end());
});

And run the test case with debug parameter:

npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.emulator.chrome --debug

Chrome driver will starts and initializes the android emulator to start the test case.

If you tries to connect Appium Inspector, it will not be possible to inspect the web elements so easy.

Android Emulator at Debug Mode

So, instead of the Appium Inspector, open the Chome Browser at your PC (same as android emulator), to inspect the web elements, and enter at address the command chrome://inspect, there will be a Remote Target pointing to the emulator device, click into the inspect link to display the DevTools inspect window:

Inspect at Remote Mobile Browser — Chrome

Now it`s possible to inspect the elements from mobile browser:

Inspect web elements at Remote Mobile Browser — Chrome

Note: If you need to inspect application elements, check this post about Native Mobile testing and the use of Appium Inspector to inspect elements: https://medium.com/@dmaioni/nightwatchjs-9a526ea984ad

Create a selector for the button accept all at cookie notifier:

button[data-test-id="cookie-notice-accept"]

It has a data-test-id attribute with value cookie-notice-accept

Update the test case to accept the terms:

describe('Ecosia.org Demo', function() {
before(browser => browser.navigateTo('https://www.ecosia.org/'));

it('Demo test ecosia.org', function(browser) {
browser
.waitForElementVisible('body')
.assert.titleContains('Ecosia')
.waitForElementVisible('button[data-test-id="cookie-notice-accept"]')
.assert.visible('button[data-test-id="cookie-notice-accept"]')
.click('button[data-test-id="cookie-notice-accept"]')
.assert.visible('input[type=search]')
.setValue('input[type=search]', 'nightwatch js')
.assert.visible('button[type=submit]')
.click('button[type=submit]')
.assert.textContains('.layout__content', 'Nightwatch.js');
});

after(browser => browser.end());
});

Exit debug mode typing .exit command (test case will continue to run after the break point and finish), remove the .debug() break point and run the same test case again without debug:

npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.emulator.chrome

Now it will accept cookies before complete the execute the test case!

Android Mobile Browser Automation

The updated test report:

New test report

Now you know how to test your website into a mobile browser!

8. Multi-environments and Parallel tests

It’s also possible to run multiple environments and parallel tests.

Let`s disable parallel tests:

Disable parallel test execution, change test_workers to false:

test_workers: {
enabled: false,
workers: 'auto'
},

and starts a multiple environment test case:

npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.emulator.chrome,android.emulator.firefox

It will run a test suite for each environment one after another.

It will be possible to follow the test execution for each one environment into the console. And finally check the report for the test results.

For parallel test, enable it, and set the number of maximum threads or set it to auto.

test_workers: {
enabled: true,
workers: 'auto'
},

Now it gonna runs the test cases at the same time.

npx nightwatch ./nightwatch/examples/basic/ecosia.js --env android.emulator.chrome,android.emulator.firefox

It will not be possible to follow the test execution for each one environment into the console cause they are running at the same time. Check the report for the test results.

Note: Depending the environment it will not be possible to use the same device, in this example use two emulators, or one real device and one emulator, otherwise test cases will fail due to session already been in use. At android avd manager it`s possible to duplicate an avd to be used as a second emulator.

The End!

For more information about Native Mobile testing or Desktop Browser testing instead of embedded Mobile Browser one, check it out our last post:

Nightwatch logo — a brown owl on a branch
Nightwatch logo

--

--