@tracelane/cli 0.1.0-alpha.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/NOTICE +11 -0
- package/README.md +104 -0
- package/dist/commands/init.d.ts +44 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +383 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/detect.d.ts +59 -0
- package/dist/lib/detect.d.ts.map +1 -0
- package/dist/lib/detect.js +140 -0
- package/dist/lib/detect.js.map +1 -0
- package/dist/lib/gitignore.d.ts +17 -0
- package/dist/lib/gitignore.d.ts.map +1 -0
- package/dist/lib/gitignore.js +40 -0
- package/dist/lib/gitignore.js.map +1 -0
- package/dist/lib/prompt.d.ts +8 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +28 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/wdio-editor.d.ts +159 -0
- package/dist/lib/wdio-editor.d.ts.map +1 -0
- package/dist/lib/wdio-editor.js +508 -0
- package/dist/lib/wdio-editor.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +14 -0
- package/dist/version.js.map +1 -0
- package/package.json +42 -0
package/NOTICE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
rrweb-stack
|
|
2
|
+
Copyright 2026 Cubenest
|
|
3
|
+
|
|
4
|
+
@tracelane/cli — the `tracelane` scaffolding CLI. Detects the user's test runner
|
|
5
|
+
and wires @tracelane/wdio into wdio.conf.* in a single `npx tracelane init`
|
|
6
|
+
invocation. Pure Node; no third-party runtime dependencies (uses only
|
|
7
|
+
node:* primitives for argv parsing, file I/O, prompts, and the package-manager
|
|
8
|
+
install spawn).
|
|
9
|
+
|
|
10
|
+
This product is licensed under the Apache License, Version 2.0.
|
|
11
|
+
See the LICENSE file for details.
|
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# @tracelane/cli
|
|
2
|
+
|
|
3
|
+
> One command to wire tracelane into your WebdriverIO project. Detects your runner + package manager, installs `@tracelane/wdio`, edits `wdio.conf.ts`, creates `tracelane-reports/`, ignores it in git. Idempotent and dry-runnable.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@tracelane/cli)
|
|
6
|
+
[](https://www.npmjs.com/package/@tracelane/cli)
|
|
7
|
+
[](https://github.com/Cubenest/rrweb-stack/blob/main/LICENSE)
|
|
8
|
+
[](https://github.com/Cubenest/rrweb-stack/actions/workflows/ci.yml)
|
|
9
|
+
[](https://scorecard.dev/viewer/?uri=github.com/Cubenest/rrweb-stack)
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
cd your-wdio-project
|
|
13
|
+
npx tracelane init
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
That's it. `npx tracelane init` does four things:
|
|
17
|
+
|
|
18
|
+
1. Detects WebdriverIO from `wdio.conf.{ts,js,mjs,cjs}` and your package manager from your lockfile.
|
|
19
|
+
2. Runs the package manager's dev-add for `@tracelane/wdio` (`pnpm add -D` / `yarn add -D` / `npm install --save-dev` / `bun add -d`).
|
|
20
|
+
3. Edits `wdio.conf.ts` in place: adds the `TraceLaneService` import and inserts the service tuple into the `services:` array.
|
|
21
|
+
4. Creates `./tracelane-reports/` and appends `tracelane-reports/` to `.gitignore`.
|
|
22
|
+
|
|
23
|
+
Run your tests. On a failing Chrome test you get `./tracelane-reports/<spec>--<title>.html` — open it in any browser, replay the run with [rrweb-player](https://www.rrweb.io), inspect console + failed-network panels, attach to any bug tracker.
|
|
24
|
+
|
|
25
|
+
See the [@tracelane/wdio README](https://github.com/Cubenest/rrweb-stack/tree/main/packages/tracelane-wdio) for the full options reference.
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
npx tracelane init [options]
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
--runner <name> Force runner choice (wdio|playwright|cypress).
|
|
34
|
+
Default: auto-detected from project files.
|
|
35
|
+
--dry-run Print what would happen; change nothing.
|
|
36
|
+
--yes, -y Skip the "about to do X, Y, Z - continue?" prompt.
|
|
37
|
+
--skip-install Don't run the package-manager install command.
|
|
38
|
+
Useful if you have @tracelane/wdio already.
|
|
39
|
+
--help, -h Show usage.
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`--dry-run` prints exactly the steps the run would take (and the conf-edit preview) without modifying anything. Re-running `init` against an already-wired conf is a no-op (idempotent).
|
|
43
|
+
|
|
44
|
+
## What this is NOT
|
|
45
|
+
|
|
46
|
+
- Not a test runner. tracelane wires itself **into** WebdriverIO; you keep using `npx wdio run wdio.conf.ts` (or whatever runner you have today).
|
|
47
|
+
- Not a SaaS or cloud uploader. The artifact is a single HTML file on your filesystem.
|
|
48
|
+
- Not coupled to the GitHub repo. The CLI only reads + writes files in the directory you ran it from.
|
|
49
|
+
|
|
50
|
+
## Playwright and Cypress
|
|
51
|
+
|
|
52
|
+
Detection works, but the v0.1 CLI exits 0 with a "coming Q3/Q4 2026" message for these. The integration packages (`@tracelane/playwright`, `@tracelane/cypress`) aren't published yet — when they are, a future bump to `@tracelane/cli` will add the wiring. Track:
|
|
53
|
+
|
|
54
|
+
- Playwright: [issue #11](https://github.com/Cubenest/rrweb-stack/issues/11) — target Q3 2026
|
|
55
|
+
- Cypress: [issue #12](https://github.com/Cubenest/rrweb-stack/issues/12) — target Q4 2026
|
|
56
|
+
|
|
57
|
+
If you have a `wdio.conf.*` alongside a Playwright/Cypress conf, the WDIO path wins by default — pass `--runner playwright` or `--runner cypress` to override (it'll still print the coming-soon message).
|
|
58
|
+
|
|
59
|
+
## How the conf edit works (and what to do if it fails)
|
|
60
|
+
|
|
61
|
+
The editor uses string-based regex to:
|
|
62
|
+
|
|
63
|
+
1. Insert `import TraceLaneService from '@tracelane/wdio';` after the last existing `import` line.
|
|
64
|
+
2. Append `[TraceLaneService, { mode: 'failed' }]` as the LAST element of the `services:` array. Three shapes are recognized:
|
|
65
|
+
- `services: []` (empty)
|
|
66
|
+
- `services: ['devtools']` (string elements)
|
|
67
|
+
- `services: [['devtools', {}]]` (tuple elements, including multi-line)
|
|
68
|
+
3. If no `services:` key exists, insert one at the end of the config object literal.
|
|
69
|
+
|
|
70
|
+
If the regex doesn't recognize the conf shape (exotic formatting, dynamically constructed config, etc.) the editor **backs out cleanly** — your conf is NEVER corrupted — and prints the snippet to paste manually. The rest of `init` (install, reports dir, .gitignore) still runs.
|
|
71
|
+
|
|
72
|
+
A backup `wdio.conf.ts.tracelane-init.backup` is written before the edit; on success it's deleted. On the rare post-write sanity-check failure, the original is restored from the backup and the `.backup` is left next to your conf for one-shot inspection.
|
|
73
|
+
|
|
74
|
+
## Manual install path
|
|
75
|
+
|
|
76
|
+
If you prefer to wire by hand (e.g. CI scripts, custom configs):
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
npm install --save-dev @tracelane/wdio
|
|
80
|
+
mkdir -p tracelane-reports
|
|
81
|
+
echo "tracelane-reports/" >> .gitignore
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// wdio.conf.ts
|
|
86
|
+
import TraceLaneService from '@tracelane/wdio';
|
|
87
|
+
|
|
88
|
+
export const config = {
|
|
89
|
+
// ...your existing config
|
|
90
|
+
services: [[TraceLaneService, { mode: 'failed' }]],
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Both routes produce the same setup. The CLI exists to remove the "edit wdio.conf.ts" step from the README install instructions.
|
|
95
|
+
|
|
96
|
+
## Versioning + telemetry
|
|
97
|
+
|
|
98
|
+
Semantic Versioning. Currently `0.1.0-alpha.x` (pre-release; the API + flags may shift before `1.0.0`).
|
|
99
|
+
|
|
100
|
+
**No telemetry.** The CLI inspects local files only (lockfile presence, conf shape) and spawns the package-manager process you'd have run by hand. Nothing is sent anywhere.
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
Apache 2.0. Contributions accepted under the [Developer Certificate of Origin (DCO)](https://developercertificate.org/) — sign commits with `git commit -s`. See [CONTRIBUTING.md](https://github.com/Cubenest/rrweb-stack/blob/main/CONTRIBUTING.md) + [SECURITY.md](https://github.com/Cubenest/rrweb-stack/blob/main/SECURITY.md).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type SpawnSyncReturns } from 'node:child_process';
|
|
2
|
+
import { type Runner } from '../lib/detect.js';
|
|
3
|
+
/** Spawn-sync signature, narrowed to what we need + injectable for tests. */
|
|
4
|
+
export type SpawnRunner = (program: string, args: readonly string[], options: {
|
|
5
|
+
cwd: string;
|
|
6
|
+
stdio: 'inherit' | 'pipe';
|
|
7
|
+
env?: NodeJS.ProcessEnv;
|
|
8
|
+
}) => SpawnSyncReturns<Buffer>;
|
|
9
|
+
/** Options accepted by the testable `runInitProgrammatic` entrypoint. */
|
|
10
|
+
export interface InitOptions {
|
|
11
|
+
/** Project root the CLI was invoked in (process.cwd() for production). */
|
|
12
|
+
readonly cwd: string;
|
|
13
|
+
/** User-passed --runner override; undefined → auto-detect. */
|
|
14
|
+
readonly runner?: Runner | undefined;
|
|
15
|
+
/** --dry-run: print but don't modify anything. */
|
|
16
|
+
readonly dryRun?: boolean;
|
|
17
|
+
/** --yes: skip the confirmation prompt. */
|
|
18
|
+
readonly yes?: boolean;
|
|
19
|
+
/** --skip-install: don't run the package-manager install. */
|
|
20
|
+
readonly skipInstall?: boolean;
|
|
21
|
+
/** Where to write stdout (defaults to process.stdout). */
|
|
22
|
+
readonly stdout?: NodeJS.WritableStream;
|
|
23
|
+
/** Where to write stderr (defaults to process.stderr). */
|
|
24
|
+
readonly stderr?: NodeJS.WritableStream;
|
|
25
|
+
/** Override the spawn function (tests stub this so we don't hit npm). */
|
|
26
|
+
readonly spawn?: SpawnRunner;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The pure-ish programmatic entrypoint. Tests call this directly with a
|
|
30
|
+
* fake cwd + fake spawn; the bin shell calls `runInit(argv)` which forwards
|
|
31
|
+
* to here with process.cwd() + the real spawn.
|
|
32
|
+
*
|
|
33
|
+
* Returns the process exit code (0 = success / coming-soon, 1 = nothing
|
|
34
|
+
* matched or a hard error).
|
|
35
|
+
*/
|
|
36
|
+
export declare function runInitProgrammatic(opts: InitOptions): Promise<number>;
|
|
37
|
+
/** Help text for `tracelane init --help`. */
|
|
38
|
+
export declare const INIT_HELP = "tracelane init - wire @tracelane/wdio into the project in this directory.\n\nUsage: npx tracelane init [options]\n\nOptions:\n --runner <name> Force runner choice (wdio|playwright|cypress).\n Default: auto-detected from project files.\n --dry-run Print what would happen; change nothing.\n --yes, -y Skip the \"about to do X, Y, Z - continue?\" prompt.\n --skip-install Don't run the package-manager install command.\n Useful if you have @tracelane/wdio already.\n --help, -h Show this help.\n\nThe CLI scans the current working directory for a wdio.conf.{ts,js,mjs,cjs},\nadds @tracelane/wdio as a devDependency via the detected package manager\n(pnpm/yarn/npm/bun), inserts the import + service tuple into the conf, creates\n./tracelane-reports/, and appends to .gitignore. Idempotent: re-running on an\nalready-wired project is a no-op.\n\nAuto-edit limitation: the conf editor uses string regex to insert into the\nservices array. If it can't recognise the array shape it BACKS OUT cleanly\nand prints the snippet to paste manually - it will NEVER corrupt your conf.\n";
|
|
39
|
+
/**
|
|
40
|
+
* Argv entry for `tracelane init`. Parses flags via node:util.parseArgs and
|
|
41
|
+
* delegates to runInitProgrammatic.
|
|
42
|
+
*/
|
|
43
|
+
export declare function runInit(argv: readonly string[]): Promise<number>;
|
|
44
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,gBAAgB,EAAa,MAAM,oBAAoB,CAAC;AAWtE,OAAO,EAGL,KAAK,MAAM,EAKZ,MAAM,kBAAkB,CAAC;AAa1B,6EAA6E;AAC7E,MAAM,MAAM,WAAW,GAAG,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,KACzE,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAK9B,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACxC,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;CAC9B;AAkFD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA+L5E;AAuFD,6CAA6C;AAC7C,eAAO,MAAM,SAAS,ipCAsBrB,CAAC;AAEF;;;GAGG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDtE"}
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
// `tracelane init` — the wedge amplifier. One npx invocation replaces the
|
|
2
|
+
// previous "npm install + manually edit wdio.conf.ts" two-step.
|
|
3
|
+
//
|
|
4
|
+
// Steps:
|
|
5
|
+
// 1. Detect runner (or honour --runner) in process.cwd().
|
|
6
|
+
// 2. Detect package manager from lockfile presence.
|
|
7
|
+
// 3. For WDIO: ask, then install @tracelane/wdio + edit conf + mkdir
|
|
8
|
+
// ./tracelane-reports/ + append to .gitignore.
|
|
9
|
+
// 4. For Playwright/Cypress: print "support coming Q3/Q4 2026" + a tracking
|
|
10
|
+
// issue link, install nothing, exit 0.
|
|
11
|
+
//
|
|
12
|
+
// Side effects (mkdirSync, writeFileSync, the package-manager spawn) are
|
|
13
|
+
// gated behind --dry-run and an interactive confirm prompt (suppressed by
|
|
14
|
+
// --yes). The package-manager spawn is injectable so tests don't hit the
|
|
15
|
+
// real npm registry.
|
|
16
|
+
import { spawnSync } from 'node:child_process';
|
|
17
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from 'node:fs';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import { parseArgs } from 'node:util';
|
|
20
|
+
import { detectPackageManager, detectRunner, findRunnerConfig, installCommand, } from '../lib/detect.js';
|
|
21
|
+
import { hasTracelaneEntry, mergeGitignore } from '../lib/gitignore.js';
|
|
22
|
+
import { confirm } from '../lib/prompt.js';
|
|
23
|
+
import { MANUAL_SNIPPET, applyWdioEdit } from '../lib/wdio-editor.js';
|
|
24
|
+
/** Tracking-issue URLs for the not-yet-shipped Playwright/Cypress paths. */
|
|
25
|
+
// NOTE for maintainer: these issue numbers don't have to exist on day one —
|
|
26
|
+
// `tracelane init` is exiting 0 either way. File them before announcement so
|
|
27
|
+
// the URL resolves to a real tracking issue instead of a 404. (#11 = Playwright,
|
|
28
|
+
// #12 = Cypress per the wedge-amplifier spec.)
|
|
29
|
+
const PLAYWRIGHT_ISSUE = 'https://github.com/Cubenest/rrweb-stack/issues/11';
|
|
30
|
+
const CYPRESS_ISSUE = 'https://github.com/Cubenest/rrweb-stack/issues/12';
|
|
31
|
+
const realSpawn = (program, args, options) => spawnSync(program, args, options);
|
|
32
|
+
/** Wrap process.stdout.write so we can swap in a fake in tests. */
|
|
33
|
+
function write(s, msg) {
|
|
34
|
+
(s ?? process.stdout).write(msg);
|
|
35
|
+
}
|
|
36
|
+
/** Stderr variant. */
|
|
37
|
+
function writeErr(s, msg) {
|
|
38
|
+
(s ?? process.stderr).write(msg);
|
|
39
|
+
}
|
|
40
|
+
/** Pretty-print the package-manager install command for the user. */
|
|
41
|
+
function commandString(cmd) {
|
|
42
|
+
return cmd.join(' ');
|
|
43
|
+
}
|
|
44
|
+
function describeSteps(detected, pm, options) {
|
|
45
|
+
const steps = [];
|
|
46
|
+
let i = 1;
|
|
47
|
+
if (!options.skipInstall) {
|
|
48
|
+
steps.push({
|
|
49
|
+
index: i++,
|
|
50
|
+
description: commandString(installCommand(pm.manager)),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
steps.push({
|
|
54
|
+
index: i++,
|
|
55
|
+
description: `Edit ${basename(detected.configPath)} to register the Service`,
|
|
56
|
+
});
|
|
57
|
+
steps.push({ index: i++, description: 'Create ./tracelane-reports/' });
|
|
58
|
+
steps.push({
|
|
59
|
+
index: i++,
|
|
60
|
+
description: options.gitignoreExists
|
|
61
|
+
? 'Append tracelane-reports/ to .gitignore'
|
|
62
|
+
: 'Create .gitignore with tracelane-reports/',
|
|
63
|
+
});
|
|
64
|
+
return steps;
|
|
65
|
+
}
|
|
66
|
+
/** node:path.basename without the import — we only need it for log lines. */
|
|
67
|
+
function basename(p) {
|
|
68
|
+
return p.split(/[/\\]/).pop() ?? p;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Print the not-yet-supported message for Playwright / Cypress. Exits 0
|
|
72
|
+
* (no error — the user has a valid project, we just don't have wiring yet).
|
|
73
|
+
*/
|
|
74
|
+
function printComingSoon(detected, stdout) {
|
|
75
|
+
const runnerLabel = detected.runner === 'playwright' ? 'Playwright' : 'Cypress';
|
|
76
|
+
const target = detected.runner === 'playwright' ? 'Q3 2026' : 'Q4 2026';
|
|
77
|
+
const issue = detected.runner === 'playwright' ? PLAYWRIGHT_ISSUE : CYPRESS_ISSUE;
|
|
78
|
+
write(stdout, [
|
|
79
|
+
`tracelane init - detected ${runnerLabel} project (${basename(detected.configPath)}).`,
|
|
80
|
+
'',
|
|
81
|
+
`tracelane ${runnerLabel} support is in development; target ship ${target}.`,
|
|
82
|
+
`Track: ${issue}`,
|
|
83
|
+
'',
|
|
84
|
+
'To use tracelane today, add a WebdriverIO suite, or pass --runner wdio',
|
|
85
|
+
'if your project already has a wdio.conf.*.',
|
|
86
|
+
'',
|
|
87
|
+
].join('\n'));
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The pure-ish programmatic entrypoint. Tests call this directly with a
|
|
92
|
+
* fake cwd + fake spawn; the bin shell calls `runInit(argv)` which forwards
|
|
93
|
+
* to here with process.cwd() + the real spawn.
|
|
94
|
+
*
|
|
95
|
+
* Returns the process exit code (0 = success / coming-soon, 1 = nothing
|
|
96
|
+
* matched or a hard error).
|
|
97
|
+
*/
|
|
98
|
+
export async function runInitProgrammatic(opts) {
|
|
99
|
+
const stdout = opts.stdout;
|
|
100
|
+
const stderr = opts.stderr;
|
|
101
|
+
const spawn = opts.spawn ?? realSpawn;
|
|
102
|
+
const cwd = opts.cwd;
|
|
103
|
+
// ---- Runner resolution -------------------------------------------------
|
|
104
|
+
let detected;
|
|
105
|
+
if (opts.runner !== undefined) {
|
|
106
|
+
// --runner forces the choice; we still try to find a config file so the
|
|
107
|
+
// editor has something to point at.
|
|
108
|
+
const configPath = findRunnerConfig(cwd, opts.runner);
|
|
109
|
+
if (configPath === undefined) {
|
|
110
|
+
// For WDIO we need a config file. For Playwright/Cypress the no-op
|
|
111
|
+
// print doesn't strictly need one — but the user asked us to pretend,
|
|
112
|
+
// so be explicit.
|
|
113
|
+
writeErr(stderr, `tracelane init: --runner ${opts.runner} was passed, but no matching config file found in ${cwd}.\n`);
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
detected = { runner: opts.runner, configPath };
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
detected = detectRunner(cwd);
|
|
120
|
+
if (detected === undefined) {
|
|
121
|
+
writeErr(stderr, `tracelane init: No supported test runner detected in ${cwd}. Run from your project root, or pass \`--runner wdio\` explicitly.\n`);
|
|
122
|
+
return 1;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// ---- Runner-specific routing ------------------------------------------
|
|
126
|
+
if (detected.runner !== 'wdio') {
|
|
127
|
+
return printComingSoon(detected, stdout);
|
|
128
|
+
}
|
|
129
|
+
// ---- WDIO happy path --------------------------------------------------
|
|
130
|
+
const pm = detectPackageManager(cwd);
|
|
131
|
+
const gitignorePath = join(cwd, '.gitignore');
|
|
132
|
+
const gitignoreExists = existsSync(gitignorePath);
|
|
133
|
+
const skipInstall = opts.skipInstall ?? false;
|
|
134
|
+
write(stdout, `tracelane init - detected WebdriverIO project (${basename(detected.configPath)}) using ${pm.manager}.\n\n`);
|
|
135
|
+
if (pm.multipleLockfiles) {
|
|
136
|
+
write(stdout, `Note: multiple lockfiles detected (${pm.lockfilesFound.join(', ')}); using ${pm.manager}.\n\n`);
|
|
137
|
+
}
|
|
138
|
+
if (pm.fallback) {
|
|
139
|
+
write(stdout, 'Note: no lockfile detected; defaulting to npm.\n\n');
|
|
140
|
+
}
|
|
141
|
+
const steps = describeSteps(detected, pm, { skipInstall, gitignoreExists });
|
|
142
|
+
write(stdout, opts.dryRun ? 'DRY RUN — would do:\n' : 'About to:\n');
|
|
143
|
+
for (const s of steps) {
|
|
144
|
+
write(stdout, ` ${s.index}. ${opts.dryRun ? 'WOULD: ' : ''}${s.description}\n`);
|
|
145
|
+
}
|
|
146
|
+
write(stdout, '\n');
|
|
147
|
+
if (opts.dryRun) {
|
|
148
|
+
// Show the conf-edit preview without writing.
|
|
149
|
+
const preview = previewConfEdit(detected.configPath);
|
|
150
|
+
if (preview !== undefined)
|
|
151
|
+
write(stdout, preview);
|
|
152
|
+
write(stdout, 'Dry run complete; no files changed.\n');
|
|
153
|
+
return 0;
|
|
154
|
+
}
|
|
155
|
+
if (!opts.yes) {
|
|
156
|
+
const proceed = await confirm('Continue?', true);
|
|
157
|
+
if (!proceed) {
|
|
158
|
+
write(stdout, 'Aborted.\n');
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ---- Execute the steps ------------------------------------------------
|
|
163
|
+
if (!skipInstall) {
|
|
164
|
+
const cmd = installCommand(pm.manager);
|
|
165
|
+
const [program, ...args] = cmd;
|
|
166
|
+
if (program === undefined) {
|
|
167
|
+
writeErr(stderr, 'tracelane init: empty install command (internal error).\n');
|
|
168
|
+
return 1;
|
|
169
|
+
}
|
|
170
|
+
write(stdout, `Running: ${commandString(cmd)}\n`);
|
|
171
|
+
const result = spawn(program, args, { cwd, stdio: 'inherit' });
|
|
172
|
+
if (result.error) {
|
|
173
|
+
writeErr(stderr, `tracelane init: install failed to launch: ${result.error.message}\n`);
|
|
174
|
+
return 1;
|
|
175
|
+
}
|
|
176
|
+
if (result.status !== 0) {
|
|
177
|
+
writeErr(stderr, `tracelane init: install exited with code ${result.status}. Re-run with --skip-install once you've added @tracelane/wdio manually.\n`);
|
|
178
|
+
return 1;
|
|
179
|
+
}
|
|
180
|
+
write(stdout, '\n');
|
|
181
|
+
}
|
|
182
|
+
// Edit the wdio.conf.* in place. Back-out path keeps a one-shot .backup
|
|
183
|
+
// next to the conf so the user can restore on their own if anything
|
|
184
|
+
// looks wrong after the run.
|
|
185
|
+
const editOutcome = editWdioConfOnDisk(detected.configPath);
|
|
186
|
+
if (editOutcome.kind === 'manual') {
|
|
187
|
+
write(stdout, [
|
|
188
|
+
`! Could not auto-edit ${basename(detected.configPath)}: ${editOutcome.reason}`,
|
|
189
|
+
' Paste the following into your conf manually:',
|
|
190
|
+
'',
|
|
191
|
+
...editOutcome.snippet.split('\n').map((l) => ` ${l}`),
|
|
192
|
+
'',
|
|
193
|
+
' The rest of init (reports dir + .gitignore) still ran.',
|
|
194
|
+
'',
|
|
195
|
+
].join('\n'));
|
|
196
|
+
}
|
|
197
|
+
else if (editOutcome.kind === 'restored') {
|
|
198
|
+
write(stdout, [
|
|
199
|
+
`! Auto-edit of ${basename(detected.configPath)} failed sanity check; original restored.`,
|
|
200
|
+
` Backup kept at ${basename(editOutcome.backupPath)} for one-shot recovery.`,
|
|
201
|
+
' Paste the following manually:',
|
|
202
|
+
'',
|
|
203
|
+
...editOutcome.snippet.split('\n').map((l) => ` ${l}`),
|
|
204
|
+
'',
|
|
205
|
+
].join('\n'));
|
|
206
|
+
}
|
|
207
|
+
else if (editOutcome.kind === 'alreadyConfigured') {
|
|
208
|
+
write(stdout, `* ${basename(detected.configPath)} already wires TraceLaneService; left it alone.\n`);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
write(stdout, `+ Edited ${basename(detected.configPath)}.\n`);
|
|
212
|
+
}
|
|
213
|
+
// mkdir is idempotent with `recursive: true`.
|
|
214
|
+
const reportsDir = join(cwd, 'tracelane-reports');
|
|
215
|
+
mkdirSync(reportsDir, { recursive: true });
|
|
216
|
+
write(stdout, '+ Created ./tracelane-reports/\n');
|
|
217
|
+
// .gitignore: read-modify-write iff our entry isn't already there.
|
|
218
|
+
let gitignoreExisting = '';
|
|
219
|
+
if (existsSync(gitignorePath)) {
|
|
220
|
+
gitignoreExisting = readFileSync(gitignorePath, 'utf8');
|
|
221
|
+
}
|
|
222
|
+
if (hasTracelaneEntry(gitignoreExisting)) {
|
|
223
|
+
write(stdout, '* .gitignore already lists tracelane-reports/; left it alone.\n');
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
const merged = mergeGitignore(gitignoreExisting);
|
|
227
|
+
writeFileSync(gitignorePath, merged, 'utf8');
|
|
228
|
+
write(stdout, gitignoreExisting.length === 0
|
|
229
|
+
? '+ Created .gitignore with tracelane-reports/\n'
|
|
230
|
+
: '+ Appended tracelane-reports/ to .gitignore\n');
|
|
231
|
+
}
|
|
232
|
+
// Final message — the "next: " call to action. Include a literal,
|
|
233
|
+
// copy-paste-ready command so the user knows exactly what to run, with
|
|
234
|
+
// the conf filename matching what we detected (handles .js/.mjs/.cjs).
|
|
235
|
+
const ok = process.stdout.isTTY ? '✔' : 'OK';
|
|
236
|
+
write(stdout, [
|
|
237
|
+
'',
|
|
238
|
+
`${ok} done.`,
|
|
239
|
+
`Run: npx wdio run ${basename(detected.configPath)}`,
|
|
240
|
+
'On a failing Chrome test you get',
|
|
241
|
+
'./tracelane-reports/<spec>--<title>.html — open it in any browser.',
|
|
242
|
+
'',
|
|
243
|
+
'Docs: https://github.com/Cubenest/rrweb-stack/tree/main/packages/tracelane-wdio',
|
|
244
|
+
'',
|
|
245
|
+
].join('\n'));
|
|
246
|
+
return 0;
|
|
247
|
+
}
|
|
248
|
+
function editWdioConfOnDisk(configPath) {
|
|
249
|
+
const original = readFileSync(configPath, 'utf8');
|
|
250
|
+
const result = applyWdioEdit(original);
|
|
251
|
+
if (!result.ok) {
|
|
252
|
+
// Pure-function back-out: the editor never touched anything; just report.
|
|
253
|
+
return { kind: 'manual', reason: result.reason, snippet: result.manualSnippet };
|
|
254
|
+
}
|
|
255
|
+
if (result.alreadyConfigured) {
|
|
256
|
+
return { kind: 'alreadyConfigured' };
|
|
257
|
+
}
|
|
258
|
+
// Belt-and-braces: persist the original to a .backup before overwriting,
|
|
259
|
+
// then sanity-check what we wrote by reading it back. If the read-back
|
|
260
|
+
// doesn't match what we expected, restore.
|
|
261
|
+
const backupPath = `${configPath}.tracelane-init.backup`;
|
|
262
|
+
writeFileSync(backupPath, original, 'utf8');
|
|
263
|
+
writeFileSync(configPath, result.source, 'utf8');
|
|
264
|
+
const verifyContent = readFileSync(configPath, 'utf8');
|
|
265
|
+
if (verifyContent !== result.source) {
|
|
266
|
+
// Disk corruption is exceedingly unlikely but we'd rather catch it.
|
|
267
|
+
renameSync(backupPath, configPath);
|
|
268
|
+
return {
|
|
269
|
+
kind: 'restored',
|
|
270
|
+
reason: 'post-write read-back did not match expected content',
|
|
271
|
+
// Single source of truth — defined alongside the editor's back-out
|
|
272
|
+
// path so the snippet copy can't drift.
|
|
273
|
+
snippet: MANUAL_SNIPPET,
|
|
274
|
+
backupPath,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
// Edit succeeded; clean up the backup since the live file is good.
|
|
278
|
+
try {
|
|
279
|
+
unlinkSync(backupPath);
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
// Non-fatal; the leftover .backup is harmless.
|
|
283
|
+
}
|
|
284
|
+
return { kind: 'edited' };
|
|
285
|
+
}
|
|
286
|
+
/** Build the WOULD-BE diff preview shown by --dry-run. */
|
|
287
|
+
function previewConfEdit(configPath) {
|
|
288
|
+
let original;
|
|
289
|
+
try {
|
|
290
|
+
original = readFileSync(configPath, 'utf8');
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
const result = applyWdioEdit(original);
|
|
296
|
+
if (!result.ok) {
|
|
297
|
+
return `Would back out of conf edit: ${result.reason}\n Manual snippet:\n${result.manualSnippet
|
|
298
|
+
.split('\n')
|
|
299
|
+
.map((l) => ` ${l}`)
|
|
300
|
+
.join('\n')}\n\n`;
|
|
301
|
+
}
|
|
302
|
+
if (result.alreadyConfigured) {
|
|
303
|
+
return `Would leave ${basename(configPath)} alone (already wires TraceLaneService).\n\n`;
|
|
304
|
+
}
|
|
305
|
+
// Show a compact summary of what would change instead of a full diff —
|
|
306
|
+
// the byte delta is small and the user can diff themselves if they want.
|
|
307
|
+
const importLine = result.addedImport
|
|
308
|
+
? "+ import TraceLaneService from '@tracelane/wdio';\n"
|
|
309
|
+
: '';
|
|
310
|
+
const entryLine = result.addedServiceEntry
|
|
311
|
+
? "+ services: [..., [TraceLaneService, { mode: 'failed' }]]\n"
|
|
312
|
+
: '';
|
|
313
|
+
return `Conf edit preview (${basename(configPath)}):\n${importLine}${entryLine}\n`;
|
|
314
|
+
}
|
|
315
|
+
/** Help text for `tracelane init --help`. */
|
|
316
|
+
export const INIT_HELP = `tracelane init - wire @tracelane/wdio into the project in this directory.
|
|
317
|
+
|
|
318
|
+
Usage: npx tracelane init [options]
|
|
319
|
+
|
|
320
|
+
Options:
|
|
321
|
+
--runner <name> Force runner choice (wdio|playwright|cypress).
|
|
322
|
+
Default: auto-detected from project files.
|
|
323
|
+
--dry-run Print what would happen; change nothing.
|
|
324
|
+
--yes, -y Skip the "about to do X, Y, Z - continue?" prompt.
|
|
325
|
+
--skip-install Don't run the package-manager install command.
|
|
326
|
+
Useful if you have @tracelane/wdio already.
|
|
327
|
+
--help, -h Show this help.
|
|
328
|
+
|
|
329
|
+
The CLI scans the current working directory for a wdio.conf.{ts,js,mjs,cjs},
|
|
330
|
+
adds @tracelane/wdio as a devDependency via the detected package manager
|
|
331
|
+
(pnpm/yarn/npm/bun), inserts the import + service tuple into the conf, creates
|
|
332
|
+
./tracelane-reports/, and appends to .gitignore. Idempotent: re-running on an
|
|
333
|
+
already-wired project is a no-op.
|
|
334
|
+
|
|
335
|
+
Auto-edit limitation: the conf editor uses string regex to insert into the
|
|
336
|
+
services array. If it can't recognise the array shape it BACKS OUT cleanly
|
|
337
|
+
and prints the snippet to paste manually - it will NEVER corrupt your conf.
|
|
338
|
+
`;
|
|
339
|
+
/**
|
|
340
|
+
* Argv entry for `tracelane init`. Parses flags via node:util.parseArgs and
|
|
341
|
+
* delegates to runInitProgrammatic.
|
|
342
|
+
*/
|
|
343
|
+
export async function runInit(argv) {
|
|
344
|
+
let parsed;
|
|
345
|
+
try {
|
|
346
|
+
parsed = parseArgs({
|
|
347
|
+
args: [...argv],
|
|
348
|
+
options: {
|
|
349
|
+
runner: { type: 'string' },
|
|
350
|
+
'dry-run': { type: 'boolean' },
|
|
351
|
+
yes: { type: 'boolean', short: 'y' },
|
|
352
|
+
'skip-install': { type: 'boolean' },
|
|
353
|
+
help: { type: 'boolean', short: 'h' },
|
|
354
|
+
},
|
|
355
|
+
allowPositionals: false,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
process.stderr.write(`tracelane init: ${err instanceof Error ? err.message : String(err)}\n\n${INIT_HELP}`);
|
|
360
|
+
return 1;
|
|
361
|
+
}
|
|
362
|
+
if (parsed.values.help) {
|
|
363
|
+
process.stdout.write(INIT_HELP);
|
|
364
|
+
return 0;
|
|
365
|
+
}
|
|
366
|
+
const rawRunner = parsed.values.runner;
|
|
367
|
+
let runner;
|
|
368
|
+
if (rawRunner !== undefined) {
|
|
369
|
+
if (rawRunner !== 'wdio' && rawRunner !== 'playwright' && rawRunner !== 'cypress') {
|
|
370
|
+
process.stderr.write(`tracelane init: --runner must be one of wdio|playwright|cypress (got '${rawRunner}').\n`);
|
|
371
|
+
return 1;
|
|
372
|
+
}
|
|
373
|
+
runner = rawRunner;
|
|
374
|
+
}
|
|
375
|
+
return runInitProgrammatic({
|
|
376
|
+
cwd: process.cwd(),
|
|
377
|
+
runner,
|
|
378
|
+
dryRun: parsed.values['dry-run'] ?? false,
|
|
379
|
+
yes: parsed.values.yes ?? false,
|
|
380
|
+
skipInstall: parsed.values['skip-install'] ?? false,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAYA,OAAO,EAAE,SAAS,EAAW,MAAM,oBAAoB,CAAC;AAexD,wBAAsB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BlE;AAED,uDAAuD;AACvD,OAAO,EAAE,SAAS,EAAE,CAAC"}
|