repterm 0.1.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/dist/api/describe.d.ts +18 -0
- package/dist/api/describe.d.ts.map +1 -0
- package/dist/api/describe.js +33 -0
- package/dist/api/describe.js.map +1 -0
- package/dist/api/expect.d.ts +43 -0
- package/dist/api/expect.d.ts.map +1 -0
- package/dist/api/expect.js +167 -0
- package/dist/api/expect.js.map +1 -0
- package/dist/api/hooks.d.ts +178 -0
- package/dist/api/hooks.d.ts.map +1 -0
- package/dist/api/hooks.js +231 -0
- package/dist/api/hooks.js.map +1 -0
- package/dist/api/steps.d.ts +45 -0
- package/dist/api/steps.d.ts.map +1 -0
- package/dist/api/steps.js +106 -0
- package/dist/api/steps.js.map +1 -0
- package/dist/api/test.d.ts +101 -0
- package/dist/api/test.d.ts.map +1 -0
- package/dist/api/test.js +207 -0
- package/dist/api/test.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +203 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/reporter.d.ts +108 -0
- package/dist/cli/reporter.d.ts.map +1 -0
- package/dist/cli/reporter.js +368 -0
- package/dist/cli/reporter.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/index.d.ts +47 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +86 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/withPlugins.d.ts +71 -0
- package/dist/plugin/withPlugins.d.ts.map +1 -0
- package/dist/plugin/withPlugins.js +101 -0
- package/dist/plugin/withPlugins.js.map +1 -0
- package/dist/recording/recorder.d.ts +45 -0
- package/dist/recording/recorder.d.ts.map +1 -0
- package/dist/recording/recorder.js +97 -0
- package/dist/recording/recorder.js.map +1 -0
- package/dist/runner/artifacts.d.ts +39 -0
- package/dist/runner/artifacts.d.ts.map +1 -0
- package/dist/runner/artifacts.js +59 -0
- package/dist/runner/artifacts.js.map +1 -0
- package/dist/runner/config.d.ts +46 -0
- package/dist/runner/config.d.ts.map +1 -0
- package/dist/runner/config.js +65 -0
- package/dist/runner/config.js.map +1 -0
- package/dist/runner/filter.d.ts +26 -0
- package/dist/runner/filter.d.ts.map +1 -0
- package/dist/runner/filter.js +88 -0
- package/dist/runner/filter.js.map +1 -0
- package/dist/runner/loader.d.ts +32 -0
- package/dist/runner/loader.d.ts.map +1 -0
- package/dist/runner/loader.js +252 -0
- package/dist/runner/loader.js.map +1 -0
- package/dist/runner/models.d.ts +261 -0
- package/dist/runner/models.d.ts.map +1 -0
- package/dist/runner/models.js +5 -0
- package/dist/runner/models.js.map +1 -0
- package/dist/runner/runner.d.ts +36 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +216 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/runner/scheduler.d.ts +59 -0
- package/dist/runner/scheduler.d.ts.map +1 -0
- package/dist/runner/scheduler.js +157 -0
- package/dist/runner/scheduler.js.map +1 -0
- package/dist/runner/worker-runner.d.ts +6 -0
- package/dist/runner/worker-runner.d.ts.map +1 -0
- package/dist/runner/worker-runner.js +51 -0
- package/dist/runner/worker-runner.js.map +1 -0
- package/dist/runner/worker.d.ts +54 -0
- package/dist/runner/worker.d.ts.map +1 -0
- package/dist/runner/worker.js +112 -0
- package/dist/runner/worker.js.map +1 -0
- package/dist/terminal/session.d.ts +56 -0
- package/dist/terminal/session.d.ts.map +1 -0
- package/dist/terminal/session.js +126 -0
- package/dist/terminal/session.js.map +1 -0
- package/dist/terminal/terminal.d.ts +284 -0
- package/dist/terminal/terminal.d.ts.map +1 -0
- package/dist/terminal/terminal.js +1167 -0
- package/dist/terminal/terminal.js.map +1 -0
- package/dist/utils/dependencies.d.ts +19 -0
- package/dist/utils/dependencies.d.ts.map +1 -0
- package/dist/utils/dependencies.js +58 -0
- package/dist/utils/dependencies.js.map +1 -0
- package/dist/utils/timing.d.ts +55 -0
- package/dist/utils/timing.d.ts.map +1 -0
- package/dist/utils/timing.js +87 -0
- package/dist/utils/timing.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* test.describe suite grouping
|
|
3
|
+
* Provides nested test organization
|
|
4
|
+
*/
|
|
5
|
+
import type { DescribeOptions } from '../runner/models.js';
|
|
6
|
+
/**
|
|
7
|
+
* Create a test suite with grouped tests
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // 普通测试套件
|
|
11
|
+
* describe('suite name', () => { ... });
|
|
12
|
+
*
|
|
13
|
+
* // 录制测试套件
|
|
14
|
+
* describe('suite name', { record: true }, () => { ... });
|
|
15
|
+
*/
|
|
16
|
+
export declare function describe(name: string, fn: () => void): void;
|
|
17
|
+
export declare function describe(name: string, options: DescribeOptions, fn: () => void): void;
|
|
18
|
+
//# sourceMappingURL=describe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/api/describe.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAItE;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;AAC7D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* test.describe suite grouping
|
|
3
|
+
* Provides nested test organization
|
|
4
|
+
*/
|
|
5
|
+
import { registry } from './test.js';
|
|
6
|
+
import { randomBytes } from 'crypto';
|
|
7
|
+
export function describe(name, optionsOrFn, maybeFn) {
|
|
8
|
+
const options = typeof optionsOrFn === 'function' ? undefined : optionsOrFn;
|
|
9
|
+
const fn = typeof optionsOrFn === 'function' ? optionsOrFn : maybeFn;
|
|
10
|
+
// Create a new suite
|
|
11
|
+
const suite = {
|
|
12
|
+
id: generateId(),
|
|
13
|
+
name,
|
|
14
|
+
tests: [],
|
|
15
|
+
suites: [],
|
|
16
|
+
config: {},
|
|
17
|
+
options,
|
|
18
|
+
};
|
|
19
|
+
// Set this as the current suite
|
|
20
|
+
registry.setCurrentSuite(suite);
|
|
21
|
+
// Execute the suite definition function
|
|
22
|
+
// This will register tests to this suite
|
|
23
|
+
fn();
|
|
24
|
+
// Reset to default suite
|
|
25
|
+
registry.resetCurrentSuite();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generate a unique ID
|
|
29
|
+
*/
|
|
30
|
+
function generateId() {
|
|
31
|
+
return randomBytes(8).toString('hex');
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=describe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../../src/api/describe.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAcrC,MAAM,UAAU,QAAQ,CACtB,IAAY,EACZ,WAA2C,EAC3C,OAAoB;IAEpB,MAAM,OAAO,GAAG,OAAO,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC;IAC5E,MAAM,EAAE,GAAG,OAAO,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAQ,CAAC;IAEtE,qBAAqB;IACrB,MAAM,KAAK,GAAc;QACvB,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI;QACJ,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE;QACV,OAAO;KACR,CAAC;IAEF,gCAAgC;IAChC,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAEhC,wCAAwC;IACxC,yCAAyC;IACzC,EAAE,EAAE,CAAC;IAEL,yBAAyB;IACzB,QAAQ,CAAC,iBAAiB,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAS,UAAU;IACjB,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expect API based on bun:test
|
|
3
|
+
*
|
|
4
|
+
* Extends bun:test's expect with domain-specific matchers for
|
|
5
|
+
* terminal output and command results. Plugins can register
|
|
6
|
+
* additional matchers via expect.extend().
|
|
7
|
+
*/
|
|
8
|
+
import { expect } from 'bun:test';
|
|
9
|
+
export type { MatcherResult } from '@repterm/plugin-api';
|
|
10
|
+
/**
|
|
11
|
+
* Assertion error with expected/actual values
|
|
12
|
+
*/
|
|
13
|
+
export declare class AssertionError extends Error {
|
|
14
|
+
expected: unknown;
|
|
15
|
+
actual: unknown;
|
|
16
|
+
constructor(message: string, expected: unknown, actual: unknown);
|
|
17
|
+
}
|
|
18
|
+
declare module 'bun:test' {
|
|
19
|
+
interface Matchers<T> {
|
|
20
|
+
/** Assert that terminal contains text */
|
|
21
|
+
toContainText(expected: string): Promise<void>;
|
|
22
|
+
/** Assert that terminal output matches regex */
|
|
23
|
+
toMatchPattern(pattern: RegExp): Promise<void>;
|
|
24
|
+
/** Assert command succeeded (exit code === 0) */
|
|
25
|
+
toSucceed(): Matchers<T>;
|
|
26
|
+
/** Assert command failed (exit code !== 0) */
|
|
27
|
+
toFail(): Matchers<T>;
|
|
28
|
+
/** Assert exit code equals expected value */
|
|
29
|
+
toHaveExitCode(expected: number): Matchers<T>;
|
|
30
|
+
/** Assert stdout contains expected text */
|
|
31
|
+
toHaveStdout(expected: string): Matchers<T>;
|
|
32
|
+
/** Assert stderr contains expected text */
|
|
33
|
+
toHaveStderr(expected: string): Matchers<T>;
|
|
34
|
+
/** Assert stdout matches regex pattern */
|
|
35
|
+
toMatchStdout(pattern: RegExp): Matchers<T>;
|
|
36
|
+
/** Assert stderr matches regex pattern */
|
|
37
|
+
toMatchStderr(pattern: RegExp): Matchers<T>;
|
|
38
|
+
/** Assert combined output contains text */
|
|
39
|
+
toContainInOutput(expected: string): Matchers<T>;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export { expect };
|
|
43
|
+
//# sourceMappingURL=expect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/api/expect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIlC,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;gBAGrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,OAAO;CAOlB;AAqKD,OAAO,QAAQ,UAAU,CAAC;IACxB,UAAU,QAAQ,CAAC,CAAC;QAClB,yCAAyC;QACzC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,gDAAgD;QAChD,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,iDAAiD;QACjD,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzB,8CAA8C;QAC9C,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtB,6CAA6C;QAC7C,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC9C,2CAA2C;QAC3C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5C,2CAA2C;QAC3C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5C,0CAA0C;QAC1C,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5C,0CAA0C;QAC1C,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5C,2CAA2C;QAC3C,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;KAClD;CACF;AAID,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expect API based on bun:test
|
|
3
|
+
*
|
|
4
|
+
* Extends bun:test's expect with domain-specific matchers for
|
|
5
|
+
* terminal output and command results. Plugins can register
|
|
6
|
+
* additional matchers via expect.extend().
|
|
7
|
+
*/
|
|
8
|
+
import { expect } from 'bun:test';
|
|
9
|
+
/**
|
|
10
|
+
* Assertion error with expected/actual values
|
|
11
|
+
*/
|
|
12
|
+
export class AssertionError extends Error {
|
|
13
|
+
expected;
|
|
14
|
+
actual;
|
|
15
|
+
constructor(message, expected, actual) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = 'AssertionError';
|
|
18
|
+
this.expected = expected;
|
|
19
|
+
this.actual = actual;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// ===== Type Guards =====
|
|
23
|
+
function isTerminalAPI(value) {
|
|
24
|
+
return (typeof value === 'object' &&
|
|
25
|
+
value !== null &&
|
|
26
|
+
'run' in value &&
|
|
27
|
+
'snapshot' in value &&
|
|
28
|
+
typeof value.run === 'function');
|
|
29
|
+
}
|
|
30
|
+
function isCommandResult(value) {
|
|
31
|
+
return (typeof value === 'object' &&
|
|
32
|
+
value !== null &&
|
|
33
|
+
'code' in value &&
|
|
34
|
+
'stdout' in value &&
|
|
35
|
+
'stderr' in value &&
|
|
36
|
+
'output' in value);
|
|
37
|
+
}
|
|
38
|
+
// ===== Register repterm matchers =====
|
|
39
|
+
expect.extend({
|
|
40
|
+
// Terminal matchers
|
|
41
|
+
async toContainText(received, expected) {
|
|
42
|
+
if (!isTerminalAPI(received)) {
|
|
43
|
+
return { pass: false, message: () => 'Expected a TerminalAPI instance' };
|
|
44
|
+
}
|
|
45
|
+
const snapshot = await received.snapshot();
|
|
46
|
+
const pass = snapshot.includes(expected);
|
|
47
|
+
return {
|
|
48
|
+
pass,
|
|
49
|
+
message: () => pass
|
|
50
|
+
? `Expected terminal NOT to contain "${expected}"`
|
|
51
|
+
: `Expected terminal to contain "${expected}"`,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
async toMatchPattern(received, pattern) {
|
|
55
|
+
if (!isTerminalAPI(received)) {
|
|
56
|
+
return { pass: false, message: () => 'Expected a TerminalAPI instance' };
|
|
57
|
+
}
|
|
58
|
+
const snapshot = await received.snapshot();
|
|
59
|
+
const pass = pattern.test(snapshot);
|
|
60
|
+
return {
|
|
61
|
+
pass,
|
|
62
|
+
message: () => pass
|
|
63
|
+
? `Expected terminal NOT to match ${pattern}`
|
|
64
|
+
: `Expected terminal to match ${pattern}`,
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
// CommandResult matchers
|
|
68
|
+
toSucceed(received) {
|
|
69
|
+
if (!isCommandResult(received)) {
|
|
70
|
+
return { pass: false, message: () => 'Expected a CommandResult' };
|
|
71
|
+
}
|
|
72
|
+
const pass = received.code === 0;
|
|
73
|
+
return {
|
|
74
|
+
pass,
|
|
75
|
+
message: () => pass
|
|
76
|
+
? 'Expected command NOT to succeed'
|
|
77
|
+
: `Expected command to succeed, got exit code ${received.code}`,
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
toFail(received) {
|
|
81
|
+
if (!isCommandResult(received)) {
|
|
82
|
+
return { pass: false, message: () => 'Expected a CommandResult' };
|
|
83
|
+
}
|
|
84
|
+
const pass = received.code !== 0;
|
|
85
|
+
return {
|
|
86
|
+
pass,
|
|
87
|
+
message: () => pass
|
|
88
|
+
? 'Expected command NOT to fail'
|
|
89
|
+
: 'Expected command to fail, but it succeeded',
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
toHaveExitCode(received, expected) {
|
|
93
|
+
if (!isCommandResult(received)) {
|
|
94
|
+
return { pass: false, message: () => 'Expected a CommandResult' };
|
|
95
|
+
}
|
|
96
|
+
const pass = received.code === expected;
|
|
97
|
+
return {
|
|
98
|
+
pass,
|
|
99
|
+
message: () => pass
|
|
100
|
+
? `Expected exit code NOT to be ${expected}`
|
|
101
|
+
: `Expected exit code ${expected}, got ${received.code}`,
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
toHaveStdout(received, expected) {
|
|
105
|
+
if (!isCommandResult(received)) {
|
|
106
|
+
return { pass: false, message: () => 'Expected a CommandResult' };
|
|
107
|
+
}
|
|
108
|
+
const pass = received.stdout.includes(expected);
|
|
109
|
+
return {
|
|
110
|
+
pass,
|
|
111
|
+
message: () => pass
|
|
112
|
+
? `Expected stdout NOT to contain "${expected}"`
|
|
113
|
+
: `Expected stdout to contain "${expected}"`,
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
toHaveStderr(received, expected) {
|
|
117
|
+
if (!isCommandResult(received)) {
|
|
118
|
+
return { pass: false, message: () => 'Expected a CommandResult' };
|
|
119
|
+
}
|
|
120
|
+
const pass = received.stderr.includes(expected);
|
|
121
|
+
return {
|
|
122
|
+
pass,
|
|
123
|
+
message: () => pass
|
|
124
|
+
? `Expected stderr NOT to contain "${expected}"`
|
|
125
|
+
: `Expected stderr to contain "${expected}"`,
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
toMatchStdout(received, pattern) {
|
|
129
|
+
if (!isCommandResult(received)) {
|
|
130
|
+
return { pass: false, message: () => 'Expected a CommandResult' };
|
|
131
|
+
}
|
|
132
|
+
const pass = pattern.test(received.stdout);
|
|
133
|
+
return {
|
|
134
|
+
pass,
|
|
135
|
+
message: () => pass
|
|
136
|
+
? `Expected stdout NOT to match ${pattern}`
|
|
137
|
+
: `Expected stdout to match ${pattern}`,
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
toMatchStderr(received, pattern) {
|
|
141
|
+
if (!isCommandResult(received)) {
|
|
142
|
+
return { pass: false, message: () => 'Expected a CommandResult' };
|
|
143
|
+
}
|
|
144
|
+
const pass = pattern.test(received.stderr);
|
|
145
|
+
return {
|
|
146
|
+
pass,
|
|
147
|
+
message: () => pass
|
|
148
|
+
? `Expected stderr NOT to match ${pattern}`
|
|
149
|
+
: `Expected stderr to match ${pattern}`,
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
toContainInOutput(received, expected) {
|
|
153
|
+
if (!isCommandResult(received)) {
|
|
154
|
+
return { pass: false, message: () => 'Expected a CommandResult' };
|
|
155
|
+
}
|
|
156
|
+
const pass = received.output.includes(expected);
|
|
157
|
+
return {
|
|
158
|
+
pass,
|
|
159
|
+
message: () => pass
|
|
160
|
+
? `Expected output NOT to contain "${expected}"`
|
|
161
|
+
: `Expected output to contain "${expected}"`,
|
|
162
|
+
};
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
// ===== Re-export =====
|
|
166
|
+
export { expect };
|
|
167
|
+
//# sourceMappingURL=expect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect.js","sourceRoot":"","sources":["../../src/api/expect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks (beforeEach, afterEach) with Named Fixture Support
|
|
3
|
+
* Provides setup and teardown functionality with lazy execution
|
|
4
|
+
*
|
|
5
|
+
* Fixtures are only executed when tests explicitly request them via parameters.
|
|
6
|
+
*/
|
|
7
|
+
import type { TestContext, TestSuite } from '../runner/models.js';
|
|
8
|
+
/**
|
|
9
|
+
* 基础 Hook 函数类型
|
|
10
|
+
*/
|
|
11
|
+
export type HookFunction = (context: TestContext) => Promise<void> | void;
|
|
12
|
+
/**
|
|
13
|
+
* 增强的 Hook 函数类型,支持返回值注入
|
|
14
|
+
* 返回的对象会被合并到后续的 context 中
|
|
15
|
+
*/
|
|
16
|
+
export type EnhancedHookFunction = (context: TestContext) => Promise<Record<string, unknown> | void> | Record<string, unknown> | void;
|
|
17
|
+
/**
|
|
18
|
+
* Global hooks storage with named fixture support
|
|
19
|
+
*/
|
|
20
|
+
declare class HooksRegistry {
|
|
21
|
+
private namedBeforeEachHooks;
|
|
22
|
+
private namedAfterEachHooks;
|
|
23
|
+
private suiteBeforeAllHooks;
|
|
24
|
+
private suiteAfterAllHooks;
|
|
25
|
+
/**
|
|
26
|
+
* Register a named beforeEach hook (lazy execution)
|
|
27
|
+
* @param name Fixture name - only executed if test requests this fixture
|
|
28
|
+
* @param fn Hook function
|
|
29
|
+
* @param suiteId Optional suite ID to scope the hook
|
|
30
|
+
*/
|
|
31
|
+
registerBeforeEach(name: string, fn: EnhancedHookFunction, suiteId?: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Register a named afterEach hook (lazy cleanup)
|
|
34
|
+
* @param name Fixture name - only executed if the corresponding beforeEach was run
|
|
35
|
+
* @param fn Hook function
|
|
36
|
+
* @param suiteId Optional suite ID to scope the hook
|
|
37
|
+
*/
|
|
38
|
+
registerAfterEach(name: string, fn: HookFunction, suiteId?: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Register a beforeAll hook for a suite
|
|
41
|
+
* @param name Optional fixture name
|
|
42
|
+
* @param fn Hook function
|
|
43
|
+
* @param suiteId Suite ID to scope the hook
|
|
44
|
+
*/
|
|
45
|
+
registerBeforeAll(name: string | undefined, fn: EnhancedHookFunction, suiteId: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Register an afterAll hook for a suite
|
|
48
|
+
* @param name Optional fixture name
|
|
49
|
+
* @param fn Hook function
|
|
50
|
+
* @param suiteId Suite ID to scope the hook
|
|
51
|
+
*/
|
|
52
|
+
registerAfterAll(name: string | undefined, fn: HookFunction, suiteId: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get the chain of suite IDs from root to the given suite
|
|
55
|
+
*/
|
|
56
|
+
private getSuiteChain;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a hook should run for a given suite
|
|
59
|
+
*/
|
|
60
|
+
private shouldRunHookForSuite;
|
|
61
|
+
/**
|
|
62
|
+
* Run beforeEach hooks for requested fixtures only (lazy execution)
|
|
63
|
+
* @param context Test context
|
|
64
|
+
* @param suite Optional suite to filter hooks
|
|
65
|
+
* @param requiredFixtures Set of fixture names requested by the test
|
|
66
|
+
* @returns Augmented context with fixture values and set of executed fixture names
|
|
67
|
+
*/
|
|
68
|
+
runBeforeEachFor(context: TestContext, suite: TestSuite | undefined, requiredFixtures: Set<string>): Promise<{
|
|
69
|
+
context: TestContext;
|
|
70
|
+
executedFixtures: Set<string>;
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* Run afterEach hooks for executed fixtures only
|
|
74
|
+
* @param context Test context
|
|
75
|
+
* @param suite Optional suite to filter hooks
|
|
76
|
+
* @param executedFixtures Set of fixture names that were actually executed
|
|
77
|
+
*/
|
|
78
|
+
runAfterEachFor(context: TestContext, suite: TestSuite | undefined, executedFixtures: Set<string>): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Run beforeAll hooks for a suite
|
|
81
|
+
* @param suite The suite to run hooks for
|
|
82
|
+
* @param inheritedContext Context inherited from parent suites
|
|
83
|
+
* @returns Augmented context with values from beforeAll hooks
|
|
84
|
+
*/
|
|
85
|
+
runBeforeAllFor(suite: TestSuite, inheritedContext?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
86
|
+
/**
|
|
87
|
+
* Run afterAll hooks for a suite
|
|
88
|
+
* @param suite The suite to run hooks for
|
|
89
|
+
* @param context Context to pass to hooks
|
|
90
|
+
*/
|
|
91
|
+
runAfterAllFor(suite: TestSuite, context?: Record<string, unknown>): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Clear all hooks (for testing)
|
|
94
|
+
*/
|
|
95
|
+
clear(): void;
|
|
96
|
+
}
|
|
97
|
+
export declare const hooksRegistry: HooksRegistry;
|
|
98
|
+
/**
|
|
99
|
+
* Register a named beforeEach hook with lazy execution
|
|
100
|
+
*
|
|
101
|
+
* 只有测试函数参数中请求了该 Fixture,才会执行此 Hook。
|
|
102
|
+
*
|
|
103
|
+
* @param name Fixture 名称(必须与返回对象的 key 一致)
|
|
104
|
+
* @param fn Hook 函数,返回对象会被注入到 context
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* describe('my tests', () => {
|
|
108
|
+
* // 注册名为 'tmpDir' 的 fixture
|
|
109
|
+
* beforeEach('tmpDir', async () => {
|
|
110
|
+
* const tmpDir = await fs.mkdtemp('/tmp/test-');
|
|
111
|
+
* return { tmpDir };
|
|
112
|
+
* });
|
|
113
|
+
*
|
|
114
|
+
* afterEach('tmpDir', async ({ tmpDir }) => {
|
|
115
|
+
* if (tmpDir) await fs.rm(tmpDir, { recursive: true });
|
|
116
|
+
* });
|
|
117
|
+
*
|
|
118
|
+
* // 这个测试会触发 tmpDir fixture
|
|
119
|
+
* test('uses tmpDir', async ({ terminal, tmpDir }) => {
|
|
120
|
+
* await terminal.run(`ls ${tmpDir}`);
|
|
121
|
+
* });
|
|
122
|
+
*
|
|
123
|
+
* // 这个测试不会触发 tmpDir fixture
|
|
124
|
+
* test('no fixture needed', async ({ terminal }) => {
|
|
125
|
+
* await terminal.run('echo hello');
|
|
126
|
+
* });
|
|
127
|
+
* });
|
|
128
|
+
*/
|
|
129
|
+
export declare function beforeEach(name: string, fn: EnhancedHookFunction): void;
|
|
130
|
+
/**
|
|
131
|
+
* Register a named afterEach hook
|
|
132
|
+
*
|
|
133
|
+
* 只有对应的 beforeEach 被执行了,此 Hook 才会执行。
|
|
134
|
+
*
|
|
135
|
+
* @param name Fixture 名称(与 beforeEach 注册的名称一致)
|
|
136
|
+
* @param fn Hook 函数
|
|
137
|
+
*/
|
|
138
|
+
export declare function afterEach(name: string, fn: HookFunction): void;
|
|
139
|
+
/**
|
|
140
|
+
* Register a beforeAll hook for the current suite
|
|
141
|
+
*
|
|
142
|
+
* 在 Suite 中所有测试执行前只运行一次。
|
|
143
|
+
* 返回的对象会被合并到 Context,传递给所有测试。
|
|
144
|
+
*
|
|
145
|
+
* @param fn Hook 函数,返回对象会被注入到 context
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* describe('admin tests', () => {
|
|
149
|
+
* beforeAll(async () => {
|
|
150
|
+
* const adminUser = await createAdminUser();
|
|
151
|
+
* return { adminUser };
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* afterAll(async ({ adminUser }) => {
|
|
155
|
+
* await deleteUser(adminUser);
|
|
156
|
+
* });
|
|
157
|
+
*
|
|
158
|
+
* test('admin can see dashboard', async ({ terminal, adminUser }) => {
|
|
159
|
+
* // adminUser is available from beforeAll
|
|
160
|
+
* });
|
|
161
|
+
* });
|
|
162
|
+
*/
|
|
163
|
+
export declare function beforeAll(fn: EnhancedHookFunction): void;
|
|
164
|
+
export declare function beforeAll(name: string, fn: EnhancedHookFunction): void;
|
|
165
|
+
/**
|
|
166
|
+
* Register an afterAll hook for the current suite
|
|
167
|
+
*
|
|
168
|
+
* 在 Suite 中所有测试执行后只运行一次。
|
|
169
|
+
*
|
|
170
|
+
* @param fn Hook 函数
|
|
171
|
+
*/
|
|
172
|
+
export declare function afterAll(fn: HookFunction): void;
|
|
173
|
+
export declare function afterAll(name: string, fn: HookFunction): void;
|
|
174
|
+
/**
|
|
175
|
+
* Export hooks registry for runner
|
|
176
|
+
*/
|
|
177
|
+
export { hooksRegistry as hooks };
|
|
178
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/api/hooks.ts"],"names":[],"mappings":"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"}
|