@react-native-harness/runtime 1.2.0-rc.1 → 1.3.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 (99) hide show
  1. package/dist/client/factory.d.ts +2 -1
  2. package/dist/client/factory.d.ts.map +1 -1
  3. package/dist/client/factory.js +53 -59
  4. package/dist/client/store.d.ts +3 -3
  5. package/dist/client/store.d.ts.map +1 -1
  6. package/dist/client/store.js +7 -7
  7. package/dist/collector/functions.d.ts +3 -3
  8. package/dist/collector/functions.d.ts.map +1 -1
  9. package/dist/collector/types.d.ts +3 -2
  10. package/dist/collector/types.d.ts.map +1 -1
  11. package/dist/collector/validation.d.ts +2 -2
  12. package/dist/collector/validation.d.ts.map +1 -1
  13. package/dist/device/index.d.ts +12 -0
  14. package/dist/device/index.d.ts.map +1 -0
  15. package/dist/device/index.js +62 -0
  16. package/dist/expect/matchers/toMatchImageSnapshot.d.ts +1 -1
  17. package/dist/expect/matchers/toMatchImageSnapshot.d.ts.map +1 -1
  18. package/dist/expect/matchers/toMatchImageSnapshot.js +4 -12
  19. package/dist/hmr.d.ts +2 -0
  20. package/dist/hmr.d.ts.map +1 -0
  21. package/dist/hmr.js +5 -0
  22. package/dist/initialize.js +14 -5
  23. package/dist/jsx/jsx-dev-runtime.d.ts +2 -1
  24. package/dist/jsx/jsx-dev-runtime.d.ts.map +1 -1
  25. package/dist/jsx/jsx-dev-runtime.js +16 -7
  26. package/dist/logbox.d.ts +4 -0
  27. package/dist/logbox.d.ts.map +1 -0
  28. package/dist/logbox.js +18 -0
  29. package/dist/runner/hooks.d.ts +2 -1
  30. package/dist/runner/hooks.d.ts.map +1 -1
  31. package/dist/runner/hooks.js +27 -17
  32. package/dist/runner/runSuite.d.ts.map +1 -1
  33. package/dist/runner/runSuite.js +56 -6
  34. package/dist/runner/test-context.d.ts +16 -0
  35. package/dist/runner/test-context.d.ts.map +1 -0
  36. package/dist/runner/test-context.js +57 -0
  37. package/dist/runner/types.d.ts +2 -1
  38. package/dist/runner/types.d.ts.map +1 -1
  39. package/dist/test-utils/react-native-url-polyfill.d.ts +9 -0
  40. package/dist/test-utils/react-native-url-polyfill.d.ts.map +1 -0
  41. package/dist/test-utils/react-native-url-polyfill.js +1 -0
  42. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  43. package/dist/waitFor.d.ts.map +1 -1
  44. package/dist/waitFor.js +5 -3
  45. package/out-tsc/vitest/src/__tests__/device.test.d.ts +2 -0
  46. package/out-tsc/vitest/src/__tests__/device.test.d.ts.map +1 -0
  47. package/out-tsc/vitest/src/__tests__/logbox.test.d.ts +2 -0
  48. package/out-tsc/vitest/src/__tests__/logbox.test.d.ts.map +1 -0
  49. package/out-tsc/vitest/src/__tests__/runner-context.test.d.ts +2 -0
  50. package/out-tsc/vitest/src/__tests__/runner-context.test.d.ts.map +1 -0
  51. package/out-tsc/vitest/src/client/factory.d.ts +2 -1
  52. package/out-tsc/vitest/src/client/factory.d.ts.map +1 -1
  53. package/out-tsc/vitest/src/client/store.d.ts +3 -3
  54. package/out-tsc/vitest/src/client/store.d.ts.map +1 -1
  55. package/out-tsc/vitest/src/collector/functions.d.ts +3 -3
  56. package/out-tsc/vitest/src/collector/functions.d.ts.map +1 -1
  57. package/out-tsc/vitest/src/collector/types.d.ts +3 -2
  58. package/out-tsc/vitest/src/collector/types.d.ts.map +1 -1
  59. package/out-tsc/vitest/src/collector/validation.d.ts +2 -2
  60. package/out-tsc/vitest/src/collector/validation.d.ts.map +1 -1
  61. package/out-tsc/vitest/src/device/index.d.ts +12 -0
  62. package/out-tsc/vitest/src/device/index.d.ts.map +1 -0
  63. package/out-tsc/vitest/src/expect/matchers/toMatchImageSnapshot.d.ts +1 -1
  64. package/out-tsc/vitest/src/expect/matchers/toMatchImageSnapshot.d.ts.map +1 -1
  65. package/out-tsc/vitest/src/hmr.d.ts +2 -0
  66. package/out-tsc/vitest/src/hmr.d.ts.map +1 -0
  67. package/out-tsc/vitest/src/jsx/jsx-dev-runtime.d.ts +2 -1
  68. package/out-tsc/vitest/src/jsx/jsx-dev-runtime.d.ts.map +1 -1
  69. package/out-tsc/vitest/src/logbox.d.ts +4 -0
  70. package/out-tsc/vitest/src/logbox.d.ts.map +1 -0
  71. package/out-tsc/vitest/src/runner/hooks.d.ts +2 -1
  72. package/out-tsc/vitest/src/runner/hooks.d.ts.map +1 -1
  73. package/out-tsc/vitest/src/runner/runSuite.d.ts.map +1 -1
  74. package/out-tsc/vitest/src/runner/test-context.d.ts +16 -0
  75. package/out-tsc/vitest/src/runner/test-context.d.ts.map +1 -0
  76. package/out-tsc/vitest/src/runner/types.d.ts +2 -1
  77. package/out-tsc/vitest/src/runner/types.d.ts.map +1 -1
  78. package/out-tsc/vitest/src/test-utils/react-native-url-polyfill.d.ts +9 -0
  79. package/out-tsc/vitest/src/test-utils/react-native-url-polyfill.d.ts.map +1 -0
  80. package/out-tsc/vitest/src/waitFor.d.ts.map +1 -1
  81. package/out-tsc/vitest/tsconfig.spec.tsbuildinfo +1 -1
  82. package/out-tsc/vitest/vite.config.d.ts.map +1 -1
  83. package/package.json +2 -2
  84. package/src/__tests__/runner-context.test.ts +483 -0
  85. package/src/client/factory.ts +63 -74
  86. package/src/client/store.ts +8 -8
  87. package/src/collector/functions.ts +5 -4
  88. package/src/collector/types.ts +4 -1
  89. package/src/collector/validation.ts +2 -2
  90. package/src/expect/matchers/toMatchImageSnapshot.ts +9 -23
  91. package/src/initialize.ts +14 -5
  92. package/src/jsx/jsx-dev-runtime.ts +34 -15
  93. package/src/runner/hooks.ts +43 -19
  94. package/src/runner/runSuite.ts +75 -9
  95. package/src/runner/test-context.ts +84 -0
  96. package/src/runner/types.ts +3 -0
  97. package/src/test-utils/react-native-url-polyfill.ts +1 -0
  98. package/src/waitFor.ts +8 -6
  99. package/vite.config.ts +4 -0
