Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/playwright-crit-flow-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: 18.16.x
cache: 'yarn'
node-version-file: .nvmrc
cache: yarn

- name: Install JS dependencies
run: yarn --immutable
Expand Down Expand Up @@ -49,7 +49,7 @@ jobs:
if: always()
id: generate_comment
run: |
node test/e2e_tests/scripts/create-playwright-report-summary.js
node --experimental-strip-types test/e2e_tests/scripts/create-playwright-report-summary.ts
COMMENT=$(cat playwright-report-summary.txt)
echo "comment<<EOF" >> $GITHUB_OUTPUT
echo "$COMMENT" >> $GITHUB_OUTPUT
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/precommit-crit-flows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ jobs:
run: yarn playwright merge-reports --config ./playwright.config.ts ./all-blob-reports

- name: Upload test report
id: upload_playwright_report
if: always()
uses: actions/upload-artifact@v4
with:
Expand All @@ -270,7 +271,7 @@ jobs:
if: always()
id: generate_comment
run: |
node test/e2e_tests/scripts/create-playwright-report-summary.js
node --experimental-strip-types test/e2e_tests/scripts/create-playwright-report-summary.ts
COMMENT=$(cat playwright-report-summary.txt)
echo "comment<<EOF" >> $GITHUB_OUTPUT
echo "$COMMENT" >> $GITHUB_OUTPUT
Expand All @@ -282,7 +283,7 @@ jobs:
with:
header: playwright-summary
message: |
🔗 [Download Full Report Artifact](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
🔗 [Download Full Report Artifact](${{ steps.upload_playwright_report.outputs.artifact-url }})

${{ steps.generate_comment.outputs.comment }}
env:
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22.16
22.18
120 changes: 0 additions & 120 deletions test/e2e_tests/scripts/create-playwright-report-summary.js

This file was deleted.

101 changes: 101 additions & 0 deletions test/e2e_tests/scripts/create-playwright-report-summary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

import type {JSONReport, JSONReportSuite, JSONReportTest} from '@playwright/test/reporter';

import {readFileSync, writeFileSync} from 'fs';

Check warning on line 22 in test/e2e_tests/scripts/create-playwright-report-summary.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `node:fs` over `fs`.

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-webapp&issues=AZrjg-evlUCGWJt4x0Y3&open=AZrjg-evlUCGWJt4x0Y3&pullRequest=19830
import {resolve} from 'path';

Check warning on line 23 in test/e2e_tests/scripts/create-playwright-report-summary.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `node:path` over `path`.

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-webapp&issues=AZrjg-evlUCGWJt4x0Y4&open=AZrjg-evlUCGWJt4x0Y4&pullRequest=19830

const jsonPath = resolve('playwright-report', 'report.json');
let report: JSONReport;

try {
report = JSON.parse(readFileSync(jsonPath, 'utf-8'));
} catch (error) {
const errorMessage = `❌ Error: report.json not found at ${jsonPath} ❌`;
writeFileSync('playwright-report-summary.txt', errorMessage);
process.exit(1);
}

Check warning on line 34 in test/e2e_tests/scripts/create-playwright-report-summary.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Handle this exception or don't catch it at all.

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-webapp&issues=AZrjg-evlUCGWJt4x0Y5&open=AZrjg-evlUCGWJt4x0Y5&pullRequest=19830

const getTests = (suite: JSONReportSuite): (JSONReportTest & {file: string; title: string; tags: string[]})[] => {
return [
...(suite.specs.flatMap(spec =>
spec.tests.map(test => ({
...test,
file: spec.file,
// If no title is provided the file would be used which is redundant
title: spec.file !== suite.title ? `${suite.title} > ${spec.title}` : spec.title,

Check warning on line 43 in test/e2e_tests/scripts/create-playwright-report-summary.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-webapp&issues=AZrjg-evlUCGWJt4x0Y6&open=AZrjg-evlUCGWJt4x0Y6&pullRequest=19830
tags: spec.tags,
})),
) ?? []),
...(suite.suites?.flatMap(suite => getTests(suite)) ?? []),
];
};

const tests = report.suites.flatMap(suite => getTests(suite));
const failedOrFlakyTests = tests.filter(test => test.status === 'unexpected' || test.status === 'flaky');
const testFilesToReport = Object.groupBy(failedOrFlakyTests, test => test.file);

const testDetails = Object.values(testFilesToReport).reduce((acc, testFile) => {
if (!testFile?.length) {
return acc;
}

const failedTests = testFile
.filter(test => test.status === 'unexpected')
.map(({title, tags}) => `❌ ${title} (tags: ${tags.join(', ')})`);

const flakyTests = testFile
.filter(test => test.status === 'flaky')
.map(({title, tags}) => `⚠️ ${title} (tags: ${tags.join(', ')})`);

acc += `
<details>
<summary>${testFile[0].file} (❌ ${failedTests.length} failed, ⚠️ ${flakyTests.length} flaky)</summary>

<ul>
${[...failedTests, ...flakyTests].map(s => `<li>${s}</li>`).join('\n ')}
</ul>
</details>
`;

return acc;
}, '');

const formatDuration = (duration: number) => {
const minutes = Math.floor(duration / 60000);
const totalSeconds = Math.round((duration % 60000) / 1000);
const seconds = totalSeconds % 60;
return `~ ${minutes} min ${seconds} sec`;
};

const summary = `
### 🧪 Playwright Test Summary

- ✅ **Passed:** ${report.stats.expected}
- ❌ **Failed:** ${report.stats.unexpected}
- ⏭ **Skipped:** ${report.stats.skipped}
- 🔁 **Flaky:** ${report.stats.flaky}
- 📊 **Total:** ${report.stats.expected + report.stats.unexpected + report.stats.skipped + report.stats.flaky}
- ⏱ **Total Runtime:** ${(report.stats.duration / 1000).toFixed(1)}s (${formatDuration(report.stats.duration)})

${testDetails}
`;

writeFileSync('playwright-report-summary.txt', summary);
Loading