Skip to content

Commit a4a23dd

Browse files
committed
feat: inline iOS simulator handling
1 parent 480c2a4 commit a4a23dd

15 files changed

Lines changed: 489 additions & 334 deletions

File tree

action.yml

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,7 @@ runs:
7272
${{ runner.os }}-metro-cache-
7373
7474
# ── iOS ──────────────────────────────────────────────────────────────────
75-
- uses: futureware-tech/simulator-action@v4
76-
if: fromJson(steps.load-config.outputs.config).platformId == 'ios'
77-
with:
78-
model: ${{ fromJson(steps.load-config.outputs.config).config.device.name }}
79-
os: iOS
80-
os_version: ${{ fromJson(steps.load-config.outputs.config).config.device.systemVersion }}
81-
wait_for_boot: true
82-
erase_before_boot: false
83-
- name: Install app
84-
if: fromJson(steps.load-config.outputs.config).platformId == 'ios'
85-
shell: bash
86-
working-directory: ${{ steps.load-config.outputs.projectRoot }}
87-
run: |
88-
xcrun simctl install booted ${{ inputs.app }}
75+
# iOS simulator boot and app installation are handled by Harness itself.
8976
# ── Android ──────────────────────────────────────────────────────────────
9077
- name: Verify Android config
9178
if: fromJson(steps.load-config.outputs.config).platformId == 'android'
@@ -232,48 +219,20 @@ runs:
232219
PRE_RUN_HOOK: ${{ inputs.preRunHook }}
233220
AFTER_RUN_HOOK: ${{ inputs.afterRunHook }}
234221
HARNESS_RUNNER: ${{ inputs.runner }}
222+
HARNESS_APP_PATH: ${{ inputs.app }}
235223
run: |
236224
export HARNESS_PROJECT_ROOT="$PWD"
237225
238-
if [ -n "$PRE_RUN_HOOK" ]; then
239-
pre_hook_file="$(mktemp "${RUNNER_TEMP:-/tmp}/harness-pre-run.XXXXXX.sh")"
240-
trap 'rm -f "$pre_hook_file"' EXIT
241-
printf '%s\n' "$PRE_RUN_HOOK" > "$pre_hook_file"
242-
chmod +x "$pre_hook_file"
243-
bash "$pre_hook_file"
244-
rm -f "$pre_hook_file"
245-
trap - EXIT
246-
fi
247-
248226
set +e
249227
${{ steps.detect-pm.outputs.runner }}react-native-harness --harnessRunner ${{ inputs.runner }} ${{ inputs.harnessArgs }}
250228
harness_exit_code=$?
251229
set -e
252230
253-
export HARNESS_EXIT_CODE="$harness_exit_code"
254-
after_run_exit_code=0
255-
if [ -n "$AFTER_RUN_HOOK" ]; then
256-
after_hook_file="$(mktemp "${RUNNER_TEMP:-/tmp}/harness-after-run.XXXXXX.sh")"
257-
trap 'rm -f "$after_hook_file"' EXIT
258-
printf '%s\n' "$AFTER_RUN_HOOK" > "$after_hook_file"
259-
chmod +x "$after_hook_file"
260-
set +e
261-
bash "$after_hook_file"
262-
after_run_exit_code=$?
263-
set -e
264-
rm -f "$after_hook_file"
265-
trap - EXIT
266-
fi
267-
268231
echo "harness_exit_code=$harness_exit_code" >> "$GITHUB_OUTPUT"
269232
270233
if [ "$harness_exit_code" -ne 0 ]; then
271234
exit "$harness_exit_code"
272235
fi
273-
274-
if [ "$after_run_exit_code" -ne 0 ]; then
275-
exit "$after_run_exit_code"
276-
fi
277236
- name: Run E2E tests
278237
id: run-tests-android
279238
if: fromJson(steps.load-config.outputs.config).platformId == 'android'

