-
Notifications
You must be signed in to change notification settings - Fork 24.9k
RNTester: Setup E2E tests for iOS and Android with Appium, Jest and Cucumber #35824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…/react-native into feature/rn-tester-e2e
…/react-native into feature/rn-tester-e2e
Hi @adzironman! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at [email protected]. Thanks! |
This Appium setup is cool, we made a babel plugin to find elements with testID, do check if it's useful in this setup. https://www.npmjs.com/package/babel-plugin-format-testid |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a couple of comments that are iOS specific. A part from that, great work!
A question out of ignorance: if we have to implement and call the JS methods, can we get rid of Gerkin? It looks a repetition of the test description and they could go out of sync easily (or become maintenance burden). If we have JS methods with descriptive names, we can use a code-as-documentation approach and simplify the setup.
Do you think that it is possible? (Another approach could be to generate the Gerkin file from the JS one)
If you are M1 mac user: | ||
1. Install ffi package `gem install ffi -v '1.15.5' --source 'https://rubygems.org/'` | ||
2. Install pods with new architecture, e.g. using JSC `USE_HERMES=0 arch -x86_64 pod install` | ||
3. Open the generated `RNTesterPods.xcworkspace`. | ||
4. Build the app. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be required anymore.
3. Open the generated `RNTesterPods.xcworkspace`. | ||
4. Build the app. | ||
|
||
Find the **RNTester.app** in `~/Library/Developer/Xcode/DerivedData/RNTesterPods-{id}/Build/Products/Debug-iphonesimulator` and move the app to the following directory `/react-native/packages/rn-tester-e2e/apps` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can use xcodebuild
from the command line and tell it to generate the app in some specific folder: above listing 8 and 9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving some very superficial feedback. This will need some cleanup I think.
More generally, I would try to think of the scenarios we want to test E2E, and what we need more than this to be able to accomplish it.
The basis here lets the test runner navigate, check for existence of controls/text. But I think the more valuable bits are understanding the impact a props, etc has on the native component. Either visually via screenshot testing, or via approaches like snapshotting the native component tree.
With the screen objects, I would try to settle on some pattern. E.g. an object per RNTester page, if we are going to have them. Though unless we solve the problem of engineers adding to the screen object when adding RNTester examples, we should not assume these will be kept up to date.
I also expect that Appium may balloon the number of dependencies we have and are caching. Please keep an eye out for its effect on the lockfile, especially for anything which will immediately come back as a security bit.
import { beforeEach, afterEach, jest } from '@jest/globals'; | ||
|
||
|
||
jest.setTimeout(40000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This contradicts the timeout we set in the config?
host: 'localhost', | ||
port: 4723, | ||
waitforTimeout: 30000, | ||
logLevel: 'silent', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logLevel: 'silent', | |
logLevel: 'error', |
packages/rn-tester-e2e/package.json
Outdated
"private": true, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"license": "ISC", | |
"license": "MIT", |
"@babel/eslint-parser": "^7.19.1", | ||
"@babel/runtime": "^7.12.5", | ||
"@react-native-community/eslint-config": "^2.0.0", | ||
"appium": "^2.0.0-beta.40", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not seeing reflected in yarn lockfile. Could we yarn install (also so we can see how many deps added)
packages/rn-tester-e2e/package.json
Outdated
"jest-cucumber": "^3.0.1", | ||
"jest-html-reporter": "^3.7.0", | ||
"metro-react-native-babel-preset": "^0.70.3", | ||
"react-test-renderer": "18.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems unused?
|
||
buttonComponentElement = Utils.platformSelect({ | ||
ios: '[label="Button Simple React Native button component."]', | ||
android: '~Button Simple React Native button component.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we search by test id instead of string?
class ButtonComponentScreen { | ||
|
||
buttonScreenElement = Utils.platformSelect({ | ||
ios: '[label="Button"]', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we search by test id instead of any string? Also means we can remove this per-platform bits.
// Common steps reusable between different features | ||
export const userIsOnMainScreen = (given) => { | ||
given('User is on the main screen', async () => { | ||
await driver.pause(2000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Harcoded waits like this should be avoided
@@ -0,0 +1,19 @@ | |||
Feature: Button component screen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need cucumber, if we don't use it anywhere else.
await driver.$(locator).waitForDisplayed(); | ||
return driver.$(locator).getText(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these should be formatted/linted, have copyright headers.
@NickGerleman @cipolleschi please ignore this PR for now, this is part 2 of #35786 but the team is still working on them both (you'll see that a good part of your comments I've already covered in the other PR). I'll ping you once this 2nd PR should be looked at ;) |
let's close this one in favour of #36267, things have changed enough that adding cucumber will need (if we decide to do it) much further down the line |
please check out this one first ➡️ #35016
Summary
The motivation is to create an e2e testing solution for the rn-tester default app. With cooperation with Callstack developers, we are trying to make a working tool. This PR is adding configuration for the BDD approach with cucumber.
Next steps:
Changelog
[General] [Added] - Added first working configuration for e2e testing with Appium, Jest and Cucumber
Test Plan
Follow Readme File
Comparison of work for approach with and without Cucumber
In a clean jest+wdio setup, test scenarios are written in one file:

In order to use the BDD approach you need to do a few additional steps in comparison to jest+wdio solution implemented here.
Additional steps:

2. Add a runner fileVideos
final_andorid.mp4
final_ios.mp4