@e2edev/e2e 0.3.0 → 0.4.0
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 +32 -3
- package/dist/agent/act.d.ts.map +1 -1
- package/dist/agent/act.js +38 -46
- package/dist/agent/act.js.map +1 -1
- package/dist/agent/default-agent.d.ts.map +1 -1
- package/dist/agent/default-agent.js +10 -23
- package/dist/agent/default-agent.js.map +1 -1
- package/dist/agent/executor.d.ts +6 -0
- package/dist/agent/executor.d.ts.map +1 -1
- package/dist/agent/executor.js.map +1 -1
- package/dist/agent/invocation.d.ts +1 -6
- package/dist/agent/invocation.d.ts.map +1 -1
- package/dist/agent/invocation.js +4 -30
- package/dist/agent/invocation.js.map +1 -1
- package/dist/agent/observation.d.ts +2 -0
- package/dist/agent/observation.d.ts.map +1 -1
- package/dist/agent/observation.js +1 -0
- package/dist/agent/observation.js.map +1 -1
- package/dist/agent/public.d.ts +1 -1
- package/dist/agent/public.d.ts.map +1 -1
- package/dist/agent/public.js +1 -1
- package/dist/agent/public.js.map +1 -1
- package/dist/agent/step-cache.d.ts +2 -2
- package/dist/agent/step-cache.d.ts.map +1 -1
- package/dist/agent/step-cache.js +2 -2
- package/dist/agent/step-cache.js.map +1 -1
- package/dist/agent/tool.d.ts +11 -16
- package/dist/agent/tool.d.ts.map +1 -1
- package/dist/agent/tool.js +19 -13
- package/dist/agent/tool.js.map +1 -1
- package/dist/agent/usage.d.ts +27 -0
- package/dist/agent/usage.d.ts.map +1 -0
- package/dist/agent/usage.js +54 -0
- package/dist/agent/usage.js.map +1 -0
- package/dist/backend/index.d.ts +22 -5
- package/dist/backend/index.d.ts.map +1 -1
- package/dist/backend/index.js +2 -1
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/session.d.ts.map +1 -1
- package/dist/backend/session.js +1 -0
- package/dist/backend/session.js.map +1 -1
- package/dist/backend/surface.d.ts +2 -0
- package/dist/backend/surface.d.ts.map +1 -1
- package/dist/backend/timing.d.ts +3 -0
- package/dist/backend/timing.d.ts.map +1 -0
- package/dist/backend/timing.js +8 -0
- package/dist/backend/timing.js.map +1 -0
- package/dist/cli/index.js +4 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/backends.d.ts +75 -0
- package/dist/cli/init/backends.d.ts.map +1 -0
- package/dist/cli/init/backends.js +98 -0
- package/dist/cli/init/backends.js.map +1 -0
- package/dist/cli/init/package.d.ts +43 -0
- package/dist/cli/init/package.d.ts.map +1 -0
- package/dist/cli/init/package.js +64 -0
- package/dist/cli/init/package.js.map +1 -0
- package/dist/cli/init/scaffold.d.ts +12 -0
- package/dist/cli/init/scaffold.d.ts.map +1 -0
- package/dist/cli/init/scaffold.js +36 -0
- package/dist/cli/init/scaffold.js.map +1 -0
- package/dist/cli/init.d.ts +8 -3
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +98 -94
- package/dist/cli/init.js.map +1 -1
- package/dist/config/app.d.ts +50 -0
- package/dist/config/app.d.ts.map +1 -0
- package/dist/config/app.js +168 -0
- package/dist/config/app.js.map +1 -0
- package/dist/config/esm.d.ts +4 -0
- package/dist/config/esm.d.ts.map +1 -0
- package/dist/config/esm.js +35 -0
- package/dist/config/esm.js.map +1 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +4 -0
- package/dist/config/load.js.map +1 -1
- package/dist/config/resolve.d.ts +6 -15
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +18 -100
- package/dist/config/resolve.js.map +1 -1
- package/dist/config/validate.d.ts +3 -1
- package/dist/config/validate.d.ts.map +1 -1
- package/dist/config/validate.js +17 -1
- package/dist/config/validate.js.map +1 -1
- package/dist/internal/time.d.ts +6 -1
- package/dist/internal/time.d.ts.map +1 -1
- package/dist/internal/time.js +25 -2
- package/dist/internal/time.js.map +1 -1
- package/dist/report/build.js +2 -2
- package/dist/report/build.js.map +1 -1
- package/dist/report/junit.d.ts +11 -0
- package/dist/report/junit.d.ts.map +1 -0
- package/dist/report/junit.js +202 -0
- package/dist/report/junit.js.map +1 -0
- package/dist/report/list.d.ts.map +1 -1
- package/dist/report/list.js +3 -0
- package/dist/report/list.js.map +1 -1
- package/dist/report/write.d.ts +2 -0
- package/dist/report/write.d.ts.map +1 -1
- package/dist/report/write.js +7 -3
- package/dist/report/write.js.map +1 -1
- package/dist/run/events.d.ts +2 -0
- package/dist/run/events.d.ts.map +1 -1
- package/dist/run/events.js.map +1 -1
- package/dist/run/fixture-legacy.d.ts +36 -0
- package/dist/run/fixture-legacy.d.ts.map +1 -0
- package/dist/run/fixture-legacy.js +143 -0
- package/dist/run/fixture-legacy.js.map +1 -0
- package/dist/run/fixture-recording.d.ts +15 -0
- package/dist/run/fixture-recording.d.ts.map +1 -0
- package/dist/run/fixture-recording.js +75 -0
- package/dist/run/fixture-recording.js.map +1 -0
- package/dist/run/fixtures.d.ts.map +1 -1
- package/dist/run/fixtures.js +26 -162
- package/dist/run/fixtures.js.map +1 -1
- package/dist/run/managed-process.d.ts +49 -0
- package/dist/run/managed-process.d.ts.map +1 -0
- package/dist/run/managed-process.js +202 -0
- package/dist/run/managed-process.js.map +1 -0
- package/dist/run/runner.d.ts +3 -1
- package/dist/run/runner.d.ts.map +1 -1
- package/dist/run/runner.js +62 -12
- package/dist/run/runner.js.map +1 -1
- package/dist/run/steps.d.ts +1 -1
- package/dist/run/steps.d.ts.map +1 -1
- package/dist/run/steps.js +12 -9
- package/dist/run/steps.js.map +1 -1
- package/dist/types.d.ts +33 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/run/app-process.d.ts +0 -18
- package/dist/run/app-process.d.ts.map +0 -1
- package/dist/run/app-process.js +0 -112
- package/dist/run/app-process.js.map +0 -1
package/dist/cli/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,4DAA4D;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAW5D,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAYD;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsGlF"}
|
package/dist/cli/init.js
CHANGED
|
@@ -1,124 +1,128 @@
|
|
|
1
1
|
/** Non-destructive project scaffolding (spec 06-cli.md). */
|
|
2
|
+
import * as clack from '@clack/prompts';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
2
4
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
5
|
import path from 'node:path';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
export default defineConfig({
|
|
10
|
-
// A scheme is optional: localhost gets http://, any other host gets https://.
|
|
11
|
-
app: { url: 'localhost:3000' },
|
|
12
|
-
// The built-in agent; its model comes from E2E_MODEL. Shape it with system,
|
|
13
|
-
// hand it tools, or pass any StepExecutor of your own instead.
|
|
14
|
-
agent: createAgent({
|
|
15
|
-
system: 'You are a thorough QA agent. Verify every outcome on screen.',
|
|
16
|
-
}),
|
|
17
|
-
// The runner knows no platform: every target names the backend that drives it.
|
|
18
|
-
targets: [{ name: 'web', platform: 'web', backend: playwright() }],
|
|
19
|
-
});
|
|
20
|
-
`;
|
|
21
|
-
/** The AI SDK is an optional peer; the scaffolded agent cannot run without it. */
|
|
22
|
-
const AGENT_PEER = 'ai';
|
|
23
|
-
const EXAMPLE_TEMPLATE = `import { test } from '@e2edev/playwright';
|
|
24
|
-
import { expect } from '@e2edev/e2e';
|
|
25
|
-
|
|
26
|
-
test('app opens', async ({ app, web }) => {
|
|
27
|
-
await app.open();
|
|
28
|
-
await expect(web).toHaveURL('/');
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// Runs when E2E_MODEL and E2E_MODEL_API_KEY are set:
|
|
32
|
-
// test('the agent drives a flow', async ({ app, agent }) => {
|
|
33
|
-
// await app.open();
|
|
34
|
-
// await agent.act('one goal in plain language');
|
|
35
|
-
// await agent.assert('one question about the screen');
|
|
36
|
-
// });
|
|
37
|
-
`;
|
|
6
|
+
import { esmPackageHint } from '../config/esm.js';
|
|
7
|
+
import { getBackendPresets, DEFAULT_BACKEND_ID } from './init/backends.js';
|
|
8
|
+
import { addDependencies, detectPackageManager, readPackage, serializePackage } from './init/package.js';
|
|
9
|
+
import { createScaffold } from './init/scaffold.js';
|
|
38
10
|
const GITIGNORE_ENTRIES = [
|
|
11
|
+
'node_modules/',
|
|
39
12
|
'.e2e/artifacts/',
|
|
40
13
|
'.e2e/cache/',
|
|
41
14
|
'.e2e/sessions/',
|
|
42
15
|
'.e2e/report.json',
|
|
43
16
|
'.e2e/ai-trace.json',
|
|
17
|
+
'.e2e/junit.xml',
|
|
44
18
|
];
|
|
45
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Runs `e2e init`. Every prompt happens before the first write, existing
|
|
21
|
+
* config and test files are never touched, and dependencies install only when
|
|
22
|
+
* the user asks.
|
|
23
|
+
*/
|
|
46
24
|
export async function init(cwd, options = {}) {
|
|
47
25
|
clack.intro('e2e init');
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
26
|
+
let pkg;
|
|
27
|
+
try {
|
|
28
|
+
pkg = readPackage(cwd);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
clack.log.error('invalid package.json; fix it before running e2e init');
|
|
32
|
+
return 2;
|
|
33
|
+
}
|
|
34
|
+
const existingConfig = ['e2e.config.ts', 'e2e.config.mts'].find((file) => existsSync(path.join(cwd, file)));
|
|
35
|
+
const examplePath = path.join('tests', 'example.e2e.ts');
|
|
36
|
+
const exampleExists = existsSync(path.join(cwd, examplePath));
|
|
37
|
+
if (existingConfig !== undefined)
|
|
38
|
+
clack.log.warn(`exists, not touching: ${existingConfig}`);
|
|
39
|
+
if (exampleExists)
|
|
40
|
+
clack.log.warn(`exists, not touching: ${examplePath}`);
|
|
41
|
+
if (pkg.original !== undefined) {
|
|
42
|
+
const hint = esmPackageHint(path.join(cwd, existingConfig ?? 'e2e.config.ts'));
|
|
43
|
+
if (hint !== undefined)
|
|
44
|
+
clack.log.warn(hint);
|
|
57
45
|
}
|
|
58
|
-
// The ignore list is reconciled on every run, not only the first: a project
|
|
59
|
-
// initialized before an entry existed (`.e2e/ai-trace.json`, say) picks it
|
|
60
|
-
// up by re-running init, without touching any scaffold file.
|
|
61
46
|
const gitignorePath = path.join(cwd, '.gitignore');
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
47
|
+
const existingIgnore = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf8') : '';
|
|
48
|
+
const ignoreLines = existingIgnore.split(/\r?\n/);
|
|
49
|
+
const missingIgnore = GITIGNORE_ENTRIES.filter((entry) => !ignoreLines.includes(entry));
|
|
50
|
+
// Backend and AI are choices for a new config only; an existing config keeps its own dependencies.
|
|
51
|
+
let backend = DEFAULT_BACKEND_ID;
|
|
52
|
+
let ai = existingConfig === undefined;
|
|
53
|
+
if (existingConfig === undefined && !options.yes) {
|
|
54
|
+
const selectedBackend = await clack.select({
|
|
55
|
+
message: 'Which backend?',
|
|
56
|
+
initialValue: DEFAULT_BACKEND_ID,
|
|
57
|
+
options: getBackendPresets().map(({ id, label, hint }) => ({ value: id, label, hint })),
|
|
58
|
+
});
|
|
59
|
+
if (clack.isCancel(selectedBackend))
|
|
60
|
+
return cancelled();
|
|
61
|
+
backend = selectedBackend;
|
|
62
|
+
const enableAi = await clack.confirm({ message: 'Enable AI testing? Adds AI SDK v7.', initialValue: true });
|
|
63
|
+
if (clack.isCancel(enableAi))
|
|
64
|
+
return cancelled();
|
|
65
|
+
ai = enableAi;
|
|
66
|
+
}
|
|
67
|
+
const scaffold = createScaffold(backend, ai);
|
|
68
|
+
const { manifest, additions } = addDependencies(pkg.manifest, scaffold.dependencies);
|
|
69
|
+
if (additions.length > 0) {
|
|
70
|
+
clack.log.info(`add dev dependencies: ${additions.map(([name, version]) => `${name}@${version}`).join(', ')}`);
|
|
71
|
+
}
|
|
72
|
+
const files = [
|
|
73
|
+
...(pkg.original === undefined || additions.length > 0
|
|
74
|
+
? [{ relative: 'package.json', content: serializePackage(manifest, pkg.original), existing: pkg.original !== undefined }]
|
|
75
|
+
: []),
|
|
76
|
+
...(existingConfig === undefined ? [{ relative: 'e2e.config.ts', content: scaffold.config, existing: false }] : []),
|
|
77
|
+
...(exampleExists ? [] : [{ relative: examplePath, content: scaffold.example, existing: false }]),
|
|
78
|
+
];
|
|
79
|
+
if (files.length === 0 && missingIgnore.length === 0) {
|
|
67
80
|
clack.outro('nothing to create; project already initialized');
|
|
68
81
|
return 0;
|
|
69
82
|
}
|
|
70
|
-
if (options.yes
|
|
83
|
+
if (!options.yes) {
|
|
71
84
|
const actions = [
|
|
72
|
-
...(
|
|
73
|
-
|
|
74
|
-
: [`create ${remaining.map((file) => file.relative).join(', ')}`]),
|
|
75
|
-
...(missing.length === 0 ? [] : ['update .gitignore']),
|
|
85
|
+
...files.map((file) => `${file.existing ? 'update' : 'create'} ${file.relative}`),
|
|
86
|
+
...(missingIgnore.length > 0 ? ['update .gitignore'] : []),
|
|
76
87
|
];
|
|
77
|
-
const proceed = await clack.confirm({ message: `${actions.join('
|
|
78
|
-
if (clack.isCancel(proceed) || proceed
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
88
|
+
const proceed = await clack.confirm({ message: `${actions.join(', ')}?` });
|
|
89
|
+
if (clack.isCancel(proceed) || !proceed)
|
|
90
|
+
return cancelled();
|
|
91
|
+
}
|
|
92
|
+
const manager = detectPackageManager(cwd, manifest);
|
|
93
|
+
let install = false;
|
|
94
|
+
if (!options.yes) {
|
|
95
|
+
const selected = await clack.confirm({ message: `Install dependencies with ${manager}?`, initialValue: true });
|
|
96
|
+
if (clack.isCancel(selected))
|
|
97
|
+
return cancelled();
|
|
98
|
+
install = selected;
|
|
82
99
|
}
|
|
83
|
-
for (const file of
|
|
100
|
+
for (const file of files) {
|
|
84
101
|
const absolute = path.join(cwd, file.relative);
|
|
85
102
|
mkdirSync(path.dirname(absolute), { recursive: true });
|
|
86
103
|
writeFileSync(absolute, file.content, 'utf8');
|
|
87
|
-
clack.log.success(
|
|
88
|
-
}
|
|
89
|
-
if (remaining.some((file) => file.relative === 'e2e.config.ts') && !declaresDependency(cwd, AGENT_PEER)) {
|
|
90
|
-
clack.log.warn(`e2e.config.ts constructs the built-in agent, which runs on the AI SDK: npm install --save-dev ${AGENT_PEER}`);
|
|
104
|
+
clack.log.success(`${file.existing ? 'updated' : 'created'} ${file.relative}`);
|
|
91
105
|
}
|
|
92
|
-
if (
|
|
93
|
-
const prefix =
|
|
94
|
-
writeFileSync(gitignorePath, `${
|
|
95
|
-
clack.log.success(`updated .gitignore (${
|
|
106
|
+
if (missingIgnore.length > 0) {
|
|
107
|
+
const prefix = existingIgnore === '' || existingIgnore.endsWith('\n') ? '' : '\n';
|
|
108
|
+
writeFileSync(gitignorePath, `${existingIgnore}${prefix}${missingIgnore.join('\n')}\n`, 'utf8');
|
|
109
|
+
clack.log.success(`updated .gitignore (${missingIgnore.length} entries)`);
|
|
96
110
|
}
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
if (install) {
|
|
112
|
+
const result = spawnSync(manager, ['install'], { cwd, stdio: 'inherit', shell: process.platform === 'win32' });
|
|
113
|
+
if (result.error !== undefined || result.status !== 0) {
|
|
114
|
+
const reason = result.error?.message ?? `exit ${result.status ?? result.signal}`;
|
|
115
|
+
clack.log.error(`installation failed (${reason}); retry with ${manager} install`);
|
|
116
|
+
clack.outro('scaffold saved');
|
|
117
|
+
return result.signal === 'SIGINT' ? 130 : 2;
|
|
118
|
+
}
|
|
100
119
|
}
|
|
101
|
-
clack.outro(
|
|
120
|
+
clack.outro(`next: ${install ? '' : `${manager} install, then `}${scaffold.runCommand}`);
|
|
102
121
|
return 0;
|
|
103
122
|
}
|
|
104
|
-
/**
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return false;
|
|
109
|
-
let manifest;
|
|
110
|
-
try {
|
|
111
|
-
manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
if (typeof manifest !== 'object' || manifest === null)
|
|
117
|
-
return false;
|
|
118
|
-
const record = manifest;
|
|
119
|
-
return ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'].some((field) => {
|
|
120
|
-
const block = record[field];
|
|
121
|
-
return typeof block === 'object' && block !== null && name in block;
|
|
122
|
-
});
|
|
123
|
+
/** Cancellation is only reachable before the first write, so nothing needs undoing. */
|
|
124
|
+
function cancelled() {
|
|
125
|
+
clack.cancel('cancelled; no changes were made');
|
|
126
|
+
return 0;
|
|
123
127
|
}
|
|
124
128
|
//# sourceMappingURL=init.js.map
|
package/dist/cli/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** App, command, and service resolution (spec 05-config.md). */
|
|
2
|
+
import { type NormalizedBaseUrl } from '../internal/urls.ts';
|
|
3
|
+
import type { AppConfig, CommandConfig, E2EConfig } from '../types.ts';
|
|
4
|
+
/**
|
|
5
|
+
* How a spawned process counts as ready: a URL that answers, or the process
|
|
6
|
+
* itself exiting with code 0 (a migration, `docker compose up --wait`).
|
|
7
|
+
*/
|
|
8
|
+
export type Readiness = {
|
|
9
|
+
readonly readyUrl: string;
|
|
10
|
+
} | {
|
|
11
|
+
readonly waitForExit: true;
|
|
12
|
+
};
|
|
13
|
+
/** A command the runner spawns, named for error messages. */
|
|
14
|
+
export interface ResolvedCommand {
|
|
15
|
+
readonly label: string;
|
|
16
|
+
readonly command: CommandConfig;
|
|
17
|
+
}
|
|
18
|
+
/** One `app.services` entry with its readiness contract already decided. */
|
|
19
|
+
export interface ResolvedService extends ResolvedCommand {
|
|
20
|
+
readonly readiness: Readiness;
|
|
21
|
+
readonly teardown: ResolvedCommand | undefined;
|
|
22
|
+
}
|
|
23
|
+
export interface ResolvedApp {
|
|
24
|
+
/** False when no app URL was configured and `base` is a synthetic loopback placeholder. */
|
|
25
|
+
readonly configured: boolean;
|
|
26
|
+
readonly base: NormalizedBaseUrl;
|
|
27
|
+
readonly readyUrl: string;
|
|
28
|
+
readonly allowedOrigins: readonly string[];
|
|
29
|
+
readonly environment: 'test' | 'staging' | 'production';
|
|
30
|
+
readonly command: CommandConfig | undefined;
|
|
31
|
+
/** Dependency processes started in order before `command` and torn down in reverse. */
|
|
32
|
+
readonly services: readonly ResolvedService[];
|
|
33
|
+
/** Stable logical app identity; overrides the origin for cache/session keying. */
|
|
34
|
+
readonly identity: string | undefined;
|
|
35
|
+
}
|
|
36
|
+
export declare function resolveApp(raw: E2EConfig, env: NodeJS.ProcessEnv): ResolvedApp;
|
|
37
|
+
/**
|
|
38
|
+
* Resolves `app.services`: every service is a command with exactly one
|
|
39
|
+
* readiness contract (`readyUrl` or `waitForExit`), and a `teardown` is a
|
|
40
|
+
* command of its own. The service fields that only steer the runner
|
|
41
|
+
* (`readyUrl`, `waitForExit`, `teardown`) are lifted out of the command.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveServices(raw: AppConfig['services']): readonly ResolvedService[];
|
|
44
|
+
/**
|
|
45
|
+
* The digest view of `app`: `app.command.env`, every service's env, and every
|
|
46
|
+
* service teardown's env become names, so no environment value contributes to
|
|
47
|
+
* the digest. Live values never appear under `app`, so nothing else changes.
|
|
48
|
+
*/
|
|
49
|
+
export declare function digestApp(app: AppConfig): Record<string, unknown>;
|
|
50
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/config/app.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAGhE,OAAO,EAAwC,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnG,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAiB,MAAM,aAAa,CAAC;AAGtF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAA;CAAE,CAAC;AAEvF,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;CACjC;AAED,4EAA4E;AAC5E,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,CAAC;CAChD;AAED,MAAM,WAAW,WAAW;IAC1B,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;IACxD,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;IAC5C,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAeD,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,WAAW,CAqF9E;AAuBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,SAAS,eAAe,EAAE,CA6BtF;AAaD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAajE"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/** App, command, and service resolution (spec 05-config.md). */
|
|
2
|
+
import { ConfigurationError } from '../internal/errors.js';
|
|
3
|
+
import { isImplicitTestHost, normalizeBaseUrl } from '../internal/urls.js';
|
|
4
|
+
import { httpUrl, positiveInt } from './validate.js';
|
|
5
|
+
const APP_KEYS = new Set([
|
|
6
|
+
'url',
|
|
7
|
+
'command',
|
|
8
|
+
'readyUrl',
|
|
9
|
+
'services',
|
|
10
|
+
'allowedOrigins',
|
|
11
|
+
'environment',
|
|
12
|
+
'identity',
|
|
13
|
+
]);
|
|
14
|
+
/** App keys that make sense without an app URL; every other key needs one. */
|
|
15
|
+
const URL_FREE_APP_KEYS = new Set(['url', 'command', 'services']);
|
|
16
|
+
export function resolveApp(raw, env) {
|
|
17
|
+
if (raw.app !== undefined) {
|
|
18
|
+
for (const key of Object.keys(raw.app)) {
|
|
19
|
+
if (!APP_KEYS.has(key)) {
|
|
20
|
+
throw new ConfigurationError('INVALID_CONFIG', `unknown app config key "${key}"`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const services = resolveServices(raw.app?.services);
|
|
25
|
+
const rawUrl = raw.app?.url ?? env['APP_URL'];
|
|
26
|
+
if (rawUrl === undefined || rawUrl === '') {
|
|
27
|
+
// Not every surface has an app URL to point at (a device, a desktop
|
|
28
|
+
// shell): a synthetic loopback base keeps navigation resolution and
|
|
29
|
+
// identity digests defined, and `app.open()` fails loud with
|
|
30
|
+
// APP_URL_REQUIRED the moment a test actually needs one. A configured
|
|
31
|
+
// app command without a URL is still a mistake worth failing early on.
|
|
32
|
+
const orphaned = Object.keys(raw.app ?? {}).filter((key) => !URL_FREE_APP_KEYS.has(key));
|
|
33
|
+
if (orphaned.length > 0) {
|
|
34
|
+
throw new ConfigurationError('INVALID_CONFIG', `app.${orphaned[0]} requires app.url: set app.url in e2e.config.ts or the APP_URL environment variable`);
|
|
35
|
+
}
|
|
36
|
+
if (raw.app?.command === undefined) {
|
|
37
|
+
return {
|
|
38
|
+
configured: false,
|
|
39
|
+
base: normalizeBaseUrl('http://127.0.0.1:1'),
|
|
40
|
+
readyUrl: 'http://127.0.0.1:1/',
|
|
41
|
+
allowedOrigins: [],
|
|
42
|
+
environment: 'test',
|
|
43
|
+
command: undefined,
|
|
44
|
+
services,
|
|
45
|
+
identity: undefined,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
throw new ConfigurationError('APP_URL_REQUIRED', 'an app URL is required alongside app.command: set app.url in e2e.config.ts or the APP_URL environment variable');
|
|
49
|
+
}
|
|
50
|
+
const base = normalizeBaseUrl(rawUrl);
|
|
51
|
+
const baseHost = new URL(base.href).hostname;
|
|
52
|
+
// The environment is a label for the report and the cache/session identity
|
|
53
|
+
// digest, not a gate: a loopback, `.localhost`, or `.test` host is `test`,
|
|
54
|
+
// any other host is `production` unless the config says otherwise.
|
|
55
|
+
const environment = raw.app?.environment ?? (isImplicitTestHost(baseHost) ? 'test' : 'production');
|
|
56
|
+
if (!['test', 'staging', 'production'].includes(environment)) {
|
|
57
|
+
throw new ConfigurationError('INVALID_CONFIG', `invalid app.environment "${environment}"`);
|
|
58
|
+
}
|
|
59
|
+
const allowedOrigins = raw.app?.allowedOrigins ?? [base.origin];
|
|
60
|
+
for (const origin of allowedOrigins) {
|
|
61
|
+
let parsed;
|
|
62
|
+
try {
|
|
63
|
+
parsed = new URL(origin);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
throw new ConfigurationError('INVALID_CONFIG', `invalid allowed origin: ${origin}`);
|
|
67
|
+
}
|
|
68
|
+
if (parsed.origin !== origin) {
|
|
69
|
+
throw new ConfigurationError('INVALID_CONFIG', `allowed origin must be a serialized origin, got ${origin} (expected ${parsed.origin})`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const command = raw.app?.command;
|
|
73
|
+
if (command !== undefined)
|
|
74
|
+
validateCommand(command, 'app.command');
|
|
75
|
+
const identity = raw.app?.identity;
|
|
76
|
+
if (identity !== undefined && (typeof identity !== 'string' || identity.trim() === '')) {
|
|
77
|
+
throw new ConfigurationError('INVALID_CONFIG', 'app.identity must be a non-empty string');
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
configured: true,
|
|
81
|
+
base,
|
|
82
|
+
readyUrl: httpUrl(raw.app?.readyUrl, 'app.readyUrl') ?? base.href,
|
|
83
|
+
allowedOrigins,
|
|
84
|
+
environment,
|
|
85
|
+
command,
|
|
86
|
+
services,
|
|
87
|
+
identity,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The shape every spawned command shares: a non-empty executable and, when
|
|
92
|
+
* set, positive integer timeouts. A NaN or infinite budget would otherwise
|
|
93
|
+
* make the readiness loop spin without a deadline.
|
|
94
|
+
*/
|
|
95
|
+
function validateCommand(command, label) {
|
|
96
|
+
if (typeof command !== 'object' || command === null) {
|
|
97
|
+
throw new ConfigurationError('INVALID_CONFIG', `${label} must be an object`);
|
|
98
|
+
}
|
|
99
|
+
if (typeof command.executable !== 'string' || command.executable.length === 0) {
|
|
100
|
+
throw new ConfigurationError('INVALID_CONFIG', `${label}.executable is required`);
|
|
101
|
+
}
|
|
102
|
+
positiveInt(command.startupTimeout, `${label}.startupTimeout`);
|
|
103
|
+
positiveInt(command.shutdownTimeout, `${label}.shutdownTimeout`);
|
|
104
|
+
}
|
|
105
|
+
/** Services carry no name, so messages name one by its position and command line. */
|
|
106
|
+
function commandLine(command) {
|
|
107
|
+
return [command.executable, ...(command.args ?? [])].join(' ');
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Resolves `app.services`: every service is a command with exactly one
|
|
111
|
+
* readiness contract (`readyUrl` or `waitForExit`), and a `teardown` is a
|
|
112
|
+
* command of its own. The service fields that only steer the runner
|
|
113
|
+
* (`readyUrl`, `waitForExit`, `teardown`) are lifted out of the command.
|
|
114
|
+
*/
|
|
115
|
+
export function resolveServices(raw) {
|
|
116
|
+
if (raw === undefined)
|
|
117
|
+
return [];
|
|
118
|
+
if (!Array.isArray(raw)) {
|
|
119
|
+
throw new ConfigurationError('INVALID_CONFIG', 'app.services must be an array');
|
|
120
|
+
}
|
|
121
|
+
return raw.map((service, index) => {
|
|
122
|
+
const position = `app.services[${index}]`;
|
|
123
|
+
validateCommand(service, position);
|
|
124
|
+
const { readyUrl: rawReadyUrl, waitForExit, teardown, ...command } = service;
|
|
125
|
+
const readyUrl = httpUrl(rawReadyUrl, `${position}.readyUrl`);
|
|
126
|
+
if ((readyUrl !== undefined) === (waitForExit === true)) {
|
|
127
|
+
throw new ConfigurationError('INVALID_CONFIG', `${position} needs exactly one readiness contract: set readyUrl or waitForExit: true`);
|
|
128
|
+
}
|
|
129
|
+
const readiness = readyUrl === undefined ? { waitForExit: true } : { readyUrl };
|
|
130
|
+
const label = `${position} (${commandLine(command)})`;
|
|
131
|
+
if (teardown !== undefined)
|
|
132
|
+
validateCommand(teardown, `${position}.teardown`);
|
|
133
|
+
return {
|
|
134
|
+
label,
|
|
135
|
+
command,
|
|
136
|
+
readiness,
|
|
137
|
+
teardown: teardown === undefined
|
|
138
|
+
? undefined
|
|
139
|
+
: { label: `${label} teardown (${commandLine(teardown)})`, command: teardown },
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function digestCommand(command) {
|
|
144
|
+
const { env, ...rest } = command;
|
|
145
|
+
if (env === undefined)
|
|
146
|
+
return rest;
|
|
147
|
+
return { ...rest, env: Object.fromEntries(Object.keys(env).map((key) => [key, { envName: key }])) };
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The digest view of `app`: `app.command.env`, every service's env, and every
|
|
151
|
+
* service teardown's env become names, so no environment value contributes to
|
|
152
|
+
* the digest. Live values never appear under `app`, so nothing else changes.
|
|
153
|
+
*/
|
|
154
|
+
export function digestApp(app) {
|
|
155
|
+
return {
|
|
156
|
+
...app,
|
|
157
|
+
...(app.command === undefined ? {} : { command: digestCommand(app.command) }),
|
|
158
|
+
...(app.services === undefined
|
|
159
|
+
? {}
|
|
160
|
+
: {
|
|
161
|
+
services: app.services.map(({ teardown, ...service }) => ({
|
|
162
|
+
...digestCommand(service),
|
|
163
|
+
...(teardown === undefined ? {} : { teardown: digestCommand(teardown) }),
|
|
164
|
+
})),
|
|
165
|
+
}),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/config/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Package-scope diagnostics for TypeScript config and test entry points. */
|
|
2
|
+
/** Explains how to opt a `.ts` entry point's package into ESM when required. */
|
|
3
|
+
export declare function esmPackageHint(modulePath: string): string | undefined;
|
|
4
|
+
//# sourceMappingURL=esm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esm.d.ts","sourceRoot":"","sources":["../../src/config/esm.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAK7E,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA2BrE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Package-scope diagnostics for TypeScript config and test entry points. */
|
|
2
|
+
import { existsSync, readFileSync, realpathSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
/** Explains how to opt a `.ts` entry point's package into ESM when required. */
|
|
5
|
+
export function esmPackageHint(modulePath) {
|
|
6
|
+
const filename = existsSync(modulePath) ? realpathSync(modulePath) : modulePath;
|
|
7
|
+
if (path.extname(filename) !== '.ts')
|
|
8
|
+
return undefined;
|
|
9
|
+
let dir = path.dirname(filename);
|
|
10
|
+
for (;;) {
|
|
11
|
+
const manifestPath = path.join(dir, 'package.json');
|
|
12
|
+
if (existsSync(manifestPath)) {
|
|
13
|
+
let manifest;
|
|
14
|
+
try {
|
|
15
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Leave malformed or unreadable manifests to the loader's own diagnostic.
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if ('type' in manifest && manifest.type === 'module')
|
|
25
|
+
return undefined;
|
|
26
|
+
return `e2e requires ES modules for .ts config and test files, but ${manifestPath} does not set "type": "module". To opt this package into ESM, run npm pkg set type=module from ${dir}. This also changes how existing .js files in the package are interpreted.`;
|
|
27
|
+
}
|
|
28
|
+
const parent = path.dirname(dir);
|
|
29
|
+
if (parent === dir || path.basename(parent) === 'node_modules')
|
|
30
|
+
break;
|
|
31
|
+
dir = parent;
|
|
32
|
+
}
|
|
33
|
+
return `e2e requires ES modules for .ts config and test files. Create a package.json with "type": "module" in ${path.dirname(filename)}, or run e2e init in the project directory.`;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esm.js","sourceRoot":"","sources":["../../src/config/esm.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAChF,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IAEvD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,CAAC;QACR,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACpD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7B,IAAI,QAAiB,CAAC;YACtB,IAAI,CAAC;gBACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC;gBACP,0EAA0E;gBAC1E,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjF,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,IAAI,MAAM,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC;YACvE,OAAO,8DAA8D,YAAY,kGAAkG,GAAG,4EAA4E,CAAC;QACrQ,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,cAAc;YAAE,MAAM;QACtE,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IAED,OAAO,yGAAyG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,6CAA6C,CAAC;AACtL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAOvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAOvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CA2BnF;AAWD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,SAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAO9F;AAED,mEAAmE;AACnE,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAmB7E"}
|
package/dist/config/load.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from 'node:path';
|
|
|
4
4
|
import { pathToFileURL } from 'node:url';
|
|
5
5
|
import { register } from 'tsx/esm/api';
|
|
6
6
|
import { ConfigurationError } from '../internal/errors.js';
|
|
7
|
+
import { esmPackageHint } from './esm.js';
|
|
7
8
|
const CONFIG_NAMES = ['e2e.config.ts', 'e2e.config.mts'];
|
|
8
9
|
/**
|
|
9
10
|
* Discovers the config file. With `--config` the explicit path wins. Otherwise
|
|
@@ -52,6 +53,9 @@ let imports = 0;
|
|
|
52
53
|
* the config file as it is now.
|
|
53
54
|
*/
|
|
54
55
|
export async function importModule(absolutePath, cacheKey = 'module') {
|
|
56
|
+
const hint = esmPackageHint(absolutePath);
|
|
57
|
+
if (hint !== undefined)
|
|
58
|
+
throw new Error(hint);
|
|
55
59
|
imports += 1;
|
|
56
60
|
const url = `${pathToFileURL(absolutePath).href}?e2e=${cacheKey}-${imports}`;
|
|
57
61
|
loader ??= register({ namespace: 'e2e' });
|
package/dist/config/load.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAA6B,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"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"}
|