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 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
- @implementation FBXCTestDaemonsProxy
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 Class FBXCTRunnerDaemonSessionClass = nil;
26
- static dispatch_once_t onceTestRunnerDaemonClass;
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
- dispatch_once(&onceTestRunnerDaemonClass, ^{
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 *)[FBXCTRunnerDaemonSessionClass sharedSession]).daemonProxy;
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
- if (nil == FBXCTRunnerDaemonSessionClass) {
75
- [[self testRunnerProxy] _XCT_synthesizeEvent:record completion:errorHandler];
76
- } else {
77
- XCEventGeneratorHandler handlerBlock = ^(XCSynthesizedEventRecord *innerRecord, NSError *invokeError) {
78
- errorHandler(invokeError);
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 = [FBXCTRunnerDaemonSessionClass sharedSession];
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 = [FBXCTRunnerDaemonSessionClass sharedSession];
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 = [FBXCTRunnerDaemonSessionClass sharedSession];
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 = [FBXCTRunnerDaemonSessionClass sharedSession];
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 = [FBXCTRunnerDaemonSessionClass sharedSession];
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "5.1.3",
3
+ "version": "5.1.4",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {