Skip to content

Commit ccaf471

Browse files
committed
fix: make in-app back the default
1 parent 92b404e commit ccaf471

8 files changed

Lines changed: 21 additions & 25 deletions

File tree

ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -510,12 +510,10 @@ extension RunnerTests {
510510
// Return path relative to app container root (tmp/ maps to NSTemporaryDirectory)
511511
return Response(ok: true, data: DataPayload(message: "tmp/\(fileName)"))
512512
#endif
513-
case .back:
514-
performDefaultBackAction(app: activeApp)
515-
return Response(ok: true, data: DataPayload(message: "back"))
516-
case .backInApp:
513+
case .back, .backInApp:
517514
if tapInAppBackControl(app: activeApp) {
518-
return Response(ok: true, data: DataPayload(message: "backInApp"))
515+
let message = command.command == .back ? "back" : "backInApp"
516+
return Response(ok: true, data: DataPayload(message: message))
519517
}
520518
return Response(ok: false, error: ErrorPayload(message: "in-app back control is not available"))
521519
case .backSystem:

ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,6 @@ extension RunnerTests {
5151
start.press(forDuration: 0.05, thenDragTo: end)
5252
}
5353

54-
func performDefaultBackAction(app: XCUIApplication) {
55-
if tapInAppBackControl(app: app) {
56-
return
57-
}
58-
performBackGesture(app: app)
59-
}
60-
6154
func performSystemBackAction(app: XCUIApplication) -> Bool {
6255
#if os(macOS)
6356
return false

skills/agent-device/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Use this skill as a router with mandatory defaults. Read this file first. For no
4848
- Use `get`, `is`, or `find` when they can answer the question without changing UI state.
4949
- Use `fill` to replace text.
5050
- Use `type` to append text.
51-
- When a task asks to "go back", prefer `back --in-app` for predictable app-owned navigation and reserve plain `back` or `back --system` for platform back gestures or button semantics.
51+
- When a task asks to "go back", use plain `back` for predictable app-owned navigation and reserve `back --system` for platform back gestures or button semantics.
5252
- If there is no simulator, no app install, or no open app session yet, switch to `bootstrap-install.md` instead of improvising setup steps.
5353
- Use the smallest unblock action first when transient UI blocks inspection, but do not navigate, search, or enter new text just to make the UI reveal data unless the user asked for that interaction.
5454
- Do not use external lookups to compensate for missing on-screen data unless the user asked for them.

src/core/__tests__/dispatch-back.test.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ async function withMockedAdb(
4343
}
4444
}
4545

46-
test('dispatch back maps explicit Android back modes to keyevent 4', async () => {
46+
test('dispatch back defaults to in-app mode and keeps Android back on keyevent 4', async () => {
4747
await withMockedAdb('agent-device-dispatch-back-modes-', async (argsLogPath) => {
48-
for (const backMode of ['in-app', 'system'] as const) {
48+
for (const backMode of [undefined, 'in-app', 'system'] as const) {
4949
const result = await dispatchCommand(ANDROID_DEVICE, 'back', [], undefined, {
5050
backMode,
5151
});
5252

5353
assert.equal(result?.action, 'back');
54-
assert.equal(result?.mode, backMode);
54+
assert.equal(result?.mode, backMode ?? 'in-app');
5555
}
5656

5757
const args = (await fs.readFile(argsLogPath, 'utf8')).trim().split('\n').filter(Boolean);
@@ -68,6 +68,12 @@ test('dispatch back maps explicit Android back modes to keyevent 4', async () =>
6868
'input',
6969
'keyevent',
7070
'4',
71+
'-s',
72+
'emulator-5554',
73+
'shell',
74+
'input',
75+
'keyevent',
76+
'4',
7177
]);
7278
});
7379
});

src/core/dispatch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ export async function dispatchCommand(
408408
}
409409
case 'back': {
410410
await interactor.back(context?.backMode);
411-
return { action: 'back', mode: context?.backMode ?? 'default' };
411+
return { action: 'back', mode: context?.backMode ?? 'in-app' };
412412
}
413413
case 'home': {
414414
await interactor.home();

src/utils/__tests__/interactors.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import test from 'node:test';
22
import assert from 'node:assert/strict';
33
import { resolveAppleBackRunnerCommand } from '../interactors.ts';
44

5-
test('resolveAppleBackRunnerCommand keeps default back behavior when no mode is provided', () => {
6-
assert.equal(resolveAppleBackRunnerCommand(), 'back');
5+
test('resolveAppleBackRunnerCommand defaults plain back to in-app navigation', () => {
6+
assert.equal(resolveAppleBackRunnerCommand(), 'backInApp');
77
});
88

99
test('resolveAppleBackRunnerCommand maps explicit back modes to runner commands', () => {

src/utils/interactors.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export type RunnerContext = {
4242
};
4343

4444
export type BackMode = 'in-app' | 'system';
45-
export type AppleBackRunnerCommand = 'back' | 'backInApp' | 'backSystem';
45+
export type AppleBackRunnerCommand = 'backInApp' | 'backSystem';
4646

4747
type Interactor = {
4848
open(
@@ -154,9 +154,8 @@ export function getInteractor(device: DeviceInfo, runnerContext: RunnerContext):
154154
}
155155

156156
export function resolveAppleBackRunnerCommand(mode?: BackMode): AppleBackRunnerCommand {
157-
if (mode === 'in-app') return 'backInApp';
158157
if (mode === 'system') return 'backSystem';
159-
return 'back';
158+
return 'backInApp';
160159
}
161160

162161
type RunnerOpts = {

website/docs/docs/commands.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ agent-device app-switcher
3737
- `open <url>` deep links are supported on Android and iOS.
3838
- `open <app> <url>` opens a deep link on iOS.
3939
- `open --platform macos --surface app|frontmost-app|desktop|menubar` selects the macOS session surface explicitly. `app` is the default when an app argument is provided.
40-
- `back` without flags preserves the legacy default: on Apple targets it prefers an in-app back control first, then falls back to the platform back gesture or remote action; on Android it sends the system back event.
41-
- `back --in-app` asks for app-owned back navigation explicitly. On Apple targets that means visible in-app back UI only. On Android this currently falls back to the same system back event because Android routes in-app back through that platform event.
40+
- `back` now defaults to app-owned back navigation. On Apple targets that means visible in-app back UI only. On Android this currently maps to the same back keyevent because Android routes in-app back through that platform event.
41+
- `back --in-app` is an explicit alias for the default app-owned behavior.
4242
- `back --system` asks for system back input explicitly. On Android this is the normal back keyevent. On iOS and tvOS it uses the platform back gesture or Siri Remote menu action. On macOS, where there is no generic system back input, `back --system` reports unavailable instead of falling back to app-owned navigation.
4343
- On iOS devices, `http(s)://` URLs open in Safari when no app is active. Custom scheme URLs require an active app in the session.
4444
- `AGENT_DEVICE_SESSION` and `AGENT_DEVICE_PLATFORM` can pre-bind a default session/platform for CLI automation runs, so normal commands (`open`, `snapshot`, `press`, `fill`, `screenshot`, `devices`, and `batch`) do not need those flags repeated on every call.
@@ -58,7 +58,7 @@ agent-device app-switcher
5858
```bash
5959
agent-device open "https://example.com" --platform ios # open link in web browser
6060
agent-device open MyApp "myapp://screen/to" --platform ios # open deep link to MyApp
61-
agent-device back --in-app --platform ios # tap visible app back UI only
61+
agent-device back --platform ios # tap visible app back UI only
6262
agent-device back --system --platform ios # use edge-swipe or remote back action
6363
agent-device open com.example.myapp --remote-config ./agent-device.remote.json --relaunch
6464
agent-device reinstall MyApp /path/to/app-debug.apk --platform android --serial emulator-5554

0 commit comments

Comments
 (0)