@bigbinary/neeto-playwright-reporter 3.0.0-beta.4 → 3.0.0-beta.5
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/bin/neetoplaydash.mjs +78 -19
- package/bin/smartOrchestration.js +4 -4
- package/package.json +1 -1
package/bin/neetoplaydash.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawn, execSync } from "child_process";
|
|
4
|
+
import fs from "fs";
|
|
4
5
|
import path from "path";
|
|
5
6
|
import { fileURLToPath } from "url";
|
|
6
7
|
import * as R from "ramda";
|
|
@@ -9,30 +10,54 @@ import smartOrchestrationApi from "./smartOrchestration.js";
|
|
|
9
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
11
|
const __dirname = path.dirname(__filename);
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
-
|
|
13
|
+
const TEST_LIST_SEPARATOR = " › ";
|
|
14
|
+
|
|
15
|
+
const buildTestListTitle = (
|
|
16
|
+
projectName,
|
|
17
|
+
file,
|
|
18
|
+
line,
|
|
19
|
+
column,
|
|
20
|
+
suiteTitles,
|
|
21
|
+
specTitle
|
|
22
|
+
) => {
|
|
23
|
+
const parts = [
|
|
24
|
+
`[${projectName}]`,
|
|
25
|
+
`${file}:${line}:${column}`,
|
|
26
|
+
...suiteTitles,
|
|
27
|
+
specTitle,
|
|
28
|
+
];
|
|
29
|
+
return parts.join(TEST_LIST_SEPARATOR);
|
|
30
|
+
};
|
|
14
31
|
|
|
15
|
-
const collectSpecs = (suite,
|
|
32
|
+
const collectSpecs = (suite, suiteTitles = []) =>
|
|
16
33
|
R.concat(
|
|
17
|
-
R.
|
|
18
|
-
spec =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
R.chain(
|
|
35
|
+
spec =>
|
|
36
|
+
R.map(
|
|
37
|
+
test => ({
|
|
38
|
+
id: spec.id,
|
|
39
|
+
title: buildTestListTitle(
|
|
40
|
+
test.projectName,
|
|
41
|
+
spec.file,
|
|
42
|
+
spec.line,
|
|
43
|
+
spec.column,
|
|
44
|
+
suiteTitles,
|
|
45
|
+
spec.title
|
|
46
|
+
),
|
|
47
|
+
}),
|
|
48
|
+
spec.tests || []
|
|
49
|
+
),
|
|
22
50
|
suite.specs || []
|
|
23
51
|
),
|
|
24
52
|
R.chain(
|
|
25
53
|
childSuite =>
|
|
26
|
-
collectSpecs(childSuite, [...
|
|
54
|
+
collectSpecs(childSuite, [...suiteTitles, childSuite.title]),
|
|
27
55
|
suite.suites || []
|
|
28
56
|
)
|
|
29
57
|
);
|
|
30
58
|
|
|
31
59
|
const extractTestTitlesAndIds = json =>
|
|
32
|
-
R.chain(
|
|
33
|
-
project => R.chain(file => collectSpecs(file, []), project.suites || []),
|
|
34
|
-
json.suites || []
|
|
35
|
-
);
|
|
60
|
+
R.chain(fileSuite => collectSpecs(fileSuite, []), json.suites || []);
|
|
36
61
|
|
|
37
62
|
const args = process.argv.slice(2);
|
|
38
63
|
|
|
@@ -163,9 +188,6 @@ const escapeShellArg = arg => {
|
|
|
163
188
|
return arg;
|
|
164
189
|
};
|
|
165
190
|
|
|
166
|
-
const escapeRegexSpecialChars = str =>
|
|
167
|
-
str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
168
|
-
|
|
169
191
|
const extractShardInfo = args => {
|
|
170
192
|
let currentShard = null;
|
|
171
193
|
let totalShards = null;
|
|
@@ -208,6 +230,14 @@ const filterArgs = (args, filterableArg) => {
|
|
|
208
230
|
|
|
209
231
|
const filterShardArgs = args => filterArgs(args, "--shard");
|
|
210
232
|
const filterGrepArgs = args => filterArgs(args, "--grep");
|
|
233
|
+
const filterGrepInvertArgs = args => filterArgs(args, "--grep-invert");
|
|
234
|
+
const filterTestListArgs = args => filterArgs(args, "--test-list");
|
|
235
|
+
const filterTestListInvertArgs = args => filterArgs(args, "--test-list-invert");
|
|
236
|
+
|
|
237
|
+
const filterAllTestSelectionArgs = args =>
|
|
238
|
+
filterTestListInvertArgs(
|
|
239
|
+
filterTestListArgs(filterGrepInvertArgs(filterGrepArgs(args)))
|
|
240
|
+
);
|
|
211
241
|
|
|
212
242
|
const removeConsecutiveDuplicates = (args, value) => {
|
|
213
243
|
return args.filter((arg, index) => {
|
|
@@ -219,7 +249,9 @@ const removeConsecutiveDuplicates = (args, value) => {
|
|
|
219
249
|
};
|
|
220
250
|
|
|
221
251
|
const { currentShard, totalShards } = extractShardInfo(playwrightArgs);
|
|
222
|
-
const filteredPlaywrightArgs =
|
|
252
|
+
const filteredPlaywrightArgs = filterAllTestSelectionArgs(
|
|
253
|
+
filterShardArgs(playwrightArgs)
|
|
254
|
+
);
|
|
223
255
|
|
|
224
256
|
const env = {
|
|
225
257
|
...process.env,
|
|
@@ -233,6 +265,7 @@ env.NEETO_CI_BUILD_ID = ciBuildId;
|
|
|
233
265
|
|
|
234
266
|
if (reporterOptions.baseURL) {
|
|
235
267
|
env.NEETO_PLAYDASH_API_BASE_URL = reporterOptions.baseURL;
|
|
268
|
+
process.env.NEETO_PLAYDASH_API_BASE_URL = reporterOptions.baseURL;
|
|
236
269
|
}
|
|
237
270
|
|
|
238
271
|
if (currentShard !== null) {
|
|
@@ -307,7 +340,19 @@ child.on("close", async code => {
|
|
|
307
340
|
projectKey,
|
|
308
341
|
});
|
|
309
342
|
const executableTests = smartOrchestrationResponse.data.tests;
|
|
310
|
-
|
|
343
|
+
|
|
344
|
+
const tmpDir = path.join(process.cwd(), "tmp");
|
|
345
|
+
if (!fs.existsSync(tmpDir)) {
|
|
346
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const testListFileName = `test-list-neeto-playdash-${
|
|
350
|
+
currentShard || 0
|
|
351
|
+
}.txt`;
|
|
352
|
+
const testListFilePath = path.join(tmpDir, testListFileName);
|
|
353
|
+
const testListContent = executableTests.join("\n");
|
|
354
|
+
fs.writeFileSync(testListFilePath, testListContent, "utf-8");
|
|
355
|
+
|
|
311
356
|
const deduplicatedArgs = removeConsecutiveDuplicates(
|
|
312
357
|
filteredPlaywrightArgs,
|
|
313
358
|
"test"
|
|
@@ -315,18 +360,32 @@ child.on("close", async code => {
|
|
|
315
360
|
const escapedArgs = deduplicatedArgs.map(escapeShellArg);
|
|
316
361
|
const command = `npx playwright ${escapedArgs.join(
|
|
317
362
|
" "
|
|
318
|
-
)} --reporter="@bigbinary/neeto-playwright-reporter" --
|
|
363
|
+
)} --reporter="@bigbinary/neeto-playwright-reporter" --test-list="${testListFilePath}"`;
|
|
319
364
|
const runChild = spawn(command, {
|
|
320
365
|
env,
|
|
321
366
|
stdio: "inherit",
|
|
322
367
|
shell: true,
|
|
323
368
|
});
|
|
324
369
|
|
|
370
|
+
const cleanupTestListFile = () => {
|
|
371
|
+
try {
|
|
372
|
+
if (fs.existsSync(testListFilePath)) {
|
|
373
|
+
fs.unlinkSync(testListFilePath);
|
|
374
|
+
}
|
|
375
|
+
} catch (error) {
|
|
376
|
+
console.error(
|
|
377
|
+
`Warning: Failed to delete test list file: ${error.message}`
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
|
|
325
382
|
runChild.on("close", exitCode => {
|
|
383
|
+
cleanupTestListFile();
|
|
326
384
|
process.exit(exitCode || 0);
|
|
327
385
|
});
|
|
328
386
|
|
|
329
387
|
runChild.on("error", error => {
|
|
388
|
+
cleanupTestListFile();
|
|
330
389
|
console.error(`Error executing test command: ${error.message}`);
|
|
331
390
|
process.exit(1);
|
|
332
391
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
|
|
3
|
-
const API_BASE_URL =
|
|
4
|
-
process.env.NEETO_PLAYDASH_API_BASE_URL ||
|
|
5
|
-
"https://connect.neetoplaydash.com";
|
|
6
|
-
|
|
7
3
|
const create = ({ payload, apiKey, projectKey }) => {
|
|
4
|
+
const API_BASE_URL =
|
|
5
|
+
process.env.NEETO_PLAYDASH_API_BASE_URL ||
|
|
6
|
+
"https://connect.neetoplaydash.com";
|
|
7
|
+
|
|
8
8
|
return axios.post(
|
|
9
9
|
"/api/v2/reporter/smart_orchestration/distribute_tests",
|
|
10
10
|
{ smart_orchestration: payload },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigbinary/neeto-playwright-reporter",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.5",
|
|
4
4
|
"description": "The custom playwright reporter for neeto-playwright-dashboard.",
|
|
5
5
|
"repository": "git@github.com:bigbinary/neeto-playwright-reporter.git",
|
|
6
6
|
"license": "Apache-2.0",
|