appium-webdriveragent 5.1.3 → 5.1.4
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/CHANGELOG.md +7 -0
- package/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h +7 -0
- package/WebDriverAgentLib/Routing/FBExceptionHandler.m +2 -1
- package/WebDriverAgentLib/Routing/FBExceptions.h +3 -0
- package/WebDriverAgentLib/Routing/FBExceptions.m +1 -0
- package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +58 -23
- package/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m +23 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [5.1.4](https://github.com/appium/WebDriverAgent/compare/v5.1.3...v5.1.4) (2023-05-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Prevent freeze on launch/activate of a missing app ([#706](https://github.com/appium/WebDriverAgent/issues/706)) ([c4976e3](https://github.com/appium/WebDriverAgent/commit/c4976e3e99afa4d471bd39c3dccfc7d9f58d8bfc))
|
|
7
|
+
|
|
1
8
|
## [5.1.3](https://github.com/appium/WebDriverAgent/compare/v5.1.2...v5.1.3) (2023-05-16)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -80,4 +80,11 @@
|
|
|
80
80
|
@property(readonly) _Bool supportsLocationSimulation;
|
|
81
81
|
#endif
|
|
82
82
|
|
|
83
|
+
// Since Xcode 10.2
|
|
84
|
+
- (void)launchApplicationWithPath:(NSString *)arg1
|
|
85
|
+
bundleID:(NSString *)arg2
|
|
86
|
+
arguments:(NSArray *)arg3
|
|
87
|
+
environment:(NSDictionary *)arg4
|
|
88
|
+
completion:(void (^)(_Bool, NSError *))arg5;
|
|
89
|
+
|
|
83
90
|
@end
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
commandStatus = [FBCommandStatus noSuchDriverErrorWithMessage:exception.reason
|
|
25
25
|
traceback:traceback];
|
|
26
26
|
} else if ([exception.name isEqualToString:FBInvalidArgumentException]
|
|
27
|
-
|| [exception.name isEqualToString:FBElementAttributeUnknownException]
|
|
27
|
+
|| [exception.name isEqualToString:FBElementAttributeUnknownException]
|
|
28
|
+
|| [exception.name isEqualToString:FBApplicationMissingException]) {
|
|
28
29
|
commandStatus = [FBCommandStatus invalidArgumentErrorWithMessage:exception.reason
|
|
29
30
|
traceback:traceback];
|
|
30
31
|
} else if ([exception.name isEqualToString:FBApplicationCrashedException]
|
|
@@ -49,4 +49,7 @@ extern NSString *const FBClassChainQueryParseException;
|
|
|
49
49
|
/*! Exception used to notify about application crash */
|
|
50
50
|
extern NSString *const FBApplicationCrashedException;
|
|
51
51
|
|
|
52
|
+
/*! Exception used to notify about the application is not installed */
|
|
53
|
+
extern NSString *const FBApplicationMissingException;
|
|
54
|
+
|
|
52
55
|
NS_ASSUME_NONNULL_END
|
|
@@ -20,3 +20,4 @@ NSString *const FBInvalidXPathException = @"FBInvalidXPathException";
|
|
|
20
20
|
NSString *const FBXPathQueryEvaluationException = @"FBXPathQueryEvaluationException";
|
|
21
21
|
NSString *const FBClassChainQueryParseException = @"FBClassChainQueryParseException";
|
|
22
22
|
NSString *const FBApplicationCrashedException = @"FBApplicationCrashedException";
|
|
23
|
+
NSString *const FBApplicationMissingException = @"FBApplicationMissingException";
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
#import "FBConfiguration.h"
|
|
15
15
|
#import "FBErrorBuilder.h"
|
|
16
|
+
#import "FBExceptions.h"
|
|
16
17
|
#import "FBLogger.h"
|
|
17
18
|
#import "FBRunLoopSpinner.h"
|
|
18
19
|
#import "XCTestDriver.h"
|
|
@@ -20,23 +21,61 @@
|
|
|
20
21
|
#import "XCUIApplication.h"
|
|
21
22
|
#import "XCUIDevice.h"
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
#define LAUNCH_APP_TIMEOUT_SEC 300
|
|
25
|
+
|
|
26
|
+
static void (*originalLaunchAppMethod)(id, SEL, NSString*, NSString*, NSArray*, NSDictionary*, void (^)(_Bool, NSError *));
|
|
24
27
|
|
|
25
|
-
static
|
|
26
|
-
|
|
28
|
+
static void swizzledLaunchApp(id self, SEL _cmd, NSString *path, NSString *bundleID,
|
|
29
|
+
NSArray *arguments, NSDictionary *environment,
|
|
30
|
+
void (^reply)(_Bool, NSError *))
|
|
31
|
+
{
|
|
32
|
+
__block BOOL isSuccessful;
|
|
33
|
+
__block NSError *error;
|
|
34
|
+
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
|
|
35
|
+
originalLaunchAppMethod(self, _cmd, path, bundleID, arguments, environment, ^(BOOL passed, NSError *innerError) {
|
|
36
|
+
isSuccessful = passed;
|
|
37
|
+
error = innerError;
|
|
38
|
+
dispatch_semaphore_signal(sem);
|
|
39
|
+
});
|
|
40
|
+
int64_t timeoutNs = (int64_t)(LAUNCH_APP_TIMEOUT_SEC * NSEC_PER_SEC);
|
|
41
|
+
if (0 != dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, timeoutNs))) {
|
|
42
|
+
NSString *message = [NSString stringWithFormat:@"The application '%@' cannot be launched within %d seconds timeout",
|
|
43
|
+
bundleID ?: path, LAUNCH_APP_TIMEOUT_SEC];
|
|
44
|
+
@throw [NSException exceptionWithName:FBTimeoutException reason:message userInfo:nil];
|
|
45
|
+
}
|
|
46
|
+
if (!isSuccessful || nil != error) {
|
|
47
|
+
[FBLogger logFmt:@"%@", error.description];
|
|
48
|
+
NSString *message = error.description ?: [NSString stringWithFormat:@"The application '%@' is not installed on the device under test",
|
|
49
|
+
bundleID ?: path];
|
|
50
|
+
@throw [NSException exceptionWithName:FBApplicationMissingException reason:message userInfo:nil];
|
|
51
|
+
}
|
|
52
|
+
reply(isSuccessful, error);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@implementation FBXCTestDaemonsProxy
|
|
27
56
|
|
|
28
57
|
#pragma clang diagnostic push
|
|
29
58
|
#pragma clang diagnostic ignored "-Wobjc-load-method"
|
|
30
59
|
|
|
31
60
|
+ (void)load
|
|
32
61
|
{
|
|
33
|
-
|
|
34
|
-
FBXCTRunnerDaemonSessionClass = objc_lookUpClass("XCTRunnerDaemonSession");
|
|
35
|
-
});
|
|
62
|
+
[self.class swizzleLaunchApp];
|
|
36
63
|
}
|
|
37
64
|
|
|
38
65
|
#pragma clang diagnostic pop
|
|
39
66
|
|
|
67
|
+
+ (void)swizzleLaunchApp {
|
|
68
|
+
Method original = class_getInstanceMethod([XCTRunnerDaemonSession class],
|
|
69
|
+
@selector(launchApplicationWithPath:bundleID:arguments:environment:completion:));
|
|
70
|
+
if (original == nil) {
|
|
71
|
+
[FBLogger log:@"Could not find method -[XCTRunnerDaemonSession launchApplicationWithPath:]"];
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Workaround for https://github.com/appium/WebDriverAgent/issues/702
|
|
75
|
+
originalLaunchAppMethod = (void(*)(id, SEL, NSString*, NSString*, NSArray*, NSDictionary*, void (^)(_Bool, NSError *))) method_getImplementation(original);
|
|
76
|
+
method_setImplementation(original, (IMP)swizzledLaunchApp);
|
|
77
|
+
}
|
|
78
|
+
|
|
40
79
|
+ (id<XCTestManager_ManagerInterface>)testRunnerProxy
|
|
41
80
|
{
|
|
42
81
|
static id<XCTestManager_ManagerInterface> proxy = nil;
|
|
@@ -56,7 +95,7 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
56
95
|
|
|
57
96
|
+ (id<XCTestManager_ManagerInterface>)retrieveTestRunnerProxy
|
|
58
97
|
{
|
|
59
|
-
return ((XCTRunnerDaemonSession *)[
|
|
98
|
+
return ((XCTRunnerDaemonSession *)[XCTRunnerDaemonSession sharedSession]).daemonProxy;
|
|
60
99
|
}
|
|
61
100
|
|
|
62
101
|
+ (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSError *__autoreleasing*)error
|
|
@@ -70,24 +109,20 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
70
109
|
didSucceed = (invokeError == nil);
|
|
71
110
|
completion();
|
|
72
111
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
[[XCUIDevice.sharedDevice eventSynthesizer] synthesizeEvent:record completion:(id)^(BOOL result, NSError *invokeError) {
|
|
81
|
-
handlerBlock(record, invokeError);
|
|
82
|
-
}];
|
|
83
|
-
}
|
|
112
|
+
|
|
113
|
+
XCEventGeneratorHandler handlerBlock = ^(XCSynthesizedEventRecord *innerRecord, NSError *invokeError) {
|
|
114
|
+
errorHandler(invokeError);
|
|
115
|
+
};
|
|
116
|
+
[[XCUIDevice.sharedDevice eventSynthesizer] synthesizeEvent:record completion:(id)^(BOOL result, NSError *invokeError) {
|
|
117
|
+
handlerBlock(record, invokeError);
|
|
118
|
+
}];
|
|
84
119
|
}];
|
|
85
120
|
return didSucceed;
|
|
86
121
|
}
|
|
87
122
|
|
|
88
123
|
+ (BOOL)openURL:(NSURL *)url usingApplication:(NSString *)bundleId error:(NSError *__autoreleasing*)error
|
|
89
124
|
{
|
|
90
|
-
XCTRunnerDaemonSession *session = [
|
|
125
|
+
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
91
126
|
if (![session respondsToSelector:@selector(openURL:usingApplication:completion:)]) {
|
|
92
127
|
if (error) {
|
|
93
128
|
[[[FBErrorBuilder builder]
|
|
@@ -112,7 +147,7 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
112
147
|
|
|
113
148
|
+ (BOOL)openDefaultApplicationForURL:(NSURL *)url error:(NSError *__autoreleasing*)error
|
|
114
149
|
{
|
|
115
|
-
XCTRunnerDaemonSession *session = [
|
|
150
|
+
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
116
151
|
if (![session respondsToSelector:@selector(openDefaultApplicationForURL:completion:)]) {
|
|
117
152
|
if (error) {
|
|
118
153
|
[[[FBErrorBuilder builder]
|
|
@@ -138,7 +173,7 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
138
173
|
#if !TARGET_OS_TV
|
|
139
174
|
+ (BOOL)setSimulatedLocation:(CLLocation *)location error:(NSError *__autoreleasing*)error
|
|
140
175
|
{
|
|
141
|
-
XCTRunnerDaemonSession *session = [
|
|
176
|
+
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
142
177
|
if (![session respondsToSelector:@selector(setSimulatedLocation:completion:)]) {
|
|
143
178
|
if (error) {
|
|
144
179
|
[[[FBErrorBuilder builder]
|
|
@@ -171,7 +206,7 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
171
206
|
|
|
172
207
|
+ (nullable CLLocation *)getSimulatedLocation:(NSError *__autoreleasing*)error;
|
|
173
208
|
{
|
|
174
|
-
XCTRunnerDaemonSession *session = [
|
|
209
|
+
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
175
210
|
if (![session respondsToSelector:@selector(getSimulatedLocationWithReply:)]) {
|
|
176
211
|
if (error) {
|
|
177
212
|
[[[FBErrorBuilder builder]
|
|
@@ -206,7 +241,7 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
206
241
|
|
|
207
242
|
+ (BOOL)clearSimulatedLocation:(NSError *__autoreleasing*)error
|
|
208
243
|
{
|
|
209
|
-
XCTRunnerDaemonSession *session = [
|
|
244
|
+
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
210
245
|
if (![session respondsToSelector:@selector(clearSimulatedLocationWithReply:)]) {
|
|
211
246
|
if (error) {
|
|
212
247
|
[[[FBErrorBuilder builder]
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
#import "FBIntegrationTestCase.h"
|
|
13
13
|
#import "FBApplication.h"
|
|
14
|
+
#import "FBExceptions.h"
|
|
14
15
|
#import "FBMacros.h"
|
|
15
16
|
#import "FBSession.h"
|
|
16
17
|
#import "FBXCodeCompatibility.h"
|
|
@@ -107,4 +108,26 @@ static NSString *const SETTINGS_BUNDLE_ID = @"com.apple.Preferences";
|
|
|
107
108
|
XCTAssertEqualObjects(SETTINGS_BUNDLE_ID, FBApplication.fb_activeApplication.bundleID);
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
- (void)testAppWithInvalidBundleIDCannotBeStarted
|
|
112
|
+
{
|
|
113
|
+
FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"];
|
|
114
|
+
@try {
|
|
115
|
+
[testedApp launch];
|
|
116
|
+
XCTFail(@"An exception is expected to be thrown");
|
|
117
|
+
} @catch (NSException *exception) {
|
|
118
|
+
XCTAssertEqualObjects(FBApplicationMissingException, exception.name);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
- (void)testAppWithInvalidBundleIDCannotBeActivated
|
|
123
|
+
{
|
|
124
|
+
FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"];
|
|
125
|
+
@try {
|
|
126
|
+
[testedApp activate];
|
|
127
|
+
XCTFail(@"An exception is expected to be thrown");
|
|
128
|
+
} @catch (NSException *exception) {
|
|
129
|
+
XCTAssertEqualObjects(FBApplicationMissingException, exception.name);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
110
133
|
@end
|