actions/ios/action.yml

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,6 @@ runs:
4343
INPUT_PROJECTROOT: ${{ inputs.projectRoot }}
4444
run: |
4545
node ${{ github.action_path }}/../shared/index.cjs
46-
- uses: futureware-tech/simulator-action@v4
47-
with:
48-
model: ${{ fromJson(steps.load-config.outputs.config).config.device.name }}
49-
os: iOS
50-
os_version: ${{ fromJson(steps.load-config.outputs.config).config.device.systemVersion }}
51-
wait_for_boot: true
52-
erase_before_boot: false
53-
- name: Install app
54-
shell: bash
55-
working-directory: ${{ inputs.projectRoot }}
56-
run: |
57-
xcrun simctl install booted ${{ inputs.app }}
5846
- name: Detect Package Manager
5947
id: detect-pm
6048
shell: bash
@@ -83,48 +71,20 @@ runs:
8371
PRE_RUN_HOOK: ${{ inputs.preRunHook }}
8472
AFTER_RUN_HOOK: ${{ inputs.afterRunHook }}
8573
HARNESS_RUNNER: ${{ inputs.runner }}
74+
HARNESS_APP_PATH: ${{ inputs.app }}
8675
run: |
8776
export HARNESS_PROJECT_ROOT="$PWD"
8877
89-
if [ -n "$PRE_RUN_HOOK" ]; then
90-
pre_hook_file="$(mktemp "${RUNNER_TEMP:-/tmp}/harness-pre-run.XXXXXX.sh")"
91-
trap 'rm -f "$pre_hook_file"' EXIT
92-
printf '%s\n' "$PRE_RUN_HOOK" > "$pre_hook_file"
93-
chmod +x "$pre_hook_file"
94-
bash "$pre_hook_file"
95-
rm -f "$pre_hook_file"
96-
trap - EXIT
97-
fi
98-
9978
set +e
10079
${{ steps.detect-pm.outputs.runner }}react-native-harness --harnessRunner ${{ inputs.runner }} ${{ inputs.harnessArgs }}
10180
harness_exit_code=$?
10281
set -e
10382
104-
export HARNESS_EXIT_CODE="$harness_exit_code"
105-
after_run_exit_code=0
106-
if [ -n "$AFTER_RUN_HOOK" ]; then
107-
after_hook_file="$(mktemp "${RUNNER_TEMP:-/tmp}/harness-after-run.XXXXXX.sh")"
108-
trap 'rm -f "$after_hook_file"' EXIT
109-
printf '%s\n' "$AFTER_RUN_HOOK" > "$after_hook_file"
110-
chmod +x "$after_hook_file"
111-
set +e
112-
bash "$after_hook_file"
113-
after_run_exit_code=$?
114-
set -e
115-
rm -f "$after_hook_file"
116-
trap - EXIT
117-
fi
118-
11983
echo "harness_exit_code=$harness_exit_code" >> "$GITHUB_OUTPUT"
12084
12185
if [ "$harness_exit_code" -ne 0 ]; then
12286
exit "$harness_exit_code"
12387
fi
124-
125-
if [ "$after_run_exit_code" -ne 0 ]; then
126-
exit "$after_run_exit_code"
127-
fi
12888
- name: Upload visual test artifacts
12989
if: always() && inputs.uploadVisualTestArtifacts == 'true'
13090
uses: actions/upload-artifact@v4

packages/github-action/src/action.yml

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,7 @@ runs:
7272
${{ runner.os }}-metro-cache-
7373
7474
# ── iOS ──────────────────────────────────────────────────────────────────
75-
- uses: futureware-tech/simulator-action@v4
76-
if: fromJson(steps.load-config.outputs.config).platformId == 'ios'
77-
with:
78-
model: ${{ fromJson(steps.load-config.outputs.config).config.device.name }}
79-
os: iOS
80-
os_version: ${{ fromJson(steps.load-config.outputs.config).config.device.systemVersion }}
81-
wait_for_boot: true
82-
erase_before_boot: false
83-
- name: Install app
84-
if: fromJson(steps.load-config.outputs.config).platformId == 'ios'
85-
shell: bash
86-
working-directory: ${{ steps.load-config.outputs.projectRoot }}
87-
run: |
88-
xcrun simctl install booted ${{ inputs.app }}
75+
# iOS simulator boot and app installation are handled by Harness itself.
8976
# ── Android ──────────────────────────────────────────────────────────────
9077
- name: Verify Android config
9178
if: fromJson(steps.load-config.outputs.config).platformId == 'android'
@@ -232,48 +219,20 @@ runs:
232219
PRE_RUN_HOOK: ${{ inputs.preRunHook }}
233220
AFTER_RUN_HOOK: ${{ inputs.afterRunHook }}
234221
HARNESS_RUNNER: ${{ inputs.runner }}
222+
HARNESS_APP_PATH: ${{ inputs.app }}
235223
run: |
236224
export HARNESS_PROJECT_ROOT="$PWD"
237225
238-
if [ -n "$PRE_RUN_HOOK" ]; then
239-
pre_hook_file="$(mktemp "${RUNNER_TEMP:-/tmp}/harness-pre-run.XXXXXX.sh")"
240-
trap 'rm -f "$pre_hook_file"' EXIT
241-
printf '%s\n' "$PRE_RUN_HOOK" > "$pre_hook_file"
242-
chmod +x "$pre_hook_file"
243-
bash "$pre_hook_file"
244-
rm -f "$pre_hook_file"
245-
trap - EXIT
246-
fi
247-
248226
set +e
249227
${{ steps.detect-pm.outputs.runner }}react-native-harness --harnessRunner ${{ inputs.runner }} ${{ inputs.harnessArgs }}
250228
harness_exit_code=$?
251229
set -e
252230
253-
export HARNESS_EXIT_CODE="$harness_exit_code"
254-
after_run_exit_code=0
255-
if [ -n "$AFTER_RUN_HOOK" ]; then
256-
after_hook_file="$(mktemp "${RUNNER_TEMP:-/tmp}/harness-after-run.XXXXXX.sh")"
257-
trap 'rm -f "$after_hook_file"' EXIT
258-
printf '%s\n' "$AFTER_RUN_HOOK" > "$after_hook_file"
259-
chmod +x "$after_hook_file"
260-
set +e
261-
bash "$after_hook_file"
262-
after_run_exit_code=$?
263-
set -e
264-
rm -f "$after_hook_file"
265-
trap - EXIT
266-
fi
267-
268231
echo "harness_exit_code=$harness_exit_code" >> "$GITHUB_OUTPUT"
269232
270233
if [ "$harness_exit_code" -ne 0 ]; then
271234
exit "$harness_exit_code"
272235
fi
273-
274-
if [ "$after_run_exit_code" -ne 0 ]; then
275-
exit "$after_run_exit_code"
276-
fi
277236
- name: Run E2E tests
278237
id: run-tests-android
279238
if: fromJson(steps.load-config.outputs.config).platformId == 'android'

