From b8ba8469f8fe9b95a45b802ad738ac23af562656 Mon Sep 17 00:00:00 2001 From: Aliaksandr Babrykovich Date: Thu, 30 Apr 2026 22:46:52 +0200 Subject: [PATCH 1/4] fix: wait for sandbox ready element instead of fixed sleep in harness beforeAll --- apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx b/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx index b39c19d..dbf08d7 100644 --- a/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx +++ b/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx @@ -15,6 +15,7 @@ import App from '../App' const isIOS = Platform.OS === 'ios' const TEST_TIMEOUT = 60_000 const RENDER_TIMEOUT = 10_000 +const SANDBOX_READY_TIMEOUT = 90_000 async function sleep(ms: number) { return new Promise(r => setTimeout(r, ms)) @@ -85,8 +86,10 @@ describe('Substitution OFF', () => { beforeAll(async () => { blockCleanup = true await render(, {timeout: RENDER_TIMEOUT}) - await sleep(4000) - }, 30_000) + await screen.findByTestId('sandbox-seg-file-access', { + timeout: SANDBOX_READY_TIMEOUT, + }) + }, SANDBOX_READY_TIMEOUT + RENDER_TIMEOUT) if (isIOS) { it( From 45da5f1d806920424df90ea167d467b61d11a1d0 Mon Sep 17 00:00:00 2001 From: Aliaksandr Babrykovich Date: Thu, 30 Apr 2026 23:58:54 +0200 Subject: [PATCH 2/4] fix: signal sandbox readiness via postMessage and wait for host-side marker in harness --- apps/fs-experiment/App.tsx | 11 ++++++++++- .../__tests__/sandbox-isolation.harness.tsx | 2 +- apps/fs-experiment/sandbox.js | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/fs-experiment/App.tsx b/apps/fs-experiment/App.tsx index 50c6ae2..9a416da 100644 --- a/apps/fs-experiment/App.tsx +++ b/apps/fs-experiment/App.tsx @@ -40,6 +40,7 @@ const SANDBOXED_SUBSTITUTIONS: Record = { function App(): React.JSX.Element { const isDarkMode = useColorScheme() === 'dark' const [useSubstitution, setUseSubstitution] = useState(false) + const [sandboxReady, setSandboxReady] = useState(false) const theme = { bg: isDarkMode ? '#000' : '#fff', @@ -54,6 +55,7 @@ function App(): React.JSX.Element { return ( + {sandboxReady && } console.log('Host received from sandbox:', msg)} + onMessage={msg => { + if (msg.cmd === 'ready') setSandboxReady(true) + console.log('Host received from sandbox:', msg) + }} onError={err => console.log('Host received error from sandbox:', err) } @@ -137,6 +142,10 @@ const styles = StyleSheet.create({ root: { flex: 1, }, + hidden: { + width: 0, + height: 0, + }, section: { borderBottomWidth: StyleSheet.hairlineWidth, }, diff --git a/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx b/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx index dbf08d7..fd54f5c 100644 --- a/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx +++ b/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx @@ -86,7 +86,7 @@ describe('Substitution OFF', () => { beforeAll(async () => { blockCleanup = true await render(, {timeout: RENDER_TIMEOUT}) - await screen.findByTestId('sandbox-seg-file-access', { + await screen.findByTestId('sandbox-ready', { timeout: SANDBOX_READY_TIMEOUT, }) }, SANDBOX_READY_TIMEOUT + RENDER_TIMEOUT) diff --git a/apps/fs-experiment/sandbox.js b/apps/fs-experiment/sandbox.js index e0bc3a3..b116f39 100644 --- a/apps/fs-experiment/sandbox.js +++ b/apps/fs-experiment/sandbox.js @@ -58,6 +58,9 @@ function installTestCommandHandler() { function SandboxApp(props) { useEffect(() => { installTestCommandHandler() + if (typeof globalThis.postMessage === 'function') { + globalThis.postMessage({cmd: 'ready'}) + } }, []) return From 99c2dadba7ac82e20f98bb3c8f2521e768665acc Mon Sep 17 00:00:00 2001 From: Aliaksandr Babrykovich Date: Fri, 1 May 2026 07:01:49 +0200 Subject: [PATCH 3/4] fix: use testID on SandboxReactNativeView directly instead of extra hidden view --- apps/fs-experiment/App.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/fs-experiment/App.tsx b/apps/fs-experiment/App.tsx index 9a416da..ec548f7 100644 --- a/apps/fs-experiment/App.tsx +++ b/apps/fs-experiment/App.tsx @@ -55,7 +55,6 @@ function App(): React.JSX.Element { return ( - {sandboxReady && } Date: Fri, 1 May 2026 08:37:27 +0200 Subject: [PATCH 4/4] fix: handle android string msg.data and pass timeout as waitForOptions --- apps/fs-experiment/App.tsx | 4 +++- .../fs-experiment/__tests__/sandbox-isolation.harness.tsx | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/fs-experiment/App.tsx b/apps/fs-experiment/App.tsx index ec548f7..c28ef7e 100644 --- a/apps/fs-experiment/App.tsx +++ b/apps/fs-experiment/App.tsx @@ -125,7 +125,9 @@ function App(): React.JSX.Element { useSubstitution ? SANDBOXED_SUBSTITUTIONS : undefined } onMessage={msg => { - if (msg.cmd === 'ready') setSandboxReady(true) + const payload = + typeof msg.data === 'string' ? JSON.parse(msg.data) : msg.data + if (payload?.cmd === 'ready') setSandboxReady(true) console.log('Host received from sandbox:', msg) }} onError={err => diff --git a/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx b/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx index fd54f5c..3812644 100644 --- a/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx +++ b/apps/fs-experiment/__tests__/sandbox-isolation.harness.tsx @@ -86,9 +86,11 @@ describe('Substitution OFF', () => { beforeAll(async () => { blockCleanup = true await render(, {timeout: RENDER_TIMEOUT}) - await screen.findByTestId('sandbox-ready', { - timeout: SANDBOX_READY_TIMEOUT, - }) + await screen.findByTestId( + 'sandbox-ready', + {}, + {timeout: SANDBOX_READY_TIMEOUT} + ) }, SANDBOX_READY_TIMEOUT + RENDER_TIMEOUT) if (isIOS) {