agent-device 0.18.0 → 0.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.0.apk → agent-device-android-multitouch-helper-0.18.2.apk} +0 -0
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.2.apk.sha256 +1 -0
- package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.0.manifest.json → agent-device-android-multitouch-helper-0.18.2.manifest.json} +4 -4
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.0.apk → agent-device-android-snapshot-helper-0.18.2.apk} +0 -0
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.2.apk.sha256 +1 -0
- package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.0.manifest.json → agent-device-android-snapshot-helper-0.18.2.manifest.json} +6 -6
- package/apple-runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +156 -0
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +10 -16
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +2 -0
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +3 -1
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +2 -0
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +2 -4
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +9 -36
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +2 -0
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -0
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +2 -0
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +2 -0
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +0 -1
- package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
- package/dist/src/1986.js +1 -0
- package/dist/src/2748.js +1 -1
- package/dist/src/2948.js +21 -21
- package/dist/src/314.js +1 -1
- package/dist/src/3340.js +8 -7
- package/dist/src/4418.js +1 -1
- package/dist/src/4428.js +3 -3
- package/dist/src/485.js +1 -0
- package/dist/src/495.js +5 -0
- package/dist/src/5484.js +1 -1
- package/dist/src/587.js +1 -1
- package/dist/src/5913.js +4 -0
- package/dist/src/6849.js +1 -0
- package/dist/src/6918.js +1 -1
- package/dist/src/6967.js +1 -0
- package/dist/src/760.js +1 -0
- package/dist/src/7871.js +1 -0
- package/dist/src/8184.js +1 -1
- package/dist/src/8225.js +1 -1
- package/dist/src/8391.js +1 -0
- package/dist/src/8404.js +2 -0
- package/dist/src/8414.js +2 -0
- package/dist/src/8875.js +4 -1
- package/dist/src/8936.js +1 -1
- package/dist/src/9581.js +3 -3
- package/dist/src/9624.js +1 -1
- package/dist/src/9722.js +37 -32
- package/dist/src/android-adb.d.ts +19 -54
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android.js +5 -5
- package/dist/src/apps.js +9 -11
- package/dist/src/audio-probe.js +1 -0
- package/dist/src/batch.d.ts +34 -26
- package/dist/src/batch.js +1 -1
- package/dist/src/cli-help.js +61 -9
- package/dist/src/cli.js +34 -22
- package/dist/src/contracts.d.ts +33 -123
- package/dist/src/contracts.js +1 -1
- package/dist/src/debug-symbols.js +3 -0
- package/dist/src/devices.js +1 -1
- package/dist/src/devices~1.js +1 -1
- package/dist/src/devices~2.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.d.ts +2 -6
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +1 -9
- package/dist/src/handler-utils.js +1 -0
- package/dist/src/index.d.ts +474 -180
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions~1.js +1 -1
- package/dist/src/install-source.d.ts +0 -26
- package/dist/src/install-source.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +1 -0
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/companion-tunnel.js +1 -1
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/metro.d.ts +10 -134
- package/dist/src/metro.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace-recording.js +3 -3
- package/dist/src/record-trace.js +1 -1
- package/dist/src/remote-config.d.ts +15 -17
- package/dist/src/remote-config.js +1 -1
- package/dist/src/runner-sequence.js +1 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.d.ts +15 -7
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session.js +11 -11
- package/dist/src/simulator.js +2 -2
- package/dist/src/snapshot.js +2 -2
- package/dist/src/web.js +1 -1
- package/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +297 -0
- package/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +30 -0
- package/package.json +15 -11
- package/server.json +2 -2
- package/android-multitouch-helper/README.md +0 -41
- package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.0.apk.sha256 +0 -1
- package/android-snapshot-helper/README.md +0 -88
- package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.0.apk.sha256 +0 -1
- package/dist/src/1848.js +0 -4
- package/dist/src/2577.js +0 -1
- package/dist/src/2954.js +0 -2
- package/dist/src/4291.js +0 -1
- package/dist/src/432.js +0 -4
- package/dist/src/4723.js +0 -1
- package/dist/src/5341.js +0 -1
- package/dist/src/5910.js +0 -2
- package/dist/src/6024.js +0 -1
- package/dist/src/733.js +0 -1
- package/dist/src/7394.js +0 -6
- package/dist/src/8275.js +0 -2
- package/dist/src/9919.js +0 -6
- package/dist/src/android-snapshot-helper.d.ts +0 -359
- package/dist/src/android-snapshot-helper.js +0 -1
- package/dist/src/apple.js +0 -1
- package/dist/src/device-ready.js +0 -2
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.swift +0 -17
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AccentColor.colorset/Contents.json +0 -11
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -36
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AppIcon.appiconset/logo.jpg +0 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Contents.json +0 -6
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Logo.imageset/Contents.json +0 -21
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Logo.imageset/logo.jpg +0 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/PoweredBy.imageset/Contents.json +0 -21
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/PoweredBy.imageset/powered-by.png +0 -0
- package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/ContentView.swift +0 -34
- package/ios-runner/README.md +0 -53
- package/ios-runner/RUNNER_PROTOCOL.md +0 -76
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
- /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
- /package/dist/src/{4069.js → 4917.js} +0 -0
- /package/dist/src/{9836.js → 893.js} +0 -0
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ It works with native iOS and Android apps, plus apps built with Expo, Flutter, a
|
|
|
31
31
|
|
|
32
32
|
- **Inspect** real app UI through structured accessibility snapshots, interactive refs like `@e3`, selectors, and React Native component trees.
|
|
33
33
|
- **Interact** by opening apps, tapping, typing, scrolling, performing gestures, waiting, asserting state, handling alerts, and closing sessions.
|
|
34
|
-
- **Capture evidence** with screenshots, videos, logs, traces, network traffic, performance samples, crash context, and React profiles.
|
|
34
|
+
- **Capture evidence** with screenshots, videos, logs, traces, network traffic, audio-level probes for browser and host-rendered simulator/emulator audio, performance samples, crash context, and React profiles.
|
|
35
35
|
- **Replay workflows** by recording `.ad` scripts for local runs, CI, repeatable e2e checks, and strict Maestro YAML export when a flow needs to run in Maestro.
|
|
36
36
|
- **Run across platforms** with iOS Simulator automation, Android Emulator automation, physical devices, tvOS, Android TV, macOS, Linux, and desktop app automation, so agents can see and feel the app they work on.
|
|
37
37
|
|
|
@@ -39,7 +39,7 @@ It works with native iOS and Android apps, plus apps built with Expo, Flutter, a
|
|
|
39
39
|
|
|
40
40
|
- Verify mobile changes on real devices, simulators, and emulators before review or merge.
|
|
41
41
|
- Give AI coding agents a real app feedback loop while they implement features.
|
|
42
|
-
- Debug regressions with screenshots, logs, traces, network evidence, and crash context.
|
|
42
|
+
- Debug regressions with screenshots, logs, traces, network/audio evidence, and crash context.
|
|
43
43
|
- Profile performance issues with CPU/memory samples and React render profiles when needed.
|
|
44
44
|
- Turn exploratory app interactions into replayable e2e checks for CI.
|
|
45
45
|
- Use one agent workflow across native iOS, Android, Expo, Flutter, React Native, TV, and desktop apps.
|
|
@@ -105,6 +105,7 @@ Snapshots come from the app's accessibility tree, so high-quality labels, roles,
|
|
|
105
105
|
|
|
106
106
|
- [Verifying mobile apps with agent-device](https://youtu.be/kZDU-k5r9kE)
|
|
107
107
|
- [Using agent-device in an AI coding workflow](https://youtu.be/dfVG_aNPkW4)
|
|
108
|
+
- [Cloud agents that test mobile apps on real devices](https://youtu.be/r5P0detC4bs?is=_KB6SZbLFRB1au_z)
|
|
108
109
|
|
|
109
110
|
## Where To Run agent-device
|
|
110
111
|
|
|
Binary file
|
package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.2.apk.sha256
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1c8e6f04f5453ecea2e26281896faf7d940237c0011ba8d50b436c0b7ba82c4e agent-device-android-multitouch-helper-0.18.2.apk
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-multitouch-helper",
|
|
3
|
-
"version": "0.18.
|
|
4
|
-
"assetName": "agent-device-android-multitouch-helper-0.18.
|
|
5
|
-
"sha256": "
|
|
3
|
+
"version": "0.18.2",
|
|
4
|
+
"assetName": "agent-device-android-multitouch-helper-0.18.2.apk",
|
|
5
|
+
"sha256": "1c8e6f04f5453ecea2e26281896faf7d940237c0011ba8d50b436c0b7ba82c4e",
|
|
6
6
|
"packageName": "com.callstack.agentdevice.multitouchhelper",
|
|
7
|
-
"versionCode":
|
|
7
|
+
"versionCode": 18002,
|
|
8
8
|
"instrumentationRunner": "com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation",
|
|
9
9
|
"statusProtocol": "android-multitouch-helper-v1"
|
|
10
10
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a91e0b0b4d8b5b1dc6d1e25abe1491efefa8b8d89cc5c406f1fd84a302e56ebf agent-device-android-snapshot-helper-0.18.2.apk
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "android-snapshot-helper",
|
|
3
|
-
"version": "0.18.
|
|
4
|
-
"releaseTag": "v0.18.
|
|
5
|
-
"assetName": "agent-device-android-snapshot-helper-0.18.
|
|
3
|
+
"version": "0.18.2",
|
|
4
|
+
"releaseTag": "v0.18.2",
|
|
5
|
+
"assetName": "agent-device-android-snapshot-helper-0.18.2.apk",
|
|
6
6
|
"apkUrl": null,
|
|
7
|
-
"sha256": "
|
|
8
|
-
"checksumName": "agent-device-android-snapshot-helper-0.18.
|
|
7
|
+
"sha256": "a91e0b0b4d8b5b1dc6d1e25abe1491efefa8b8d89cc5c406f1fd84a302e56ebf",
|
|
8
|
+
"checksumName": "agent-device-android-snapshot-helper-0.18.2.apk.sha256",
|
|
9
9
|
"packageName": "com.callstack.agentdevice.snapshothelper",
|
|
10
|
-
"versionCode":
|
|
10
|
+
"versionCode": 18002,
|
|
11
11
|
"instrumentationRunner": "com.callstack.agentdevice.snapshothelper/.SnapshotInstrumentation",
|
|
12
12
|
"minSdk": 23,
|
|
13
13
|
"targetSdk": 36,
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#import <TargetConditionals.h>
|
|
2
|
+
|
|
3
|
+
#if TARGET_OS_OSX
|
|
4
|
+
#import <Cocoa/Cocoa.h>
|
|
5
|
+
|
|
6
|
+
@interface AgentDeviceRunnerAppDelegate : NSObject <NSApplicationDelegate>
|
|
7
|
+
@property(nonatomic, strong) NSWindow *window;
|
|
8
|
+
@end
|
|
9
|
+
|
|
10
|
+
@implementation AgentDeviceRunnerAppDelegate
|
|
11
|
+
|
|
12
|
+
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
|
|
13
|
+
(void)notification;
|
|
14
|
+
|
|
15
|
+
NSRect frame = NSMakeRect(0, 0, 360, 220);
|
|
16
|
+
self.window = [[NSWindow alloc] initWithContentRect:frame
|
|
17
|
+
styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
|
|
18
|
+
NSWindowStyleMaskMiniaturizable)
|
|
19
|
+
backing:NSBackingStoreBuffered
|
|
20
|
+
defer:NO];
|
|
21
|
+
self.window.title = @"Agent Device Runner";
|
|
22
|
+
|
|
23
|
+
NSTextField *label = [NSTextField labelWithString:@"Agent Device Runner"];
|
|
24
|
+
label.font = [NSFont systemFontOfSize:20 weight:NSFontWeightSemibold];
|
|
25
|
+
label.translatesAutoresizingMaskIntoConstraints = NO;
|
|
26
|
+
|
|
27
|
+
NSView *contentView = [[NSView alloc] initWithFrame:frame];
|
|
28
|
+
[contentView addSubview:label];
|
|
29
|
+
self.window.contentView = contentView;
|
|
30
|
+
|
|
31
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
32
|
+
[label.centerXAnchor constraintEqualToAnchor:contentView.centerXAnchor],
|
|
33
|
+
[label.centerYAnchor constraintEqualToAnchor:contentView.centerYAnchor],
|
|
34
|
+
]];
|
|
35
|
+
|
|
36
|
+
[self.window center];
|
|
37
|
+
[self.window makeKeyAndOrderFront:nil];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@end
|
|
41
|
+
|
|
42
|
+
int main(int argc, const char *argv[]) {
|
|
43
|
+
(void)argc;
|
|
44
|
+
(void)argv;
|
|
45
|
+
|
|
46
|
+
@autoreleasepool {
|
|
47
|
+
NSApplication *application = [NSApplication sharedApplication];
|
|
48
|
+
AgentDeviceRunnerAppDelegate *delegate = [[AgentDeviceRunnerAppDelegate alloc] init];
|
|
49
|
+
application.delegate = delegate;
|
|
50
|
+
[application setActivationPolicy:NSApplicationActivationPolicyRegular];
|
|
51
|
+
[application run];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#else
|
|
58
|
+
#import <UIKit/UIKit.h>
|
|
59
|
+
|
|
60
|
+
@interface AgentDeviceRunnerViewController : UIViewController
|
|
61
|
+
@end
|
|
62
|
+
|
|
63
|
+
@implementation AgentDeviceRunnerViewController
|
|
64
|
+
|
|
65
|
+
- (void)viewDidLoad {
|
|
66
|
+
[super viewDidLoad];
|
|
67
|
+
|
|
68
|
+
self.view.backgroundColor = UIColor.whiteColor;
|
|
69
|
+
|
|
70
|
+
UILabel *label = [[UILabel alloc] init];
|
|
71
|
+
label.text = @"Agent Device Runner";
|
|
72
|
+
label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle2];
|
|
73
|
+
label.textAlignment = NSTextAlignmentCenter;
|
|
74
|
+
label.translatesAutoresizingMaskIntoConstraints = NO;
|
|
75
|
+
|
|
76
|
+
[self.view addSubview:label];
|
|
77
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
78
|
+
[label.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
|
|
79
|
+
[label.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
|
|
80
|
+
]];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@end
|
|
84
|
+
|
|
85
|
+
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
|
|
86
|
+
@interface AgentDeviceRunnerSceneDelegate : UIResponder <UIWindowSceneDelegate>
|
|
87
|
+
@property(nonatomic, strong) UIWindow *window;
|
|
88
|
+
@end
|
|
89
|
+
|
|
90
|
+
@implementation AgentDeviceRunnerSceneDelegate
|
|
91
|
+
|
|
92
|
+
- (void)scene:(UIScene *)scene
|
|
93
|
+
willConnectToSession:(UISceneSession *)session
|
|
94
|
+
options:(UISceneConnectionOptions *)connectionOptions {
|
|
95
|
+
(void)session;
|
|
96
|
+
(void)connectionOptions;
|
|
97
|
+
|
|
98
|
+
if (![scene isKindOfClass:UIWindowScene.class]) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
self.window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene];
|
|
103
|
+
self.window.rootViewController = [[AgentDeviceRunnerViewController alloc] init];
|
|
104
|
+
[self.window makeKeyAndVisible];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@end
|
|
108
|
+
#endif
|
|
109
|
+
|
|
110
|
+
@interface AgentDeviceRunnerAppDelegate : UIResponder <UIApplicationDelegate>
|
|
111
|
+
@property(nonatomic, strong) UIWindow *window;
|
|
112
|
+
@end
|
|
113
|
+
|
|
114
|
+
@implementation AgentDeviceRunnerAppDelegate
|
|
115
|
+
|
|
116
|
+
- (BOOL)application:(UIApplication *)application
|
|
117
|
+
didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
|
|
118
|
+
(void)application;
|
|
119
|
+
(void)launchOptions;
|
|
120
|
+
|
|
121
|
+
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
|
|
122
|
+
return YES;
|
|
123
|
+
#else
|
|
124
|
+
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
|
|
125
|
+
self.window.rootViewController = [[AgentDeviceRunnerViewController alloc] init];
|
|
126
|
+
[self.window makeKeyAndVisible];
|
|
127
|
+
|
|
128
|
+
return YES;
|
|
129
|
+
#endif
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
|
|
133
|
+
- (UISceneConfiguration *)application:(UIApplication *)application
|
|
134
|
+
configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession
|
|
135
|
+
options:(UISceneConnectionOptions *)options {
|
|
136
|
+
(void)application;
|
|
137
|
+
(void)connectingSceneSession;
|
|
138
|
+
(void)options;
|
|
139
|
+
|
|
140
|
+
UISceneConfiguration *configuration =
|
|
141
|
+
[[UISceneConfiguration alloc] initWithName:@"Default Configuration"
|
|
142
|
+
sessionRole:UIWindowSceneSessionRoleApplication];
|
|
143
|
+
configuration.delegateClass = AgentDeviceRunnerSceneDelegate.class;
|
|
144
|
+
return configuration;
|
|
145
|
+
}
|
|
146
|
+
#endif
|
|
147
|
+
|
|
148
|
+
@end
|
|
149
|
+
|
|
150
|
+
int main(int argc, char *argv[]) {
|
|
151
|
+
@autoreleasepool {
|
|
152
|
+
return UIApplicationMain(argc, argv, nil, NSStringFromClass(AgentDeviceRunnerAppDelegate.class));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
#endif
|
package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj
RENAMED
|
@@ -206,7 +206,6 @@
|
|
|
206
206
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
207
207
|
AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID = com.callstack.agentdevice.runner;
|
|
208
208
|
AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID = "$(AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID).uitests";
|
|
209
|
-
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
|
210
209
|
CLANG_ANALYZER_NONNULL = YES;
|
|
211
210
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
|
212
211
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
|
@@ -273,7 +272,6 @@
|
|
|
273
272
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
274
273
|
AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID = com.callstack.agentdevice.runner;
|
|
275
274
|
AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID = "$(AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID).uitests";
|
|
276
|
-
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
|
277
275
|
CLANG_ANALYZER_NONNULL = YES;
|
|
278
276
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
|
279
277
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
|
@@ -330,14 +328,12 @@
|
|
|
330
328
|
20EA2EE82F2CFC7C001CF0EF /* Debug */ = {
|
|
331
329
|
isa = XCBuildConfiguration;
|
|
332
330
|
buildSettings = {
|
|
333
|
-
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
334
|
-
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
|
335
331
|
CODE_SIGN_STYLE = Automatic;
|
|
336
332
|
CURRENT_PROJECT_VERSION = 1;
|
|
337
333
|
DEVELOPMENT_TEAM = 2S799L9W4M;
|
|
338
334
|
ENABLE_PREVIEWS = YES;
|
|
339
335
|
GENERATE_INFOPLIST_FILE = YES;
|
|
340
|
-
INFOPLIST_KEY_UIApplicationSceneManifest_Generation =
|
|
336
|
+
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = NO;
|
|
341
337
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
|
342
338
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
|
343
339
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
|
@@ -357,8 +353,8 @@
|
|
|
357
353
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
|
358
354
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
|
359
355
|
SWIFT_VERSION = 5.0;
|
|
360
|
-
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator";
|
|
361
|
-
TARGETED_DEVICE_FAMILY = "1,2,3";
|
|
356
|
+
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator xros xrsimulator";
|
|
357
|
+
TARGETED_DEVICE_FAMILY = "1,2,3,7";
|
|
362
358
|
TVOS_DEPLOYMENT_TARGET = 15.6;
|
|
363
359
|
};
|
|
364
360
|
name = Debug;
|
|
@@ -366,14 +362,12 @@
|
|
|
366
362
|
20EA2EE92F2CFC7C001CF0EF /* Release */ = {
|
|
367
363
|
isa = XCBuildConfiguration;
|
|
368
364
|
buildSettings = {
|
|
369
|
-
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
370
|
-
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
|
371
365
|
CODE_SIGN_STYLE = Automatic;
|
|
372
366
|
CURRENT_PROJECT_VERSION = 1;
|
|
373
367
|
DEVELOPMENT_TEAM = 2S799L9W4M;
|
|
374
368
|
ENABLE_PREVIEWS = YES;
|
|
375
369
|
GENERATE_INFOPLIST_FILE = YES;
|
|
376
|
-
INFOPLIST_KEY_UIApplicationSceneManifest_Generation =
|
|
370
|
+
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = NO;
|
|
377
371
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
|
378
372
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
|
379
373
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
|
@@ -393,8 +387,8 @@
|
|
|
393
387
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
|
394
388
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
|
395
389
|
SWIFT_VERSION = 5.0;
|
|
396
|
-
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator";
|
|
397
|
-
TARGETED_DEVICE_FAMILY = "1,2,3";
|
|
390
|
+
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator xros xrsimulator";
|
|
391
|
+
TARGETED_DEVICE_FAMILY = "1,2,3,7";
|
|
398
392
|
TVOS_DEPLOYMENT_TARGET = 15.6;
|
|
399
393
|
};
|
|
400
394
|
name = Release;
|
|
@@ -418,8 +412,8 @@
|
|
|
418
412
|
SWIFT_OBJC_BRIDGING_HEADER = "AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h";
|
|
419
413
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
|
420
414
|
SWIFT_VERSION = 5.0;
|
|
421
|
-
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator";
|
|
422
|
-
TARGETED_DEVICE_FAMILY = "1,2,3";
|
|
415
|
+
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator xros xrsimulator";
|
|
416
|
+
TARGETED_DEVICE_FAMILY = "1,2,3,7";
|
|
423
417
|
TVOS_DEPLOYMENT_TARGET = 15.6;
|
|
424
418
|
TEST_TARGET_NAME = AgentDeviceRunner;
|
|
425
419
|
};
|
|
@@ -444,8 +438,8 @@
|
|
|
444
438
|
SWIFT_OBJC_BRIDGING_HEADER = "AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h";
|
|
445
439
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
|
446
440
|
SWIFT_VERSION = 5.0;
|
|
447
|
-
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator";
|
|
448
|
-
TARGETED_DEVICE_FAMILY = "1,2,3";
|
|
441
|
+
SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator xros xrsimulator";
|
|
442
|
+
TARGETED_DEVICE_FAMILY = "1,2,3,7";
|
|
449
443
|
TVOS_DEPLOYMENT_TARGET = 15.6;
|
|
450
444
|
TEST_TARGET_NAME = AgentDeviceRunner;
|
|
451
445
|
};
|
|
@@ -208,6 +208,7 @@ extension RunnerTests {
|
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
211
212
|
// MARK: - In-bundle unit tests
|
|
212
213
|
|
|
213
214
|
extension RunnerTests {
|
|
@@ -325,3 +326,4 @@ extension RunnerTests {
|
|
|
325
326
|
XCTAssertFalse(labels.contains("Admin settings"))
|
|
326
327
|
}
|
|
327
328
|
}
|
|
329
|
+
#endif
|
|
@@ -130,6 +130,7 @@ extension RunnerTests {
|
|
|
130
130
|
return Response(ok: true, data: data)
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
133
134
|
func testGestureResponseIncludesSynthesizedTapFallbackDiagnostics() {
|
|
134
135
|
let response = gestureResponse(
|
|
135
136
|
message: "tapped",
|
|
@@ -180,6 +181,7 @@ extension RunnerTests {
|
|
|
180
181
|
)
|
|
181
182
|
XCTAssertNil(xctestRecordedFailureResponse(command: tapCommand, response: runnerFatalResponse))
|
|
182
183
|
}
|
|
184
|
+
#endif
|
|
183
185
|
|
|
184
186
|
func execute(command: Command) throws -> Response {
|
|
185
187
|
if command.command == .status {
|
|
@@ -882,7 +884,7 @@ extension RunnerTests {
|
|
|
882
884
|
ok: false,
|
|
883
885
|
error: ErrorPayload(
|
|
884
886
|
code: "UNSUPPORTED_OPERATION",
|
|
885
|
-
message: "Unable to dismiss the iOS keyboard without a native dismiss
|
|
887
|
+
message: "Unable to dismiss the iOS keyboard without a safe native dismiss control"
|
|
886
888
|
)
|
|
887
889
|
)
|
|
888
890
|
}
|
|
@@ -153,6 +153,7 @@ final class RunnerCommandJournal {
|
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
156
157
|
extension RunnerTests {
|
|
157
158
|
func testUptimeBypassesCommandJournal() throws {
|
|
158
159
|
let command = runnerJournalCommand("uptime", id: "uptime-probe")
|
|
@@ -439,3 +440,4 @@ extension RunnerTests {
|
|
|
439
440
|
return try JSONDecoder().decode(Response.self, from: Data(responseJson.utf8))
|
|
440
441
|
}
|
|
441
442
|
}
|
|
443
|
+
#endif
|
|
@@ -7,10 +7,6 @@ struct FlatSnapshotFilterNode {
|
|
|
7
7
|
let valueText: String?
|
|
8
8
|
let visible: Bool
|
|
9
9
|
|
|
10
|
-
var hasContent: Bool {
|
|
11
|
-
return !label.isEmpty || !identifier.isEmpty || valueText != nil
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
func matchesScope(_ scope: String) -> Bool {
|
|
15
11
|
let haystack = [label, identifier, valueText ?? ""].joined(separator: "\n")
|
|
16
12
|
return haystack.localizedCaseInsensitiveContains(scope)
|
|
@@ -68,6 +64,7 @@ extension RunnerTests {
|
|
|
68
64
|
return type
|
|
69
65
|
}
|
|
70
66
|
|
|
67
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
71
68
|
func testFlatSnapshotFilterDecisionMatrixCoversOptions() {
|
|
72
69
|
let visibleContent = FlatSnapshotFilterNode(
|
|
73
70
|
isRoot: false,
|
|
@@ -168,4 +165,5 @@ extension RunnerTests {
|
|
|
168
165
|
"private AX marks scroll containers as interactive candidates"
|
|
169
166
|
)
|
|
170
167
|
}
|
|
168
|
+
#endif
|
|
171
169
|
}
|
|
@@ -122,7 +122,7 @@ extension RunnerTests {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
func rotateDevice(to orientationName: String) -> Bool {
|
|
125
|
-
#if os(macOS) || os(tvOS)
|
|
125
|
+
#if os(macOS) || os(tvOS) || os(visionOS)
|
|
126
126
|
return false
|
|
127
127
|
#else
|
|
128
128
|
switch orientationName {
|
|
@@ -355,27 +355,12 @@ extension RunnerTests {
|
|
|
355
355
|
let visible = isKeyboardVisible(app: app)
|
|
356
356
|
return (wasVisible: true, dismissed: !visible, visible: visible)
|
|
357
357
|
#else
|
|
358
|
-
let keyboard = app.keyboards.firstMatch
|
|
359
|
-
keyboard.swipeDown()
|
|
360
|
-
sleepFor(0.2)
|
|
361
|
-
if !isKeyboardVisible(app: app) {
|
|
362
|
-
return (wasVisible: true, dismissed: true, visible: false)
|
|
363
|
-
}
|
|
364
|
-
|
|
365
358
|
if tapKeyboardDismissControl(app: app) {
|
|
366
359
|
sleepFor(0.2)
|
|
367
360
|
let visible = isKeyboardVisible(app: app)
|
|
368
361
|
return (wasVisible: true, dismissed: !visible, visible: visible)
|
|
369
362
|
}
|
|
370
363
|
|
|
371
|
-
if tapKeyboardReturnControl(app: app, allowCoordinateFallback: true) {
|
|
372
|
-
sleepFor(0.2)
|
|
373
|
-
let visible = isKeyboardVisible(app: app)
|
|
374
|
-
if !visible {
|
|
375
|
-
return (wasVisible: true, dismissed: true, visible: false)
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
364
|
return (wasVisible: true, dismissed: false, visible: isKeyboardVisible(app: app))
|
|
380
365
|
#endif
|
|
381
366
|
}
|
|
@@ -417,6 +402,7 @@ extension RunnerTests {
|
|
|
417
402
|
app: XCUIApplication,
|
|
418
403
|
wasVisible: Bool
|
|
419
404
|
) -> (wasVisible: Bool, pressed: Bool, visible: Bool) {
|
|
405
|
+
#if os(iOS)
|
|
420
406
|
let exceptionMessage = RunnerObjCExceptionCatcher.catchException({
|
|
421
407
|
element.tap()
|
|
422
408
|
element.typeText(XCUIKeyboardKey.return.rawValue)
|
|
@@ -430,6 +416,9 @@ extension RunnerTests {
|
|
|
430
416
|
}
|
|
431
417
|
sleepFor(0.2)
|
|
432
418
|
return (wasVisible: wasVisible, pressed: true, visible: isKeyboardVisible(app: app))
|
|
419
|
+
#else
|
|
420
|
+
return (wasVisible: wasVisible, pressed: false, visible: false)
|
|
421
|
+
#endif
|
|
433
422
|
}
|
|
434
423
|
|
|
435
424
|
private func singleTextEntryElement(app: XCUIApplication) -> XCUIElement? {
|
|
@@ -474,7 +463,7 @@ extension RunnerTests {
|
|
|
474
463
|
label,
|
|
475
464
|
label
|
|
476
465
|
)
|
|
477
|
-
let toolbarButtons = app.
|
|
466
|
+
let toolbarButtons = app.descendants(matching: .button)
|
|
478
467
|
.matching(toolbarButtonPredicate)
|
|
479
468
|
.allElementsBoundByIndex
|
|
480
469
|
if let hittable = toolbarButtons.first(where: {
|
|
@@ -488,10 +477,7 @@ extension RunnerTests {
|
|
|
488
477
|
#endif
|
|
489
478
|
}
|
|
490
479
|
|
|
491
|
-
private func tapKeyboardReturnControl(
|
|
492
|
-
app: XCUIApplication,
|
|
493
|
-
allowCoordinateFallback: Bool = false
|
|
494
|
-
) -> Bool {
|
|
480
|
+
private func tapKeyboardReturnControl(app: XCUIApplication) -> Bool {
|
|
495
481
|
#if os(iOS)
|
|
496
482
|
for label in ["return", "Return", "Enter", "Go", "Search", "Next", "Done", "Send", "Join"] {
|
|
497
483
|
let candidates = [
|
|
@@ -502,21 +488,6 @@ extension RunnerTests {
|
|
|
502
488
|
hittable.tap()
|
|
503
489
|
return true
|
|
504
490
|
}
|
|
505
|
-
if allowCoordinateFallback,
|
|
506
|
-
let keyboardFrame = visibleKeyboardFrame(app: app),
|
|
507
|
-
let framed = candidates.first(where: {
|
|
508
|
-
guard $0.exists else { return false }
|
|
509
|
-
let frame = $0.frame
|
|
510
|
-
return !frame.isEmpty && keyboardFrame.contains(CGPoint(x: frame.midX, y: frame.midY))
|
|
511
|
-
}) {
|
|
512
|
-
let frame = framed.frame
|
|
513
|
-
switch tapAt(app: app, x: frame.midX, y: frame.midY) {
|
|
514
|
-
case .performed:
|
|
515
|
-
return true
|
|
516
|
-
case .unsupported:
|
|
517
|
-
return false
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
491
|
}
|
|
521
492
|
#endif
|
|
522
493
|
return false
|
|
@@ -1261,6 +1232,7 @@ extension RunnerTests {
|
|
|
1261
1232
|
return element.exists ? element : nil
|
|
1262
1233
|
}
|
|
1263
1234
|
|
|
1235
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
1264
1236
|
// Identity in portrait/unknown, 90° per landscape, 180° upside-down.
|
|
1265
1237
|
func testNativeSynthesizedPointRotatesByInterfaceOrientation() {
|
|
1266
1238
|
let portrait = CGRect(x: 0, y: 0, width: 834, height: 1210)
|
|
@@ -1329,4 +1301,5 @@ extension RunnerTests {
|
|
|
1329
1301
|
XCTAssertEqual(events.count, 1)
|
|
1330
1302
|
XCTAssertEqual(events.first?.vertical, -200)
|
|
1331
1303
|
}
|
|
1304
|
+
#endif
|
|
1332
1305
|
}
|
|
@@ -62,6 +62,7 @@ func runnerScrollGesturePlan(
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
65
66
|
extension RunnerTests {
|
|
66
67
|
// Cross-language parity vectors mirroring src/core/__tests__/scroll-gesture.test.ts. Keep these
|
|
67
68
|
// in sync with the vitest vectors so the two buildScrollGesturePlan implementations cannot drift.
|
|
@@ -216,3 +217,4 @@ extension RunnerTests {
|
|
|
216
217
|
)
|
|
217
218
|
}
|
|
218
219
|
}
|
|
220
|
+
#endif
|
|
@@ -273,6 +273,7 @@ extension RunnerTests {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
276
277
|
// MARK: - In-bundle unit tests (device-free)
|
|
277
278
|
|
|
278
279
|
extension RunnerTests {
|
|
@@ -448,3 +449,4 @@ extension RunnerTests {
|
|
|
448
449
|
return try! JSONDecoder().decode(Command.self, from: data)
|
|
449
450
|
}
|
|
450
451
|
}
|
|
452
|
+
#endif
|
|
@@ -426,6 +426,7 @@ extension RunnerTests {
|
|
|
426
426
|
)
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
429
430
|
func testSnapshotAccessibilityUnavailableMarksSparseSnapshotRunnerFatal() {
|
|
430
431
|
currentApp = app
|
|
431
432
|
currentBundleId = "com.example.app"
|
|
@@ -468,6 +469,7 @@ extension RunnerTests {
|
|
|
468
469
|
XCTAssertTrue(failure.message.contains("\(Self.rawSnapshotMaxNodes) nodes"))
|
|
469
470
|
XCTAssertEqual(failure.hint, Self.rawSnapshotTooLargeHint)
|
|
470
471
|
}
|
|
472
|
+
#endif
|
|
471
473
|
|
|
472
474
|
private func interactiveRootNode(rect: CGRect) -> SnapshotNode {
|
|
473
475
|
SnapshotNode(
|
|
@@ -304,6 +304,7 @@ extension RunnerTests {
|
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
+
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
|
|
307
308
|
// MARK: - In-bundle unit tests
|
|
308
309
|
|
|
309
310
|
extension RunnerTests {
|
|
@@ -423,3 +424,4 @@ extension RunnerTests {
|
|
|
423
424
|
XCTAssertEqual(payload.snapshotQuality?.reasonCode, "ax-rejected")
|
|
424
425
|
}
|
|
425
426
|
}
|
|
427
|
+
#endif
|
|
@@ -12,7 +12,6 @@ extension RunnerTests {
|
|
|
12
12
|
|
|
13
13
|
enum TextEntryTiming {
|
|
14
14
|
static let focusTimeout: TimeInterval = 0.4
|
|
15
|
-
static let repairReadinessTimeout: TimeInterval = 1.0
|
|
16
15
|
static let readinessTimeout: TimeInterval = 2.0
|
|
17
16
|
static let hardwareKeyboardFallbackTimeout: TimeInterval = 0.35
|
|
18
17
|
static let pollInterval: TimeInterval = 0.02
|
package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift
RENAMED
|
@@ -46,7 +46,8 @@ final class RunnerTests: XCTestCase {
|
|
|
46
46
|
let firstInteractionAfterActivateDelay: TimeInterval = 0.25
|
|
47
47
|
let scrollInteractionIdleTimeoutDefault: TimeInterval = 1.0
|
|
48
48
|
let tvRemoteDoublePressDelayDefault: TimeInterval = 0.0
|
|
49
|
-
|
|
49
|
+
// Keep a periodic XCTest liveness marker in runner.log without flooding long-lived sessions.
|
|
50
|
+
let xctestIdleKeepaliveInterval: TimeInterval = 60.0
|
|
50
51
|
let minRecordingFps = 1
|
|
51
52
|
let maxRecordingFps = 120
|
|
52
53
|
var needsPostSnapshotInteractionDelay = false
|
package/dist/src/1986.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AppError as e}from"./485.js";import{daemonRuntimeSchema as a}from"./6849.js";let n={alert:"alert",audio:"audio",appState:"appstate",appSwitcher:"app-switcher",artifacts:"artifacts",apps:"apps",back:"back",batch:"batch",boot:"boot",click:"click",close:"close",clipboard:"clipboard",devices:"devices",doctor:"doctor",diff:"diff",fill:"fill",find:"find",focus:"focus",gesture:"gesture",get:"get",home:"home",install:"install",installFromSource:"install-from-source",is:"is",keyboard:"keyboard",logs:"logs",longPress:"longpress",network:"network",open:"open",perf:"perf",prepare:"prepare",press:"press",push:"push",record:"record",reactNative:"react-native",reinstall:"reinstall",replay:"replay",rotate:"rotate",scroll:"scroll",screenshot:"screenshot",settings:"settings",shutdown:"shutdown",snapshot:"snapshot",swipe:"swipe",test:"test",trace:"trace",triggerAppEvent:"trigger-app-event",type:"type",viewport:"viewport",wait:"wait"},i={installSource:"install_source",leaseAllocate:"lease_allocate",leaseHeartbeat:"lease_heartbeat",leaseRelease:"lease_release",releaseMaterializedPaths:"release_materialized_paths",runtime:"runtime",sessionList:"session_list"},t={cdp:"cdp",auth:"auth",connect:"connect",connection:"connection",debug:"debug",disconnect:"disconnect",mcp:"mcp",metro:"metro",proxy:"proxy",reactDevtools:"react-devtools",session:"session",web:"web"},o=["pan","fling","swipe","pinch","rotate","transform"],r=`gesture requires one of: ${o.join(", ")}`,l=s(t.auth,t.cdp,t.connect,t.connection,t.disconnect,t.mcp,t.proxy,t.reactDevtools,t.web,n.prepare);function s(...e){return new Set(e)}function c(){return[...Object.values(n),...Object.values(t)].sort()}function d(e){return Object.values(n).includes(e)||e===t.debug||e===t.metro||e===t.session}function p(){return c().filter(e=>!l.has(e))}function u(a,n,i,t){let o=i(a[n]);if(void 0===o)throw new e("COMMAND_FAILED",t,{response:a});return o}function m(e,a){return u(e,a,D,`Daemon response is missing "${a}".`)}function b(e,a){return D(e[a])}function h(e,a){var n;let i;return n=D,null===(i=e[a])?null:n(i)}function y(e,a){return u(e,a,w,`Daemon response is missing numeric "${a}".`)}function f(e,a){return u(e,a,k,`Daemon response has invalid "${a}".`)}function g(e,a){return u(e,a,_,`Daemon response has invalid "${a}".`)}function S(e,a){return function(e){return"tv"===e||"mobile"===e||"desktop"===e?e:void 0}(e[a])??"mobile"}function v(e){if(!E(e))return;let a=x(e,"x"),n=x(e,"y"),i=x(e,"width"),t=x(e,"height");if(void 0!==a&&void 0!==n&&void 0!==i&&void 0!==t)return{x:a,y:n,width:i,height:t}}function A(e){if(!E(e))return;let a=x(e,"x"),n=x(e,"y");if(void 0!==a&&void 0!==n)return{x:a,y:n}}function x(e,a){let n=e[a];return"number"==typeof n?n:void 0}function D(e){return"string"==typeof e&&e.length>0?e:void 0}function w(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function k(e){return"apple"===e?"ios":"ios"===e||"macos"===e||"android"===e||"linux"===e||"web"===e?e:void 0}function _(e){return"simulator"===e||"emulator"===e||"device"===e?e:void 0}s(t.auth,t.cdp,t.connect,t.connection,t.debug,t.disconnect,t.mcp,t.metro,t.proxy,t.reactDevtools,t.session,t.web,n.artifacts,n.appState,n.prepare,n.batch,n.devices,n.doctor,n.gesture,n.replay,n.test,n.trace);function B(a){if(!E(a))throw new e("COMMAND_FAILED","Daemon returned an unexpected response shape.",{value:a});return a}function E(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}function N(e){let a={};for(let[n,i]of Object.entries(e))void 0!==i&&(a[n]=i);return a}function R(e){return e.split("\n").map(e=>e.trim()).filter(e=>e.length>0)}let C=a=>new e("INVALID_ARGS",a);function G(e){return Number.isInteger(e)&&e>=1&&e<=1e3}function K(e,a,n=C){if(e>a)throw n(`batch has ${e} steps; max allowed is ${a}.`)}function M(e,a,n=C){if(!E(e))throw n(`Invalid batch step ${a}.`);return e}function I(e,a,n=C){let i=e.input;if(!E(i))throw n(`Batch step ${a} input must be an object.`);return i}function O(e,n,i=C){if(void 0!==e)try{return a.parse(e)}catch(e){throw i(`Batch step ${n} runtime is invalid: ${e instanceof Error?e.message:String(e)}`)}}function P(e){let a=[];for(let n of e)n.daemon&&a.push({command:n.name,...n.daemon});return a}function L(e){let a={};for(let n of e)n.capability&&(a[n.name]=n.capability);return a}let $={leaseAdmissionExempt:!0,sessionExecutionLockExempt:!0},T={leaseAdmissionExempt:!0,sessionExecutionLockExempt:!0,selectorValidationExempt:!0},U=()=>!0,j=e=>e.command===n.test&&("number"==typeof e.flags?.shardAll||"number"==typeof e.flags?.shardSplit),H={simulator:!0,device:!0},F={emulator:!0,device:!0,unknown:!0},q={device:!0},V={},z={apple:H,android:F,linux:q},Y={apple:H,android:F,linux:V},J=[{name:i.leaseAllocate,daemon:{route:"lease",...$},batchable:!1},{name:i.leaseHeartbeat,daemon:{route:"lease",...$},batchable:!1},{name:i.leaseRelease,daemon:{route:"lease",...$},batchable:!1},{name:n.artifacts,daemon:{route:"lease",...$},batchable:!1},{name:i.sessionList,daemon:{route:"session",sessionKind:"inventory",...T},batchable:!1},{name:n.devices,daemon:{route:"session",sessionKind:"inventory",lockPolicySelectorOverride:!0,...T},batchable:!0},{name:n.doctor,daemon:{route:"session",sessionKind:"inventory",lockPolicySelectorOverride:!0,allowSessionlessDefaultDevice:U,...T},batchable:!0},{name:n.apps,daemon:{route:"session",sessionKind:"inventory",lockPolicySelectorOverride:!0,preferExplicitDeviceOverExistingSession:!0},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.boot,daemon:{route:"session",sessionKind:"state"},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.shutdown,daemon:{route:"session",sessionKind:"state"},capability:{apple:{simulator:!0},android:{emulator:!0},linux:V},batchable:!0},{name:n.appState,daemon:{route:"session",sessionKind:"state"},batchable:!0},{name:n.perf,daemon:{route:"session",sessionKind:"observability"},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.logs,daemon:{route:"session",sessionKind:"observability"},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.network,daemon:{route:"session",sessionKind:"observability"},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.audio,daemon:{route:"session",sessionKind:"observability"},capability:{apple:H,android:{emulator:!0},linux:V},batchable:!0},{name:n.replay,daemon:{route:"session",sessionKind:"replay",skipSessionlessProviderDevice:j},batchable:!1},{name:n.test,daemon:{route:"session",sessionKind:"replay",skipSessionlessProviderDevice:j},batchable:!0},{name:i.runtime,daemon:{route:"session"},batchable:!1},{name:n.clipboard,daemon:{route:"session",replayScopedAction:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.keyboard,daemon:{route:"session",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.install,daemon:{route:"session"},capability:Y,batchable:!0},{name:n.reinstall,daemon:{route:"session"},capability:Y,batchable:!0},{name:i.installSource,daemon:{route:"session"},batchable:!1},{name:i.releaseMaterializedPaths,daemon:{route:"session",...T},batchable:!1},{name:n.push,daemon:{route:"session"},capability:{apple:{simulator:!0},android:F,linux:V},batchable:!0},{name:n.triggerAppEvent,daemon:{route:"session"},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.open,daemon:{route:"session",allowSessionlessDefaultDevice:U},capability:z,batchable:!0},{name:n.prepare,daemon:{route:"session"},batchable:!1},{name:n.batch,daemon:{route:"session"},batchable:!1},{name:n.close,daemon:{route:"session",allowInvalidRecording:!0},capability:z,batchable:!0},{name:n.snapshot,daemon:{route:"snapshot",replayScopedAction:!0},capability:z,batchable:!0},{name:n.diff,daemon:{route:"snapshot",replayScopedAction:!0},capability:z,batchable:!0},{name:n.wait,daemon:{route:"snapshot",replayScopedAction:!0},capability:z,batchable:!0},{name:n.alert,daemon:{route:"snapshot",replayScopedAction:!0},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.settings,daemon:{route:"snapshot",replayScopedAction:!0},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.reactNative,daemon:{route:"reactNative",replayScopedAction:!0},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.record,daemon:{route:"recordTrace",replayScopedAction:!0,allowInvalidRecording:!0,allowSessionlessDefaultDevice:e=>"start"===(e.positionals?.[0]??"").toLowerCase()},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.trace,daemon:{route:"recordTrace"},batchable:!0},{name:n.find,daemon:{route:"find",replayScopedAction:!0},capability:z,batchable:!0},{name:n.click,daemon:{route:"interaction",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.fill,daemon:{route:"interaction",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.longPress,daemon:{route:"interaction",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.press,daemon:{route:"interaction",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.type,daemon:{route:"interaction",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:z,batchable:!0},{name:n.get,daemon:{route:"interaction",replayScopedAction:!0},capability:z,batchable:!0},{name:n.is,daemon:{route:"interaction",replayScopedAction:!0},capability:z,batchable:!0},{name:n.back,daemon:{route:"generic",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.gesture,daemon:{route:"generic",replayScopedAction:!0,androidBlockingDialogGuard:!0},batchable:!0},{name:n.home,daemon:{route:"generic",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.rotate,daemon:{route:"generic",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.scroll,daemon:{route:"generic",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.swipe,daemon:{route:"generic",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:"pinch",daemon:{route:"generic",replayScopedAction:!0,androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:V},batchable:!1},{name:n.focus,daemon:{route:"generic",androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!0},{name:n.screenshot,daemon:{route:"generic",replayScopedAction:!0},capability:z,batchable:!0},{name:n.viewport,daemon:{route:"generic",replayScopedAction:!0},capability:{apple:H,android:F,linux:V},batchable:!1},{name:"pan",daemon:{route:"generic",androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:q},batchable:!1},{name:"fling",daemon:{route:"generic",androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:V},batchable:!1},{name:"rotate-gesture",daemon:{route:"generic",androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:V},batchable:!1},{name:"transform-gesture",daemon:{route:"generic",androidBlockingDialogGuard:!0},capability:{apple:H,android:F,linux:V},batchable:!1},{name:n.appSwitcher,capability:{apple:H,android:F,linux:V},batchable:!0},{name:n.installFromSource,capability:Y,batchable:!0}],Q=new Set(p()),W=J.map(e=>({...e,mcpExposed:Q.has(e.name)})),X=W.filter(e=>e.batchable).map(e=>e.name),Z=new Set(["batch","replay"]),ee=["command","positionals","flags","runtime"],ea=["platform","target","device","udid","serial","verbose","out"],en=new Set(X);function ei(e){return"string"==typeof e?e.trim().toLowerCase():""}function et(a,n){let i=ei(a);if(en.has(i))return i;throw new e("INVALID_ARGS",`Batch step ${n} command is not available through command batch: ${String(a)}`)}function eo(a,n){if(Z.has(a))throw new e("INVALID_ARGS",`Batch step ${n} cannot run ${a}.`)}export{ee as BATCH_DAEMON_STEP_KEYS,o as GESTURE_KINDS,r as GESTURE_SUBCOMMAND_ERROR,ea as INHERITED_PARENT_FLAG_KEYS,i as INTERNAL_COMMANDS,n as PUBLIC_COMMANDS,X as STRUCTURED_BATCH_COMMAND_NAMES,B as asRecord,eo as assertBatchRuntimeCommandAllowed,K as assertBatchStepCount,W as commandDescriptors,L as deriveCapabilityMatrix,P as deriveDaemonCommandDescriptors,d as isClientBackedCliCommandName,E as isRecord,G as isValidBatchMaxSteps,c as listCliCommandNames,p as listMcpExposedCommandNames,ei as normalizeBatchCommandName,O as parseBatchStepRuntime,A as parsePoint,v as parseRect,I as readBatchStepInputObject,M as readBatchStepRecord,S as readDeviceTarget,h as readNullableString,b as readOptionalString,g as readRequiredDeviceKind,y as readRequiredNumber,f as readRequiredPlatform,m as readRequiredString,et as readStructuredBatchCommandName,R as splitNonEmptyTrimmedLines,N as stripUndefined};
|
package/dist/src/2748.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AppError as e}from"./
|
|
1
|
+
import{AppError as e}from"./485.js";let r="user-installed";function t(e){return e??r}function o(r){if(void 0===r)throw new e("INVALID_ARGS","appsFilter must be resolved before executing the apps command");return r}export{r as DEFAULT_APPS_FILTER,o as assertResolvedAppsFilter,t as resolveAppsFilter};
|