Skip to content

Commit 61cae9c

Browse files
committed
chore: address snapshot session review
1 parent 1cfb649 commit 61cae9c

6 files changed

Lines changed: 11 additions & 42 deletions

File tree

android-snapshot-helper/src/main/java/com/callstack/agentdevice/snapshothelper/SnapshotInstrumentation.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public final class SnapshotInstrumentation extends Instrumentation {
2323
private static final String OUTPUT_FORMAT = "uiautomator-xml";
2424
private static final String HELPER_API_VERSION = "1";
2525
private static final int CHUNK_SIZE = 2 * 1024;
26+
// Keep the default quiet window short: RN/animation-heavy apps often never become fully idle,
27+
// and callers can still override this for alert-style flows that need a longer settle period.
2628
private static final long DEFAULT_WAIT_FOR_IDLE_TIMEOUT_MS = 25;
2729
private static final long DEFAULT_WAIT_FOR_IDLE_QUIET_MS = 25;
2830
private static final long DEFAULT_TIMEOUT_MS = 8_000;
@@ -334,6 +336,9 @@ private static void appendNode(
334336
Rect bounds = new Rect();
335337
node.getBoundsInScreen(bounds);
336338
xml.append("<node");
339+
// Emit only fields consumed by the host parser. Extra boolean attrs made every node larger
340+
// without affecting current snapshot semantics; add fields back here when TS starts reading
341+
// them.
337342
appendAttribute(xml, "index", Integer.toString(nodeIndex));
338343
appendNonEmptyAttribute(xml, "text", node.getText());
339344
appendNonEmptyAttribute(xml, "resource-id", node.getViewIdResourceName());

docs/adr/0002-persistent-platform-helper-sessions.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Status
44

5-
Accepted
5+
Accepted (implementation pending)
66

77
## Context
88

@@ -47,7 +47,9 @@ The session pattern is:
4747

4848
For Android snapshots, productize a persistent helper mode that keeps `UiAutomation` alive and
4949
serves fresh snapshot requests over an `adb forward` socket. Do not add snapshot result caching as
50-
part of that first step. The first reliable win is infrastructure reuse, not data reuse.
50+
part of that first step. The first reliable win is infrastructure reuse, not data reuse. The current
51+
PR only lands one-shot snapshot improvements and this decision record; the persistent Android
52+
session implementation is follow-up work.
5153

5254
For iOS, keep the XCTest runner session as the reference implementation for lifecycle and
5355
invalidation behavior. Android does not need to copy iOS internals, but it should reuse the same

src/daemon/handlers/__tests__/session-open-runtime.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ vi.mock('../../../platforms/ios/runner-client.ts', async (importOriginal) => {
2424
return {
2525
...actual,
2626
prewarmIosRunnerSession: vi.fn(),
27-
prewarmIosRunnerXctestrun: vi.fn(),
2827
stopIosRunnerSession: vi.fn(async () => {}),
2928
};
3029
});

src/daemon/handlers/__tests__/session.test.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ vi.mock('../../../platforms/ios/runner-client.ts', async (importOriginal) => {
1818
return {
1919
...actual,
2020
prewarmIosRunnerSession: vi.fn(),
21-
prewarmIosRunnerXctestrun: vi.fn(),
2221
stopIosRunnerSession: vi.fn(async () => {}),
2322
};
2423
});
@@ -97,7 +96,6 @@ import { ensureDeviceReady } from '../../device-ready.ts';
9796
import { applyRuntimeHintsToApp, clearRuntimeHintsFromApp } from '../../runtime-hints.ts';
9897
import {
9998
prewarmIosRunnerSession,
100-
prewarmIosRunnerXctestrun,
10199
stopIosRunnerSession,
102100
} from '../../../platforms/ios/runner-client.ts';
103101
import { runMacOsAlertAction } from '../../../platforms/ios/macos-helper.ts';
@@ -120,7 +118,6 @@ const mockEnsureDeviceReady = vi.mocked(ensureDeviceReady);
120118
const mockApplyRuntimeHints = vi.mocked(applyRuntimeHintsToApp);
121119
const mockClearRuntimeHints = vi.mocked(clearRuntimeHintsFromApp);
122120
const mockPrewarmIosRunnerSession = vi.mocked(prewarmIosRunnerSession);
123-
const mockPrewarmIosRunnerXctestrun = vi.mocked(prewarmIosRunnerXctestrun);
124121
const mockStopIosRunner = vi.mocked(stopIosRunnerSession);
125122
const mockDismissMacOsAlert = vi.mocked(runMacOsAlertAction);
126123
const mockSettleSimulator = vi.mocked(settleIosSimulator);
@@ -151,7 +148,6 @@ beforeEach(() => {
151148
mockClearRuntimeHints.mockReset();
152149
mockClearRuntimeHints.mockResolvedValue(undefined);
153150
mockPrewarmIosRunnerSession.mockReset();
154-
mockPrewarmIosRunnerXctestrun.mockReset();
155151
mockStopIosRunner.mockReset();
156152
mockStopIosRunner.mockResolvedValue(undefined);
157153
mockDismissMacOsAlert.mockReset();
@@ -1962,7 +1958,6 @@ test('open custom URL on fresh iOS simulator session infers app bundle id from U
19621958
expect(updated?.appName).toBe('rne://navigator-layout');
19631959
expect(dispatchedContext?.appBundleId).toBe('org.reactnavigation.playground');
19641960
expect(mockPrewarmIosRunnerSession).toHaveBeenCalledTimes(1);
1965-
expect(mockPrewarmIosRunnerXctestrun).not.toHaveBeenCalled();
19661961
});
19671962

19681963
test('open iOS app session prewarms runner session when app bundle id is known', async () => {
@@ -2001,7 +1996,6 @@ test('open iOS app session prewarms runner session when app bundle id is known',
20011996
expect.objectContaining({ platform: 'ios', id: 'ios-device-1' }),
20021997
expect.objectContaining({ logPath: expect.stringMatching(/daemon\.log$/) }),
20031998
);
2004-
expect(mockPrewarmIosRunnerXctestrun).not.toHaveBeenCalled();
20051999
});
20062000

20072001
test('open iOS URL without app bundle id skips runner prewarm', async () => {
@@ -2035,7 +2029,6 @@ test('open iOS URL without app bundle id skips runner prewarm', async () => {
20352029
expect(response).toBeTruthy();
20362030
expect(response?.ok).toBe(true);
20372031
expect(mockPrewarmIosRunnerSession).not.toHaveBeenCalled();
2038-
expect(mockPrewarmIosRunnerXctestrun).not.toHaveBeenCalled();
20392032
});
20402033

20412034
test('open web URL on iOS device session without active app falls back to Safari', async () => {

src/platforms/android/snapshot-helper-capture.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ function buildAndroidSnapshotHelperArgs(
126126
'-e',
127127
'maxNodes',
128128
String(options.maxNodes),
129+
// Default production snapshots use instrumentation status chunks. File output remains a
130+
// fallback/testing transport for devices where status output cannot carry the payload.
129131
...(options.outputPath ? ['-e', 'outputPath', options.outputPath] : []),
130132
...(options.emitChunks !== undefined ? ['-e', 'emitChunks', String(options.emitChunks)] : []),
131133
options.runner,

src/platforms/ios/runner-client.ts

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
resolveAppleRunnerProvider,
2727
type AppleRunnerCommandOptions,
2828
} from './runner-provider.ts';
29-
import { ensureXctestrun } from './runner-xctestrun.ts';
3029
export {
3130
isRetryableRunnerError,
3231
resolveRunnerEarlyExitHint,
@@ -67,37 +66,6 @@ export async function runIosRunnerCommand(
6766
return provider.runCommand(device, command, options);
6867
}
6968

70-
export function prewarmIosRunnerXctestrun(
71-
device: DeviceInfo,
72-
options: RunnerSessionOptions = {},
73-
): Promise<void> | undefined {
74-
if (device.platform !== 'ios') {
75-
return undefined;
76-
}
77-
if (hasScopedAppleRunnerProvider(device, { requestId: options.requestId })) {
78-
emitDiagnostic({
79-
level: 'debug',
80-
phase: 'ios_runner_xctestrun_prewarm_skipped_scoped_provider',
81-
data: { deviceId: device.id },
82-
});
83-
return undefined;
84-
}
85-
const prewarm = ensureXctestrun(device, options)
86-
.then(() => {})
87-
.catch((error: unknown) => {
88-
emitDiagnostic({
89-
level: 'warn',
90-
phase: 'ios_runner_xctestrun_prewarm_failed',
91-
data: {
92-
deviceId: device.id,
93-
error: error instanceof Error ? error.message : String(error),
94-
},
95-
});
96-
});
97-
void prewarm;
98-
return prewarm;
99-
}
100-
10169
export function prewarmIosRunnerSession(
10270
device: DeviceInfo,
10371
options: RunnerSessionOptions = {},

0 commit comments

Comments
 (0)