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.
@@ -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
+ [![Assert Test](https://console.testdriver.ai/api/replay/.../gif)](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
+ [![Login test](https://app.testdriver.ai/api/replay/.../gif)](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
  // ============================================================================