mirror of
https://github.com/status-im/react-native.git
synced 2025-01-09 09:12:02 +00:00
f9bd789206
Summary:- converted shell script `scripts/e2e-test.sh` into JS script to have more programming flexibility - using appium execute 2 tests after a fresh React Native app installation: check HMR and that debugging mode does not crash the app - made sure tests can be stable on limited CI systems and added ways to debug any problems in the future Using appium we can now interact with Android app and test its state. As a follow up i am planning to write a blog post on how to use appium with android and ios for e2e testing. Closes https://github.com/facebook/react-native/pull/6840 Differential Revision: D3173635 Pulled By: mkonicek fb-gh-sync-id: 3cf044bc9f64d1a842ae4589dd1bcab76de3d66a fbshipit-source-id: 3cf044bc9f64d1a842ae4589dd1bcab76de3d66a
127 lines
4.8 KiB
JavaScript
127 lines
4.8 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Used in run-ci-e2e-test.js and executed in Travis and Circle CI.
|
|
* E2e test that verifies that init app can be installed, compiled, started and Hot Module reloading and Chrome debugging work.
|
|
* For other examples of appium refer to: https://github.com/appium/sample-code/tree/master/sample-code/examples/node and
|
|
* https://www.npmjs.com/package/wd-android
|
|
*
|
|
*
|
|
* To set up:
|
|
* - npm install --save-dev appium@1.5.1 mocha@2.4.5 wd@0.3.11 colors@1.0.3 pretty-data2@0.40.1
|
|
* - cp <this file> <to app installation path>
|
|
* - keytool -genkey -v -keystore android/keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US
|
|
*
|
|
* To run this test:
|
|
* - npm start
|
|
* - node node_modules/.bin/appium
|
|
* - (cd android && ./gradlew :app:copyDownloadableDepsToLibs)
|
|
* - buck build android/app
|
|
* - node ../node_modules/.bin/_mocha ../android-e2e-test.js
|
|
*/
|
|
|
|
const wd = require('wd');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const pd = require('pretty-data2').pd;
|
|
require('colors');
|
|
// value in ms to print out screen contents, set this value in CI to debug if tests are failing
|
|
const appiumDebugInterval = process.env.APPIUM_DEBUG_INTERVAL;
|
|
|
|
describe('Android Test App', function () {
|
|
this.timeout(600000);
|
|
let driver;
|
|
let debugIntervalId;
|
|
|
|
before(function () {
|
|
driver = wd.promiseChainRemote({
|
|
host: 'localhost',
|
|
port: 4723
|
|
});
|
|
driver.on('status', function (info) {
|
|
console.log(info.cyan);
|
|
});
|
|
driver.on('command', function (method, path, data) {
|
|
if (path === 'source()' && data) {
|
|
console.log(' > ' + method.yellow, 'Screen contents'.grey, '\n', pd.xml(data).yellow);
|
|
} else {
|
|
console.log(' > ' + method.yellow, path.grey, data || '');
|
|
}
|
|
});
|
|
driver.on('http', function (method, path, data) {
|
|
console.log(' > ' + method.magenta, path, (data || '').grey);
|
|
});
|
|
|
|
// every interval print what is on the screen
|
|
if (appiumDebugInterval) {
|
|
debugIntervalId = setInterval(() => {
|
|
// it driver.on('command') will log the screen contents
|
|
driver.source();
|
|
}, appiumDebugInterval);
|
|
}
|
|
|
|
const desired = {
|
|
platformName: 'Android',
|
|
deviceName: 'Android Emulator',
|
|
app: path.resolve('buck-out/gen/android/app/app.apk')
|
|
};
|
|
|
|
// React Native in dev mode often starts with Red Box "Can't fibd variable __fbBatchedBridge..."
|
|
// This is fixed by clicking Reload JS which will trigger a request to packager server
|
|
return driver
|
|
.init(desired)
|
|
.setImplicitWaitTimeout(5000)
|
|
.waitForElementByXPath('//android.widget.Button[@text="Reload JS"]').
|
|
then((elem) => {
|
|
elem.click();
|
|
}, (err) => {
|
|
// ignoring if Reload JS button can't be located
|
|
})
|
|
.setImplicitWaitTimeout(150000);
|
|
});
|
|
|
|
after(function () {
|
|
if (debugIntervalId) {
|
|
clearInterval(debugIntervalId);
|
|
}
|
|
return driver.quit();
|
|
});
|
|
|
|
it('should have Hot Module Reloading working', function () {
|
|
const androidAppCode = fs.readFileSync('index.android.js', 'utf-8');
|
|
let intervalToUpdate;
|
|
return driver
|
|
.waitForElementByXPath('//android.widget.TextView[starts-with(@text, "Welcome to React Native!")]')
|
|
// http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_MENU
|
|
.pressDeviceKey(82)
|
|
.elementByXPath('//android.widget.TextView[starts-with(@text, "Enable Hot Reloading")]')
|
|
.click()
|
|
.waitForElementByXPath('//android.widget.TextView[starts-with(@text, "Welcome to React Native!")]')
|
|
.then(() => {
|
|
let iteration = 0;
|
|
// CI environment can be quite slow and we can't guarantee that it can consistently motice a file change
|
|
// so we change the file every few seconds just in case
|
|
intervalToUpdate = setInterval(() => {
|
|
fs.writeFileSync('index.android.js', androidAppCode.replace('Welcome to React Native!', 'Welcome to React Native with HMR!' + iteration), 'utf-8');
|
|
}, 3000);
|
|
})
|
|
.waitForElementByXPath('//android.widget.TextView[starts-with(@text, "Welcome to React Native with HMR!")]')
|
|
.finally(() => {
|
|
clearInterval(intervalToUpdate);
|
|
fs.writeFileSync('index.android.js', androidAppCode, 'utf-8');
|
|
});
|
|
});
|
|
|
|
|
|
it('should have Debug In Chrome working', function () {
|
|
const androidAppCode = fs.readFileSync('index.android.js', 'utf-8');
|
|
// http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_MENU
|
|
return driver
|
|
.waitForElementByXPath('//android.widget.TextView[starts-with(@text, "Welcome to React Native!")]')
|
|
.pressDeviceKey(82)
|
|
.elementByXPath('//android.widget.TextView[starts-with(@text, "Debug")]')
|
|
.click()
|
|
.waitForElementByXPath('//android.widget.TextView[starts-with(@text, "Welcome to React Native!")]');
|
|
});
|
|
});
|