Skip to content

Commit 8f14a0a

Browse files
chore: use github ci
1 parent 09900ba commit 8f14a0a

File tree

17 files changed

+310
-18
lines changed

17 files changed

+310
-18
lines changed

.github/workflows/e2e.yml

+219
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
name: Testplane E2E
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
testplane-e2e:
11+
runs-on: ubuntu-latest
12+
13+
permissions:
14+
contents: write
15+
pull-requests: write
16+
17+
env:
18+
DOCKER_IMAGE_NAME: html-reporter-browsers
19+
SOURCE_REPORTS_DIR: test/func/tests/reports
20+
21+
steps:
22+
- uses: actions/checkout@v2
23+
24+
- name: Use Node.js 20
25+
uses: actions/setup-node@v2
26+
with:
27+
node-version: 20
28+
cache: 'npm'
29+
30+
- name: Install dependencies
31+
run: npm ci
32+
33+
- name: Build the package
34+
run: npm run build
35+
36+
- name: 'Prepare e2e tests: Install pwt-chromium'
37+
run: npx playwright install chromium
38+
39+
- name: 'Prepare e2e tests: Build-packages'
40+
run: npm run e2e:build-packages
41+
42+
- name: 'Prepare e2e tests: Cache browser docker image'
43+
uses: actions/cache@v3
44+
with:
45+
path: ~/.docker/cache
46+
key: docker-browser-image-${{ hashFiles('test/func/docker/Dockerfile') }}
47+
48+
- name: 'Prepare e2e tests: Pull browser docker image'
49+
run: |
50+
mkdir -p ~/.docker/cache
51+
if [ -f ~/.docker/cache/image.tar ]; then
52+
docker load -i ~/.docker/cache/image.tar
53+
else
54+
docker pull yinfra/html-reporter-browsers
55+
docker save yinfra/html-reporter-browsers -o ~/.docker/cache/image.tar
56+
fi
57+
58+
- name: 'Prepare e2e tests: Run browser docker image'
59+
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
60+
61+
- name: 'Prepare e2e tests: Generate fixtures'
62+
run: npm run e2e:generate-fixtures || true
63+
64+
- name: 'Prepare e2e tests: Setup env'
65+
run: |
66+
REPORT_PREFIX=testplane-reports
67+
REPORT_DATE=$(date '+%y-%m-%d')
68+
echo "DEST_REPORTS_DIR=$REPORT_PREFIX/$REPORT_DATE/${{ github.run_id }}/${{ github.run_attempt }}" >> $GITHUB_ENV
69+
70+
- name: Upload fixtures reports
71+
uses: actions/upload-artifact@v4
72+
with:
73+
name: testplane-fixtures
74+
path: test/func/fixtures/*/report
75+
76+
- name: 'e2e: Run Testplane testplane-common'
77+
id: 'testplane-testplane-common'
78+
continue-on-error: true
79+
working-directory: 'test/func/tests'
80+
run: npm run testplane:testplane-common
81+
82+
- name: 'e2e: Run Testplane testplane-eye'
83+
id: 'testplane-testplane-eye'
84+
continue-on-error: true
85+
working-directory: 'test/func/tests'
86+
run: npm run testplane:testplane-eye
87+
88+
- name: 'e2e: Run Testplane testplane-gui'
89+
id: 'testplane-testplane-gui'
90+
continue-on-error: true
91+
working-directory: 'test/func/tests'
92+
run: npm run testplane:testplane-gui
93+
94+
- name: 'e2e: Run Testplane playwright'
95+
id: 'testplane-playwright'
96+
continue-on-error: true
97+
working-directory: 'test/func/tests'
98+
run: npm run testplane:playwright
99+
100+
- name: 'e2e: Run Testplane plugins'
101+
id: 'testplane-plugins'
102+
continue-on-error: true
103+
working-directory: 'test/func/tests'
104+
run: npm run testplane:plugins
105+
106+
- name: 'e2e: Run Testplane testplane-tinder'
107+
id: 'testplane-testplane-tinder'
108+
continue-on-error: true
109+
working-directory: 'test/func/tests'
110+
run: npm run testplane:testplane-tinder
111+
112+
- name: 'e2e: Run Testplane analytics'
113+
id: 'testplane-analytics'
114+
continue-on-error: true
115+
working-directory: 'test/func/tests'
116+
run: npm run testplane:analytics
117+
118+
- name: 'e2e: Stop browser docker image'
119+
run: |
120+
docker kill ${{ env.DOCKER_IMAGE_NAME }} || true
121+
docker rm ${{ env.DOCKER_IMAGE_NAME }} || true
122+
123+
- name: Set IS_FAILED if any step didn't succeed
124+
if: always()
125+
run: |
126+
if [ "${{ steps.testplane-testplane-common.outcome }}" != "success" ] || \
127+
[ "${{ steps.testplane-testplane-gui.outcome }}" != "success" ] || \
128+
[ "${{ steps.testplane-plugins.outcome }}" != "success" ] || \
129+
[ "${{ steps.testplane-analytics.outcome }}" != "success" ] || \
130+
[ "${{ steps.testplane-playwright.outcome }}" != "success" ] || \
131+
[ "${{ steps.testplane-testplane-eye.outcome }}" != "success" ] || \
132+
[ "${{ steps.testplane-testplane-tinder.outcome }}" != "success" ]; then
133+
echo "IS_FAILED=true" >> $GITHUB_ENV
134+
fi
135+
136+
- name: Deploy Testplane html-reporter reports
137+
if: ${{ env.IS_FAILED }}
138+
uses: peaceiris/actions-gh-pages@v4
139+
with:
140+
github_token: ${{ secrets.GITHUB_TOKEN }}
141+
publish_dir: ${{ env.SOURCE_REPORTS_DIR }}
142+
destination_dir: ${{ env.DEST_REPORTS_DIR }}
143+
keep_files: true
144+
145+
- name: Construct failed PR comment
146+
if: ${{ env.IS_FAILED }}
147+
run: |
148+
comment="### ❌ Testplane run failed<br><br>"
149+
link_base="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ env.DEST_REPORTS_DIR }}"
150+
151+
if [[ ${{ steps.testplane-testplane-common.outcome }} == "success" ]]; then
152+
comment+="- ✅ testplane-common: success. "
153+
else
154+
comment+="- ❌ testplane-common: failure. "
155+
fi
156+
comment+="[Report](${link_base}/testplane) <br>"
157+
158+
if [[ ${{ steps.testplane-testplane-gui.outcome }} == "success" ]]; then
159+
comment+="- ✅ testplane-gui: success. "
160+
else
161+
comment+="- ❌ testplane-gui: failure. "
162+
fi
163+
comment+="[Report](${link_base}/testplane-gui) <br>"
164+
165+
if [[ ${{ steps.testplane-plugins.outcome }} == "success" ]]; then
166+
comment+="- ✅ plugins: success. "
167+
else
168+
comment+="- ❌ plugins: failure. "
169+
fi
170+
comment+="[Report](${link_base}/plugins) <br>"
171+
172+
if [[ ${{ steps.testplane-analytics.outcome }} == "success" ]]; then
173+
comment+="- ✅ analytics: success. "
174+
else
175+
comment+="- ❌ analytics: failure. "
176+
fi
177+
comment+="[Report](${link_base}/analytics) <br>"
178+
179+
if [[ ${{ steps.testplane-playwright.outcome }} == "success" ]]; then
180+
comment+="- ✅ playwright: success. "
181+
else
182+
comment+="- ❌ playwright: failure. "
183+
fi
184+
comment+="[Report](${link_base}/playwright) <br>"
185+
186+
if [[ ${{ steps.testplane-testplane-eye.outcome }} == "success" ]]; then
187+
comment+="- ✅ testplane-eye: success. "
188+
else
189+
comment+="- ❌ testplane-eye: failure. "
190+
fi
191+
comment+="[Report](${link_base}/testplane-eye) <br>"
192+
193+
if [[ ${{ steps.testplane-testplane-tinder.outcome }} == "success" ]]; then
194+
comment+="- ✅ testplane-tinder: success. "
195+
else
196+
comment+="- ❌ testplane-tinder: failure. "
197+
fi
198+
comment+="[Report](${link_base}/testplane-tinder) <br>"
199+
200+
echo "FAILED_PR_COMMENT=${comment}" >> $GITHUB_ENV
201+
202+
- name: Leave failed comment to PR with link to Testplane HTML reports
203+
if: env.IS_FAILED
204+
id: leave-failed-comment-step
205+
uses: thollander/actions-comment-pull-request@v3
206+
with:
207+
message: ${{ env.FAILED_PR_COMMENT }}
208+
comment-tag: testplane_results
209+
210+
- name: Leave success comment to PR
211+
if: steps.leave-failed-comment-step.outcome == 'skipped'
212+
uses: thollander/actions-comment-pull-request@v3
213+
with:
214+
message: '### ✅ Testplane run succeed'
215+
comment-tag: testplane_results
216+
217+
- name: Fail the job if any Testplane job is failed
218+
if: env.IS_FAILED
219+
run: exit 1

package-lock.json

+11-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/func/fixtures/playwright/tests/failed-describe.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ test.describe('failed describe', () => {
3838
test('test with successful assertView and error', async ({page, baseURL}) => {
3939
await page.goto(baseURL as string);
4040

41-
await expect(page.locator('header')).toHaveScreenshot('header-success.png');
41+
await expect(page.locator('header')).toHaveScreenshot('header-success.png', {maxDiffPixelRatio: 1});
4242

4343
throw new Error('Some error');
4444
});

test/func/fixtures/plugins/success-describe.testplane.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ describe('success describe', function() {
88
it('test with screenshot', async ({browser}) => {
99
await browser.url(browser.options.baseUrl);
1010

11-
await browser.assertView('header', 'header');
11+
await browser.assertView('header', 'header', {ignoreDiffPixelCount: '100%'});
1212
});
1313
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
const _ = require('lodash');
4+
5+
const {getFixturesConfig} = require('../fixtures.testplane.conf');
6+
7+
module.exports = _.merge(getFixturesConfig(__dirname), {});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en" dir="ltr">
3+
<head>
4+
<meta charset="utf-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<p id="paragraph-1">Hello, world!</p>
9+
<p id="paragraph-2">Another line...</p>
10+
<p id="paragraph-3">The third line.</p>
11+
</body>
12+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "testplane-tinder",
3+
"version": "0.0.0",
4+
"private": true,
5+
"scripts": {
6+
"clean": "rm -rf report",
7+
"generate": "npx testplane --grep 'tests to run'",
8+
"gui": "npx testplane gui --hostname 0.0.0.0 --port $(../../utils/get-port.js testplane-tinder gui)"
9+
}
10+
}
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
describe('tests to run', () => {
2+
it('test with image comparison diff', async ({browser}) => {
3+
await browser.url(browser.options.baseUrl);
4+
5+
await browser.assertView('paragraph', '#paragraph-1');
6+
});
7+
8+
it('test with no reference image', async ({browser}) => {
9+
await browser.url(browser.options.baseUrl);
10+
11+
await browser.assertView('paragraph', '#paragraph-3');
12+
});
13+
});
14+
15+
describe('tests not to run', () => {
16+
it('successful test', async ({browser}) => {
17+
await browser.url(browser.options.baseUrl);
18+
19+
assert.isTrue(true);
20+
});
21+
});

test/func/fixtures/testplane/failed-describe.testplane.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ describe('failed describe', function() {
2424
it('test with successful assertView and error', async ({browser}) => {
2525
await browser.url(browser.options.baseUrl);
2626

27-
await browser.assertView('header', 'header');
27+
await browser.assertView('header', 'header', {ignoreDiffPixelCount: '100%'});
2828

2929
throw new Error('Some error');
3030
});

test/func/fixtures/testplane/success-describe.testplane.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ describe('success describe', function() {
88
it('test with screenshot', async ({browser}) => {
99
await browser.url(browser.options.baseUrl);
1010

11-
await browser.assertView('header', 'header');
11+
await browser.assertView('header', 'header', {ignoreDiffPixelCount: '100%'});
1212
});
1313
});

test/func/packages/html-reporter-test-server/index.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,24 @@ module.exports = (testplane, pluginConfig) => {
1818
testplane.on(testplane.events.RUNNER_START, () => {
1919
const app = express();
2020
app.use(express.static(path.resolve(__dirname, '../..')));
21+
2122
server = app.listen(port, (err) => {
2223
if (err) {
2324
console.error('Failed to start test server:');
2425
throw new Error(err);
2526
}
2627

2728
console.info(`Server is listening on http://localhost:${port}`);
29+
}).on('error', err => {
30+
if (err.code === 'EADDRINUSE') {
31+
console.warn(`Skip running server, because port ${port} is busy`);
32+
} else {
33+
throw err;
34+
}
2835
});
2936
});
3037

3138
testplane.on(testplane.events.RUNNER_END, () => {
32-
server.close(() => console.info(`Server was closed`));
39+
server && server.close(() => console.info(`Server was closed`));
3340
});
3441
};

0 commit comments

Comments
 (0)