Skip to content

Commit a65b4f0

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

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
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 with proof link columns per platform
53+
const header = ['Device'];
54+
const separator = ['--------'];
55+
if (desktopChanged) {
56+
header.push('Proof (Desktop)');
57+
separator.push('---');
58+
}
59+
if (mobileChanged) {
60+
header.push('Proof (Mobile)');
61+
separator.push('---');
62+
}
63+
64+
const devices = ['nanoS', 'nanoSP', 'nanoX', 'stax', 'flex', 'nanoGen5'];
65+
const rows = devices.map(device => {
66+
const cols = [`| ${device}`];
67+
if (desktopChanged) cols.push('_paste link_');
68+
if (mobileChanged) cols.push('_paste link_');
69+
return cols.join(' | ') + ' |';
70+
});
71+
72+
const deviceTable = [
73+
'| ' + header.join(' | ') + ' |',
74+
'| ' + separator.join(' | ') + ' |',
75+
...rows
76+
].join('\n');
77+
78+
// Build workflow trigger instructions
79+
const workflowLinks = [];
80+
if (desktopChanged) {
81+
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');
82+
}
83+
if (mobileChanged) {
84+
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');
85+
}
86+
87+
88+
const e2eChecklist = `## 🧪 E2E Test Checklist — ${platformLabel}
89+
90+
> This checklist was added automatically because your PR touches \`e2e/\` files.
91+
92+
### General
93+
- [ ] Tests pass locally before pushing
94+
- [ ] Tests are independent and can run in any order
95+
96+
### Test Quality
97+
- [ ] Page Object Model (POM) pattern is followed for new pages/components
98+
- [ ] Appropriate device tags are added: \`@NanoSP\`, \`@NanoX\`, \`@Stax\`, \`@Flex\`, \`@NanoGen5\`
99+
- [ ] Family tags are added where applicable: \`@family-evm\`, \`@family-bitcoin\`, etc.
100+
- [ ] TMS/Xray ticket IDs are linked in test annotations (e.g., \`B2CQA-XXXX\`)
101+
102+
### Device Coverage (Required for new/updated tests)
103+
Run your tests on **all supported devices** using the E2E workflow(s):
104+
105+
${workflowLinks.join('\n')}
106+
107+
${deviceTable}
108+
109+
> 💡 Use \`workflow_dispatch\` to trigger the workflow manually on your branch. Set the \`speculos_device\` input to test each device. Replace *paste link* with a link to the workflow run or Allure report.
110+
`;
111+
112+
// Paginate through all comments to reliably find an existing bot comment
113+
const marker = '## 🧪 E2E Test Checklist';
114+
let botComment = null;
115+
for await (const { data: comments } of github.paginate.iterator(
116+
github.rest.issues.listComments,
117+
{ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, per_page: 100 }
118+
)) {
119+
botComment = comments.find(c => c.user.type === 'Bot' && c.body.includes(marker));
120+
if (botComment) break;
121+
}
122+
123+
if (!botComment) {
124+
await github.rest.issues.createComment({
125+
owner: context.repo.owner,
126+
repo: context.repo.repo,
127+
issue_number: context.issue.number,
128+
body: e2eChecklist
129+
});
130+
console.log(`E2E checklist comment added (${platformLabel})`);
131+
} else {
132+
// Update existing comment if platforms changed (e.g., mobile added after desktop-only)
133+
if (!botComment.body.includes(platformLabel)) {
134+
await github.rest.issues.updateComment({
135+
owner: context.repo.owner,
136+
repo: context.repo.repo,
137+
comment_id: botComment.id,
138+
body: e2eChecklist
139+
});
140+
console.log(`E2E checklist comment updated to ${platformLabel}`);
141+
} else {
142+
console.log('E2E checklist comment already exists and is up to date, skipping');
143+
}
144+
}

0 commit comments

Comments
 (0)