testdriverai 7.2.25 → 7.2.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/test-with-comments.yml +73 -0
- package/docs/GITHUB_COMMENTS.md +330 -0
- package/docs/GITHUB_COMMENTS_ANNOUNCEMENT.md +167 -0
- package/docs/QUICK-START-GITHUB-COMMENTS.md +84 -0
- package/docs/TEST-GITHUB-COMMENTS.md +129 -0
- package/docs/github-integration-setup.md +266 -0
- package/examples/github-actions.yml +68 -0
- package/examples/github-comment-demo.test.mjs +42 -0
- package/interfaces/vitest-plugin.mjs +100 -0
- package/lib/github-comment-formatter.js +263 -0
- package/lib/github-comment.mjs +424 -0
- package/lib/vitest/hooks.mjs +15 -0
- package/package.json +2 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Testing GitHub Comments Feature
|
|
2
|
+
|
|
3
|
+
## Quick Test Instructions
|
|
4
|
+
|
|
5
|
+
1. **Ensure TD_API_KEY is set**
|
|
6
|
+
- Go to: https://github.com/testdriverai/testdriverai/settings/secrets/actions
|
|
7
|
+
- Add secret named `TD_API_KEY` with your API key from https://console.testdriver.ai/team
|
|
8
|
+
- If already set, you're good to go!
|
|
9
|
+
|
|
10
|
+
2. **Create a test branch and PR**
|
|
11
|
+
```bash
|
|
12
|
+
cd /Users/ianjennings/Development/testdriverai
|
|
13
|
+
git checkout -b test-github-comments
|
|
14
|
+
|
|
15
|
+
# Make a small change to trigger the workflow
|
|
16
|
+
echo "# Test GitHub Comments" >> test-comment.md
|
|
17
|
+
git add test-comment.md
|
|
18
|
+
git commit -m "test: trigger GitHub comment workflow"
|
|
19
|
+
git push origin test-github-comments
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3. **Create Pull Request**
|
|
23
|
+
```bash
|
|
24
|
+
gh pr create --title "Test: GitHub Comments Feature" \
|
|
25
|
+
--body "Testing automatic GitHub comments with test results and dashcam replays"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or create via web: https://github.com/testdriverai/testdriverai/compare
|
|
29
|
+
|
|
30
|
+
4. **Watch the Magic Happen! ✨**
|
|
31
|
+
- The workflow will automatically run: `.github/workflows/test-with-comments.yml`
|
|
32
|
+
- View progress at: https://github.com/testdriverai/testdriverai/actions
|
|
33
|
+
- After ~30-60 seconds, you'll see a comment on your PR with:
|
|
34
|
+
- ✅ Test results summary
|
|
35
|
+
- 🎥 Embedded dashcam GIF replay
|
|
36
|
+
- 📊 Test statistics
|
|
37
|
+
- 📋 Link to full test run
|
|
38
|
+
|
|
39
|
+
## What the Test Does
|
|
40
|
+
|
|
41
|
+
The workflow runs `test/testdriver/assert.test.mjs` which:
|
|
42
|
+
- Provisions a Chrome browser
|
|
43
|
+
- Navigates to https://saucedemo.com
|
|
44
|
+
- Performs login actions
|
|
45
|
+
- Uses TestDriver's `assert()` to verify elements
|
|
46
|
+
- Records a dashcam replay of the entire test
|
|
47
|
+
- Posts results to your PR automatically
|
|
48
|
+
|
|
49
|
+
## Expected Comment Output
|
|
50
|
+
|
|
51
|
+
You should see a comment like:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
# 🟢 TestDriver Test Results
|
|
55
|
+
|
|
56
|
+
**Status:** ✅ PASSED
|
|
57
|
+
**Duration:** 25.3s
|
|
58
|
+
**Platform:** linux
|
|
59
|
+
**Branch:** `test-github-comments`
|
|
60
|
+
**Commit:** `abc1234`
|
|
61
|
+
|
|
62
|
+
## 📊 Test Summary
|
|
63
|
+
|
|
64
|
+
Total: 1
|
|
65
|
+
Passed: 1 ✅
|
|
66
|
+
Failed: 0 ❌
|
|
67
|
+
Skipped: 0 ⏭️
|
|
68
|
+
|
|
69
|
+
### [📋 View Full Test Run](https://console.testdriver.ai/runs/...)
|
|
70
|
+
|
|
71
|
+
## 📝 Test Results
|
|
72
|
+
|
|
73
|
+
| Status | Test | File | Duration | Replay |
|
|
74
|
+
|--------|------|------|----------|--------|
|
|
75
|
+
| ✅ | Assert Test | `test/testdriver/assert.test.mjs` | 25.3s | [🎥 View](https://console.testdriver.ai/replay/...) |
|
|
76
|
+
|
|
77
|
+
## 🎥 Dashcam Replays
|
|
78
|
+
|
|
79
|
+
### Assert Test
|
|
80
|
+
|
|
81
|
+
[](https://console.testdriver.ai/replay/...)
|
|
82
|
+
|
|
83
|
+
[🎬 View Full Replay](https://console.testdriver.ai/replay/...)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Troubleshooting
|
|
87
|
+
|
|
88
|
+
### No comment appears
|
|
89
|
+
- Check Actions tab for errors: https://github.com/testdriverai/testdriverai/actions
|
|
90
|
+
- Verify `TD_API_KEY` secret is set correctly
|
|
91
|
+
- Ensure workflow has `pull-requests: write` permission (it does in the provided workflow)
|
|
92
|
+
|
|
93
|
+
### Workflow doesn't run
|
|
94
|
+
- Make sure the workflow file is on the branch you're testing
|
|
95
|
+
- Check that PR is from the same repository (not a fork)
|
|
96
|
+
|
|
97
|
+
### Test fails
|
|
98
|
+
- View the workflow logs for details
|
|
99
|
+
- Check TestDriver API status
|
|
100
|
+
- Verify your API key is valid
|
|
101
|
+
|
|
102
|
+
## Manual Trigger
|
|
103
|
+
|
|
104
|
+
You can also trigger the workflow manually:
|
|
105
|
+
1. Go to: https://github.com/testdriverai/testdriverai/actions/workflows/test-with-comments.yml
|
|
106
|
+
2. Click "Run workflow"
|
|
107
|
+
3. Select your branch
|
|
108
|
+
4. Click "Run workflow"
|
|
109
|
+
|
|
110
|
+
Note: Manual triggers won't post PR comments (no PR context), but will still run tests.
|
|
111
|
+
|
|
112
|
+
## Clean Up
|
|
113
|
+
|
|
114
|
+
After testing, delete the test branch:
|
|
115
|
+
```bash
|
|
116
|
+
gh pr close YOUR_PR_NUMBER
|
|
117
|
+
git checkout main
|
|
118
|
+
git branch -D test-github-comments
|
|
119
|
+
git push origin --delete test-github-comments
|
|
120
|
+
rm test-comment.md # if it exists on main
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Next Steps
|
|
124
|
+
|
|
125
|
+
Once you've confirmed it works:
|
|
126
|
+
1. Customize the workflow for your needs
|
|
127
|
+
2. Add more test files to the run command
|
|
128
|
+
3. Set up for all PRs in your repository
|
|
129
|
+
4. Share with your team!
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# GitHub Integration Setup
|
|
2
|
+
|
|
3
|
+
TestDriver automatically posts beautiful test result comments to GitHub Pull Requests, including:
|
|
4
|
+
- ✅ Test results summary with pass/fail counts
|
|
5
|
+
- 🎥 Dashcam GIF replays embedded directly in comments
|
|
6
|
+
- 📊 Detailed test statistics and duration
|
|
7
|
+
- 🔴 Exception details with stack traces
|
|
8
|
+
- 📋 Links to full test runs
|
|
9
|
+
|
|
10
|
+
This guide explains how to configure GitHub authentication so TestDriver can post these comments.
|
|
11
|
+
|
|
12
|
+
## How It Works
|
|
13
|
+
|
|
14
|
+
TestDriver's Vitest plugin automatically detects GitHub context and posts comments when tests complete. Here's what it needs:
|
|
15
|
+
|
|
16
|
+
### Required Environment Variables
|
|
17
|
+
|
|
18
|
+
1. **GITHUB_TOKEN** or **GH_TOKEN** - GitHub Personal Access Token for authentication
|
|
19
|
+
2. **GITHUB_REPOSITORY** - Repository in `owner/repo` format (auto-detected in GitHub Actions)
|
|
20
|
+
3. **GITHUB_PR_NUMBER** - Pull Request number (auto-detected in GitHub Actions)
|
|
21
|
+
4. **GITHUB_SHA** - Commit SHA (optional, auto-detected in GitHub Actions)
|
|
22
|
+
|
|
23
|
+
### Auto-Detection in GitHub Actions
|
|
24
|
+
|
|
25
|
+
When running in GitHub Actions, most variables are automatically available:
|
|
26
|
+
- `GITHUB_REPOSITORY` - Set automatically
|
|
27
|
+
- `GITHUB_SHA` - Set automatically
|
|
28
|
+
- `GITHUB_REF` - Used to detect PR number
|
|
29
|
+
- Pull request info extracted from event data
|
|
30
|
+
|
|
31
|
+
You only need to configure the token permissions!
|
|
32
|
+
|
|
33
|
+
### Method 1: GitHub Actions (Recommended)
|
|
34
|
+
|
|
35
|
+
GitHub Actions provides automatic authentication. TestDriver will detect the context automatically.
|
|
36
|
+
|
|
37
|
+
**Required Permissions:**
|
|
38
|
+
|
|
39
|
+
In your workflow file, use the built-in `GITHUB_TOKEN` with write permissions:
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
name: TestDriver Tests
|
|
43
|
+
|
|
44
|
+
on:
|
|
45
|
+
pull_request:
|
|
46
|
+
types: [opened, synchronize]
|
|
47
|
+
|
|
48
|
+
jobs:
|
|
49
|
+
test:
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
permissions:
|
|
52
|
+
contents: read
|
|
53
|
+
pull-requests: write # Required to post comments
|
|
54
|
+
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Setup Node.js
|
|
59
|
+
uses: actions/setup-node@v4
|
|
60
|
+
with:
|
|
61
|
+
node-version: '20'
|
|
62
|
+
|
|
63
|
+
- name: Install dependencies
|
|
64
|
+
run: npm ci
|
|
65
|
+
|
|
66
|
+
- name: Run TestDriver tests
|
|
67
|
+
env:
|
|
68
|
+
TD_API_KEY: ${{ secrets.TD_API_KEY }}
|
|
69
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Automatically provided
|
|
70
|
+
run: npm run test
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**What happens automatically:**
|
|
74
|
+
- `GITHUB_TOKEN`: Provided by GitHub Actions
|
|
75
|
+
- `GITHUB_REPOSITORY`: Automatically set (e.g., `testdriverai/testdriverai`)
|
|
76
|
+
- `GITHUB_REF`: Automatically set (e.g., `refs/pull/123/merge`)
|
|
77
|
+
- PR number: Extracted automatically from `GITHUB_REF` or event data
|
|
78
|
+
|
|
79
|
+
### Method 2: Manual Setup (Local or Other CI)
|
|
80
|
+
|
|
81
|
+
For local development or other CI systems, set these environment variables:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# .env or export in your shell
|
|
85
|
+
GITHUB_TOKEN=ghp_your_personal_access_token_here
|
|
86
|
+
GITHUB_PR_NUMBER=123
|
|
87
|
+
# GITHUB_REPOSITORY is auto-detected from git if not set
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Creating a Personal Access Token:**
|
|
91
|
+
|
|
92
|
+
1. Go to [GitHub Settings → Developer settings → Personal access tokens](https://github.com/settings/tokens)
|
|
93
|
+
2. Click "Generate new token" → "Generate new token (classic)"
|
|
94
|
+
3. Give it a descriptive name (e.g., "TestDriver CI")
|
|
95
|
+
4. Select scopes:
|
|
96
|
+
- ✅ `repo` (Full control of private repositories)
|
|
97
|
+
- Or just ✅ `public_repo` (for public repositories only)
|
|
98
|
+
5. Click "Generate token"
|
|
99
|
+
6. Copy the token immediately (you won't see it again!)
|
|
100
|
+
7. Store it securely:
|
|
101
|
+
- **In GitHub Actions**: Add as repository secret (`Settings → Secrets and variables → Actions → New repository secret`)
|
|
102
|
+
- **Locally**: Add to `.env` file (and add `.env` to `.gitignore`!)
|
|
103
|
+
|
|
104
|
+
### Method 3: Other CI Systems
|
|
105
|
+
|
|
106
|
+
#### CircleCI
|
|
107
|
+
```yaml
|
|
108
|
+
environment:
|
|
109
|
+
GITHUB_TOKEN: $GITHUB_TOKEN
|
|
110
|
+
GITHUB_REPOSITORY: $CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME
|
|
111
|
+
GITHUB_PR_NUMBER: $CIRCLE_PR_NUMBER
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### GitLab CI
|
|
115
|
+
```yaml
|
|
116
|
+
variables:
|
|
117
|
+
GITHUB_TOKEN: $GITHUB_TOKEN
|
|
118
|
+
GITHUB_REPOSITORY: "your-org/your-repo"
|
|
119
|
+
GITHUB_PR_NUMBER: $CI_MERGE_REQUEST_IID
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### Jenkins
|
|
123
|
+
```groovy
|
|
124
|
+
environment {
|
|
125
|
+
GITHUB_TOKEN = credentials('github-token')
|
|
126
|
+
GITHUB_REPOSITORY = "${env.GITHUB_ORG}/${env.GITHUB_REPO}"
|
|
127
|
+
GITHUB_PR_NUMBER = "${env.CHANGE_ID}"
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Environment Variables Reference
|
|
132
|
+
|
|
133
|
+
| Variable | Priority | Description | Example | Source |
|
|
134
|
+
|----------|----------|-------------|---------|--------|
|
|
135
|
+
| `GITHUB_TOKEN` | 1 | GitHub personal access token | `ghp_abc...` | Auto-provided in GitHub Actions |
|
|
136
|
+
| `GH_TOKEN` | 2 | Alternative GitHub token | `ghp_xyz...` | Manual setup |
|
|
137
|
+
| `GITHUB_REPOSITORY` | - | Repository in `owner/repo` format | `testdriverai/testdriverai` | Auto-set in GitHub Actions |
|
|
138
|
+
| `GITHUB_PR_NUMBER` | - | Pull request number | `123` | Must be set manually or by CI |
|
|
139
|
+
| `GITHUB_SHA` | - | Commit SHA | `abc1234def...` | Auto-set in GitHub Actions |
|
|
140
|
+
| `TESTDRIVER_SKIP_GITHUB_COMMENT` | - | Disable comment posting | `true` | Set to skip comments |
|
|
141
|
+
|
|
142
|
+
**Note**: Git repository info (owner/repo, branch, commit) is auto-detected from your local `.git` directory if not provided via environment variables.
|
|
143
|
+
|
|
144
|
+
## Disabling GitHub Comments
|
|
145
|
+
|
|
146
|
+
To disable GitHub comments:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Method 1: Set environment variable
|
|
150
|
+
TESTDRIVER_SKIP_GITHUB_COMMENT=true npm run test
|
|
151
|
+
|
|
152
|
+
# Method 2: Remove/unset the GitHub token
|
|
153
|
+
unset GITHUB_TOKEN
|
|
154
|
+
unset GH_TOKEN
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
In GitHub Actions workflow:
|
|
158
|
+
```yaml
|
|
159
|
+
- name: Run tests without GitHub comments
|
|
160
|
+
env:
|
|
161
|
+
TD_API_KEY: ${{ secrets.TD_API_KEY }}
|
|
162
|
+
TESTDRIVER_SKIP_GITHUB_COMMENT: true
|
|
163
|
+
run: npm test
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Troubleshooting
|
|
167
|
+
|
|
168
|
+
### "GitHub token not found, skipping comment posting"
|
|
169
|
+
|
|
170
|
+
Check that the token is set:
|
|
171
|
+
```bash
|
|
172
|
+
echo $GITHUB_TOKEN # or GH_TOKEN
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### "Neither PR number nor commit SHA found"
|
|
176
|
+
|
|
177
|
+
Set the PR number:
|
|
178
|
+
```bash
|
|
179
|
+
export GITHUB_PR_NUMBER=123
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Or ensure `GITHUB_SHA` is set (auto-set in GitHub Actions).
|
|
183
|
+
|
|
184
|
+
### "Repository info not available"
|
|
185
|
+
|
|
186
|
+
The plugin auto-detects repo info from your `.git` directory. If that fails, set:
|
|
187
|
+
```bash
|
|
188
|
+
export GITHUB_REPOSITORY=owner/repo
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### "Resource not accessible by integration"
|
|
192
|
+
|
|
193
|
+
Your token doesn't have `pull-requests: write` permission. Check:
|
|
194
|
+
- GitHub Actions: Add `permissions.pull-requests: write` to workflow
|
|
195
|
+
- Personal token: Ensure it has `repo` or `public_repo` scope
|
|
196
|
+
|
|
197
|
+
### "Not Found" or "403 Forbidden"
|
|
198
|
+
|
|
199
|
+
- Token doesn't have access to the repository
|
|
200
|
+
- Repository name format is incorrect (must be `owner/repo`)
|
|
201
|
+
- PR number is invalid
|
|
202
|
+
|
|
203
|
+
### Comments not appearing
|
|
204
|
+
|
|
205
|
+
- Check that tests are running in the context of a pull request
|
|
206
|
+
- Verify the token has write access
|
|
207
|
+
- Look for error messages in the test output
|
|
208
|
+
- Run with `DEBUG=testdriver:github` for verbose logging
|
|
209
|
+
|
|
210
|
+
## Security Best Practices
|
|
211
|
+
|
|
212
|
+
1. **Never commit tokens** to git repositories
|
|
213
|
+
2. **Use GitHub Actions secrets** for CI/CD
|
|
214
|
+
3. **Use fine-grained tokens** with minimum required permissions
|
|
215
|
+
4. **Rotate tokens regularly** (at least every 90 days)
|
|
216
|
+
5. **Revoke tokens** immediately if compromised
|
|
217
|
+
6. **Use organization secrets** for shared tokens across repos
|
|
218
|
+
|
|
219
|
+
## Example Comment Output
|
|
220
|
+
|
|
221
|
+
When properly configured, TestDriver will post comments like:
|
|
222
|
+
|
|
223
|
+
```markdown
|
|
224
|
+
# 🟢 TestDriver Test Results
|
|
225
|
+
|
|
226
|
+
**Status:** ✅ PASSED
|
|
227
|
+
**Duration:** 45.23s
|
|
228
|
+
**Platform:** linux
|
|
229
|
+
**Branch:** `feature/new-login`
|
|
230
|
+
**Commit:** `abc1234`
|
|
231
|
+
|
|
232
|
+
## 📊 Test Summary
|
|
233
|
+
|
|
234
|
+
Total: 3
|
|
235
|
+
Passed: 3 ✅
|
|
236
|
+
Failed: 0 ❌
|
|
237
|
+
Skipped: 0 ⏭️
|
|
238
|
+
|
|
239
|
+
### [📋 View Full Test Run](https://app.testdriver.ai/runs/...)
|
|
240
|
+
|
|
241
|
+
## 📝 Test Results
|
|
242
|
+
|
|
243
|
+
| Status | Test | File | Duration | Replay |
|
|
244
|
+
|--------|------|------|----------|--------|
|
|
245
|
+
| ✅ | should log in successfully | `login.test.mjs` | 12.34s | [🎥 View](https://app.testdriver.ai/replay/...) |
|
|
246
|
+
| ✅ | should navigate to dashboard | `navigation.test.mjs` | 8.91s | [🎥 View](https://app.testdriver.ai/replay/...) |
|
|
247
|
+
|
|
248
|
+
## 🎥 Dashcam Replays
|
|
249
|
+
|
|
250
|
+
### should log in successfully
|
|
251
|
+
|
|
252
|
+
[](https://app.testdriver.ai/replay/...)
|
|
253
|
+
|
|
254
|
+
[🎬 View Full Replay](https://app.testdriver.ai/replay/...)
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
<sub>Generated by [TestDriver](https://testdriver.ai) • Run ID: `run_abc123`</sub>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The GIF replays are automatically embedded so reviewers can see what happened without leaving GitHub!
|
|
261
|
+
|
|
262
|
+
## Getting Help
|
|
263
|
+
|
|
264
|
+
- 📚 [Full Documentation](https://docs.testdriver.ai)
|
|
265
|
+
- 💬 [Discord Community](https://discord.gg/testdriver)
|
|
266
|
+
- 🐛 [Report Issues](https://github.com/testdriverai/testdriverai/issues)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: TestDriver Tests with GitHub Comments
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, reopened]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main, develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
# Required for posting comments on PRs
|
|
15
|
+
pull-requests: write
|
|
16
|
+
# Required for posting comments on commits
|
|
17
|
+
contents: write
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout code
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Setup Node.js
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: '20'
|
|
27
|
+
cache: 'npm'
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: npm ci
|
|
31
|
+
|
|
32
|
+
- name: Run TestDriver tests
|
|
33
|
+
env:
|
|
34
|
+
# TestDriver API key (add this to your repository secrets)
|
|
35
|
+
TD_API_KEY: ${{ secrets.TD_API_KEY }}
|
|
36
|
+
|
|
37
|
+
# GitHub token for posting comments (automatically provided)
|
|
38
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
+
|
|
40
|
+
# PR number for PR comments
|
|
41
|
+
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
42
|
+
|
|
43
|
+
# Git information (automatically available)
|
|
44
|
+
# GITHUB_SHA, GITHUB_REF_NAME, GITHUB_REPOSITORY, GITHUB_ACTOR
|
|
45
|
+
|
|
46
|
+
run: npm run test:sdk
|
|
47
|
+
|
|
48
|
+
- name: Upload test results
|
|
49
|
+
if: always()
|
|
50
|
+
uses: actions/upload-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: test-results
|
|
53
|
+
path: |
|
|
54
|
+
test-report.junit.xml
|
|
55
|
+
test-results/
|
|
56
|
+
retention-days: 30
|
|
57
|
+
|
|
58
|
+
- name: Comment PR on failure
|
|
59
|
+
if: failure() && github.event_name == 'pull_request'
|
|
60
|
+
uses: actions/github-script@v7
|
|
61
|
+
with:
|
|
62
|
+
script: |
|
|
63
|
+
github.rest.issues.createComment({
|
|
64
|
+
issue_number: context.issue.number,
|
|
65
|
+
owner: context.repo.owner,
|
|
66
|
+
repo: context.repo.repo,
|
|
67
|
+
body: '❌ TestDriver tests failed. Check the workflow logs for details.'
|
|
68
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example test demonstrating GitHub comment integration
|
|
3
|
+
*
|
|
4
|
+
* When run in CI with proper environment variables set, this will:
|
|
5
|
+
* 1. Run the tests
|
|
6
|
+
* 2. Record dashcam replays
|
|
7
|
+
* 3. Post a beautiful GitHub comment with results
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it } from "vitest";
|
|
11
|
+
import { TestDriver } from "../lib/vitest/hooks.mjs";
|
|
12
|
+
|
|
13
|
+
describe("GitHub Comment Demo", () => {
|
|
14
|
+
it("should pass with dashcam replay", async (context) => {
|
|
15
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
16
|
+
|
|
17
|
+
await testdriver.provision.chrome({
|
|
18
|
+
url: 'https://www.example.com',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const heading = await testdriver.find("heading with Example Domain");
|
|
22
|
+
const result = await testdriver.assert("I can see 'Example Domain' heading");
|
|
23
|
+
expect(result).toBeTruthy();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should demonstrate failure handling", async (context) => {
|
|
27
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
28
|
+
|
|
29
|
+
await testdriver.provision.chrome({
|
|
30
|
+
url: 'https://www.example.com',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// This will fail intentionally to show error reporting
|
|
34
|
+
const result = await testdriver.assert("I can see a navigation menu with 20 items");
|
|
35
|
+
expect(result).toBeTruthy(); // This will fail
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("should skip when needed", async (context) => {
|
|
39
|
+
// Skipped tests show in the summary
|
|
40
|
+
context.skip();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -3,6 +3,7 @@ import crypto from "crypto";
|
|
|
3
3
|
import { createRequire } from "module";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { setTestRunInfo } from "./shared-test-state.mjs";
|
|
6
|
+
import { generateGitHubComment, postOrUpdateTestResults } from "../lib/github-comment.mjs";
|
|
6
7
|
|
|
7
8
|
// Use createRequire to import CommonJS modules without esbuild processing
|
|
8
9
|
const require = createRequire(import.meta.url);
|
|
@@ -132,6 +133,7 @@ export const pluginState = {
|
|
|
132
133
|
client: null,
|
|
133
134
|
startTime: null,
|
|
134
135
|
testCases: new Map(),
|
|
136
|
+
recordedTestCases: [], // Store recorded test case data for GitHub comment
|
|
135
137
|
token: null,
|
|
136
138
|
detectedPlatform: null,
|
|
137
139
|
pendingTestCaseRecords: new Set(),
|
|
@@ -658,6 +660,9 @@ class TestDriverReporter {
|
|
|
658
660
|
logger.debug(`🔗 View test run: ${testRunUrl}`);
|
|
659
661
|
// Output in a parseable format for CI
|
|
660
662
|
console.log(`TESTDRIVER_RUN_URL=${testRunUrl}`);
|
|
663
|
+
|
|
664
|
+
// Post GitHub comment if in CI environment
|
|
665
|
+
await postGitHubCommentIfEnabled(testRunUrl, stats, completeData);
|
|
661
666
|
}
|
|
662
667
|
|
|
663
668
|
logger.debug(`✅ Test run completed: ${stats.passedTests}/${stats.totalTests} passed`);
|
|
@@ -793,6 +798,12 @@ class TestDriverReporter {
|
|
|
793
798
|
const testCaseDbId = testCaseResponse.data?.id;
|
|
794
799
|
const testRunDbId = process.env.TD_TEST_RUN_DB_ID;
|
|
795
800
|
|
|
801
|
+
// Store test case data for GitHub comment generation
|
|
802
|
+
pluginState.recordedTestCases.push({
|
|
803
|
+
...testCaseData,
|
|
804
|
+
id: testCaseDbId,
|
|
805
|
+
});
|
|
806
|
+
|
|
796
807
|
console.log('');
|
|
797
808
|
console.log(`🔗 Test Report: ${getConsoleUrl(pluginState.apiRoot)}/runs/${testRunDbId}/${testCaseDbId}`);
|
|
798
809
|
} catch (error) {
|
|
@@ -977,6 +988,95 @@ function getGitInfo() {
|
|
|
977
988
|
return info;
|
|
978
989
|
}
|
|
979
990
|
|
|
991
|
+
// ============================================================================
|
|
992
|
+
// GitHub Comment Helper
|
|
993
|
+
// ============================================================================
|
|
994
|
+
|
|
995
|
+
/**
|
|
996
|
+
* Post GitHub comment with test results if enabled
|
|
997
|
+
* Checks for GitHub token and PR number in environment variables
|
|
998
|
+
* @param {string} testRunUrl - URL to the test run
|
|
999
|
+
* @param {Object} stats - Test statistics
|
|
1000
|
+
* @param {Object} completeData - Test run completion data
|
|
1001
|
+
*/
|
|
1002
|
+
async function postGitHubCommentIfEnabled(testRunUrl, stats, completeData) {
|
|
1003
|
+
try {
|
|
1004
|
+
// Check if GitHub comments are explicitly disabled
|
|
1005
|
+
if (process.env.TESTDRIVER_SKIP_GITHUB_COMMENT === 'true') {
|
|
1006
|
+
logger.debug('GitHub comments disabled via TESTDRIVER_SKIP_GITHUB_COMMENT');
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// Check if GitHub comment posting is enabled
|
|
1011
|
+
const githubToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
|
|
1012
|
+
const prNumber = process.env.GITHUB_PR_NUMBER;
|
|
1013
|
+
const commitSha = process.env.GITHUB_SHA || pluginState.gitInfo.commit;
|
|
1014
|
+
|
|
1015
|
+
// Only post if we have a token and either a PR number or commit SHA
|
|
1016
|
+
if (!githubToken) {
|
|
1017
|
+
logger.debug('GitHub token not found, skipping comment posting');
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (!prNumber && !commitSha) {
|
|
1022
|
+
logger.debug('Neither PR number nor commit SHA found, skipping comment posting');
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// Extract owner/repo from git info
|
|
1027
|
+
const repo = pluginState.gitInfo.repo;
|
|
1028
|
+
if (!repo) {
|
|
1029
|
+
logger.warn('Repository info not available, skipping GitHub comment');
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
const [owner, repoName] = repo.split('/');
|
|
1034
|
+
if (!owner || !repoName) {
|
|
1035
|
+
logger.warn('Invalid repository format, expected owner/repo');
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
logger.debug('Preparing GitHub comment...');
|
|
1040
|
+
|
|
1041
|
+
// Prepare test run data for comment
|
|
1042
|
+
const testRunData = {
|
|
1043
|
+
runId: pluginState.testRunId,
|
|
1044
|
+
status: completeData.status,
|
|
1045
|
+
totalTests: stats.totalTests,
|
|
1046
|
+
passedTests: stats.passedTests,
|
|
1047
|
+
failedTests: stats.failedTests,
|
|
1048
|
+
skippedTests: stats.skippedTests,
|
|
1049
|
+
duration: completeData.duration,
|
|
1050
|
+
testRunUrl,
|
|
1051
|
+
platform: completeData.platform || pluginState.detectedPlatform || 'unknown',
|
|
1052
|
+
branch: pluginState.gitInfo.branch || 'unknown',
|
|
1053
|
+
commit: commitSha || 'unknown',
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
// Use recorded test cases from pluginState
|
|
1057
|
+
const testCases = pluginState.recordedTestCases || [];
|
|
1058
|
+
|
|
1059
|
+
logger.info(`Posting GitHub comment with ${testCases.length} test cases...`);
|
|
1060
|
+
|
|
1061
|
+
// Post or update GitHub comment
|
|
1062
|
+
const githubOptions = {
|
|
1063
|
+
token: githubToken,
|
|
1064
|
+
owner,
|
|
1065
|
+
repo: repoName,
|
|
1066
|
+
prNumber: prNumber ? parseInt(prNumber, 10) : undefined,
|
|
1067
|
+
commitSha: commitSha,
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
const comment = await postOrUpdateTestResults(testRunData, testCases, githubOptions);
|
|
1071
|
+
logger.info(`✅ GitHub comment posted: ${comment.html_url}`);
|
|
1072
|
+
console.log(`\n🔗 GitHub Comment: ${comment.html_url}\n`);
|
|
1073
|
+
|
|
1074
|
+
} catch (error) {
|
|
1075
|
+
logger.warn('Failed to post GitHub comment:', error.message);
|
|
1076
|
+
logger.debug('GitHub comment error stack:', error.stack);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
980
1080
|
// ============================================================================
|
|
981
1081
|
// API Methods
|
|
982
1082
|
// ============================================================================
|