@react-native-harness/jest 1.4.0-rc.1 → 1.4.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.
Files changed (98) hide show
  1. package/dist/crash-monitor.d.ts +7 -0
  2. package/dist/crash-monitor.d.ts.map +1 -1
  3. package/dist/crash-monitor.js +19 -0
  4. package/dist/diagnostics/derivers.d.ts +24 -0
  5. package/dist/diagnostics/derivers.d.ts.map +1 -0
  6. package/dist/diagnostics/derivers.js +146 -0
  7. package/dist/diagnostics/index.d.ts +3 -0
  8. package/dist/diagnostics/index.d.ts.map +1 -0
  9. package/dist/diagnostics/index.js +2 -0
  10. package/dist/diagnostics/report.d.ts +7 -0
  11. package/dist/diagnostics/report.d.ts.map +1 -0
  12. package/dist/diagnostics/report.js +84 -0
  13. package/dist/environment-reset.d.ts +51 -0
  14. package/dist/environment-reset.d.ts.map +1 -0
  15. package/dist/environment-reset.js +83 -0
  16. package/dist/execute-run.d.ts.map +1 -1
  17. package/dist/execute-run.js +121 -69
  18. package/dist/format-harness-error.d.ts +5 -0
  19. package/dist/format-harness-error.d.ts.map +1 -0
  20. package/dist/format-harness-error.js +43 -0
  21. package/dist/harness-session.d.ts +26 -1
  22. package/dist/harness-session.d.ts.map +1 -1
  23. package/dist/harness-session.js +260 -87
  24. package/dist/run.d.ts.map +1 -1
  25. package/dist/run.js +21 -4
  26. package/package.json +8 -7
  27. package/src/crash-monitor.ts +28 -0
  28. package/src/diagnostics/derivers.ts +170 -0
  29. package/src/diagnostics/index.ts +2 -0
  30. package/src/diagnostics/report.ts +124 -0
  31. package/src/environment-reset.ts +138 -0
  32. package/src/execute-run.ts +136 -77
  33. package/src/format-harness-error.ts +73 -0
  34. package/src/harness-session.ts +369 -131
  35. package/src/run.ts +23 -4
  36. package/tsconfig.json +3 -0
  37. package/tsconfig.lib.json +3 -0
  38. package/dist/__tests__/bridge.test.d.ts +0 -2
  39. package/dist/__tests__/bridge.test.d.ts.map +0 -1
  40. package/dist/__tests__/bridge.test.js +0 -163
  41. package/dist/__tests__/client-log-handler.test.d.ts +0 -2
  42. package/dist/__tests__/client-log-handler.test.d.ts.map +0 -1
  43. package/dist/__tests__/client-log-handler.test.js +0 -306
  44. package/dist/__tests__/crash-monitor.test.d.ts +0 -2
  45. package/dist/__tests__/crash-monitor.test.d.ts.map +0 -1
  46. package/dist/__tests__/crash-monitor.test.js +0 -166
  47. package/dist/__tests__/crash-supervisor.test.d.ts +0 -2
  48. package/dist/__tests__/crash-supervisor.test.d.ts.map +0 -1
  49. package/dist/__tests__/crash-supervisor.test.js +0 -151
  50. package/dist/__tests__/errors.test.d.ts +0 -2
  51. package/dist/__tests__/errors.test.d.ts.map +0 -1
  52. package/dist/__tests__/errors.test.js +0 -98
  53. package/dist/__tests__/execute-run.test.d.ts +0 -2
  54. package/dist/__tests__/execute-run.test.d.ts.map +0 -1
  55. package/dist/__tests__/execute-run.test.js +0 -393
  56. package/dist/__tests__/fixtures/mock-platform-runner.d.ts +0 -7
  57. package/dist/__tests__/fixtures/mock-platform-runner.d.ts.map +0 -1
  58. package/dist/__tests__/fixtures/mock-platform-runner.js +0 -6
  59. package/dist/__tests__/harness-cache.test.d.ts +0 -2
  60. package/dist/__tests__/harness-cache.test.d.ts.map +0 -1
  61. package/dist/__tests__/harness-cache.test.js +0 -51
  62. package/dist/__tests__/harness-session.test.d.ts +0 -2
  63. package/dist/__tests__/harness-session.test.d.ts.map +0 -1
  64. package/dist/__tests__/harness-session.test.js +0 -74
  65. package/dist/__tests__/harness.test.d.ts +0 -2
  66. package/dist/__tests__/harness.test.d.ts.map +0 -1
  67. package/dist/__tests__/harness.test.js +0 -636
  68. package/dist/__tests__/hook-queue.test.d.ts +0 -2
  69. package/dist/__tests__/hook-queue.test.d.ts.map +0 -1
  70. package/dist/__tests__/hook-queue.test.js +0 -56
  71. package/dist/__tests__/index.test.d.ts +0 -2
  72. package/dist/__tests__/index.test.d.ts.map +0 -1
  73. package/dist/__tests__/index.test.js +0 -148
  74. package/dist/__tests__/metro-port.test.d.ts +0 -2
  75. package/dist/__tests__/metro-port.test.d.ts.map +0 -1
  76. package/dist/__tests__/metro-port.test.js +0 -52
  77. package/dist/__tests__/resource-lock.test.d.ts +0 -2
  78. package/dist/__tests__/resource-lock.test.d.ts.map +0 -1
  79. package/dist/__tests__/resource-lock.test.js +0 -138
  80. package/dist/__tests__/test-file-platform-filter.test.d.ts +0 -2
  81. package/dist/__tests__/test-file-platform-filter.test.d.ts.map +0 -1
  82. package/dist/__tests__/test-file-platform-filter.test.js +0 -47
  83. package/dist/cli-args.test.d.ts +0 -2
  84. package/dist/cli-args.test.d.ts.map +0 -1
  85. package/dist/cli-args.test.js +0 -1
  86. package/dist/tsconfig.lib.tsbuildinfo +0 -1
  87. package/src/__tests__/bridge.test.ts +0 -219
  88. package/src/__tests__/client-log-handler.test.ts +0 -364
  89. package/src/__tests__/crash-monitor.test.ts +0 -239
  90. package/src/__tests__/errors.test.ts +0 -157
  91. package/src/__tests__/execute-run.test.ts +0 -526
  92. package/src/__tests__/harness-session.test.ts +0 -93
  93. package/src/__tests__/hook-queue.test.ts +0 -77
  94. package/src/__tests__/index.test.ts +0 -219
  95. package/src/__tests__/metro-port.test.ts +0 -61
  96. package/src/__tests__/resource-lock.test.ts +0 -179
  97. package/src/__tests__/test-file-platform-filter.test.ts +0 -83
  98. package/tsconfig.tsbuildinfo +0 -1
