@trackunit/iris-app-playwright 0.1.1
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/README.md +230 -0
- package/generators.json +12 -0
- package/package.json +43 -0
- package/src/fixtures/baseTest.d.ts +9 -0
- package/src/fixtures/baseTest.js +12 -0
- package/src/fixtures/describe.d.ts +11 -0
- package/src/fixtures/describe.js +23 -0
- package/src/fixtures/featureFlags.fixture.d.ts +19 -0
- package/src/fixtures/featureFlags.fixture.js +76 -0
- package/src/fixtures/harRecording.fixture.d.ts +12 -0
- package/src/fixtures/harRecording.fixture.js +35 -0
- package/src/fixtures/hydrateStorageState.d.ts +36 -0
- package/src/fixtures/hydrateStorageState.js +43 -0
- package/src/fixtures/irisApp.fixture.d.ts +15 -0
- package/src/fixtures/irisApp.fixture.js +13 -0
- package/src/fixtures/localDevMode.fixture.d.ts +5 -0
- package/src/fixtures/localDevMode.fixture.js +17 -0
- package/src/fixtures/login.fixture.d.ts +24 -0
- package/src/fixtures/login.fixture.js +95 -0
- package/src/fixtures/loginCacheKey.d.ts +25 -0
- package/src/fixtures/loginCacheKey.js +29 -0
- package/src/fixtures/resolveCredentials.d.ts +14 -0
- package/src/fixtures/resolveCredentials.js +49 -0
- package/src/generators/playwright-configuration/files/root/playwright/fixtures/auth.json__tmpl__ +4 -0
- package/src/generators/playwright-configuration/files/root/playwright/support/fixtures.ts__tmpl__ +1 -0
- package/src/generators/playwright-configuration/files/root/playwright/tests/app.spec.ts__tmpl__ +16 -0
- package/src/generators/playwright-configuration/files/root/playwright/tsconfig.json__tmpl__ +15 -0
- package/src/generators/playwright-configuration/files/root/playwright.config.ts__tmpl__ +13 -0
- package/src/generators/playwright-configuration/generator.d.ts +18 -0
- package/src/generators/playwright-configuration/generator.js +77 -0
- package/src/generators/playwright-configuration/schema.d.ts +3 -0
- package/src/generators/playwright-configuration/schema.json +18 -0
- package/src/index.d.ts +15 -0
- package/src/index.js +14 -0
- package/src/plugins/createLogFile.d.ts +24 -0
- package/src/plugins/createLogFile.js +51 -0
- package/src/plugins/defaultPlaywrightConfig.d.ts +68 -0
- package/src/plugins/defaultPlaywrightConfig.js +150 -0
- package/src/plugins/logsReporter.d.ts +55 -0
- package/src/plugins/logsReporter.js +119 -0
- package/src/plugins/nxPreset.d.ts +9 -0
- package/src/plugins/nxPreset.js +17 -0
- package/src/plugins/redactHar.d.ts +17 -0
- package/src/plugins/redactHar.js +138 -0
- package/src/plugins/redactSensitive.d.ts +31 -0
- package/src/plugins/redactSensitive.js +72 -0
- package/src/plugins/redactTrace.d.ts +12 -0
- package/src/plugins/redactTrace.js +48 -0
- package/src/plugins/setupPlugins.d.ts +11 -0
- package/src/plugins/setupPlugins.js +68 -0
- package/src/plugins/writeFileWithPrettier.d.ts +17 -0
- package/src/plugins/writeFileWithPrettier.js +37 -0
- package/src/support.d.ts +2 -0
- package/src/support.js +6 -0
- package/src/utils/Codeowner.d.ts +26 -0
- package/src/utils/Codeowner.js +89 -0
- package/src/utils/fileNameBuilder.d.ts +18 -0
- package/src/utils/fileNameBuilder.js +32 -0
- package/src/utils/fileUpdater.d.ts +16 -0
- package/src/utils/fileUpdater.js +38 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.redactTraceFile = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const jszip_1 = tslib_1.__importDefault(require("jszip"));
|
|
7
|
+
const redactSensitive_1 = require("./redactSensitive");
|
|
8
|
+
/**
|
|
9
|
+
* File suffixes inside a Playwright trace.zip whose contents are JSON Lines
|
|
10
|
+
* with action/network metadata — i.e. the places where a `page.goto(url)`
|
|
11
|
+
* call's URL argument is recorded verbatim. Other entries (binary resources,
|
|
12
|
+
* screenshots, network bodies under `sha1/`) are left alone; their content is
|
|
13
|
+
* referenced by hash so redacting the metadata is sufficient to suppress the
|
|
14
|
+
* sensitive string from any human-readable trace view.
|
|
15
|
+
*/
|
|
16
|
+
const TEXT_TRACE_SUFFIXES = [".trace", ".network", ".stacks"];
|
|
17
|
+
const isTextTraceEntry = (relPath) => TEXT_TRACE_SUFFIXES.some(s => relPath.endsWith(s));
|
|
18
|
+
/**
|
|
19
|
+
* Rewrites a Playwright trace.zip in place with sensitive values stripped from
|
|
20
|
+
* the action/network metadata. The `login()` fixture issues a `page.goto`
|
|
21
|
+
* against `/auth/manager-classic#session_token=...`; Playwright records the
|
|
22
|
+
* full URL as the action argument, so without this pass a retained trace zip
|
|
23
|
+
* would carry a live Okta session token alongside the test artifacts.
|
|
24
|
+
*
|
|
25
|
+
* The fragment is client-side only — it never reaches the HTTP server, and
|
|
26
|
+
* HAR/log redaction already covers everything that does — so this pass is the
|
|
27
|
+
* defense-in-depth layer that scrubs the remaining surface.
|
|
28
|
+
*/
|
|
29
|
+
const redactTraceFile = async (filePath) => {
|
|
30
|
+
const buf = (0, fs_1.readFileSync)(filePath);
|
|
31
|
+
const zip = await jszip_1.default.loadAsync(buf);
|
|
32
|
+
const rewrites = [];
|
|
33
|
+
zip.forEach((relPath, file) => {
|
|
34
|
+
if (file.dir)
|
|
35
|
+
return;
|
|
36
|
+
if (!isTextTraceEntry(relPath))
|
|
37
|
+
return;
|
|
38
|
+
rewrites.push((async () => {
|
|
39
|
+
const text = await file.async("text");
|
|
40
|
+
zip.file(relPath, (0, redactSensitive_1.redactSensitive)(text));
|
|
41
|
+
})());
|
|
42
|
+
});
|
|
43
|
+
await Promise.all(rewrites);
|
|
44
|
+
const out = await zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
|
|
45
|
+
(0, fs_1.writeFileSync)(filePath, out);
|
|
46
|
+
};
|
|
47
|
+
exports.redactTraceFile = redactTraceFile;
|
|
48
|
+
//# sourceMappingURL=redactTrace.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PlaywrightTestConfig } from "@playwright/test";
|
|
2
|
+
import type { Formatter } from "./writeFileWithPrettier";
|
|
3
|
+
/**
|
|
4
|
+
* Augments a partial Playwright config with the Trackunit logs reporter and HAR folder env setup.
|
|
5
|
+
* Call this in `playwright.config.ts` after `defaultPlaywrightConfig()`.
|
|
6
|
+
*
|
|
7
|
+
* @param config - Partial config from `defaultPlaywrightConfig()`
|
|
8
|
+
* @param formatter - Prettier formatter used by `LogsReporter` to format JSON log files
|
|
9
|
+
* @returns {Partial<PlaywrightTestConfig>} A new partial config with the logs reporter merged into the reporter array
|
|
10
|
+
*/
|
|
11
|
+
export declare const setupPlugins: (config: Partial<PlaywrightTestConfig>, formatter: Formatter) => Partial<PlaywrightTestConfig>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupPlugins = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const path = tslib_1.__importStar(require("path"));
|
|
6
|
+
const defaultPlaywrightConfig_1 = require("./defaultPlaywrightConfig");
|
|
7
|
+
/**
|
|
8
|
+
* Resolves a Playwright `outputDir` (relative or absolute) to an absolute
|
|
9
|
+
* path anchored at `nxRoot`.
|
|
10
|
+
*
|
|
11
|
+
* Why this exists: `defaultPlaywrightConfig` intentionally returns a relative
|
|
12
|
+
* `outputDir` like `../../dist/playwright/apps/<project>/test-results` so it
|
|
13
|
+
* stays portable across machines and snapshot-stable for tests. Playwright
|
|
14
|
+
* itself resolves that string against `rootDir` (the directory containing
|
|
15
|
+
* `playwright.config.ts`) and writes screenshots/videos/traces in the right
|
|
16
|
+
* place. The custom `LogsReporter` however runs as a Playwright `Reporter`
|
|
17
|
+
* and calls `mkdirSync(logsFolder, { recursive: true })` directly — Node
|
|
18
|
+
* resolves the relative path against `process.cwd()`, which under
|
|
19
|
+
* `nx:run-commands` is the **workspace root**. The leading `../..` then
|
|
20
|
+
* walks the reporter two directories *above* the workspace, scattering log
|
|
21
|
+
* files (and HARs) into a sibling repo.
|
|
22
|
+
*
|
|
23
|
+
* The relative path Playwright emits always has the shape
|
|
24
|
+
* `<../>+<workspace-relative-subpath>`, so stripping the leading `../`s and
|
|
25
|
+
* anchoring the remainder at `nxRoot` yields the same absolute directory
|
|
26
|
+
* Playwright would land on — regardless of how the test runner was spawned.
|
|
27
|
+
*/
|
|
28
|
+
const absolutiseOutputDir = (outputDir, nxRoot) => {
|
|
29
|
+
if (path.isAbsolute(outputDir)) {
|
|
30
|
+
return outputDir;
|
|
31
|
+
}
|
|
32
|
+
const withoutLeadingDotDots = outputDir.replace(/^(?:\.\.[\\/])+/, "");
|
|
33
|
+
return path.resolve(nxRoot, withoutLeadingDotDots);
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Augments a partial Playwright config with the Trackunit logs reporter and HAR folder env setup.
|
|
37
|
+
* Call this in `playwright.config.ts` after `defaultPlaywrightConfig()`.
|
|
38
|
+
*
|
|
39
|
+
* @param config - Partial config from `defaultPlaywrightConfig()`
|
|
40
|
+
* @param formatter - Prettier formatter used by `LogsReporter` to format JSON log files
|
|
41
|
+
* @returns {Partial<PlaywrightTestConfig>} A new partial config with the logs reporter merged into the reporter array
|
|
42
|
+
*/
|
|
43
|
+
const setupPlugins = (config, formatter) => {
|
|
44
|
+
const nxRoot = (0, defaultPlaywrightConfig_1.findWorkspaceRoot)();
|
|
45
|
+
// Both HARs and logs derive from the resolved `outputDir`, so every Playwright
|
|
46
|
+
// artifact for a run stays inside the one `dist/playwright` tree (under the
|
|
47
|
+
// per-executor partition on CI). This removes the legacy fixed
|
|
48
|
+
// `dist/playwright-results` location and the `hars_folders` env override.
|
|
49
|
+
const outputDirBase = typeof config.outputDir === "string"
|
|
50
|
+
? absolutiseOutputDir(config.outputDir, nxRoot)
|
|
51
|
+
: path.join(nxRoot, "dist", "playwright");
|
|
52
|
+
const harsFolder = path.join(outputDirBase, "hars");
|
|
53
|
+
const logsFolder = path.join(outputDirBase, "logs");
|
|
54
|
+
const reporterOptions = {
|
|
55
|
+
logsFolder,
|
|
56
|
+
harsFolder,
|
|
57
|
+
nxRoot,
|
|
58
|
+
formatter,
|
|
59
|
+
};
|
|
60
|
+
const logsReporterEntry = [path.resolve(__dirname, "./logsReporter"), reporterOptions];
|
|
61
|
+
const existingReporters = Array.isArray(config.reporter) ? config.reporter : [];
|
|
62
|
+
return {
|
|
63
|
+
...config,
|
|
64
|
+
reporter: [...existingReporters, logsReporterEntry],
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
exports.setupPlugins = setupPlugins;
|
|
68
|
+
//# sourceMappingURL=setupPlugins.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { WriteFileOptions } from "fs";
|
|
2
|
+
import { format, resolveConfig } from "prettier";
|
|
3
|
+
export type Formatter = {
|
|
4
|
+
resolveConfig: typeof resolveConfig;
|
|
5
|
+
format: typeof format;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Writes a file with Prettier formatting applied.
|
|
9
|
+
* Automatically detects parser based on file extension.
|
|
10
|
+
*
|
|
11
|
+
* @param nxRoot - Absolute path to the NX workspace root (used to locate `.prettierrc`)
|
|
12
|
+
* @param filePath - Destination file path
|
|
13
|
+
* @param content - Raw file content to format and write
|
|
14
|
+
* @param writer - Prettier formatter instance
|
|
15
|
+
* @param writeOptions - Node.js `writeFileSync` options (default: UTF-8)
|
|
16
|
+
*/
|
|
17
|
+
export declare const writeFileWithPrettier: (nxRoot: string, filePath: string, content: string, writer: Formatter, writeOptions?: WriteFileOptions) => Promise<void>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeFileWithPrettier = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const devkit_1 = require("@nx/devkit");
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const path = tslib_1.__importStar(require("path"));
|
|
8
|
+
/**
|
|
9
|
+
* Writes a file with Prettier formatting applied.
|
|
10
|
+
* Automatically detects parser based on file extension.
|
|
11
|
+
*
|
|
12
|
+
* @param nxRoot - Absolute path to the NX workspace root (used to locate `.prettierrc`)
|
|
13
|
+
* @param filePath - Destination file path
|
|
14
|
+
* @param content - Raw file content to format and write
|
|
15
|
+
* @param writer - Prettier formatter instance
|
|
16
|
+
* @param writeOptions - Node.js `writeFileSync` options (default: UTF-8)
|
|
17
|
+
*/
|
|
18
|
+
const writeFileWithPrettier = async (nxRoot, filePath, content, writer, writeOptions = { encoding: "utf-8" }) => {
|
|
19
|
+
const prettierConfigPath = path.join(nxRoot, ".prettierrc");
|
|
20
|
+
const options = await writer.resolveConfig(prettierConfigPath).catch(error => {
|
|
21
|
+
devkit_1.logger.info(`Prettier config error: ${String(error)}`);
|
|
22
|
+
return undefined;
|
|
23
|
+
});
|
|
24
|
+
if (!options) {
|
|
25
|
+
throw new Error("Could not find prettier config");
|
|
26
|
+
}
|
|
27
|
+
if (filePath.endsWith("json")) {
|
|
28
|
+
options.parser = "json";
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
options.parser = "typescript";
|
|
32
|
+
}
|
|
33
|
+
const prettySrc = await writer.format(content, options);
|
|
34
|
+
(0, fs_1.writeFileSync)(filePath, prettySrc, writeOptions);
|
|
35
|
+
};
|
|
36
|
+
exports.writeFileWithPrettier = writeFileWithPrettier;
|
|
37
|
+
//# sourceMappingURL=writeFileWithPrettier.js.map
|
package/src/support.d.ts
ADDED
package/src/support.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./fixtures/baseTest"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./fixtures/describe"), exports);
|
|
6
|
+
//# sourceMappingURL=support.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses lines from a CODEOWNERS-style file into a mapping of patterns → owners.
|
|
3
|
+
* Skips blank lines and comments (lines beginning with `#`).
|
|
4
|
+
*
|
|
5
|
+
* @param {string[]} lines - Each element is a line from your CODEOWNERS file.
|
|
6
|
+
* @returns {Record<string, string>} An object whose keys are normalized path patterns and values are the owner handle.
|
|
7
|
+
*/
|
|
8
|
+
export declare const parseCodeowners: (lines: Array<string>) => Record<string, string>;
|
|
9
|
+
/**
|
|
10
|
+
* Converts a full team handle (potentially namespaced and with platform suffix)
|
|
11
|
+
* into its "short" team name.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} teamName - e.g. `"@trackunit/backend-be"` or `"@trackunit/frontend-fe"`
|
|
14
|
+
* @returns {string | undefined} e.g. `"backend"` or `"frontend"`, or `undefined` if no name given.
|
|
15
|
+
*/
|
|
16
|
+
export declare const toShortTeamName: (teamName?: string) => string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Recursively looks up the CODEOWNER for a given file or directory path
|
|
19
|
+
* by reading your workspace's CODEOWNERS file.
|
|
20
|
+
*
|
|
21
|
+
* @param {string} currentPath - Absolute path to the file/directory you're querying.
|
|
22
|
+
* @param {string} workspaceRoot - Absolute path to your repo/workspace root.
|
|
23
|
+
* @param {string} [codeownersFileName="TEAM_CODEOWNERS"] - Filename to read at the root.
|
|
24
|
+
* @returns {string|undefined} The owner handle or `undefined` if none found.
|
|
25
|
+
*/
|
|
26
|
+
export declare const getCodeowner: (currentPath: string, workspaceRoot: string, codeownersFileName?: string) => string | undefined;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCodeowner = exports.toShortTeamName = exports.parseCodeowners = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
6
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
+
/**
|
|
8
|
+
* Parses lines from a CODEOWNERS-style file into a mapping of patterns → owners.
|
|
9
|
+
* Skips blank lines and comments (lines beginning with `#`).
|
|
10
|
+
*
|
|
11
|
+
* @param {string[]} lines - Each element is a line from your CODEOWNERS file.
|
|
12
|
+
* @returns {Record<string, string>} An object whose keys are normalized path patterns and values are the owner handle.
|
|
13
|
+
*/
|
|
14
|
+
const parseCodeowners = (lines) => {
|
|
15
|
+
const patterns = {};
|
|
16
|
+
for (const line of lines) {
|
|
17
|
+
const trimmed = line.trim();
|
|
18
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const [pattern, owner] = trimmed.split(/\s+/, 2);
|
|
22
|
+
if (pattern && owner) {
|
|
23
|
+
const normalizedPattern = pattern.replace(/^\/+|\/+$/g, "");
|
|
24
|
+
patterns[normalizedPattern] = owner;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return patterns;
|
|
28
|
+
};
|
|
29
|
+
exports.parseCodeowners = parseCodeowners;
|
|
30
|
+
/**
|
|
31
|
+
* Converts a full team handle (potentially namespaced and with platform suffix)
|
|
32
|
+
* into its "short" team name.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} teamName - e.g. `"@trackunit/backend-be"` or `"@trackunit/frontend-fe"`
|
|
35
|
+
* @returns {string | undefined} e.g. `"backend"` or `"frontend"`, or `undefined` if no name given.
|
|
36
|
+
*/
|
|
37
|
+
const toShortTeamName = (teamName) => {
|
|
38
|
+
if (!teamName) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
let shortName = teamName;
|
|
42
|
+
if (teamName.startsWith("@")) {
|
|
43
|
+
shortName = shortName.slice(shortName.indexOf("/") + 1);
|
|
44
|
+
}
|
|
45
|
+
if (shortName.endsWith("-be") || shortName.endsWith("-fe")) {
|
|
46
|
+
shortName = shortName.slice(0, shortName.lastIndexOf("-"));
|
|
47
|
+
}
|
|
48
|
+
return shortName;
|
|
49
|
+
};
|
|
50
|
+
exports.toShortTeamName = toShortTeamName;
|
|
51
|
+
/**
|
|
52
|
+
* Recursively looks up the CODEOWNER for a given file or directory path
|
|
53
|
+
* by reading your workspace's CODEOWNERS file.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} currentPath - Absolute path to the file/directory you're querying.
|
|
56
|
+
* @param {string} workspaceRoot - Absolute path to your repo/workspace root.
|
|
57
|
+
* @param {string} [codeownersFileName="TEAM_CODEOWNERS"] - Filename to read at the root.
|
|
58
|
+
* @returns {string|undefined} The owner handle or `undefined` if none found.
|
|
59
|
+
*/
|
|
60
|
+
const getCodeowner = (currentPath, workspaceRoot, codeownersFileName = "TEAM_CODEOWNERS") => {
|
|
61
|
+
if (!workspaceRoot) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
const codeownersPath = path_1.default.join(workspaceRoot, codeownersFileName);
|
|
65
|
+
if (!fs_1.default.existsSync(codeownersPath)) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const codeownersLines = fs_1.default.readFileSync(codeownersPath, "utf8").split("\n");
|
|
69
|
+
const codeowners = (0, exports.parseCodeowners)(codeownersLines);
|
|
70
|
+
let relPath = path_1.default
|
|
71
|
+
.relative(workspaceRoot, currentPath)
|
|
72
|
+
.replace(/\\/g, "/")
|
|
73
|
+
.replace(/^\/+|\/+$/g, "");
|
|
74
|
+
let parent = path_1.default.posix.dirname(relPath);
|
|
75
|
+
while (relPath !== parent) {
|
|
76
|
+
const codeowner = codeowners[relPath];
|
|
77
|
+
if (codeowner) {
|
|
78
|
+
return codeowner;
|
|
79
|
+
}
|
|
80
|
+
if (parent === ".") {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
relPath = parent;
|
|
84
|
+
parent = path_1.default.posix.dirname(relPath);
|
|
85
|
+
}
|
|
86
|
+
return codeowners["."];
|
|
87
|
+
};
|
|
88
|
+
exports.getCodeowner = getCodeowner;
|
|
89
|
+
//# sourceMappingURL=Codeowner.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes a string to be safe for use in filenames.
|
|
3
|
+
* Removes special characters and normalizes whitespace and hyphens.
|
|
4
|
+
*
|
|
5
|
+
* @param str - The string to sanitize (e.g., test suite or test name)
|
|
6
|
+
* @returns {string} Sanitized string safe for filesystem use
|
|
7
|
+
*/
|
|
8
|
+
export declare function sanitizeForFilename(str: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Builds a standardized filename for test artifacts (e.g., screenshots, traces).
|
|
11
|
+
* Combines test name, state, and attempt number into a readable filename.
|
|
12
|
+
*
|
|
13
|
+
* @param testName - The name of the test (will be sanitized)
|
|
14
|
+
* @param state - The test state (e.g., 'passed', 'failed')
|
|
15
|
+
* @param currentRetry - The current retry attempt number (0-based)
|
|
16
|
+
* @returns {string} A sanitized filename in the format: "testName (state) (attempt N)"
|
|
17
|
+
*/
|
|
18
|
+
export declare function fileNameBuilder(testName: string, state: string, currentRetry?: number): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitizeForFilename = sanitizeForFilename;
|
|
4
|
+
exports.fileNameBuilder = fileNameBuilder;
|
|
5
|
+
/**
|
|
6
|
+
* Sanitizes a string to be safe for use in filenames.
|
|
7
|
+
* Removes special characters and normalizes whitespace and hyphens.
|
|
8
|
+
*
|
|
9
|
+
* @param str - The string to sanitize (e.g., test suite or test name)
|
|
10
|
+
* @returns {string} Sanitized string safe for filesystem use
|
|
11
|
+
*/
|
|
12
|
+
function sanitizeForFilename(str) {
|
|
13
|
+
return str
|
|
14
|
+
.replace(/[^a-zA-Z0-9-_\s\[\]\(\)]/g, "")
|
|
15
|
+
.replace(/-+/g, "-")
|
|
16
|
+
.replace(/\s+/g, " ")
|
|
17
|
+
.replace(/^-|-$/g, "");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Builds a standardized filename for test artifacts (e.g., screenshots, traces).
|
|
21
|
+
* Combines test name, state, and attempt number into a readable filename.
|
|
22
|
+
*
|
|
23
|
+
* @param testName - The name of the test (will be sanitized)
|
|
24
|
+
* @param state - The test state (e.g., 'passed', 'failed')
|
|
25
|
+
* @param currentRetry - The current retry attempt number (0-based)
|
|
26
|
+
* @returns {string} A sanitized filename in the format: "testName (state) (attempt N)"
|
|
27
|
+
*/
|
|
28
|
+
function fileNameBuilder(testName, state, currentRetry) {
|
|
29
|
+
const fileName = `${testName} ${currentRetry !== undefined ? `(Attempt ${currentRetry + 1})` : ""} (${state.toLowerCase()})`;
|
|
30
|
+
return sanitizeForFilename(fileName);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=fileNameBuilder.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Tree } from "@nx/devkit";
|
|
2
|
+
/**
|
|
3
|
+
* Reads a file from an NX Tree, applies an updater function, and writes it back if changed.
|
|
4
|
+
*
|
|
5
|
+
* @param tree - File system tree
|
|
6
|
+
* @param path - Path to source file in the Tree
|
|
7
|
+
* @param updater - Function that maps the current file content to new content
|
|
8
|
+
*/
|
|
9
|
+
export declare const updateFileInTree: (tree: Tree, path: string, updater: (fileContent: string) => string) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Deletes a file from an NX Tree. No-op if the file does not exist.
|
|
12
|
+
*
|
|
13
|
+
* @param tree - File system tree
|
|
14
|
+
* @param path - Path to source file in the Tree
|
|
15
|
+
*/
|
|
16
|
+
export declare const deleteFileInTree: (tree: Tree, path: string) => void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteFileInTree = exports.updateFileInTree = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Reads a file from an NX Tree, applies an updater function, and writes it back if changed.
|
|
6
|
+
*
|
|
7
|
+
* @param tree - File system tree
|
|
8
|
+
* @param path - Path to source file in the Tree
|
|
9
|
+
* @param updater - Function that maps the current file content to new content
|
|
10
|
+
*/
|
|
11
|
+
const updateFileInTree = (tree, path, updater) => {
|
|
12
|
+
if (!tree.exists(path)) {
|
|
13
|
+
throw new Error("File not found: " + path);
|
|
14
|
+
}
|
|
15
|
+
const fileContent = tree.read(path, "utf-8");
|
|
16
|
+
if (!fileContent) {
|
|
17
|
+
throw new Error("File is empty: " + path);
|
|
18
|
+
}
|
|
19
|
+
const result = updater(fileContent);
|
|
20
|
+
if (result !== fileContent) {
|
|
21
|
+
tree.write(path, result);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
exports.updateFileInTree = updateFileInTree;
|
|
25
|
+
/**
|
|
26
|
+
* Deletes a file from an NX Tree. No-op if the file does not exist.
|
|
27
|
+
*
|
|
28
|
+
* @param tree - File system tree
|
|
29
|
+
* @param path - Path to source file in the Tree
|
|
30
|
+
*/
|
|
31
|
+
const deleteFileInTree = (tree, path) => {
|
|
32
|
+
if (!tree.exists(path)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
tree.delete(path);
|
|
36
|
+
};
|
|
37
|
+
exports.deleteFileInTree = deleteFileInTree;
|
|
38
|
+
//# sourceMappingURL=fileUpdater.js.map
|