@dionlarson/playwright-orchestrator-core 1.3.0 → 1.3.2
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/program.js
CHANGED
|
@@ -4,8 +4,11 @@ import run from './run.js';
|
|
|
4
4
|
import create from './create.js';
|
|
5
5
|
import createReport from './create-report.js';
|
|
6
6
|
import { readFile } from 'node:fs/promises';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { dirname, join } from 'node:path';
|
|
7
9
|
export const program = new Command();
|
|
8
|
-
const
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const package_json = JSON.parse(await readFile(join(__dirname, '..', '..', 'package.json'), 'utf-8'));
|
|
9
12
|
program
|
|
10
13
|
.name('playwright-orchestrator')
|
|
11
14
|
.description('CLI to orchestrate Playwright tests')
|
package/dist/helpers/plugin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { STORAGES } from '../plugins-list.js';
|
|
2
2
|
export async function loadPluginModule(storage) {
|
|
3
3
|
try {
|
|
4
|
-
const a = await import(`@playwright-orchestrator
|
|
4
|
+
const a = await import(`@dionlarson/playwright-orchestrator-${storage}`);
|
|
5
5
|
return a;
|
|
6
6
|
}
|
|
7
7
|
catch (error) {
|
|
@@ -17,5 +17,5 @@ export async function loadRunInfo(args) {
|
|
|
17
17
|
}
|
|
18
18
|
function buildCommand(args) {
|
|
19
19
|
// last param wins, so we need to put our reporter at the end
|
|
20
|
-
return `npx playwright test --list ${args.join(' ')} --reporter "@playwright-orchestrator
|
|
20
|
+
return `npx playwright test --list ${args.join(' ')} --reporter "@dionlarson/playwright-orchestrator-core/tests-info-reporter"`;
|
|
21
21
|
}
|
package/dist/test-runner.js
CHANGED
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
import child_process from 'node:child_process';
|
|
2
|
+
import child_process, { spawn } from 'node:child_process';
|
|
3
3
|
import { promisify } from 'node:util';
|
|
4
4
|
import { 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 spawnWithOutput(command, args, env) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const proc = spawn(command, args, {
|
|
12
|
+
env,
|
|
13
|
+
shell: true,
|
|
14
|
+
stdio: ['inherit', 'pipe', 'inherit'] // stdin inherit, stdout pipe, stderr inherit
|
|
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
|
+
}
|
|
34
|
+
});
|
|
35
|
+
proc.on('error', reject);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
9
38
|
export class TestRunner {
|
|
10
39
|
adapter;
|
|
11
40
|
runId;
|
|
@@ -17,11 +46,14 @@ export class TestRunner {
|
|
|
17
46
|
this.outputFolder = options.output;
|
|
18
47
|
}
|
|
19
48
|
async runTests() {
|
|
49
|
+
console.log(`[orchestrator] Starting shard for run ${this.runId}`);
|
|
20
50
|
await this.removePreviousReports();
|
|
21
51
|
const config = await this.adapter.startShard(this.runId);
|
|
52
|
+
console.log(`[orchestrator] Shard started. Workers: ${config.workers}, Config: ${config.configFile || 'default'}`);
|
|
22
53
|
config.configFile = await this.createTempConfig(config.configFile);
|
|
23
54
|
try {
|
|
24
55
|
await this.runTestsUntilAvailable(config);
|
|
56
|
+
console.log(`[orchestrator] All tests completed, finishing shard`);
|
|
25
57
|
await this.adapter.finishShard(this.runId);
|
|
26
58
|
await this.adapter.dispose();
|
|
27
59
|
this.reporter.printSummary();
|
|
@@ -33,9 +65,14 @@ export class TestRunner {
|
|
|
33
65
|
}
|
|
34
66
|
async runTestsUntilAvailable(config) {
|
|
35
67
|
const runningTests = new Set();
|
|
68
|
+
console.log(`[orchestrator] Fetching first test...`);
|
|
36
69
|
let next = await this.adapter.getNextTest(this.runId, config);
|
|
70
|
+
console.log(`[orchestrator] First test: ${next ? `[${next.project}] ${next.file}:${next.position}` : 'none available'}`);
|
|
71
|
+
let testCount = 0;
|
|
37
72
|
while (next || runningTests.size > 0) {
|
|
38
73
|
if (next && runningTests.size < config.workers) {
|
|
74
|
+
testCount++;
|
|
75
|
+
console.log(`[orchestrator] Running test #${testCount}: [${next.project}] ${next.file}:${next.position}`);
|
|
39
76
|
const testPromise = this.runTest(next, config).then(() => {
|
|
40
77
|
runningTests.delete(testPromise);
|
|
41
78
|
});
|
|
@@ -46,6 +83,7 @@ export class TestRunner {
|
|
|
46
83
|
await Promise.race(runningTests);
|
|
47
84
|
}
|
|
48
85
|
}
|
|
86
|
+
console.log(`[orchestrator] Finished ${testCount} tests`);
|
|
49
87
|
await Promise.all(runningTests);
|
|
50
88
|
}
|
|
51
89
|
async removePreviousReports() {
|
|
@@ -55,15 +93,14 @@ export class TestRunner {
|
|
|
55
93
|
const testPosition = `${test.file}:${test.position}`;
|
|
56
94
|
const testName = `[${test.project}] > ${testPosition}`;
|
|
57
95
|
const testHash = createHash('md5').update(testName).digest('hex');
|
|
96
|
+
const args = [testPosition, ...this.buildParams(test, config, testHash).split(' ')];
|
|
97
|
+
const env = {
|
|
98
|
+
...process.env,
|
|
99
|
+
PLAYWRIGHT_BLOB_OUTPUT_FILE: `${this.outputFolder}/${testHash}.zip`,
|
|
100
|
+
};
|
|
58
101
|
try {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
...process.env,
|
|
62
|
-
PLAYWRIGHT_BLOB_OUTPUT_FILE: `${this.outputFolder}/${testHash}.zip`,
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
this.reporter.addTest(test, run);
|
|
66
|
-
const { stdout } = await run;
|
|
102
|
+
const stdout = await spawnWithOutput('npx', ['playwright', 'test', ...args], env);
|
|
103
|
+
this.reporter.finishTest(test);
|
|
67
104
|
await this.adapter.finishTest({
|
|
68
105
|
runId: this.runId,
|
|
69
106
|
test,
|
|
@@ -74,6 +111,7 @@ export class TestRunner {
|
|
|
74
111
|
catch (error) {
|
|
75
112
|
if (!error.stdout)
|
|
76
113
|
throw error;
|
|
114
|
+
this.reporter.failTest(test);
|
|
77
115
|
await this.adapter.failTest({
|
|
78
116
|
runId: this.runId,
|
|
79
117
|
test,
|
|
@@ -88,7 +126,7 @@ export class TestRunner {
|
|
|
88
126
|
buildParams(test, config, testHash) {
|
|
89
127
|
const args = [...config.args];
|
|
90
128
|
args.push('--workers', '1');
|
|
91
|
-
args.push('--reporter', 'blob,@playwright-orchestrator
|
|
129
|
+
args.push('--reporter', 'blob,@dionlarson/playwright-orchestrator-core/test-result-reporter');
|
|
92
130
|
args.push('--project', `"${test.project}"`);
|
|
93
131
|
args.push('--output', `"${this.outputFolder}/${testHash}"`);
|
|
94
132
|
if (config.configFile) {
|