Skip to content

Commit c81776f

Browse files
ci: workflow to add comment for e2e test changes
1 parent eebc5ff commit c81776f

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: "E2E PR Checklist"
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
paths:
7+
- "e2e/**"
8+
9+
permissions:
10+
pull-requests: read
11+
contents: read
12+
13+
jobs:
14+
add-e2e-checklist:
15+
name: "Add E2E Checklist"
16+
runs-on: ubuntu-latest
17+
permissions:
18+
pull-requests: write
19+
steps:
20+
- name: Detect changed E2E platforms
21+
id: detect
22+
uses: actions/github-script@v7
23+
with:
24+
script: |
25+
const { data: files } = await github.rest.pulls.listFiles({
26+
owner: context.repo.owner,
27+
repo: context.repo.repo,
28+
pull_number: context.issue.number,
29+
per_page: 100
30+
});
31+
32+
const desktop = files.some(f => f.filename.startsWith('e2e/desktop/'));
33+
const mobile = files.some(f => f.filename.startsWith('e2e/mobile/'));
34+
35+
core.setOutput('desktop', desktop.toString());
36+
core.setOutput('mobile', mobile.toString());
37+
38+
- name: Add E2E checklist comment
39+
uses: actions/github-script@v7
40+
env:
41+
CHANGED_DESKTOP: ${{ steps.detect.outputs.desktop }}
42+
CHANGED_MOBILE: ${{ steps.detect.outputs.mobile }}
43+
with:
44+
script: |
45+
const desktopChanged = process.env.CHANGED_DESKTOP === 'true';
46+
const mobileChanged = process.env.CHANGED_MOBILE === 'true';
47+
48+
const platformLabel = desktopChanged && mobileChanged
49+
? 'Desktop & Mobile'
50+
: desktopChanged ? 'Desktop' : 'Mobile';
51+
52+
// Build device table columns based on changed platforms
53+
const header = ['Device'];
54+
const separator = ['--------'];
55+
if (desktopChanged) { header.push('Desktop'); separator.push('---------'); }
56+
if (mobileChanged) { header.push('Mobile'); separator.push('--------'); }
57+
58+
const devices = ['nanoS', 'nanoSP', 'nanoX', 'stax', 'flex', 'nanoGen5'];
59+
const rows = devices.map(device => {
60+
const cols = [`| ${device}`];
61+
if (desktopChanged) cols.push('⬜ Passed');
62+
if (mobileChanged) cols.push('⬜ Passed');
63+
return cols.join(' | ') + ' |';
64+
});
65+
66+
const deviceTable = [
67+
'| ' + header.join(' | ') + ' |',
68+
'| ' + separator.join(' | ') + ' |',
69+
...rows
70+
].join('\n');
71+
72+
// Build workflow trigger instructions
73+
const workflowLinks = [];
74+
if (desktopChanged) {
75+
workflowLinks.push('- **Desktop:** Trigger [`test-ui-e2e-only-desktop.yml`](../actions/workflows/test-ui-e2e-only-desktop.yml) with `test_filter` set to your test name/tag');
76+
}
77+
if (mobileChanged) {
78+
workflowLinks.push('- **Mobile:** Trigger [`test-mobile-e2e-reusable.yml`](../actions/workflows/test-mobile-e2e-reusable.yml) with `test_filter` set to your test name/tag');
79+
}
80+
81+
82+
const e2eChecklist = `## 🧪 E2E Test Checklist — ${platformLabel}
83+
84+
> This checklist was added automatically because your PR touches \`e2e/\` files.
85+
86+
### General
87+
- [ ] Tests pass locally before pushing
88+
- [ ] No \`.only\` or \`.skip\` left in test files (unless intentional and documented)
89+
- [ ] Tests are independent and can run in any order
90+
91+
### Test Quality
92+
- [ ] Page Object Model (POM) pattern is followed for new pages/components
93+
- [ ] Appropriate device tags are added: \`@NanoSP\`, \`@NanoX\`, \`@Stax\`, \`@Flex\`, \`@NanoGen5\`
94+
- [ ] Family tags are added where applicable: \`@family-evm\`, \`@family-bitcoin\`, etc.
95+
- [ ] \`@smoke\` tag added for critical path tests (if applicable)
96+
- [ ] TMS/Xray ticket IDs are linked in test annotations (e.g., \`B2CQA-XXXX\`)
97+
98+
### Device Coverage (Required for new/updated tests)
99+
Run your tests on **all supported devices** using the E2E workflow(s):
100+
101+
${workflowLinks.join('\n')}
102+
103+
${deviceTable}
104+
105+
> 💡 Use \`workflow_dispatch\` to trigger the workflow manually on your branch. Set the \`speculos_device\` input to test each device.
106+
`;
107+
108+
// Paginate through all comments to reliably find an existing bot comment
109+
const marker = '## 🧪 E2E Test Checklist';
110+
let botComment = null;
111+
for await (const { data: comments } of github.paginate.iterator(
112+
github.rest.issues.listComments,
113+
{ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, per_page: 100 }
114+
)) {
115+
botComment = comments.find(c => c.user.type === 'Bot' && c.body.includes(marker));
116+
if (botComment) break;
117+
}
118+
119+
if (!botComment) {
120+
await github.rest.issues.createComment({
121+
owner: context.repo.owner,
122+
repo: context.repo.repo,
123+
issue_number: context.issue.number,
124+
body: e2eChecklist
125+
});
126+
console.log(`E2E checklist comment added (${platformLabel})`);
127+
} else {
128+
// Update existing comment if platforms changed (e.g., mobile added after desktop-only)
129+
if (!botComment.body.includes(platformLabel)) {
130+
await github.rest.issues.updateComment({
131+
owner: context.repo.owner,
132+
repo: context.repo.repo,
133+
comment_id: botComment.id,
134+
body: e2eChecklist
135+
});
136+
console.log(`E2E checklist comment updated to ${platformLabel}`);
137+
} else {
138+
console.log('E2E checklist comment already exists and is up to date, skipping');
139+
}
140+
}

0 commit comments

Comments
 (0)