Skip to content

Commit a089cc2

Browse files
CDFNbohdanprogjakex7
authored
feat: e2e snapshot tests (#2338)
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please follow the template so that the reviewers can easily understand what the code changes affect --> # Summary This PR adds E2E tests based on view screenshots done via `react-native-view-shot`. It only works with devices that have their [pixel ratio](https://reactnative.dev/docs/pixelratio) equal `3`. If you want to use device with different pixel ratio, you need to adjust it in `e2e/generateReferences.ts` viewport and regenerate reference images (see below). Steps to run tests: - Run Metro server for example app via `yarn start` in example app's directory - Run `example` app on platform of your choice (currently only Android & iOS are supported) via `yarn android` or `yarn ios` in example app's directory - Run `yarn e2e` in project's root directory to start Jest server - Select `E2E` tab in example app - Wait for tests to finish - You can see test results, as well as diffs (actual rendered svg vs reference image) in `e2e/diffs` directory Steps to add new test cases: - Put SVG of your choice to `e2e/cases` directory - Run `yarn generateE2eRefrences`, this will open headless chrome browser via `puppeteer` and snapshot all rendered SVGs to .png files and later use them as reference in tests - You should see new .png files in `e2e/references` - When you run E2E tests again, it will use new test case(s) you've added ## Test Plan https://github.com/software-mansion/react-native-svg/assets/41289688/24ee5447-ce9a-43b6-9dde-76229d25a30a https://github.com/software-mansion/react-native-svg/assets/41289688/71d1873f-8155-4494-80bd-e4c1fa72a065 ### What's required for testing (prerequisites)? See Summary ### What are the steps to reproduce (after prerequisites)? See Summary ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ✅ | | Android | ✅ | | Web | ❌ | ## Checklist <!-- Check completed item, when applicable, via: [X] --> - [X] I have tested this on a device and a simulator - [x] I added documentation in `README.md` - [X] I updated the typed files (typescript) - [X] I added a test for the API in the `__tests__` folder --------- Co-authored-by: bohdanprog <[email protected]> Co-authored-by: Jakub Grzywacz <[email protected]>
1 parent 53ba6f2 commit a089cc2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1899
-101
lines changed

.github/workflows/android-e2e.yml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
name: Test Android e2e
2+
on:
3+
pull_request:
4+
paths:
5+
- '.github/workflows/android-e2e-test.yml'
6+
- 'apps/examples/**'
7+
- 'example/**'
8+
- 'android/**'
9+
- 'src/**'
10+
- 'e2e/**'
11+
- 'package.json'
12+
# push:
13+
# branches:
14+
# - main
15+
workflow_dispatch:
16+
jobs:
17+
test:
18+
runs-on: macos-12
19+
timeout-minutes: 60
20+
env:
21+
WORKING_DIRECTORY: example
22+
API_LEVEL: 34
23+
SYSTEM_IMAGES: system-images;android-34;google_apis;x86_64
24+
AVD_NAME: rn-svg-avd
25+
concurrency:
26+
group: android-e2e-example-${{ github.ref }}
27+
cancel-in-progress: true
28+
steps:
29+
- name: checkout
30+
uses: actions/checkout@v3
31+
with:
32+
submodules: recursive
33+
- uses: actions/setup-node@v3
34+
with:
35+
node-version: 18
36+
cache: 'yarn'
37+
- name: Set up JDK 17
38+
uses: actions/setup-java@v2
39+
with:
40+
java-version: '17'
41+
distribution: 'zulu'
42+
cache: 'gradle'
43+
- name: Install NDK
44+
uses: nttld/setup-ndk@v1
45+
id: setup-ndk
46+
with:
47+
ndk-version: r26d
48+
local-cache: true
49+
- name: Set ANDROID_NDK
50+
run: echo "ANDROID_NDK=$ANDROID_HOME/ndk-bundle" >> $GITHUB_ENV
51+
- name: Cache SDK image
52+
id: cache-sdk-img
53+
uses: actions/cache@v3
54+
with:
55+
path: $ANDROID_HOME/system-images/
56+
key: ${{ runner.os }}-build-system-images-${{ env.SYSTEM_IMAGES }}
57+
- name: SKDs - download required images
58+
if: ${{ steps.cache-sdd-img.outputs.cache-hit != 'true' }}
59+
run: $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "system-images;android-34;google_apis;x86_64"
60+
- name: Cache AVD
61+
id: cache-avd
62+
uses: actions/cache@v3
63+
with:
64+
path: ~/.android/avd/${{ env.AVD_NAME }}.avd
65+
key: ${{ runner.os }}-avd-images-${{ env.SYSTEM_IMAGES }}-${{ env.AVD_NAME }}
66+
- name: Emulator - Create
67+
if: ${{ steps.cache-avd.outputs.cache-hit != 'true' }}
68+
run: $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd -n ${{ env.AVD_NAME }} --device 28 --package "${{ env.SYSTEM_IMAGES }}" --sdcard 512M
69+
- name: Emulator - Set screen settings
70+
if: ${{ steps.cache-avd.outputs.cache-hit != 'true' }}
71+
run: |
72+
echo "AVD config path: $HOME/.android/avd/${{ env.AVD_NAME }}.avd/config.ini"
73+
sed -i '' 's/.*hw\.lcd\.density.*/hw\.lcd\.density = 480/g' $HOME/.android/avd/${{ env.AVD_NAME }}.avd/config.ini
74+
sed -i '' 's/.*hw\.lcd\.width.*/hw\.lcd\.width = 1344/g' $HOME/.android/avd/${{ env.AVD_NAME }}.avd/config.ini
75+
sed -i '' 's/.*hw\.lcd\.height.*/hw\.lcd\.height = 2992/g' $HOME/.android/avd/${{ env.AVD_NAME }}.avd/config.ini
76+
- name: Emulator - Boot
77+
run: $ANDROID_HOME/emulator/emulator -memory 4096 -avd ${{ env.AVD_NAME }} -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim &
78+
79+
- name: ADB Wait For Device
80+
run: adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;'
81+
timeout-minutes: 10
82+
83+
- name: Reverse TCP
84+
working-directory: ${{ env.WORKING_DIRECTORY }}
85+
run: adb devices | grep '\t' | awk '{print $1}' | sed 's/\\s//g' | xargs -I {} adb -s {} reverse tcp:8081 tcp:8081
86+
87+
- name: Install root node dependencies
88+
run: yarn
89+
90+
- name: Install example app node dependencies
91+
run: yarn
92+
working-directory: ${{ env.WORKING_DIRECTORY }}
93+
94+
- name: Build Android app
95+
working-directory: ${{ env.WORKING_DIRECTORY }}/android
96+
run: ./gradlew assembleDebug
97+
98+
- name: Start Metro server
99+
working-directory: ${{ env.WORKING_DIRECTORY }}
100+
run: E2E=true yarn start &> output.log &
101+
102+
- name: Install APK
103+
run: adb install -r ${{ env.WORKING_DIRECTORY }}/android/app/build/outputs/apk/debug/app-debug.apk
104+
105+
- name: Launch APK
106+
run: 'while ! (adb shell monkey -p com.example 1 | grep -q "Events injected: 1"); do sleep 1; echo "Retrying due to errors in previous run..."; done'
107+
108+
- name: Run e2e Tests
109+
run: E2E=true yarn e2e
110+
111+
- name: Upload test report
112+
uses: actions/upload-artifact@v4
113+
with:
114+
name: report
115+
path: |
116+
report.html
117+
jest-html-reporters-attach/
118+
119+
- name: Kill emulator (so it can be cached safely)
120+
run: adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done

.github/workflows/ios-e2e.yml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: Test iOS e2e
2+
on:
3+
pull_request:
4+
paths:
5+
- '.github/workflows/android-e2e-test.yml'
6+
- 'apps/examples/**'
7+
- 'example/**'
8+
- 'apple/**'
9+
- 'src/**'
10+
- 'e2e/**'
11+
- 'package.json'
12+
push:
13+
branches:
14+
- main
15+
workflow_dispatch:
16+
jobs:
17+
test:
18+
runs-on: macos-14
19+
timeout-minutes: 60
20+
env:
21+
WORKING_DIRECTORY: example
22+
DEVICE: iPhone 14 Pro
23+
XCODE_VERSION: latest-stable
24+
concurrency:
25+
group: ios-e2e-example-${{ github.ref }}
26+
cancel-in-progress: true
27+
steps:
28+
- name: checkout
29+
uses: actions/checkout@v3
30+
with:
31+
submodules: recursive
32+
- name: Use latest stable Xcode
33+
uses: maxim-lobanov/setup-xcode@v1
34+
with:
35+
xcode-version: ${{ env.XCODE_VERSION }}
36+
37+
- name: Restore react-native-svg node_modules from cache
38+
uses: actions/cache@v3
39+
with:
40+
path: node_modules
41+
key: ${{ runner.os }}-node-modules-svg-${{ hashFiles('yarn.lock') }}
42+
restore-keys: ${{ runner.os }}-node-modules-svg-
43+
44+
- name: Install react-native-svg node_modules
45+
run: yarn install --frozen-lockfile
46+
47+
- name: Restore app node_modules from cache
48+
uses: actions/cache@v3
49+
with:
50+
path: ${{ env.WORKING_DIRECTORY }}/node_modules
51+
key: ${{ runner.os }}-node-modules-${{ env.WORKING_DIRECTORY }}-${{ hashFiles(format('{0}/yarn.lock', env.WORKING_DIRECTORY)) }}
52+
restore-keys: ${{ runner.os }}-node-modules-${{ env.WORKING_DIRECTORY }}-
53+
54+
- name: Install app node_modules
55+
working-directory: ${{ env.WORKING_DIRECTORY }}
56+
run: yarn install --frozen-lockfile
57+
58+
- name: Restore Pods from cache
59+
uses: actions/cache@v3
60+
with:
61+
path: |
62+
${{ env.WORKING_DIRECTORY }}/ios/Pods
63+
~/Library/Caches/CocoaPods
64+
~/.cocoapods
65+
key: ${{ runner.os }}-pods-${{ env.WORKING_DIRECTORY }}-${{ hashFiles(format('{0}/ios/Podfile.lock', env.WORKING_DIRECTORY)) }}
66+
67+
- name: Install Pods
68+
working-directory: ${{ env.WORKING_DIRECTORY }}/ios
69+
run: pod install
70+
71+
- name: Restore build artifacts from cache
72+
uses: actions/cache@v3
73+
with:
74+
path: ~/Library/Developer/Xcode/DerivedData
75+
key: ${{ runner.os }}-ios-derived-data-${{ env.WORKING_DIRECTORY }}-${{ hashFiles(format('{0}/ios/Podfile.lock', env.WORKING_DIRECTORY)) }}
76+
- name: Start Metro server
77+
working-directory: ${{ env.WORKING_DIRECTORY }}
78+
run: E2E=true yarn start &> output.log &
79+
80+
- name: Build app
81+
working-directory: ${{ env.WORKING_DIRECTORY }}
82+
run: E2E=true npx react-native@latest run-ios --simulator="${{ env.DEVICE }}" --mode Debug --verbose
83+
84+
- name: Run e2e Tests
85+
run: E2E=true yarn e2e
86+
87+
- name: Upload test report
88+
uses: actions/upload-artifact@v4
89+
with:
90+
name: report
91+
path: |
92+
report.html
93+
jest-html-reporters-attach/

.github/workflows/windows-build-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,4 @@ jobs:
5757

5858
- name: Build app
5959
working-directory: ${{ matrix.working-directory }}/windows
60-
run: npx react-native run-windows --logging --no-packager --no-deploy
60+
run: npx react-native run-windows --logging --no-packager --no-deploy --no-autolink

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ experimental/
5050

5151
# VS Code
5252
.vscode/
53+
54+
jest-html-reporters-attach/
55+
report.html

CONTRIBUTING.md

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Contributing to React Native Svg
22

33
Thank you for helping out with react-native-svg!
4-
We'd like to make contributions as pleasant as possible, so here's a small guide of how we see it. Happy to hear your feedback about anything, so please let us know.
4+
We'd like to make contributions as pleasant as possible, so here's a small guide of how we see it. Happy to hear your
5+
feedback about anything, so please let us know.
56

67
### Modifying react-native-svg
78

@@ -13,24 +14,51 @@ We'd like to make contributions as pleasant as possible, so here's a small guide
1314

1415
### Testing your changes
1516

16-
Add test example in [tests-example](https://github.com/react-native-svg/react-native-svg/tree/main/tests-example) concerning your change following the convention of `TestX.tsx` where `X` is your PR number.
17+
Add test example in [tests-example](https://github.com/react-native-svg/react-native-svg/tree/main/tests-example)
18+
concerning your change following the convention of `TestX.tsx` where `X` is your PR number.
1719

1820
## Tests
1921

20-
We use `typescript` for type checks, `eslint` with `prettier` for linting/formatting. All tests are run by github actions for all opened pull requests.
22+
We use `typescript` for type checks, `eslint` with `prettier` for linting/formatting. All tests are run by github
23+
actions for all opened pull requests.
2124

2225
- `yarn test`: Run all tests, except for e2e (see note below).
2326
- `yarn lint`: Run `eslint` check.
2427
- `yarn tsc`: Run `typescript` check.
2528
- `yarn jest`: Run `jest` type check.
29+
- `yarn e2e`: Run E2E tests (see section below)
2630

27-
Currently e2e tests exist here: https://github.com/msand/react-native-svg-e2e/
31+
### Running E2E tests:
32+
33+
> [!WARNING]
34+
> Reference images in this repository are generated with [pixel ratio](https://reactnative.dev/docs/pixelratio) = `3`.
35+
> Make sure to run tests on a device that also has pixel ratio equal 3. Otherwise tests will fail.
36+
> In order to use device with different pixel ratio, adjust it in `e2e/generateRefereces.ts` viewport and regenerate
37+
> references.
38+
39+
1. Navigate to the example application's directory and initiate the Metro server using the yarn start command.
40+
2. To run the example application on your preferred platform (note: currently only Android and iOS are supported),
41+
execute the command `yarn android` or `yarn ios` within the example app's directory.
42+
3. Start the Jest server by running `yarn e2e` in the project's root directory.
43+
4. In the example application, select the E2E tab.
44+
5. Allow the tests to complete.
45+
6. The test results, along with any differences (i.e. the actual rendered svg versus the reference image), can be viewed
46+
in the `e2e/diffs` directory.
47+
48+
### To add new E2E test cases, proceed as follows:
49+
50+
1. Put an SVG file of your selection into the `e2e/cases` directory.
51+
2. Execute `yarn generateE2eRefrences`. This action launches a headless Chrome browser via Puppeteer, capturing
52+
snapshots of all rendered SVGs as .png files. These files will serve as a reference during testing.
53+
3. Check the `e2e/references` directory to observe newly created .png files.
54+
4. When you rerun the E2E tests, the new test case(s) you've added will be incorporated.
2855

2956
## Sending a pull request
3057

3158
When you're sending a pull request:
3259

33-
- Communication is a key. If you want fix/add something, please consider either opening a new issue or finding an existing one so we can further discuss it.
60+
- Communication is a key. If you want fix/add something, please consider either opening a new issue or finding an
61+
existing one so we can further discuss it.
3462
- We prefer small pull requests focused on one change, as those are easier to test/check.
3563
- Please make sure that all tests are passing on your local machine.
3664
- Follow the template when opening a PR.
@@ -43,7 +71,8 @@ Most notably prefixes you'll see:
4371

4472
- **fix**: Bug fixes
4573
- **feat**: New feature implemented
46-
- **chore**: Changes that are not affecting end user (CI config changes, scripts, ["grunt work"](https://stackoverflow.com/a/26944812/3510245))
74+
- **chore**: Changes that are not affecting end user (CI config changes,
75+
scripts, ["grunt work"](https://stackoverflow.com/a/26944812/3510245))
4776
- **docs**: Documentation changes.
4877
- **perf**: A code change that improves performance.
4978
- **refactor**: A code change that neither fixes a bug nor adds a feature.
@@ -55,7 +84,8 @@ We use [release-it](https://github.com/release-it/release-it) to release new ver
5584

5685
## Reporting issues
5786

58-
You can report issues on our [bug tracker](https://github.com/react-native-community/react-native-svg/issues). Please search for existing issues and follow the issue template when opening one.
87+
You can report issues on our [bug tracker](https://github.com/react-native-community/react-native-svg/issues). Please
88+
search for existing issues and follow the issue template when opening one.
5989

6090
## License
6191

0 commit comments

Comments
 (0)