@bigbinary/neeto-playwright-reporter 3.0.0-beta.3 → 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 +82 -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,
|
|
@@ -231,6 +263,11 @@ env.NEETO_PROJECT_KEY = projectKey;
|
|
|
231
263
|
env.NEETO_API_KEY = apiKey;
|
|
232
264
|
env.NEETO_CI_BUILD_ID = ciBuildId;
|
|
233
265
|
|
|
266
|
+
if (reporterOptions.baseURL) {
|
|
267
|
+
env.NEETO_PLAYDASH_API_BASE_URL = reporterOptions.baseURL;
|
|
268
|
+
process.env.NEETO_PLAYDASH_API_BASE_URL = reporterOptions.baseURL;
|
|
269
|
+
}
|
|
270
|
+
|
|
234
271
|
if (currentShard !== null) {
|
|
235
272
|
env.NEETO_PLAYDASH_CURRENT_SHARD = currentShard.toString();
|
|
236
273
|
}
|
|
@@ -303,7 +340,19 @@ child.on("close", async code => {
|
|
|
303
340
|
projectKey,
|
|
304
341
|
});
|
|
305
342
|
const executableTests = smartOrchestrationResponse.data.tests;
|
|
306
|
-
|
|
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
|
+
|
|
307
356
|
const deduplicatedArgs = removeConsecutiveDuplicates(
|
|
308
357
|
filteredPlaywrightArgs,
|
|
309
358
|
"test"
|
|
@@ -311,18 +360,32 @@ child.on("close", async code => {
|
|
|
311
360
|
const escapedArgs = deduplicatedArgs.map(escapeShellArg);
|
|
312
361
|
const command = `npx playwright ${escapedArgs.join(
|
|
313
362
|
" "
|
|
314
|
-
)} --reporter="@bigbinary/neeto-playwright-reporter" --
|
|
363
|
+
)} --reporter="@bigbinary/neeto-playwright-reporter" --test-list="${testListFilePath}"`;
|
|
315
364
|
const runChild = spawn(command, {
|
|
316
365
|
env,
|
|
317
366
|
stdio: "inherit",
|
|
318
367
|
shell: true,
|
|
319
368
|
});
|
|
320
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
|
+
|
|
321
382
|
runChild.on("close", exitCode => {
|
|
383
|
+
cleanupTestListFile();
|
|
322
384
|
process.exit(exitCode || 0);
|
|
323
385
|
});
|
|
324
386
|
|
|
325
387
|
runChild.on("error", error => {
|
|
388
|
+
cleanupTestListFile();
|
|
326
389
|
console.error(`Error executing test command: ${error.message}`);
|
|
327
390
|
process.exit(1);
|
|
328
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",
|