Skip to content

Commit 07d5280

Browse files
authored
fix: harden iOS alert smoke scenario (#1767)
* fix: harden iOS alert smoke scenario * fix: address iOS alert smoke review feedback * fix: present fixture alert after React commit
1 parent 85aef7a commit 07d5280

2 files changed

Lines changed: 49 additions & 5 deletions

File tree

examples/test-app/src/screens/AutomationLabScreen.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ export function AutomationLabScreen(props: {
8484
};
8585
}, []);
8686

87-
function showAutomationAlert() {
87+
useEffect(() => {
88+
if (alertResult !== 'opened') return;
89+
90+
// The opened canary is committed before this effect; the smoke step separately waits for native presentation.
8891
Alert.alert('Automation confirmation', 'Choose either result to update the visible canary.', [
8992
{
9093
style: 'cancel',
@@ -96,6 +99,10 @@ export function AutomationLabScreen(props: {
9699
onPress: () => setAlertResult('accepted'),
97100
},
98101
]);
102+
}, [alertResult]);
103+
104+
function showAutomationAlert() {
105+
setAlertResult('opened');
99106
}
100107

101108
async function requestMicrophonePermission() {

test/integration/ios-simulator-e2e/live-automation-scenario.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import assert from 'node:assert/strict';
22
import fs from 'node:fs';
33
import path from 'node:path';
44

5+
import { DEFAULT_ALERT_TIMEOUT_MS } from '@agent-device/contracts/interaction';
6+
57
import { PUBLIC_COMMANDS } from '../../../src/command-catalog.ts';
68
import {
79
assertElementText,
@@ -13,6 +15,7 @@ import { clearStateLaunchUrlMaestroFlow } from './live-fixtures.ts';
1315
import { type LiveContext, runStep, verifyBehavior, verifyCommand } from './live-harness.ts';
1416

1517
const C = PUBLIC_COMMANDS;
18+
const ALERT_WAIT_TIMEOUT = String(DEFAULT_ALERT_TIMEOUT_MS);
1619
const FIXTURE_HOME_TITLE = 'Agent Device Tester';
1720
const AUTOMATION_DEEP_LINK =
1821
'agent-device-test-app:///automation?event=cold.start&payload=%7B%22source%22%3A%22deep-link%22%7D';
@@ -33,6 +36,22 @@ async function observeFixtureHome(context: LiveContext) {
3336
return snapshot;
3437
}
3538

39+
async function assertAutomationAlertTriggerVisible(context: LiveContext): Promise<void> {
40+
const visible = await runStep(context, 'assert automation-open-alert is visible', [
41+
'is',
42+
'visible',
43+
'id="automation-open-alert"',
44+
]);
45+
assert.equal(visible.json?.data?.pass, true, JSON.stringify(visible.json));
46+
}
47+
48+
async function openNativeAlert(context: LiveContext, step: string): Promise<void> {
49+
await assertAutomationAlertTriggerVisible(context);
50+
await runStep(context, step, ['click', 'id="automation-open-alert"']);
51+
// The canary proves JS ran and the state update is observable; alert wait proves native presentation.
52+
await assertWaitText(context, 'Alert result: opened');
53+
}
54+
3655
export async function assertAutomationInput(context: LiveContext): Promise<void> {
3756
const opened = await runStep(context, 'cold launch fixture', [
3857
'open',
@@ -148,15 +167,33 @@ export async function assertAutomationInput(context: LiveContext): Promise<void>
148167
await assertWaitText(context, 'Long presses: 1');
149168
verifyCommand(context, C.longPress, '800ms hold increments the long-press counter');
150169

151-
await runStep(context, 'scroll native alert canary into view', ['scroll', 'down', '1']);
152-
await runStep(context, 'open native alert', ['click', 'id="automation-open-alert"']);
153-
const alert = await runStep(context, 'wait for native alert', ['alert', 'wait', '5000']);
170+
await assertElementTextAfterScrolling(
171+
context,
172+
'id="automation-open-alert"',
173+
'Open automation alert',
174+
);
175+
await openNativeAlert(context, 'open native alert');
176+
const alert = await runStep(context, 'wait for native alert', [
177+
'alert',
178+
'wait',
179+
ALERT_WAIT_TIMEOUT,
180+
]);
154181
assertJsonContains(alert, 'Automation confirmation', 'alert wait should return fixture alert');
155182
await runStep(context, 'inspect native alert', ['alert', 'get']);
156183
await runStep(context, 'dismiss native alert', ['alert', 'dismiss']);
157184
await assertWaitText(context, 'Alert result: cancelled');
158185

159-
await runStep(context, 'reopen native alert', ['click', 'id="automation-open-alert"']);
186+
await openNativeAlert(context, 'reopen native alert');
187+
const reopenedAlert = await runStep(context, 'wait for reopened native alert', [
188+
'alert',
189+
'wait',
190+
ALERT_WAIT_TIMEOUT,
191+
]);
192+
assertJsonContains(
193+
reopenedAlert,
194+
'Automation confirmation',
195+
'alert wait should return the reopened fixture alert',
196+
);
160197
await runStep(context, 'accept native alert', ['alert', 'accept']);
161198
await assertWaitText(context, 'Alert result: accepted');
162199
verifyCommand(context, C.alert, 'alert wait/get/dismiss/accept produce both fixture outcomes');

0 commit comments

Comments
 (0)