@testivai/witness-playwright 0.1.0 → 0.1.1
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/README.md +13 -1
- package/dist/cli/init.js +10 -4
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/reporter-entry.d.ts +2 -0
- package/dist/reporter-entry.js +5 -0
- package/dist/reporter.d.ts +1 -1
- package/dist/reporter.js +27 -5
- package/package.json +2 -2
- package/progress.md +53 -2
- package/src/cli/init.ts +10 -4
- package/src/index.ts +0 -1
- package/src/reporter-entry.ts +6 -0
- package/src/reporter.ts +31 -6
- package/tsconfig.json +1 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @testivai/witness-playwright
|
|
2
2
|
|
|
3
|
-
**Status**: ✅ Production Ready | **Last Updated**:
|
|
3
|
+
**Status**: ✅ Production Ready | **Last Updated**: January 9, 2026
|
|
4
4
|
|
|
5
5
|
**Project:** @testivai/witness-playwright (MVP - 1 Month Plan)
|
|
6
6
|
|
|
@@ -16,6 +16,18 @@ This package provides two main exports:
|
|
|
16
16
|
|
|
17
17
|
To use the reporter, you need to configure it in your `playwright.config.ts` file. You must also provide your API URL and Key via environment variables (`TESTIVAI_API_URL` and `TESTIVAI_API_KEY`).
|
|
18
18
|
|
|
19
|
+
**Get Your API Key:**
|
|
20
|
+
1. Go to your TestivAI dashboard
|
|
21
|
+
2. Create a new project
|
|
22
|
+
3. Copy your API key (format: `tstvai-xxxxxxxxxxxx`)
|
|
23
|
+
|
|
24
|
+
**Environment Setup:**
|
|
25
|
+
```bash
|
|
26
|
+
# Create .env file
|
|
27
|
+
echo "TESTIVAI_API_KEY=tstvai-your-key-here" > .env
|
|
28
|
+
echo "TESTIVAI_API_URL=https://core-api-147980626268.us-central1.run.app" >> .env
|
|
29
|
+
```
|
|
30
|
+
|
|
19
31
|
```typescript
|
|
20
32
|
// playwright.config.ts
|
|
21
33
|
import { defineConfig } from '@playwright/test';
|
package/dist/cli/init.js
CHANGED
|
@@ -126,11 +126,17 @@ async function createConfigFile() {
|
|
|
126
126
|
console.log('📁 Config file:', configPath);
|
|
127
127
|
console.log('');
|
|
128
128
|
console.log('📖 Next steps:');
|
|
129
|
-
console.log(' 1.
|
|
130
|
-
console.log('
|
|
131
|
-
console.log('
|
|
129
|
+
console.log(' 1. Set up environment variables:');
|
|
130
|
+
console.log(' TESTIVAI_API_KEY=tstvai-your-key-here');
|
|
131
|
+
console.log(' TESTIVAI_API_URL=https://core-api-147980626268.us-central1.run.app');
|
|
132
132
|
console.log('');
|
|
133
|
-
console.log('
|
|
133
|
+
console.log(' 2. Update your playwright.config.ts to use TestivAI reporter:');
|
|
134
|
+
console.log(' reporter: [[\'@testivai/witness-playwright/reporter\']]');
|
|
135
|
+
console.log('');
|
|
136
|
+
console.log(' 3. Review and customize testivai.config.ts');
|
|
137
|
+
console.log(' 4. Run your tests: npx playwright test');
|
|
138
|
+
console.log('');
|
|
139
|
+
console.log('💡 Get your API key from: https://dashboard-147980626268.us-central1.run.app');
|
|
134
140
|
}
|
|
135
141
|
catch (error) {
|
|
136
142
|
console.error('❌ Failed to create configuration file:', error);
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/reporter.d.ts
CHANGED
package/dist/reporter.js
CHANGED
|
@@ -111,10 +111,23 @@ class TestivAIPlaywrightReporter {
|
|
|
111
111
|
const metadata = await fs.readJson(metadataPath);
|
|
112
112
|
const domPath = metadata.files.dom;
|
|
113
113
|
const screenshotPath = metadata.files.screenshot;
|
|
114
|
+
// Extract the first selector's layout data (usually 'body')
|
|
115
|
+
const layoutKeys = Object.keys(metadata.layout || {});
|
|
116
|
+
if (layoutKeys.length === 0) {
|
|
117
|
+
console.warn(`Testivai Reporter: No layout data found for ${metadata.snapshotName}, skipping...`);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const firstSelector = layoutKeys[0];
|
|
121
|
+
const layoutData = metadata.layout[firstSelector];
|
|
114
122
|
const snapshotPayload = {
|
|
115
123
|
...metadata,
|
|
116
124
|
dom: { html: await fs.readFile(domPath, 'utf-8') },
|
|
117
|
-
layout:
|
|
125
|
+
layout: {
|
|
126
|
+
x: layoutData.x,
|
|
127
|
+
y: layoutData.y,
|
|
128
|
+
width: layoutData.width,
|
|
129
|
+
height: layoutData.height
|
|
130
|
+
},
|
|
118
131
|
testivaiConfig: metadata.testivaiConfig
|
|
119
132
|
};
|
|
120
133
|
snapshots.push(snapshotPayload);
|
|
@@ -129,9 +142,12 @@ class TestivAIPlaywrightReporter {
|
|
|
129
142
|
};
|
|
130
143
|
// Start batch and get upload URLs
|
|
131
144
|
const startBatchResponse = await axios_1.default.post(`${this.options.apiUrl}/api/v1/ingest/start-batch`, batchPayload, {
|
|
132
|
-
headers: { '
|
|
145
|
+
headers: { 'X-API-KEY': this.options.apiKey },
|
|
133
146
|
});
|
|
134
|
-
|
|
147
|
+
console.log('Testivai Reporter: API Response:', JSON.stringify(startBatchResponse.data, null, 2));
|
|
148
|
+
// Handle both snake_case and camelCase response formats
|
|
149
|
+
const batchId = startBatchResponse.data.batch_id || startBatchResponse.data.batchId;
|
|
150
|
+
const uploadInstructions = startBatchResponse.data.upload_instructions || startBatchResponse.data.uploadInstructions;
|
|
135
151
|
// Upload files
|
|
136
152
|
const uploadPromises = filesToUpload.map((file, index) => {
|
|
137
153
|
const instruction = uploadInstructions[index];
|
|
@@ -140,7 +156,7 @@ class TestivAIPlaywrightReporter {
|
|
|
140
156
|
await Promise.all(uploadPromises);
|
|
141
157
|
// Finalize batch
|
|
142
158
|
await axios_1.default.post(`${this.options.apiUrl}/api/v1/ingest/finish-batch/${batchId}`, {}, {
|
|
143
|
-
headers: { '
|
|
159
|
+
headers: { 'X-API-KEY': this.options.apiKey },
|
|
144
160
|
});
|
|
145
161
|
console.log(`Testivai Reporter: Successfully uploaded ${snapshots.length} snapshots with Batch ID: ${batchId}`);
|
|
146
162
|
// Clean up temp files
|
|
@@ -148,8 +164,14 @@ class TestivAIPlaywrightReporter {
|
|
|
148
164
|
console.log('Testivai Reporter: Cleaned up temporary evidence files.');
|
|
149
165
|
}
|
|
150
166
|
catch (error) {
|
|
151
|
-
console.error('Testivai Reporter: An error occurred during the onEnd hook:', error);
|
|
167
|
+
console.error('Testivai Reporter: An error occurred during the onEnd hook:', error.message);
|
|
168
|
+
console.error('Error stack:', error.stack);
|
|
169
|
+
if (error.response) {
|
|
170
|
+
console.error('Response status:', error.response.status);
|
|
171
|
+
console.error('Response data:', JSON.stringify(error.response.data, null, 2));
|
|
172
|
+
}
|
|
152
173
|
}
|
|
153
174
|
}
|
|
154
175
|
}
|
|
155
176
|
exports.TestivAIPlaywrightReporter = TestivAIPlaywrightReporter;
|
|
177
|
+
exports.default = TestivAIPlaywrightReporter;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testivai/witness-playwright",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Playwright sensor for Testivai Visual Regression Test system",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"exports": {
|
|
11
11
|
".": "./dist/index.js",
|
|
12
|
-
"./reporter": "./dist/reporter.js",
|
|
12
|
+
"./reporter": "./dist/reporter-entry.js",
|
|
13
13
|
"./cli": "./dist/cli/init.js"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
package/progress.md
CHANGED
|
@@ -612,9 +612,60 @@ The Playwright SDK provides two main components that are production-ready:
|
|
|
612
612
|
|
|
613
613
|
---
|
|
614
614
|
|
|
615
|
-
|
|
616
|
-
|
|
615
|
+
## NPM Publication & API Key Format Update (January 9, 2026)
|
|
616
|
+
|
|
617
|
+
### SDK Published to npm ✅ COMPLETE
|
|
618
|
+
|
|
619
|
+
**Goal**: Publish SDK to npm registry for public consumption and update documentation for new API key format.
|
|
620
|
+
|
|
621
|
+
#### Changes Implemented
|
|
622
|
+
|
|
623
|
+
1. **NPM Publication** ✅
|
|
624
|
+
- Published `@testivai/witness-playwright@0.1.0` to npm registry
|
|
625
|
+
- Package now publicly available: https://www.npmjs.com/package/@testivai/witness-playwright
|
|
626
|
+
- Users can install via: `npm install @testivai/witness-playwright`
|
|
627
|
+
|
|
628
|
+
2. **Documentation Updates** ✅
|
|
629
|
+
- Updated README.md with new API key format (`tstvai-xxxxxxxxxxxx`)
|
|
630
|
+
- Added "Get Your API Key" section with step-by-step instructions
|
|
631
|
+
- Added environment setup examples
|
|
632
|
+
- Updated all code examples to show correct usage
|
|
633
|
+
|
|
634
|
+
3. **Integration Tests** ✅
|
|
635
|
+
- Created visual regression tests in `integration-tests/tests/visual/`
|
|
636
|
+
- Tests use published npm package (not local file reference)
|
|
637
|
+
- All 10 visual tests passing
|
|
638
|
+
- Tests capture dashboard snapshots and send to TestivAI backend
|
|
639
|
+
|
|
640
|
+
4. **Example Usage** ✅
|
|
641
|
+
```typescript
|
|
642
|
+
import { test } from '@playwright/test';
|
|
643
|
+
import { testivai } from '@testivai/witness-playwright';
|
|
644
|
+
|
|
645
|
+
test('visual test', async ({ page }, testInfo) => {
|
|
646
|
+
await page.goto('https://example.com');
|
|
647
|
+
await testivai.witness(page, testInfo, 'homepage');
|
|
648
|
+
});
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
#### API Key Format
|
|
652
|
+
- **New Format**: `tstvai-{32-character-secure-random-string}`
|
|
653
|
+
- **Example**: `tstvai-Ml5Ahr4vxHNht9WJPZ0LndDBQIkEfT9OvpXqB-NGjOs`
|
|
654
|
+
- **Masked Display**: `tstvai-**************NGjOs` (last 6 chars visible)
|
|
655
|
+
|
|
656
|
+
#### Files Updated
|
|
657
|
+
- `README.md` - Added API key format and setup instructions
|
|
658
|
+
- `package.json` - Published version 0.1.0 to npm
|
|
659
|
+
- `integration-tests/package.json` - Uses npm package instead of local file
|
|
660
|
+
- `integration-tests/tests/visual/dashboard-visual.spec.ts` - Example visual tests
|
|
661
|
+
|
|
662
|
+
---
|
|
663
|
+
|
|
664
|
+
**Last Updated**: January 9, 2026
|
|
665
|
+
**Status**: 🎉 PUBLISHED TO NPM ✅ - Publicly available
|
|
666
|
+
**NPM Package**: @testivai/witness-playwright@0.1.0
|
|
617
667
|
**Core Features**: Evidence capture and batch upload fully functional
|
|
618
668
|
**Configuration**: ✅ COMPLETE - End-to-end flow working
|
|
669
|
+
**API Key Format**: tstvai-{secure-random-string}
|
|
619
670
|
**Known Issues**: Minor UX improvements (retry logic, progress reporting)
|
|
620
671
|
**Blocker**: None - All critical features implemented
|
package/src/cli/init.ts
CHANGED
|
@@ -96,11 +96,17 @@ async function createConfigFile(): Promise<void> {
|
|
|
96
96
|
console.log('📁 Config file:', configPath);
|
|
97
97
|
console.log('');
|
|
98
98
|
console.log('📖 Next steps:');
|
|
99
|
-
console.log(' 1.
|
|
100
|
-
console.log('
|
|
101
|
-
console.log('
|
|
99
|
+
console.log(' 1. Set up environment variables:');
|
|
100
|
+
console.log(' TESTIVAI_API_KEY=tstvai-your-key-here');
|
|
101
|
+
console.log(' TESTIVAI_API_URL=https://core-api-147980626268.us-central1.run.app');
|
|
102
102
|
console.log('');
|
|
103
|
-
console.log('
|
|
103
|
+
console.log(' 2. Update your playwright.config.ts to use TestivAI reporter:');
|
|
104
|
+
console.log(' reporter: [[\'@testivai/witness-playwright/reporter\']]');
|
|
105
|
+
console.log('');
|
|
106
|
+
console.log(' 3. Review and customize testivai.config.ts');
|
|
107
|
+
console.log(' 4. Run your tests: npx playwright test');
|
|
108
|
+
console.log('');
|
|
109
|
+
console.log('💡 Get your API key from: https://dashboard-147980626268.us-central1.run.app');
|
|
104
110
|
|
|
105
111
|
} catch (error) {
|
|
106
112
|
console.error('❌ Failed to create configuration file:', error);
|
package/src/index.ts
CHANGED
package/src/reporter.ts
CHANGED
|
@@ -94,10 +94,24 @@ export class TestivAIPlaywrightReporter implements Reporter {
|
|
|
94
94
|
const domPath = metadata.files.dom;
|
|
95
95
|
const screenshotPath = metadata.files.screenshot;
|
|
96
96
|
|
|
97
|
+
// Extract the first selector's layout data (usually 'body')
|
|
98
|
+
const layoutKeys = Object.keys(metadata.layout || {});
|
|
99
|
+
if (layoutKeys.length === 0) {
|
|
100
|
+
console.warn(`Testivai Reporter: No layout data found for ${metadata.snapshotName}, skipping...`);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const firstSelector = layoutKeys[0];
|
|
104
|
+
const layoutData = metadata.layout[firstSelector];
|
|
105
|
+
|
|
97
106
|
const snapshotPayload: SnapshotPayload = {
|
|
98
107
|
...metadata,
|
|
99
108
|
dom: { html: await fs.readFile(domPath, 'utf-8') },
|
|
100
|
-
layout:
|
|
109
|
+
layout: {
|
|
110
|
+
x: layoutData.x,
|
|
111
|
+
y: layoutData.y,
|
|
112
|
+
width: layoutData.width,
|
|
113
|
+
height: layoutData.height
|
|
114
|
+
},
|
|
101
115
|
testivaiConfig: metadata.testivaiConfig
|
|
102
116
|
};
|
|
103
117
|
snapshots.push(snapshotPayload);
|
|
@@ -115,10 +129,14 @@ export class TestivAIPlaywrightReporter implements Reporter {
|
|
|
115
129
|
|
|
116
130
|
// Start batch and get upload URLs
|
|
117
131
|
const startBatchResponse = await axios.post(`${this.options.apiUrl}/api/v1/ingest/start-batch`, batchPayload, {
|
|
118
|
-
headers: { '
|
|
132
|
+
headers: { 'X-API-KEY': this.options.apiKey },
|
|
119
133
|
});
|
|
120
134
|
|
|
121
|
-
|
|
135
|
+
console.log('Testivai Reporter: API Response:', JSON.stringify(startBatchResponse.data, null, 2));
|
|
136
|
+
|
|
137
|
+
// Handle both snake_case and camelCase response formats
|
|
138
|
+
const batchId = startBatchResponse.data.batch_id || startBatchResponse.data.batchId;
|
|
139
|
+
const uploadInstructions = startBatchResponse.data.upload_instructions || startBatchResponse.data.uploadInstructions;
|
|
122
140
|
|
|
123
141
|
// Upload files
|
|
124
142
|
const uploadPromises = filesToUpload.map((file, index) => {
|
|
@@ -132,7 +150,7 @@ export class TestivAIPlaywrightReporter implements Reporter {
|
|
|
132
150
|
|
|
133
151
|
// Finalize batch
|
|
134
152
|
await axios.post(`${this.options.apiUrl}/api/v1/ingest/finish-batch/${batchId}`, {}, {
|
|
135
|
-
headers: { '
|
|
153
|
+
headers: { 'X-API-KEY': this.options.apiKey },
|
|
136
154
|
});
|
|
137
155
|
|
|
138
156
|
console.log(`Testivai Reporter: Successfully uploaded ${snapshots.length} snapshots with Batch ID: ${batchId}`);
|
|
@@ -141,8 +159,15 @@ export class TestivAIPlaywrightReporter implements Reporter {
|
|
|
141
159
|
await fs.emptyDir(this.tempDir);
|
|
142
160
|
console.log('Testivai Reporter: Cleaned up temporary evidence files.');
|
|
143
161
|
|
|
144
|
-
} catch (error) {
|
|
145
|
-
console.error('Testivai Reporter: An error occurred during the onEnd hook:', error);
|
|
162
|
+
} catch (error: any) {
|
|
163
|
+
console.error('Testivai Reporter: An error occurred during the onEnd hook:', error.message);
|
|
164
|
+
console.error('Error stack:', error.stack);
|
|
165
|
+
if (error.response) {
|
|
166
|
+
console.error('Response status:', error.response.status);
|
|
167
|
+
console.error('Response data:', JSON.stringify(error.response.data, null, 2));
|
|
168
|
+
}
|
|
146
169
|
}
|
|
147
170
|
}
|
|
148
171
|
}
|
|
172
|
+
|
|
173
|
+
export default TestivAIPlaywrightReporter;
|