Skip to content

Commit e762801

Browse files
committed
test: lock Apple fling fallback route
1 parent 120db28 commit e762801

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import assert from 'node:assert/strict';
2+
import fs from 'node:fs';
3+
import path from 'node:path';
4+
import { fileURLToPath } from 'node:url';
5+
import { test } from 'vitest';
6+
7+
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
8+
const commandExecutionSwiftPath = path.join(
9+
repoRoot,
10+
'apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift',
11+
);
12+
13+
test('Apple gesture command preserves the fling fast-swipe and coordinate fallback route', () => {
14+
const source = fs.readFileSync(commandExecutionSwiftPath, 'utf8');
15+
const gestureCase = extractSwiftSwitchCase(source, '.gesture', '.gestureViewport');
16+
const fastSwipeBranch = extractSourceSegment(
17+
gestureCase,
18+
'if plannedGestureExecution(for: plan) == .fastSwipe',
19+
'let (timing, outcome)',
20+
);
21+
22+
assert.match(fastSwipeBranch, /executeDragGesture\(/);
23+
assert.match(fastSwipeBranch, /synthesized:\s*true/);
24+
assert.match(fastSwipeBranch, /synthesizedPolicyKind:\s*\.synthesizedDrag/);
25+
assert.match(fastSwipeBranch, /synthesizedProfile:\s*\.fastSwipe/);
26+
assert.doesNotMatch(fastSwipeBranch, /sampledPlannedGesture/);
27+
28+
const dragExecutor = extractSwiftFunction(source, 'executeDragGesture');
29+
assert.match(
30+
dragExecutor,
31+
/fallback = gestureFallback\(strategy: "xctest-coordinate-drag", from: outcome\)/,
32+
);
33+
assert.match(dragExecutor, /dragAt\(/);
34+
});
35+
36+
function extractSwiftSwitchCase(source: string, name: string, nextName: string): string {
37+
return extractSourceSegment(source, `case ${name}:`, `case ${nextName}:`);
38+
}
39+
40+
function extractSourceSegment(source: string, startMarker: string, endMarker: string): string {
41+
const start = source.indexOf(startMarker);
42+
assert.notEqual(start, -1, `missing source marker ${startMarker}`);
43+
const end = source.indexOf(endMarker, start);
44+
assert.notEqual(end, -1, `missing source marker ${endMarker}`);
45+
return source.slice(start, end);
46+
}
47+
48+
function extractSwiftFunction(source: string, name: string): string {
49+
const signatureIndex = source.indexOf(`func ${name}`);
50+
assert.notEqual(signatureIndex, -1, `missing Swift function ${name}`);
51+
const bodyStart = source.indexOf('{', signatureIndex);
52+
assert.notEqual(bodyStart, -1, `missing Swift function body ${name}`);
53+
let depth = 0;
54+
for (let index = bodyStart; index < source.length; index += 1) {
55+
const char = source[index];
56+
if (char === '{') depth += 1;
57+
if (char === '}') depth -= 1;
58+
if (depth === 0) return source.slice(signatureIndex, index + 1);
59+
}
60+
assert.fail(`unterminated Swift function ${name}`);
61+
}

0 commit comments

Comments
 (0)