Skip to content

Commit 25a935c

Browse files
committed
fix: verify iOS Maestro visibility waits
1 parent bd23ec5 commit 25a935c

2 files changed

Lines changed: 48 additions & 4 deletions

File tree

src/compat/maestro/__tests__/runtime-assertions.test.ts

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ test('invokeMaestroAssertVisible retries transient snapshot failures until a lat
9898
}
9999
});
100100

101-
test('invokeMaestroAssertVisible uses native wait for short simple iOS assertions', async () => {
101+
test('invokeMaestroAssertVisible verifies native wait success on iOS with an exact snapshot', async () => {
102102
const calls: Array<[string, string[] | undefined]> = [];
103103
const response = await invokeMaestroAssertVisible({
104104
baseReq: {
@@ -112,12 +112,18 @@ test('invokeMaestroAssertVisible uses native wait for short simple iOS assertion
112112
if (req.command === 'wait') {
113113
return { ok: true, data: { matches: 1 } };
114114
}
115+
if (req.command === 'snapshot') {
116+
return { ok: true, data: snapshot([node('Ready')]) };
117+
}
115118
return { ok: false, error: { code: 'UNEXPECTED_COMMAND', message: req.command } };
116119
},
117120
});
118121

119122
assert.equal(response.ok, true);
120-
assert.deepEqual(calls, [['wait', ['Ready', '1000']]]);
123+
assert.deepEqual(calls, [
124+
['wait', ['Ready', '1000']],
125+
['snapshot', []],
126+
]);
121127
});
122128

123129
test('invokeMaestroAssertVisible uses the Maestro default timeout when omitted', async () => {
@@ -134,12 +140,50 @@ test('invokeMaestroAssertVisible uses the Maestro default timeout when omitted',
134140
if (req.command === 'wait') {
135141
return { ok: true, data: { matches: 1 } };
136142
}
143+
if (req.command === 'snapshot') {
144+
return { ok: true, data: snapshot([node('Ready')]) };
145+
}
137146
return { ok: false, error: { code: 'UNEXPECTED_COMMAND', message: req.command } };
138147
},
139148
});
140149

141150
assert.equal(response.ok, true);
142-
assert.deepEqual(calls, [['wait', ['Ready', '17000']]]);
151+
assert.deepEqual(calls, [
152+
['wait', ['Ready', '17000']],
153+
['snapshot', []],
154+
]);
155+
});
156+
157+
test('invokeMaestroAssertVisible does not trust an iOS native wait when the exact snapshot disagrees', async () => {
158+
vi.useFakeTimers();
159+
160+
const calls: Array<[string, string[] | undefined]> = [];
161+
const responsePromise = invokeMaestroAssertVisible({
162+
baseReq: {
163+
token: 't',
164+
session: 's',
165+
flags: { platform: 'ios' },
166+
},
167+
positionals: ['label="page number 0" || text="page number 0" || id="page number 0"', '1000'],
168+
invoke: async (req): Promise<DaemonResponse> => {
169+
calls.push([req.command, req.positionals]);
170+
if (req.command === 'wait') return { ok: true, data: { matches: 1 } };
171+
if (req.command === 'snapshot') {
172+
return { ok: true, data: snapshot([node('PagerView Example')]) };
173+
}
174+
return { ok: false, error: { code: 'UNEXPECTED_COMMAND', message: req.command } };
175+
},
176+
});
177+
178+
await vi.advanceTimersByTimeAsync(6500);
179+
const response = await responsePromise;
180+
181+
assert.equal(response.ok, false);
182+
assert.deepEqual(calls.slice(0, 3), [
183+
['wait', ['page number 0', '1000']],
184+
['snapshot', []],
185+
['snapshot', []],
186+
]);
143187
});
144188

145189
test('invokeMaestroAssertVisible verifies Android native wait success with exact snapshot matching', async () => {

src/compat/maestro/runtime-assertions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ async function invokeNativeMaestroVisibleWaitWithSnapshotFallback(
130130
}
131131

132132
function shouldVerifyNativeVisibleWait(baseReq: ReplayBaseRequest): boolean {
133-
return baseReq.flags?.platform === 'android';
133+
return baseReq.flags?.platform === 'android' || baseReq.flags?.platform === 'ios';
134134
}
135135

136136
async function runNativeVisibleWait(

0 commit comments

Comments
 (0)