packages/github-action/src/ios/action.yml

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,6 @@ runs:
4343
INPUT_PROJECTROOT: ${{ inputs.projectRoot }}
4444
run: |
4545
node ${{ github.action_path }}/../shared/index.cjs
46-
- uses: futureware-tech/simulator-action@v4
47-
with:
48-
model: ${{ fromJson(steps.load-config.outputs.config).config.device.name }}
49-
os: iOS
50-
os_version: ${{ fromJson(steps.load-config.outputs.config).config.device.systemVersion }}
51-
wait_for_boot: true
52-
erase_before_boot: false
53-
- name: Install app
54-
shell: bash
55-
working-directory: ${{ inputs.projectRoot }}
56-
run: |
57-
xcrun simctl install booted ${{ inputs.app }}
5846
- name: Detect Package Manager
5947
id: detect-pm
6048
shell: bash
@@ -83,48 +71,20 @@ runs:
8371
PRE_RUN_HOOK: ${{ inputs.preRunHook }}
8472
AFTER_RUN_HOOK: ${{ inputs.afterRunHook }}
8573
HARNESS_RUNNER: ${{ inputs.runner }}
74+
HARNESS_APP_PATH: ${{ inputs.app }}
8675
run: |
8776
export HARNESS_PROJECT_ROOT="$PWD"
8877
89-
if [ -n "$PRE_RUN_HOOK" ]; then
90-
pre_hook_file="$(mktemp "${RUNNER_TEMP:-/tmp}/harness-pre-run.XXXXXX.sh")"
91-
trap 'rm -f "$pre_hook_file"' EXIT
92-
printf '%s\n' "$PRE_RUN_HOOK" > "$pre_hook_file"
93-
chmod +x "$pre_hook_file"
94-
bash "$pre_hook_file"
95-
rm -f "$pre_hook_file"
96-
trap - EXIT
97-
fi
98-
9978
set +e
10079
${{ steps.detect-pm.outputs.runner }}react-native-harness --harnessRunner ${{ inputs.runner }} ${{ inputs.harnessArgs }}
10180
harness_exit_code=$?
10281
set -e
10382
104-
export HARNESS_EXIT_CODE="$harness_exit_code"
105-
after_run_exit_code=0
106-
if [ -n "$AFTER_RUN_HOOK" ]; then
107-
after_hook_file="$(mktemp "${RUNNER_TEMP:-/tmp}/harness-after-run.XXXXXX.sh")"
108-
trap 'rm -f "$after_hook_file"' EXIT
109-
printf '%s\n' "$AFTER_RUN_HOOK" > "$after_hook_file"
110-
chmod +x "$after_hook_file"
111-
set +e
112-
bash "$after_hook_file"
113-
after_run_exit_code=$?
114-
set -e
115-
rm -f "$after_hook_file"
116-
trap - EXIT
117-
fi
118-
11983
echo "harness_exit_code=$harness_exit_code" >> "$GITHUB_OUTPUT"
12084
12185
if [ "$harness_exit_code" -ne 0 ]; then
12286
exit "$harness_exit_code"
12387
fi
124-
125-
if [ "$after_run_exit_code" -ne 0 ]; then
126-
exit "$after_run_exit_code"
127-
fi
12888
- name: Upload visual test artifacts
12989
if: always() && inputs.uploadVisualTestArtifacts == 'true'
13090
uses: actions/upload-artifact@v4