@@ -1,9 +1,14 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import path from 'node:path';
3
3
  import { runHarnessTestFile } from './run.js';
4
+ import { resolveResetStrategyKind } from './environment-reset.js';
4
5
  import { NativeCrashError, RuntimeDisconnectError, StartupStallError, } from './errors.js';
5
6
  import { AppBridgeDisconnectedError, DeviceNotRespondingError, } from '@react-native-harness/bridge/server';
6
7
  import { createPlatformSkippedTestResult, shouldRunHarnessTestFile, } from './test-file-platform-filter.js';
8
+ import { formatHarnessErrorMessage } from './format-harness-error.js';
9
+ import { logger } from '@react-native-harness/tools';
10
+ import { printSummary, writeTraceFile } from './diagnostics/index.js';
11
+ const diagnosticsLogger = logger.child('diagnostics');
7
12
  const createRunSummary = () => ({ passed: 0, failed: 0, skipped: 0, todo: 0 });
8
13
  const applyJestResultToSummary = (summary, result) => {
9
14
  summary.passed += result.numPassingTests;
@@ -38,8 +43,10 @@ const emitHarnessTestStarted = async (emitEvent, event) => {
38
43
  });
39
44
  };
40
45
  const emitHarnessTestFinished = async (emitEvent, event) => {
41
- const failureMessage = event.error?.message;
42
46
  const codeFrame = event.error?.codeFrame;
47
+ const failureMessage = formatHarnessErrorMessage(event.error, {
48
+ testStartedAt: event.startedAt,
49
+ });
43
50
  const location = codeFrame?.location
44
51
  ? { column: codeFrame.location.column, line: codeFrame.location.row }
45
52
  : null;
@@ -47,9 +54,7 @@ const emitHarnessTestFinished = async (emitEvent, event) => {
47
54
  ancestorTitles: event.ancestorTitles,
48
55
  duration: event.duration,
49
56
  failureDetails: [],
50
- failureMessages: failureMessage
51
- ? [`${failureMessage}${codeFrame ? `\n\n${codeFrame.content}` : ''}`]
52
- : [],
57
+ failureMessages: failureMessage ? [failureMessage] : [],
53
58
  fullName: event.fullName,
54
59
  location,
55
60
  numPassingAsserts: event.status === 'passed' ? 1 : 0,
@@ -60,8 +65,17 @@ const emitHarnessTestFinished = async (emitEvent, event) => {
60
65
  await emitEvent('test-case-result', event.file, testCaseResult);
61
66
  };
62
67
  const isHarnessCaseEvent = (event) => event.type === 'test-started' || event.type === 'test-finished';
68
+ const TIMEOUT_ERROR_NAMES = new Set([
69
+ 'SuiteHookTimeoutError',
70
+ 'TestCaseTimeoutError',
71
+ ]);
72
+ const hasRuntimeTimeout = (result) => (result.error ? TIMEOUT_ERROR_NAMES.has(result.error.name) : false) ||
73
+ result.tests.some((test) => test.error ? TIMEOUT_ERROR_NAMES.has(test.error.name) : false) ||
74
+ result.suites.some(hasRuntimeTimeout);
63
75
  export const executeRun = async (session, tests, watcher, emitEvent, globalConfig) => {
64
76
  const runId = randomUUID();
77
+ const diagnostics = session.diagnostics.child({ runId });
78
+ const runSpan = diagnostics.start('run.total', { runId });
65
79
  const startTime = Date.now();
66
80
  const watchMode = globalConfig.watch || globalConfig.watchAll;
67
81
  const rootDir = globalConfig.rootDir ?? process.cwd();
@@ -82,6 +96,7 @@ export const executeRun = async (session, tests, watcher, emitEvent, globalConfi
82
96
  testFiles,
83
97
  watchMode,
84
98
  coverageEnabled: globalConfig.collectCoverage,
99
+ completed: false,
85
100
  summary,
86
101
  status: summary.failed > 0 ? 'failed' : 'passed',
87
102
  ...overrides,
@@ -102,10 +117,11 @@ export const executeRun = async (session, tests, watcher, emitEvent, globalConfi
102
117
  port: session.config.metroPort,
103
118
  host: session.config.host?.trim() || undefined,
104
119
  });
105
- const shouldResetEnv = session.config.resetEnvironmentBetweenTestFiles;
120
+ const resetStrategyKind = resolveResetStrategyKind(session.config.resetEnvironmentBetweenTestFiles);
106
121
  const platformId = session.context.platform.platformId;
107
122
  const knownPlatformIds = new Set(session.config.runners.map((runner) => runner.platformId));
108
123
  let isFirstTest = true;
124
+ let shouldRestartAfterTimeout = false;
109
125
  let runError;
110
126
  try {
111
127
  for (const test of tests) {
@@ -125,20 +141,82 @@ export const executeRun = async (session, tests, watcher, emitEvent, globalConfi
125
141
  });
126
142
  };
127
143
  await session.callHook('test-file:started', { runId, file: relativeTestPath });
128
- if (!shouldRunHarnessTestFile(test.path, platformId, knownPlatformIds)) {
144
+ const fileSpan = diagnostics.start('run.file', { file: relativeTestPath });
145
+ let fileStatus = 'failed';
146
+ try {
147
+ if (!shouldRunHarnessTestFile(test.path, platformId, knownPlatformIds)) {
148
+ try {
149
+ await emitEvent('test-file-start', test);
150
+ const skippedResult = createPlatformSkippedTestResult(test.path);
151
+ applyJestResultToSummary(summary, skippedResult);
152
+ updateRunState();
153
+ fileStatus = 'skipped';
154
+ await emitTestFileFinished({
155
+ status: 'skipped',
156
+ duration: Date.now() - fileStartedAt,
157
+ result: null,
158
+ });
159
+ await emitEvent('test-file-success', test, skippedResult);
160
+ }
161
+ catch (err) {
162
+ fileStatus = 'failed';
163
+ if (!emittedTestFileFinished) {
164
+ await emitTestFileFinished({
165
+ status: 'failed',
166
+ duration: Date.now() - fileStartedAt,
167
+ result: null,
168
+ });
169
+ }
170
+ updateRunState({ error: err });
171
+ await emitEvent('test-file-failure', test, buildTestFailure(err));
172
+ }
173
+ continue;
174
+ }
129
175
  try {
176
+ if (shouldRestartAfterTimeout) {
177
+ // Recovery from a runtime timeout always uses the (stronger)
178
+ // process restart, never the configured reset strategy.
179
+ await session.restartApp(test.path);
180
+ shouldRestartAfterTimeout = false;
181
+ }
182
+ else if (resetStrategyKind !== null && !isFirstTest) {
183
+ await session.resetEnvironment(test.path);
184
+ }
185
+ isFirstTest = false;
186
+ session.flushClientLogs();
130
187
  await emitEvent('test-file-start', test);
131
- const skippedResult = createPlatformSkippedTestResult(test.path);
132
- applyJestResultToSummary(summary, skippedResult);
188
+ await session.ensureAppReady(test.path);
189
+ // Crash detection is handled inside session.runTestFile; NativeCrashError
190
+ // propagates here if a crash wins the race.
191
+ const result = await runHarnessTestFile({
192
+ testPath: test.path,
193
+ session,
194
+ globalConfig,
195
+ projectConfig: test.context.config,
196
+ });
197
+ applyJestResultToSummary(summary, result.jestResult);
198
+ const clientLogs = session.flushClientLogs();
199
+ if (clientLogs.length > 0) {
200
+ result.jestResult.console = clientLogs;
201
+ }
133
202
  updateRunState();
203
+ fileStatus = result.harnessResult.status;
134
204
  await emitTestFileFinished({
135
- status: 'skipped',
136
- duration: Date.now() - fileStartedAt,
137
- result: null,
205
+ status: result.harnessResult.status,
206
+ duration: result.duration,
207
+ result: result.harnessResult,
138
208
  });
139
- await emitEvent('test-file-success', test, skippedResult);
209
+ const didRuntimeTimeout = hasRuntimeTimeout(result.harnessResult);
210
+ shouldRestartAfterTimeout = didRuntimeTimeout;
211
+ await caseEventChain;
212
+ await emitEvent('test-file-success', test, result.jestResult);
213
+ if (didRuntimeTimeout) {
214
+ await session.restartApp(test.path);
215
+ shouldRestartAfterTimeout = false;
216
+ }
140
217
  }
141
218
  catch (err) {
219
+ fileStatus = 'failed';
142
220
  if (!emittedTestFileFinished) {
143
221
  await emitTestFileFinished({
144
222
  status: 'failed',
@@ -146,64 +224,25 @@ export const executeRun = async (session, tests, watcher, emitEvent, globalConfi
146
224
  result: null,
147
225
  });
148
226
  }
149
- updateRunState({ error: err });
227
+ const isRuntimeFailure = err instanceof NativeCrashError ||
228
+ err instanceof RuntimeDisconnectError ||
229
+ err instanceof StartupStallError ||
230
+ err instanceof AppBridgeDisconnectedError ||
231
+ err instanceof DeviceNotRespondingError;
232
+ if (isRuntimeFailure) {
233
+ summary.failed += 1;
234
+ updateRunState();
235
+ }
236
+ if (err instanceof NativeCrashError || err instanceof RuntimeDisconnectError) {
237
+ session.resetCrashState();
238
+ }
239
+ updateRunState({ error: isRuntimeFailure ? undefined : err });
240
+ await caseEventChain;
150
241
  await emitEvent('test-file-failure', test, buildTestFailure(err));
151
242
  }
152
- continue;
153
243
  }
154
- try {
155
- if (shouldResetEnv && !isFirstTest) {
156
- await session.restartApp(test.path);
157
- }
158
- isFirstTest = false;
159
- session.flushClientLogs();
160
- await emitEvent('test-file-start', test);
161
- await session.ensureAppReady(test.path);
162
- // Crash detection is handled inside session.runTestFile; NativeCrashError
163
- // propagates here if a crash wins the race.
164
- const result = await runHarnessTestFile({
165
- testPath: test.path,
166
- session,
167
- globalConfig,
168
- projectConfig: test.context.config,
169
- });
170
- applyJestResultToSummary(summary, result.jestResult);
171
- const clientLogs = session.flushClientLogs();
172
- if (clientLogs.length > 0) {
173
- result.jestResult.console = clientLogs;
174
- }
175
- updateRunState();
176
- await emitTestFileFinished({
177
- status: result.harnessResult.status,
178
- duration: result.duration,
179
- result: result.harnessResult,
180
- });
181
- await caseEventChain;
182
- await emitEvent('test-file-success', test, result.jestResult);
183
- }
184
- catch (err) {
185
- if (!emittedTestFileFinished) {
186
- await emitTestFileFinished({
187
- status: 'failed',
188
- duration: Date.now() - fileStartedAt,
189
- result: null,
190
- });
191
- }
192
- const isRuntimeFailure = err instanceof NativeCrashError ||
193
- err instanceof RuntimeDisconnectError ||
194
- err instanceof StartupStallError ||
195
- err instanceof AppBridgeDisconnectedError ||
196
- err instanceof DeviceNotRespondingError;
197
- if (isRuntimeFailure) {
198
- summary.failed += 1;
199
- updateRunState();
200
- }
201
- if (err instanceof NativeCrashError || err instanceof RuntimeDisconnectError) {
202
- session.resetCrashState();
203
- }
204
- updateRunState({ error: isRuntimeFailure ? undefined : err });
205
- await caseEventChain;
206
- await emitEvent('test-file-failure', test, buildTestFailure(err));
244
+ finally {
245
+ fileSpan.end({ status: fileStatus });
207
246
  }
208
247
  }
209
248
  }
@@ -213,17 +252,30 @@ export const executeRun = async (session, tests, watcher, emitEvent, globalConfi
213
252
  throw err;
214
253
  }
215
254
  finally {
216
- const runState = updateRunState(runError != null ? { error: runError, status: 'failed' } : {});
255
+ const runState = updateRunState(runError != null ? { completed: true, error: runError, status: 'failed' } : { completed: true });
256
+ const finalStatus = runState.status ?? (runError != null ? 'failed' : 'passed');
217
257
  await session.callHook('run:finished', {
218
258
  runId,
219
259
  startTime,
220
260
  duration: Date.now() - startTime,
221
261
  testFiles,
222
262
  summary,
223
- status: runState.status ?? (runError != null ? 'failed' : 'passed'),
263
+ status: finalStatus,
224
264
  ...(runError != null ? { error: runError } : {}),
225
265
  });
226
266
  await caseEventChain;
227
267
  unsubscribe();
268
+ runSpan.end({ runId, status: finalStatus });
269
+ if (session.diagnostics.enabled) {
270
+ const entries = session.diagnostics.flush();
271
+ try {
272
+ printSummary(entries, (line) => diagnosticsLogger.info(line));
273
+ const tracePath = await writeTraceFile(entries, { projectRoot: rootDir, runId });
274
+ diagnosticsLogger.info(`wrote diagnostics trace to ${tracePath}`);
275
+ }
276
+ catch (reportError) {
277
+ diagnosticsLogger.warn('failed to write diagnostics report: %s', reportError);
278
+ }
279
+ }
228
280
  }
229
281
  };
@@ -0,0 +1,5 @@
1
+ import type { SerializedError } from '@react-native-harness/bridge';
2
+ export declare const formatHarnessErrorMessage: (error: SerializedError | undefined, options?: {
3
+ testStartedAt?: number;
4
+ }) => string | undefined;
5
+ //# sourceMappingURL=format-harness-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-harness-error.d.ts","sourceRoot":"","sources":["../src/format-harness-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AA6CpE,eAAO,MAAM,yBAAyB,GACpC,OAAO,eAAe,GAAG,SAAS,EAClC,UAAS;IACP,aAAa,CAAC,EAAE,MAAM,CAAC;CACnB,KACL,MAAM,GAAG,SAsBX,CAAC"}
@@ -0,0 +1,43 @@
1
+ const formatPendingPromiseStack = (stack) => stack
2
+ .split('\n')
3
+ .map((line) => ` ${line}`)
4
+ .join('\n');
5
+ const formatPendingPromises = (pendingPromises, testStartedAt) => {
6
+ if (pendingPromises.total === 0) {
7
+ return null;
8
+ }
9
+ const lines = [`Pending promises at timeout: ${pendingPromises.total}`];
10
+ if (pendingPromises.items.length < pendingPromises.total) {
11
+ lines.push(`Showing ${pendingPromises.items.length} of ${pendingPromises.total} pending promises.`);
12
+ }
13
+ for (const promise of pendingPromises.items) {
14
+ const age = testStartedAt !== undefined
15
+ ? `, created ${Math.max(0, promise.createdAt - testStartedAt)}ms after test start`
16
+ : '';
17
+ lines.push('');
18
+ lines.push(`Promise #${promise.id}${age}:`);
19
+ if (promise.stack) {
20
+ lines.push(formatPendingPromiseStack(promise.stack));
21
+ }
22
+ else {
23
+ lines.push(' <stack unavailable>');
24
+ }
25
+ }
26
+ return lines.join('\n');
27
+ };
28
+ export const formatHarnessErrorMessage = (error, options = {}) => {
29
+ if (!error) {
30
+ return undefined;
31
+ }
32
+ const parts = [error.message];
33
+ const pendingPromiseDetails = error.diagnostics?.pendingPromises
34
+ ? formatPendingPromises(error.diagnostics.pendingPromises, options.testStartedAt)
35
+ : null;
36
+ if (pendingPromiseDetails) {
37
+ parts.push(pendingPromiseDetails);
38
+ }
39
+ if (error.codeFrame) {
40
+ parts.push(error.codeFrame.content);
41
+ }
42
+ return parts.join('\n\n');
43
+ };
@@ -1,7 +1,8 @@
1
- import { type AppConnection } from '@react-native-harness/bridge/server';
1
+ import { type HarnessBridge, type AppConnection } from '@react-native-harness/bridge/server';
2
2
  import { type HarnessContext, type TestRunnerEvents, type TestExecutionOptions, type TestSuiteResult } from '@react-native-harness/bridge';
3
3
  import { type HarnessPlatform } from '@react-native-harness/platforms';
4
4
  import { type HarnessPluginManager, type HarnessRunStatus, type HarnessRunSummary } from '@react-native-harness/plugins';
5
+ import { type Diagnostics } from '@react-native-harness/tools';
5
6
  import { type Config as HarnessConfig } from '@react-native-harness/config';
6
7
  import type { Config as JestConfig } from 'jest-runner';
7
8
  import { type CrashMonitor } from './crash-monitor.js';
@@ -17,12 +18,17 @@ export declare const waitForBridgeDisconnectOrTimeout: ({ bridge, connection, ti
17
18
  connection: AppConnection;
18
19
  timeoutMs: number;
19
20
  }) => Promise<boolean>;
21
+ export declare const waitForNextConnected: ({ bridge, signal, }: {
22
+ bridge: Pick<HarnessBridge, "on" | "off">;
23
+ signal: AbortSignal;
24
+ }) => Promise<void>;
20
25
  export type HarnessRunState = {
21
26
  readonly runId: string;
22
27
  readonly startTime: number;
23
28
  readonly testFiles: string[];
24
29
  readonly watchMode: boolean;
25
30
  readonly coverageEnabled: boolean;
31
+ readonly completed?: boolean;
26
32
  readonly summary?: HarnessRunSummary;
27
33
  readonly status?: HarnessRunStatus;
28
34
  readonly error?: unknown;
@@ -31,22 +37,41 @@ export type HarnessRunTestsOptions = Exclude<TestExecutionOptions, 'platform'>;
31
37
  export type HarnessSession = {
32
38
  readonly config: HarnessConfig;
33
39
  readonly context: HarnessContext;
40
+ readonly diagnostics: Diagnostics;
34
41
  onTestRunnerEvent: (listener: (event: TestRunnerEvents) => void) => () => void;
35
42
  runTestFile: (path: string, options: HarnessRunTestsOptions) => Promise<TestSuiteResult>;
36
43
  ensureAppReady: (testFilePath: string) => Promise<void>;
37
44
  restartApp: (testFilePath?: string) => Promise<void>;
45
+ resetEnvironment: (testFilePath: string) => Promise<void>;
38
46
  resetCrashState: () => void;
39
47
  flushClientLogs: () => ClientLogBuffer;
40
48
  callHook: HarnessPluginManager<HarnessConfig, HarnessPlatform>['callHook'];
41
49
  setRunState: (state: HarnessRunState | null) => void;
42
50
  dispose: (reason?: 'normal' | 'abort' | 'error') => Promise<void>;
43
51
  };
52
+ export declare const getSignalExitCodeForRunState: (state: HarnessRunState | null) => number;
53
+ export declare const withPlatformReadyTimeout: <T>(options: {
54
+ timeout: number;
55
+ signal: AbortSignal;
56
+ work: (signal: AbortSignal) => Promise<T>;
57
+ }) => Promise<T>;
44
58
  export declare const waitForStartupCrash: ({ crashMonitor, detectNativeCrashes, testFilePath, signal, }: {
45
59
  crashMonitor: CrashMonitor;
46
60
  detectNativeCrashes: boolean;
47
61
  testFilePath: string;
48
62
  signal: AbortSignal;
49
63
  }) => Promise<never>;
64
+ /**
65
+ * Logs the "Reusing Metro cache" message when persistent Metro caching is
66
+ * enabled and the cache is warm. `projectRoot` must be the config-resolved
67
+ * project root so the warmth check looks at the same directory Metro caches
68
+ * into.
69
+ */
70
+ export declare const maybeLogMetroCacheReused: (options: {
71
+ config: Pick<HarnessConfig, "cache" | "unstable__enableMetroCache">;
72
+ projectRoot: string;
73
+ platform: HarnessPlatform;
74
+ }) => void;
50
75
  export declare const createHarnessSession: (globalConfig: JestConfig.GlobalConfig, { lockManager }?: {
51
76
  lockManager?: ResourceLockManager;
52
77
  }) => Promise<HarnessSession>;
@@ -1 +1 @@
1
- {"version":3,"file":"harness-session.d.ts","sourceRoot":"","sources":["../src/harness-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"harness-session.d.ts","sourceRoot":"","sources":["../src/harness-session.ts"],"names":[],"mappings":"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"}