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.
Files changed (97) hide show
  1. package/dist/api/describe.d.ts +18 -0
  2. package/dist/api/describe.d.ts.map +1 -0
  3. package/dist/api/describe.js +33 -0
  4. package/dist/api/describe.js.map +1 -0
  5. package/dist/api/expect.d.ts +43 -0
  6. package/dist/api/expect.d.ts.map +1 -0
  7. package/dist/api/expect.js +167 -0
  8. package/dist/api/expect.js.map +1 -0
  9. package/dist/api/hooks.d.ts +178 -0
  10. package/dist/api/hooks.d.ts.map +1 -0
  11. package/dist/api/hooks.js +231 -0
  12. package/dist/api/hooks.js.map +1 -0
  13. package/dist/api/steps.d.ts +45 -0
  14. package/dist/api/steps.d.ts.map +1 -0
  15. package/dist/api/steps.js +106 -0
  16. package/dist/api/steps.js.map +1 -0
  17. package/dist/api/test.d.ts +101 -0
  18. package/dist/api/test.d.ts.map +1 -0
  19. package/dist/api/test.js +207 -0
  20. package/dist/api/test.js.map +1 -0
  21. package/dist/cli/index.d.ts +7 -0
  22. package/dist/cli/index.d.ts.map +1 -0
  23. package/dist/cli/index.js +203 -0
  24. package/dist/cli/index.js.map +1 -0
  25. package/dist/cli/reporter.d.ts +108 -0
  26. package/dist/cli/reporter.d.ts.map +1 -0
  27. package/dist/cli/reporter.js +368 -0
  28. package/dist/cli/reporter.js.map +1 -0
  29. package/dist/index.d.ts +15 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +24 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/plugin/index.d.ts +47 -0
  34. package/dist/plugin/index.d.ts.map +1 -0
  35. package/dist/plugin/index.js +86 -0
  36. package/dist/plugin/index.js.map +1 -0
  37. package/dist/plugin/withPlugins.d.ts +71 -0
  38. package/dist/plugin/withPlugins.d.ts.map +1 -0
  39. package/dist/plugin/withPlugins.js +101 -0
  40. package/dist/plugin/withPlugins.js.map +1 -0
  41. package/dist/recording/recorder.d.ts +45 -0
  42. package/dist/recording/recorder.d.ts.map +1 -0
  43. package/dist/recording/recorder.js +97 -0
  44. package/dist/recording/recorder.js.map +1 -0
  45. package/dist/runner/artifacts.d.ts +39 -0
  46. package/dist/runner/artifacts.d.ts.map +1 -0
  47. package/dist/runner/artifacts.js +59 -0
  48. package/dist/runner/artifacts.js.map +1 -0
  49. package/dist/runner/config.d.ts +46 -0
  50. package/dist/runner/config.d.ts.map +1 -0
  51. package/dist/runner/config.js +65 -0
  52. package/dist/runner/config.js.map +1 -0
  53. package/dist/runner/filter.d.ts +26 -0
  54. package/dist/runner/filter.d.ts.map +1 -0
  55. package/dist/runner/filter.js +88 -0
  56. package/dist/runner/filter.js.map +1 -0
  57. package/dist/runner/loader.d.ts +32 -0
  58. package/dist/runner/loader.d.ts.map +1 -0
  59. package/dist/runner/loader.js +252 -0
  60. package/dist/runner/loader.js.map +1 -0
  61. package/dist/runner/models.d.ts +261 -0
  62. package/dist/runner/models.d.ts.map +1 -0
  63. package/dist/runner/models.js +5 -0
  64. package/dist/runner/models.js.map +1 -0
  65. package/dist/runner/runner.d.ts +36 -0
  66. package/dist/runner/runner.d.ts.map +1 -0
  67. package/dist/runner/runner.js +216 -0
  68. package/dist/runner/runner.js.map +1 -0
  69. package/dist/runner/scheduler.d.ts +59 -0
  70. package/dist/runner/scheduler.d.ts.map +1 -0
  71. package/dist/runner/scheduler.js +157 -0
  72. package/dist/runner/scheduler.js.map +1 -0
  73. package/dist/runner/worker-runner.d.ts +6 -0
  74. package/dist/runner/worker-runner.d.ts.map +1 -0
  75. package/dist/runner/worker-runner.js +51 -0
  76. package/dist/runner/worker-runner.js.map +1 -0
  77. package/dist/runner/worker.d.ts +54 -0
  78. package/dist/runner/worker.d.ts.map +1 -0
  79. package/dist/runner/worker.js +112 -0
  80. package/dist/runner/worker.js.map +1 -0
  81. package/dist/terminal/session.d.ts +56 -0
  82. package/dist/terminal/session.d.ts.map +1 -0
  83. package/dist/terminal/session.js +126 -0
  84. package/dist/terminal/session.js.map +1 -0
  85. package/dist/terminal/terminal.d.ts +284 -0
  86. package/dist/terminal/terminal.d.ts.map +1 -0
  87. package/dist/terminal/terminal.js +1167 -0
  88. package/dist/terminal/terminal.js.map +1 -0
  89. package/dist/utils/dependencies.d.ts +19 -0
  90. package/dist/utils/dependencies.d.ts.map +1 -0
  91. package/dist/utils/dependencies.js +58 -0
  92. package/dist/utils/dependencies.js.map +1 -0
  93. package/dist/utils/timing.d.ts +55 -0
  94. package/dist/utils/timing.d.ts.map +1 -0
  95. package/dist/utils/timing.js +87 -0
  96. package/dist/utils/timing.js.map +1 -0
  97. 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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"}