@@ -2,8 +2,26 @@ import { setCurrentExpectTestState, } from '../expect/context.js';
2
2
  import { flushExpectTestState } from '../expect/errors.js';
3
3
  import { runHooks } from './hooks.js';
4
4
  import { getTestExecutionError } from './errors.js';
5
+ import { createTestContext, createTestLifecycleState, isSkipTestError, runOnTestFailed, runOnTestFinished, } from './test-context.js';
5
6
  const runTest = async (test, suite, context) => {
6
7
  const startTime = Date.now();
8
+ const task = {
9
+ name: test.name,
10
+ type: 'test',
11
+ mode: test.status === 'active'
12
+ ? 'run'
13
+ : test.status === 'skipped'
14
+ ? 'skip'
15
+ : 'todo',
16
+ file: {
17
+ name: context.testFilePath,
18
+ },
19
+ suite: {
20
+ name: suite.name,
21
+ },
22
+ };
23
+ const lifecycleState = createTestLifecycleState();
24
+ const activeTestContext = createTestContext(task, lifecycleState);
7
25
  // Emit test-started event
8
26
  context.events.emit({
9
27
  type: 'test-started',
@@ -50,13 +68,43 @@ const runTest = async (test, suite, context) => {
50
68
  const expectTestState = {};
51
69
  setCurrentExpectTestState(expectTestState);
52
70
  try {
53
- // Run all beforeEach hooks from the current suite and its parents
54
- await runHooks(suite, 'beforeEach');
55
- // Run the actual test
56
- await test.fn();
57
- // Run all afterEach hooks from the current suite and its parents
58
- await runHooks(suite, 'afterEach');
71
+ let didSkip = false;
72
+ try {
73
+ // Run all beforeEach hooks from the current suite and its parents
74
+ await runHooks(suite, 'beforeEach', activeTestContext);
75
+ // Run the actual test
76
+ await test.fn(activeTestContext);
77
+ }
78
+ catch (error) {
79
+ if (!isSkipTestError(error)) {
80
+ throw error;
81
+ }
82
+ didSkip = true;
83
+ }
84
+ finally {
85
+ // Run all afterEach hooks from the current suite and its parents
86
+ await runHooks(suite, 'afterEach', activeTestContext);
87
+ }
88
+ if (didSkip) {
89
+ const duration = Date.now() - startTime;
90
+ await runOnTestFinished(lifecycleState);
91
+ const result = {
92
+ name: test.name,
93
+ status: 'skipped',
94
+ duration,
95
+ };
96
+ context.events.emit({
97
+ type: 'test-finished',
98
+ file: context.testFilePath,
99
+ suite: suite.name,
100
+ name: test.name,
101
+ duration,
102
+ status: 'skipped',
103
+ });
104
+ return result;
105
+ }
59
106
  await flushExpectTestState(expectTestState);
107
+ await runOnTestFinished(lifecycleState);
60
108
  }
61
109
  finally {
62
110
  setCurrentExpectTestState(undefined);
@@ -79,6 +127,8 @@ const runTest = async (test, suite, context) => {
79
127
  return result;
80
128
  }
81
129
  catch (error) {
130
+ await runOnTestFailed(lifecycleState);
131
+ await runOnTestFinished(lifecycleState);
82
132
  const testError = await getTestExecutionError(error, context.testFilePath, suite.name, test.name);
83
133
  const duration = Date.now() - startTime;
84
134
  const result = {
@@ -0,0 +1,16 @@
1
+ import type { HarnessTaskContext } from '@react-native-harness/bridge';
2
+ import type { ActiveTestContext } from './types.js';
3
+ export type TestLifecycleState = {
4
+ onTestFailed: Array<() => void | Promise<void>>;
5
+ onTestFinished: Array<() => void | Promise<void>>;
6
+ };
7
+ export declare class SkipTestError extends Error {
8
+ note?: string;
9
+ constructor(note?: string);
10
+ }
11
+ export declare const isSkipTestError: (error: unknown) => error is SkipTestError;
12
+ export declare const createTestLifecycleState: () => TestLifecycleState;
13
+ export declare const runOnTestFailed: (state: TestLifecycleState) => Promise<void>;
14
+ export declare const runOnTestFinished: (state: TestLifecycleState) => Promise<void>;
15
+ export declare const createTestContext: (task: HarnessTaskContext, state: TestLifecycleState) => ActiveTestContext;
16
+ //# sourceMappingURL=test-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-context.d.ts","sourceRoot":"","sources":["../../src/runner/test-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,cAAc,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACnD,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEF,IAAI,CAAC,EAAE,MAAM;CAK1B;AAED,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,aAEzD,CAAC;AA8BF,eAAO,MAAM,wBAAwB,QAAO,kBAK3C,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,OAAO,kBAAkB,KACxB,OAAO,CAAC,IAAI,CAId,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,kBAAkB,KACxB,OAAO,CAAC,IAAI,CAId,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,kBAAkB,EACxB,OAAO,kBAAkB,KACxB,iBAOF,CAAC"}
@@ -0,0 +1,57 @@
1
+ export class SkipTestError extends Error {
2
+ note;
3
+ constructor(note) {
4
+ super(note ?? 'Test skipped');
5
+ this.name = 'SkipTestError';
6
+ this.note = note;
7
+ }
8
+ }
9
+ export const isSkipTestError = (error) => {
10
+ return error instanceof SkipTestError;
11
+ };
12
+ const createSkip = () => {
13
+ function skip(noteOrCondition, note) {
14
+ if (typeof noteOrCondition === 'boolean') {
15
+ if (!noteOrCondition) {
16
+ return;
17
+ }
18
+ throw new SkipTestError(note);
19
+ }
20
+ throw new SkipTestError(noteOrCondition);
21
+ }
22
+ return skip;
23
+ };
24
+ const createOnTestFinished = (state) => {
25
+ return (fn) => {
26
+ state.onTestFinished.push(fn);
27
+ };
28
+ };
29
+ const createOnTestFailed = (state) => {
30
+ return (fn) => {
31
+ state.onTestFailed.push(fn);
32
+ };
33
+ };
34
+ export const createTestLifecycleState = () => {
35
+ return {
36
+ onTestFailed: [],
37
+ onTestFinished: [],
38
+ };
39
+ };
40
+ export const runOnTestFailed = async (state) => {
41
+ for (let i = state.onTestFailed.length - 1; i >= 0; i--) {
42
+ await state.onTestFailed[i]();
43
+ }
44
+ };
45
+ export const runOnTestFinished = async (state) => {
46
+ for (let i = state.onTestFinished.length - 1; i >= 0; i--) {
47
+ await state.onTestFinished[i]();
48
+ }
49
+ };
50
+ export const createTestContext = (task, state) => {
51
+ return {
52
+ task,
53
+ onTestFailed: createOnTestFailed(state),
54
+ onTestFinished: createOnTestFinished(state),
55
+ skip: createSkip(),
56
+ };
57
+ };
@@ -1,10 +1,11 @@
1
1
  import { EventEmitter } from '../utils/emitter.js';
2
- import type { TestRunnerEvents, TestSuite, TestSuiteResult } from '@react-native-harness/bridge';
2
+ import type { HarnessTestContext, TestRunnerEvents, TestSuite, TestSuiteResult } from '@react-native-harness/bridge';
3
3
  export type TestRunnerEventsEmitter = EventEmitter<TestRunnerEvents>;
4
4
  export type TestRunnerContext = {
5
5
  events: TestRunnerEventsEmitter;
6
6
  testFilePath: string;
7
7
  };
8
+ export type ActiveTestContext = HarnessTestContext;
8
9
  export type RunTestsOptions = {
9
10
  testSuite: TestSuite;
10
11
  testFilePath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runner/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,EACT,eAAe,EAChB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAErE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,uBAAuB,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,uBAAuB,CAAC;IAChC,GAAG,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runner/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,eAAe,EAChB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAErE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,uBAAuB,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAEnD,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,uBAAuB,CAAC;IAChC,GAAG,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const URL: {
2
+ new (url: string | URL, base?: string | URL): URL;
3
+ prototype: URL;
4
+ canParse(url: string | URL, base?: string | URL): boolean;
5
+ createObjectURL(obj: Blob | MediaSource): string;
6
+ parse(url: string | URL, base?: string | URL): URL | null;
7
+ revokeObjectURL(url: string): void;
8
+ };
9
+ //# sourceMappingURL=react-native-url-polyfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-native-url-polyfill.d.ts","sourceRoot":"","sources":["../../src/test-utils/react-native-url-polyfill.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,GAAG;;;;;;;CAAiB,CAAC"}
@@ -0,0 +1 @@
1
+ export const URL = globalThis.URL;