packages/jest/src/__tests__/harness.test.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@ const mocks = vi.hoisted(() => ({
2929
}));
3030

3131
vi.mock('@react-native-harness/bundler-metro', async () => {
32-
const actual =
33-
await vi.importActual<typeof import('@react-native-harness/bundler-metro')>(
34-
'@react-native-harness/bundler-metro'
35-
);
32+
const actual = await vi.importActual<
33+
typeof import('@react-native-harness/bundler-metro')
34+
>('@react-native-harness/bundler-metro');
3635

3736
return {
3837
...actual,
@@ -51,10 +50,9 @@ vi.mock('../logs.js', () => ({
5150
}));
5251

5352
vi.mock('@react-native-harness/tools', async () => {
54-
const actual =
55-
await vi.importActual<typeof import('@react-native-harness/tools')>(
56-
'@react-native-harness/tools'
57-
);
53+
const actual = await vi.importActual<
54+
typeof import('@react-native-harness/tools')
55+
>('@react-native-harness/tools');
5856

5957
return {
6058
...actual,
@@ -186,7 +184,7 @@ const createHarnessConfig = (
186184
unstable__skipAlreadyIncludedModules: false,
187185
webSocketPort: 3001,
188186
...overrides,
189-
}) as HarnessConfig;
187+
} as HarnessConfig);
190188

191189
beforeEach(() => {
192190
vi.clearAllMocks();
@@ -310,9 +308,7 @@ describe('getHarness', () => {
310308
mocks.waitForMetroBackedAppReady.mockImplementationOnce(
311309
async (options: WaitForMetroBackedAppReadyOptions) => {
312310
await options.startAttempt();
313-
const readyPromise = options.waitForReady(
314-
new AbortController().signal
315-
);
311+
const readyPromise = options.waitForReady(new AbortController().signal);
316312
emitReady();
317313
await readyPromise;
318314
}
@@ -375,9 +371,7 @@ describe('getHarness', () => {
375371
mocks.waitForMetroBackedAppReady.mockImplementationOnce(
376372
async (options: WaitForMetroBackedAppReadyOptions) => {
377373
await options.startAttempt();
378-
const readyPromise = options.waitForReady(
379-
new AbortController().signal
380-
);
374+
const readyPromise = options.waitForReady(new AbortController().signal);
381375
emitReady();
382376
await readyPromise;
383377
}
@@ -473,7 +467,25 @@ describe('plugins', () => {
473467
beforeCreation: (ctx) => {
474468
ctx.state.creationCount += 1;
475469
observedHooks.push(
476-
`beforeCreation:${ctx.platform.platformId}:${ctx.appLaunchOptions == null ? 'no-launch-options' : 'launch-options'}`
470+
`beforeCreation:${ctx.platform.platformId}:${
471+
ctx.appLaunchOptions == null
472+
? 'no-launch-options'
473+
: 'launch-options'
474+
}`
475+
);
476+
},
477+
beforeRun: (ctx) => {
478+
observedHooks.push(
479+
`beforeRun:${ctx.platform.platformId}:${
480+
ctx.appLaunchOptions == null
481+
? 'no-launch-options'
482+
: 'launch-options'
483+
}`
484+
);
485+
},
486+
afterRun: (ctx) => {
487+
observedHooks.push(
488+
`afterRun:${ctx.state.creationCount}:${ctx.reason}`
477489
);
478490
},
479491
beforeDispose: (ctx) => {
@@ -484,7 +496,9 @@ describe('plugins', () => {
484496
},
485497
runtime: {
486498
ready: (ctx) => {
487-
observedHooks.push(`runtime.ready:${ctx.runId}:${ctx.device.platform}`);
499+
observedHooks.push(
500+
`runtime.ready:${ctx.runId}:${ctx.device.platform}`
501+
);
488502
},
489503
disconnected: (ctx) => {
490504
observedHooks.push(`runtime.disconnected:${ctx.reason}`);
@@ -547,9 +561,11 @@ describe('plugins', () => {
547561

548562
expect(observedHooks).toEqual([
549563
'beforeCreation:ios:launch-options',
564+
'beforeRun:ios:launch-options',
550565
'runtime.ready:run-1:ios',
551566
'collection.started:example.harness.ts',
552567
'runtime.disconnected:bridge-disconnected',
568+
'afterRun:1:normal',
553569
'beforeDispose:1:normal',
554570
]);
555571
});

0 commit comments

Comments
 (0)