@testspectra/cli 1.1.8-rc.29 → 1.1.8-rc.30
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/dist/commands/__tests__/test-error-streaming.test.js +41 -8
- package/dist/runner/bridge.js +22 -10
- package/dist/runner/reporter.d.ts +1 -0
- package/dist/runner/reporter.js +11 -13
- package/package.json +7 -7
- package/templates/default/package.json +2 -2
- package/templates/nx/package.json +2 -2
- package/templates/react-component/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
2
|
import { isVitestNoise, sanitizeErrorMessage } from '@testspectra/react';
|
|
3
3
|
import { Reporter } from '../../runner/reporter.js';
|
|
4
4
|
describe('spectra test error streaming and formatting', () => {
|
|
@@ -40,13 +40,46 @@ describe('spectra test error streaming and formatting', () => {
|
|
|
40
40
|
expect(result.passedCount).toBe(0);
|
|
41
41
|
expect(result.status).toBe('failed');
|
|
42
42
|
});
|
|
43
|
-
it('
|
|
43
|
+
it('prints error message below test title and steps on failure', () => {
|
|
44
44
|
const reporter = new Reporter();
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
const consoleLogs = [];
|
|
46
|
+
const spy = vi.spyOn(console, 'log').mockImplementation((msg) => {
|
|
47
|
+
if (typeof msg === 'string')
|
|
48
|
+
consoleLogs.push(msg);
|
|
49
|
+
});
|
|
50
|
+
reporter.addLog({
|
|
51
|
+
timestamp: '12:00:00',
|
|
52
|
+
level: 'INFO',
|
|
53
|
+
message: '[TESTSPECTRA_TEST_START] {"title":"ApiInterception / TC-0009-post-mocking"}',
|
|
54
|
+
});
|
|
55
|
+
reporter.addLog({
|
|
56
|
+
timestamp: '12:00:00',
|
|
57
|
+
level: 'INFO',
|
|
58
|
+
message: '[TESTSPECTRA_STEP_PASS] {"type":"action","key":"navigate","args":["/#api-post"],"test":"ApiInterception / TC-0009-post-mocking"} (8ms)',
|
|
59
|
+
});
|
|
60
|
+
reporter.addLog({
|
|
61
|
+
timestamp: '12:00:00',
|
|
62
|
+
level: 'INFO',
|
|
63
|
+
message: '[TESTSPECTRA_STEP_FAIL] {"type":"assertion","target":"#post-status-badge","args":["201 Created"],"test":"ApiInterception / TC-0009-post-mocking"} (2005ms)',
|
|
64
|
+
});
|
|
65
|
+
reporter.addLog({
|
|
66
|
+
timestamp: '12:00:00',
|
|
67
|
+
level: 'INFO',
|
|
68
|
+
message: '[TESTSPECTRA_TEST_ERROR] Expected element "#post-status-badge" to have text "201 Created", but got ""',
|
|
69
|
+
});
|
|
70
|
+
reporter.addLog({
|
|
71
|
+
timestamp: '12:00:00',
|
|
72
|
+
level: 'INFO',
|
|
73
|
+
message: '[TESTSPECTRA_TEST_FAIL] ApiInterception / TC-0009-post-mocking (2066ms)',
|
|
74
|
+
});
|
|
75
|
+
spy.mockRestore();
|
|
76
|
+
const titleIndex = consoleLogs.findIndex((log) => log.includes('ApiInterception / TC-0009-post-mocking'));
|
|
77
|
+
const stepPassIndex = consoleLogs.findIndex((log) => log.includes('Navigate to'));
|
|
78
|
+
const stepFailIndex = consoleLogs.findIndex((log) => log.includes('#post-status-badge'));
|
|
79
|
+
const errorIndex = consoleLogs.findIndex((log) => log.includes('↳ Error:'));
|
|
80
|
+
expect(titleIndex).toBeGreaterThanOrEqual(0);
|
|
81
|
+
expect(stepPassIndex).toBeGreaterThan(titleIndex);
|
|
82
|
+
expect(stepFailIndex).toBeGreaterThan(stepPassIndex);
|
|
83
|
+
expect(errorIndex).toBeGreaterThan(stepFailIndex);
|
|
51
84
|
});
|
|
52
85
|
});
|
package/dist/runner/bridge.js
CHANGED
|
@@ -29,20 +29,32 @@ export class RustCoreBridge {
|
|
|
29
29
|
const binaryName = isWindows ? 'testspectra-runner.exe' : 'testspectra-runner';
|
|
30
30
|
// In local monorepo development (where core/Cargo.toml exists), prioritize the locally-built
|
|
31
31
|
// binary in core/target/release or cli/bin over any stale optionalDependency in node_modules.
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
let workspaceRoot = null;
|
|
33
|
+
let curr = __dirname;
|
|
34
|
+
while (curr !== path.dirname(curr)) {
|
|
35
|
+
if (fs.existsSync(path.join(curr, 'core/Cargo.toml')) || fs.existsSync(path.join(curr, 'pnpm-workspace.yaml'))) {
|
|
36
|
+
workspaceRoot = curr;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
curr = path.dirname(curr);
|
|
40
|
+
}
|
|
34
41
|
const candidatePaths = [
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
...(workspaceRoot
|
|
43
|
+
? [
|
|
44
|
+
path.join(workspaceRoot, 'core/target/release', binaryName),
|
|
45
|
+
path.join(workspaceRoot, 'target/release', binaryName),
|
|
46
|
+
path.join(workspaceRoot, 'cli/bin', binaryName),
|
|
47
|
+
path.join(workspaceRoot, 'core/cli/target/release', binaryName),
|
|
48
|
+
path.join(workspaceRoot, 'core/target/debug', binaryName),
|
|
49
|
+
path.join(workspaceRoot, 'target/debug', binaryName),
|
|
50
|
+
path.join(workspaceRoot, 'core/cli/target/debug', binaryName),
|
|
51
|
+
]
|
|
52
|
+
: []),
|
|
53
|
+
path.join(__dirname, '../bin', binaryName),
|
|
38
54
|
path.join(__dirname, '../../bin', binaryName),
|
|
39
|
-
path.join(workspaceRoot, 'core/cli/target/release', binaryName),
|
|
40
|
-
path.join(workspaceRoot, 'core/target/debug', binaryName),
|
|
41
|
-
path.join(workspaceRoot, 'target/debug', binaryName),
|
|
42
|
-
path.join(workspaceRoot, 'core/cli/target/debug', binaryName),
|
|
43
55
|
path.join(__dirname, '../../bin/testspectra-runner'),
|
|
44
56
|
];
|
|
45
|
-
if (
|
|
57
|
+
if (workspaceRoot) {
|
|
46
58
|
for (const p of candidatePaths) {
|
|
47
59
|
if (fs.existsSync(p)) {
|
|
48
60
|
return p;
|
package/dist/runner/reporter.js
CHANGED
|
@@ -155,6 +155,7 @@ export class Reporter {
|
|
|
155
155
|
networkEvents = [];
|
|
156
156
|
pendingTests = new Map();
|
|
157
157
|
workerToTest = new Map();
|
|
158
|
+
pendingErrorMsg;
|
|
158
159
|
passedCount = 0;
|
|
159
160
|
failedCount = 0;
|
|
160
161
|
isInteractive;
|
|
@@ -358,11 +359,7 @@ export class Reporter {
|
|
|
358
359
|
latest.errorMsg = latest.errorMsg ? `${latest.errorMsg}\n${err}` : err;
|
|
359
360
|
}
|
|
360
361
|
else {
|
|
361
|
-
|
|
362
|
-
console.log(` \x1b[38;2;251;191;36m↳ Error:\x1b[0m \x1b[38;2;248;113;113m${errLines[0]}\x1b[0m`);
|
|
363
|
-
for (let i = 1; i < errLines.length; i++) {
|
|
364
|
-
console.log(` \x1b[38;2;248;113;113m${errLines[i]}\x1b[0m`);
|
|
365
|
-
}
|
|
362
|
+
this.pendingErrorMsg = this.pendingErrorMsg ? `${this.pendingErrorMsg}\n${err}` : err;
|
|
366
363
|
}
|
|
367
364
|
return;
|
|
368
365
|
}
|
|
@@ -398,20 +395,14 @@ export class Reporter {
|
|
|
398
395
|
this.failedCount++;
|
|
399
396
|
const testCase = this.pendingTests.get(title) || this.resolveTestCase(title);
|
|
400
397
|
const steps = testCase?.steps || [];
|
|
401
|
-
const errorMsg = testCase?.errorMsg;
|
|
398
|
+
const errorMsg = testCase?.errorMsg || this.pendingErrorMsg;
|
|
399
|
+
this.pendingErrorMsg = undefined;
|
|
402
400
|
const workerId = testCase?.workerId;
|
|
403
401
|
this.pendingTests.delete(title);
|
|
404
402
|
if (workerId !== undefined) {
|
|
405
403
|
this.workerToTest.delete(workerId);
|
|
406
404
|
}
|
|
407
405
|
this.clearActiveSlots();
|
|
408
|
-
if (errorMsg) {
|
|
409
|
-
const errLines = errorMsg.split('\n');
|
|
410
|
-
console.log(` \x1b[38;2;251;191;36m↳ Error:\x1b[0m \x1b[38;2;248;113;113m${errLines[0]}\x1b[0m`);
|
|
411
|
-
for (let i = 1; i < errLines.length; i++) {
|
|
412
|
-
console.log(` \x1b[38;2;248;113;113m${errLines[i]}\x1b[0m`);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
406
|
console.log(`${chalk.hex('#f87171')('✗')} ${chalk.white.bold(title)} ${chalk.gray(`(${duration}ms)`)}`);
|
|
416
407
|
for (const step of steps) {
|
|
417
408
|
if (step.passed) {
|
|
@@ -421,6 +412,13 @@ export class Reporter {
|
|
|
421
412
|
console.log(` ${chalk.red('✖')} ${chalk.red(step.text)} ${chalk.gray(`(${step.duration}ms)`)}`);
|
|
422
413
|
}
|
|
423
414
|
}
|
|
415
|
+
if (errorMsg) {
|
|
416
|
+
const errLines = errorMsg.split('\n');
|
|
417
|
+
console.log(` \x1b[38;2;251;191;36m↳ Error:\x1b[0m \x1b[38;2;248;113;113m${errLines[0]}\x1b[0m`);
|
|
418
|
+
for (let i = 1; i < errLines.length; i++) {
|
|
419
|
+
console.log(` \x1b[38;2;248;113;113m${errLines[i]}\x1b[0m`);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
424
422
|
console.log('');
|
|
425
423
|
this.renderActiveSlots();
|
|
426
424
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testspectra/cli",
|
|
3
|
-
"version": "1.1.8-rc.
|
|
3
|
+
"version": "1.1.8-rc.30",
|
|
4
4
|
"description": "TestSpectra Cross-Platform Test Runner CLI",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@clack/prompts": "^1.7.0",
|
|
29
|
-
"@testspectra/matchers": "^1.1.8-rc.
|
|
30
|
-
"@testspectra/react": "^1.1.8-rc.
|
|
31
|
-
"@testspectra/skills": "^1.1.8-rc.
|
|
29
|
+
"@testspectra/matchers": "^1.1.8-rc.30",
|
|
30
|
+
"@testspectra/react": "^1.1.8-rc.30",
|
|
31
|
+
"@testspectra/skills": "^1.1.8-rc.30",
|
|
32
32
|
"chalk": "^5.3.0",
|
|
33
33
|
"commander": "^12.1.0",
|
|
34
34
|
"dotenv": "^16.4.5",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"zod": "^3.23.8"
|
|
39
39
|
},
|
|
40
40
|
"optionalDependencies": {
|
|
41
|
-
"@testspectra/cli-darwin-arm64": "1.1.8-rc.
|
|
42
|
-
"@testspectra/cli-linux-x64": "1.1.8-rc.
|
|
43
|
-
"@testspectra/cli-win32-x64": "1.1.8-rc.
|
|
41
|
+
"@testspectra/cli-darwin-arm64": "1.1.8-rc.30",
|
|
42
|
+
"@testspectra/cli-linux-x64": "1.1.8-rc.30",
|
|
43
|
+
"@testspectra/cli-win32-x64": "1.1.8-rc.30"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^20.14.0",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"postinstall": "spectra sync-types"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@testspectra/cli": "^1.1.8-rc.
|
|
21
|
-
"@testspectra/matchers": "^1.1.8-rc.
|
|
20
|
+
"@testspectra/cli": "^1.1.8-rc.30",
|
|
21
|
+
"@testspectra/matchers": "^1.1.8-rc.30",
|
|
22
22
|
"@types/node": "^20.14.0",
|
|
23
23
|
"@wdio/cli": "^9.2.8",
|
|
24
24
|
"@wdio/local-runner": "^9.2.8",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"postinstall": "spectra sync-types"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@testspectra/cli": "^1.1.8-rc.
|
|
16
|
-
"@testspectra/matchers": "^1.1.8-rc.
|
|
15
|
+
"@testspectra/cli": "^1.1.8-rc.30",
|
|
16
|
+
"@testspectra/matchers": "^1.1.8-rc.30",
|
|
17
17
|
"@types/node": "^20.14.0",
|
|
18
18
|
"@wdio/cli": "^9.2.8",
|
|
19
19
|
"@wdio/local-runner": "^9.2.8",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"postinstall": "spectra sync-types"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@testspectra/cli": "^1.1.8-rc.
|
|
18
|
-
"@testspectra/matchers": "^1.1.8-rc.
|
|
19
|
-
"@testspectra/react": "^1.1.8-rc.
|
|
17
|
+
"@testspectra/cli": "^1.1.8-rc.30",
|
|
18
|
+
"@testspectra/matchers": "^1.1.8-rc.30",
|
|
19
|
+
"@testspectra/react": "^1.1.8-rc.30",
|
|
20
20
|
"@types/node": "^20.14.0",
|
|
21
21
|
"@types/react": "^18.3.3",
|
|
22
22
|
"@types/react-dom": "^18.3.0",
|