Skip to content

Commit 3e4c68f

Browse files
authored
feat: implement two up interactive diff viewer (#707)
* feat: implement two up interactive diff viewer mode * chore: split 2 up interactive mode into pure and connected components * fix: save changes when working on component tests * fix: fix incorrect placement of smaller images in fit to view mode * test: install testing library, generate test images, implement first pack of tests on 2-up interactive viewer * test: updated packages with fixes for component tests and implement component tests ci action * ci: upload reports to S3 instead of gh-pages * ci: fix component tests report path in S3 * test: implement component tests for 2up diff viewer * chore: remove test images gen script and improve diff comment generation * fix: do not list 2up interactive in old UI, because it can't work there
1 parent 40e9cb1 commit 3e4c68f

File tree

112 files changed

+2584
-568
lines changed

Some content is hidden

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

112 files changed

+2584
-568
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ hot
1515
/testplane-report
1616
tmp
1717
**/playwright-report
18+
**/html-report/*

.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ module.exports = {
3030
files: ['test/**'],
3131
rules: {
3232
// For convenient casting of test objects
33-
'@typescript-eslint/no-explicit-any': 'off'
33+
'@typescript-eslint/no-explicit-any': 'off',
34+
'@typescript-eslint/no-restricted-imports': 'off'
3435
}
3536
}
3637
]
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: Testplane Component Tests
2+
3+
on:
4+
pull_request:
5+
branches: [ master ]
6+
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
9+
cancel-in-progress: true
10+
11+
jobs:
12+
testplane-component:
13+
runs-on: ubuntu-latest
14+
15+
permissions:
16+
contents: read
17+
pull-requests: write
18+
19+
env:
20+
DOCKER_IMAGE_NAME: html-reporter-browsers
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Use Node.js 22
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: 22
29+
cache: 'npm'
30+
31+
- name: Install dependencies
32+
run: npm ci
33+
34+
- name: Build the package
35+
run: npm run build
36+
37+
- name: 'Prepare component tests: Cache browser docker image'
38+
uses: actions/cache@v3
39+
with:
40+
path: ~/.docker/cache
41+
key: docker-browser-image-${{ hashFiles('test/func/docker/Dockerfile') }}
42+
43+
- name: 'Prepare component tests: Pull browser docker image'
44+
run: |
45+
mkdir -p ~/.docker/cache
46+
if [ -f ~/.docker/cache/image.tar ]; then
47+
docker load -i ~/.docker/cache/image.tar
48+
else
49+
docker pull yinfra/html-reporter-browsers
50+
docker save yinfra/html-reporter-browsers -o ~/.docker/cache/image.tar
51+
fi
52+
53+
- name: 'Prepare component tests: Run browser docker image'
54+
run: docker run -d --name ${{ env.DOCKER_IMAGE_NAME }} -it --rm --network=host $(which colima >/dev/null || echo --add-host=host.docker.internal:0.0.0.0) yinfra/html-reporter-browsers
55+
56+
- name: 'component-tests: Run Testplane'
57+
id: 'testplane'
58+
continue-on-error: true
59+
run: npm run component-tests
60+
61+
- name: 'component-tests: Stop browser docker image'
62+
run: |
63+
docker kill ${{ env.DOCKER_IMAGE_NAME }} || true
64+
docker rm ${{ env.DOCKER_IMAGE_NAME }} || true
65+
66+
- name: Upload Testplane html-reporter reports to S3
67+
uses: jakejarvis/[email protected]
68+
with:
69+
args: --acl public-read --follow-symlinks
70+
env:
71+
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
72+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
73+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
74+
AWS_S3_ENDPOINT: https://s3.yandexcloud.net/
75+
SOURCE_DIR: "test/component/html-report"
76+
DEST_DIR: "testplane-ci/component-tests-reports/${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}/"
77+
78+
- name: Construct PR comment
79+
run: |
80+
link="https://${{ secrets.AWS_S3_BUCKET }}.s3.yandexcloud.net/testplane-ci/component-tests-reports/${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}/index.html"
81+
if [ "${{ steps.testplane.outcome }}" != "success" ]; then
82+
comment="### ❌ Component tests failed<br><br>[Report](${link})"
83+
echo "PR_COMMENT=${comment}" >> $GITHUB_ENV
84+
else
85+
comment="### ✅ Component tests succeed<br><br>[Report](${link})"
86+
echo "PR_COMMENT=${comment}" >> $GITHUB_ENV
87+
fi
88+
89+
- name: Leave comment to PR with link to Testplane HTML reports
90+
if: github.event.pull_request
91+
uses: thollander/actions-comment-pull-request@v3
92+
with:
93+
message: ${{ env.PR_COMMENT }}
94+
comment-tag: testplane_component_results
95+
96+
- name: Fail the job if any Testplane job is failed
97+
if: ${{ steps.testplane.outcome != 'success' }}
98+
run: exit 1

.github/workflows/e2e.yml

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,6 @@ jobs:
6464
- name: 'Prepare e2e tests: Generate fixtures'
6565
run: npm run e2e:generate-fixtures || true
6666

67-
- name: 'Prepare e2e tests: Setup env'
68-
run: |
69-
REPORT_PREFIX=testplane-reports
70-
REPORT_DATE=$(date '+%Y-%m-%d')
71-
echo "DEST_REPORTS_DIR=$REPORT_PREFIX/$REPORT_DATE/${{ github.run_id }}/${{ github.run_attempt }}" >> $GITHUB_ENV
72-
7367
- name: 'e2e: Run Testplane'
7468
id: 'testplane'
7569
continue-on-error: true
@@ -84,25 +78,29 @@ jobs:
8478
- name: Merge Testplane html-reporter reports
8579
working-directory: 'test/func/tests'
8680
run: |
87-
mkdir -p ../../../${{ env.DEST_REPORTS_DIR }}
88-
npx testplane merge-reports reports/*/sqlite.db -d ../../../${{ env.DEST_REPORTS_DIR }}
81+
mkdir -p ../../../e2e-report
82+
npx testplane merge-reports reports/*/sqlite.db -d ../../../e2e-report
8983
90-
- name: Deploy Testplane html-reporter reports
91-
uses: peaceiris/actions-gh-pages@v4
84+
- name: Upload Testplane html-reporter reports to S3
85+
uses: jakejarvis/[email protected]
9286
with:
93-
github_token: ${{ secrets.GITHUB_TOKEN }}
94-
publish_dir: ${{ env.DEST_REPORTS_DIR }}
95-
destination_dir: ${{ env.DEST_REPORTS_DIR }}
96-
keep_files: true
87+
args: --acl public-read --follow-symlinks
88+
env:
89+
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
90+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
91+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
92+
AWS_S3_ENDPOINT: https://s3.yandexcloud.net/
93+
SOURCE_DIR: "e2e-report"
94+
DEST_DIR: "testplane-ci/e2e-tests-reports/${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}/"
9795

9896
- name: Construct PR comment
9997
run: |
100-
link="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ env.DEST_REPORTS_DIR }}"
98+
link="https://${{ secrets.AWS_S3_BUCKET }}.s3.yandexcloud.net/testplane-ci/e2e-tests-reports/${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}/index.html"
10199
if [ "${{ steps.testplane.outcome }}" != "success" ]; then
102-
comment="### ❌ Testplane run failed<br><br>[Report](${link})"
100+
comment="### ❌ E2E tests failed<br><br>[Report](${link})"
103101
echo "PR_COMMENT=${comment}" >> $GITHUB_ENV
104102
else
105-
comment="### ✅ Testplane run succeed<br><br>[Report](${link})"
103+
comment="### ✅ E2E tests succeed<br><br>[Report](${link})"
106104
echo "PR_COMMENT=${comment}" >> $GITHUB_ENV
107105
fi
108106
@@ -111,7 +109,7 @@ jobs:
111109
uses: thollander/actions-comment-pull-request@v3
112110
with:
113111
message: ${{ env.PR_COMMENT }}
114-
comment-tag: testplane_results
112+
comment-tag: testplane_e2e_results
115113

116114
- name: Fail the job if any Testplane job is failed
117115
if: ${{ steps.testplane.outcome != 'success' }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ html-reporter-*.tgz
2626

2727
**/playwright-report
2828
hermione-report
29+
html-report
2930
testplane-report
3031
test/func/**/report
3132
test/func/**/report-backup

lib/constants/diff-modes.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {pick} from 'lodash';
12
import type {ValueOf} from 'type-fest';
23

34
export const DiffModes = {
@@ -35,9 +36,16 @@ export const DiffModes = {
3536
id: 'onion-skin',
3637
title: 'Onion skin',
3738
description: 'Onion Skin. Change the image opacity to compare expected and actual images.'
39+
},
40+
TWO_UP_INTERACTIVE: {
41+
id: '2-up-interactive',
42+
title: '2-up Interactive',
43+
description: '2-up Interactive. Compare expected and actual images side by side with synchronized pan and zoom.'
3844
}
3945
} as const;
4046

47+
export const ClassicDiffModes = pick(DiffModes, ['THREE_UP', 'THREE_UP_SCALED', 'THREE_UP_SCALED_TO_FIT', 'ONLY_DIFF', 'SWITCH', 'SWIPE', 'ONION_SKIN']);
48+
4149
export type DiffModes = typeof DiffModes;
4250

4351
export type DiffMode = ValueOf<DiffModes>;

lib/constants/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export * from './plugin-events';
1111
export * from './save-formats';
1212
export * from './test-statuses';
1313
export * from './tool-names';
14+
export * from './two-up-modes';
1415
export * from './view-modes';

lib/constants/local-storage.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ export enum LocalStorageKey {
44
}
55

66
export const TIME_TRAVEL_PLAYER_VISIBILITY_KEY = 'time-travel-player-visibility';
7+
export const TWO_UP_DIFF_VISIBILITY_KEY = '2up-diff-visibility';
8+
export const TWO_UP_FIT_MODE_KEY = '2up-fit-mode';
79

810
export enum UiMode {
911
Old = 'old',

lib/constants/two-up-modes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum TwoUpFitMode {
2+
FitToView = 'fit-to-view',
3+
FitToWidth = 'fit-to-width'
4+
}

lib/static/components/controls/common-controls.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import BaseHostInput from './base-host-input';
1010
import MenuBar from './menu-bar';
1111
import ReportInfo from './report-info';
1212
import {ViewMode} from '../../../constants/view-modes';
13-
import {DiffModes} from '../../../constants/diff-modes';
13+
import {ClassicDiffModes} from '../../../constants/diff-modes';
1414
import {EXPAND_ALL, COLLAPSE_ALL, EXPAND_ERRORS, EXPAND_RETRIES} from '../../../constants/expand-modes';
1515

1616
class ControlButtons extends Component {
@@ -77,7 +77,7 @@ class ControlButtons extends Component {
7777
label="Diff mode"
7878
value={view.diffMode}
7979
handler={diffModeId => actions.setDiffMode({diffModeId})}
80-
options = {Object.values(DiffModes).map((dm) => {
80+
options = {Object.values(ClassicDiffModes).map((dm) => {
8181
return {value: dm.id, content: dm.title};
8282
})}
8383
extendClassNames="diff-mode"

0 commit comments

Comments
 (0)