@dionlarson/playwright-orchestrator-core 1.3.2 → 1.3.4
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.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
1
2
|
export default class TestResultReporter {
|
|
2
3
|
testResults = [];
|
|
3
4
|
testCases = [];
|
|
@@ -58,6 +59,13 @@ export default class TestResultReporter {
|
|
|
58
59
|
retry,
|
|
59
60
|
})),
|
|
60
61
|
};
|
|
61
|
-
|
|
62
|
+
const outputFile = process.env.PLAYWRIGHT_ORCHESTRATOR_RESULT_FILE;
|
|
63
|
+
if (outputFile) {
|
|
64
|
+
writeFileSync(outputFile, JSON.stringify(output));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Fallback to stdout if no file specified
|
|
68
|
+
console.log(JSON.stringify(output));
|
|
69
|
+
}
|
|
62
70
|
}
|
|
63
71
|
}
|
package/dist/test-runner.d.ts
CHANGED
package/dist/test-runner.js
CHANGED
|
@@ -1,37 +1,19 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import child_process, { spawn } from 'node:child_process';
|
|
3
3
|
import { promisify } from 'node:util';
|
|
4
|
-
import { rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
5
5
|
import { TestExecutionReporter } from './reporters/test-execution-reporter.js';
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import * as uuid from 'uuid';
|
|
8
8
|
const exec = promisify(child_process.exec);
|
|
9
|
-
function
|
|
9
|
+
function spawnPassthrough(command, env) {
|
|
10
10
|
return new Promise((resolve, reject) => {
|
|
11
|
-
const proc = spawn(command,
|
|
11
|
+
const proc = spawn(command, {
|
|
12
12
|
env,
|
|
13
13
|
shell: true,
|
|
14
|
-
stdio:
|
|
15
|
-
});
|
|
16
|
-
let stdout = '';
|
|
17
|
-
proc.stdout?.on('data', (data) => {
|
|
18
|
-
const str = data.toString();
|
|
19
|
-
stdout += str;
|
|
20
|
-
// Stream output but filter out the JSON reporter output
|
|
21
|
-
if (!str.trim().startsWith('{')) {
|
|
22
|
-
process.stdout.write(data);
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
proc.on('close', (code) => {
|
|
26
|
-
if (code === 0) {
|
|
27
|
-
resolve(stdout);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
const error = new Error(`Process exited with code ${code}`);
|
|
31
|
-
error.stdout = stdout;
|
|
32
|
-
reject(error);
|
|
33
|
-
}
|
|
14
|
+
stdio: 'inherit' // Full passthrough - all output goes directly to terminal
|
|
34
15
|
});
|
|
16
|
+
proc.on('close', (code) => resolve(code ?? 1));
|
|
35
17
|
proc.on('error', reject);
|
|
36
18
|
});
|
|
37
19
|
}
|
|
@@ -88,45 +70,55 @@ export class TestRunner {
|
|
|
88
70
|
}
|
|
89
71
|
async removePreviousReports() {
|
|
90
72
|
await rm(`./${this.outputFolder}`, { recursive: true, force: true });
|
|
73
|
+
await mkdir(`./${this.outputFolder}`, { recursive: true });
|
|
91
74
|
}
|
|
92
75
|
async runTest(test, config) {
|
|
93
76
|
const testPosition = `${test.file}:${test.position}`;
|
|
94
77
|
const testName = `[${test.project}] > ${testPosition}`;
|
|
95
78
|
const testHash = createHash('md5').update(testName).digest('hex');
|
|
79
|
+
const resultFile = `${this.outputFolder}/${testHash}.result.json`;
|
|
96
80
|
const args = [testPosition, ...this.buildParams(test, config, testHash).split(' ')];
|
|
97
81
|
const env = {
|
|
98
82
|
...process.env,
|
|
99
83
|
PLAYWRIGHT_BLOB_OUTPUT_FILE: `${this.outputFolder}/${testHash}.zip`,
|
|
84
|
+
PLAYWRIGHT_ORCHESTRATOR_RESULT_FILE: resultFile,
|
|
100
85
|
};
|
|
86
|
+
const fullCommand = `npx playwright test ${args.join(' ')}`;
|
|
87
|
+
const exitCode = await spawnPassthrough(fullCommand, env);
|
|
88
|
+
let testResult;
|
|
101
89
|
try {
|
|
102
|
-
const
|
|
90
|
+
const resultJson = await readFile(resultFile, 'utf-8');
|
|
91
|
+
testResult = JSON.parse(resultJson);
|
|
92
|
+
await rm(resultFile, { force: true });
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
console.error(`[orchestrator] Failed to read test result for [${test.project}] ${test.file}:${test.position}`, e);
|
|
96
|
+
throw e;
|
|
97
|
+
}
|
|
98
|
+
if (exitCode === 0) {
|
|
99
|
+
console.log(`[orchestrator] Test passed: [${test.project}] ${test.file}:${test.position}`);
|
|
103
100
|
this.reporter.finishTest(test);
|
|
104
101
|
await this.adapter.finishTest({
|
|
105
102
|
runId: this.runId,
|
|
106
103
|
test,
|
|
107
|
-
testResult
|
|
104
|
+
testResult,
|
|
108
105
|
config,
|
|
109
106
|
});
|
|
110
107
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
throw error;
|
|
108
|
+
else {
|
|
109
|
+
console.log(`[orchestrator] Test failed: [${test.project}] ${test.file}:${test.position}`);
|
|
114
110
|
this.reporter.failTest(test);
|
|
115
111
|
await this.adapter.failTest({
|
|
116
112
|
runId: this.runId,
|
|
117
113
|
test,
|
|
118
|
-
testResult
|
|
114
|
+
testResult,
|
|
119
115
|
config,
|
|
120
116
|
});
|
|
121
117
|
}
|
|
122
118
|
}
|
|
123
|
-
parseTestResult(stdout) {
|
|
124
|
-
return JSON.parse(stdout);
|
|
125
|
-
}
|
|
126
119
|
buildParams(test, config, testHash) {
|
|
127
120
|
const args = [...config.args];
|
|
128
121
|
args.push('--workers', '1');
|
|
129
|
-
args.push('--reporter', 'blob,@dionlarson/playwright-orchestrator-core/test-result-reporter');
|
|
130
122
|
args.push('--project', `"${test.project}"`);
|
|
131
123
|
args.push('--output', `"${this.outputFolder}/${testHash}"`);
|
|
132
124
|
if (config.configFile) {
|
|
@@ -137,10 +129,22 @@ export class TestRunner {
|
|
|
137
129
|
async createTempConfig(file) {
|
|
138
130
|
if (!file)
|
|
139
131
|
return;
|
|
140
|
-
//
|
|
132
|
+
// Modify config: remove webServer, add our reporters while preserving existing ones
|
|
141
133
|
const content = `
|
|
142
134
|
import config from '${path.resolve(file)}';
|
|
135
|
+
|
|
136
|
+
// Remove webServer - not supported in orchestrator (server should already be running)
|
|
143
137
|
delete config.webServer;
|
|
138
|
+
|
|
139
|
+
// Add our reporters while preserving existing reporters from config
|
|
140
|
+
const existingReporters = Array.isArray(config.reporter) ? config.reporter :
|
|
141
|
+
config.reporter ? [[config.reporter]] : [];
|
|
142
|
+
config.reporter = [
|
|
143
|
+
...existingReporters,
|
|
144
|
+
['blob'],
|
|
145
|
+
['@dionlarson/playwright-orchestrator-core/test-result-reporter'],
|
|
146
|
+
];
|
|
147
|
+
|
|
144
148
|
export default config;`;
|
|
145
149
|
const tempFile = `.playwright-${uuid.v7()}.config.tmp.ts`;
|
|
146
150
|
await writeFile(tempFile, content);
|