appium-webdriveragent 5.15.9 → 6.1.0
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 +17 -2
- package/PrivateHeaders/XCTest/XCUIApplication.h +0 -1
- package/WebDriverAgent.xcodeproj/project.pbxproj +6 -18
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +38 -0
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +148 -5
- package/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +1 -1
- package/WebDriverAgentLib/Categories/XCUIDevice+FBRotation.h +0 -1
- package/WebDriverAgentLib/Categories/XCUIDevice+FBRotation.m +5 -3
- package/WebDriverAgentLib/Categories/XCUIElement+FBSwiping.h +14 -0
- package/WebDriverAgentLib/Categories/XCUIElement+FBSwiping.m +27 -10
- package/WebDriverAgentLib/Categories/XCUIElement+FBTVFocuse.m +2 -2
- package/WebDriverAgentLib/Commands/FBAlertViewCommands.m +4 -4
- package/WebDriverAgentLib/Commands/FBCustomCommands.m +2 -2
- package/WebDriverAgentLib/Commands/FBDebugCommands.m +2 -3
- package/WebDriverAgentLib/Commands/FBElementCommands.m +113 -89
- package/WebDriverAgentLib/Commands/FBFindElementCommands.m +0 -1
- package/WebDriverAgentLib/Commands/FBOrientationCommands.m +9 -8
- package/WebDriverAgentLib/Commands/FBSessionCommands.m +43 -10
- package/WebDriverAgentLib/Commands/FBTouchActionCommands.m +0 -1
- package/WebDriverAgentLib/FBAlert.m +3 -3
- package/WebDriverAgentLib/Routing/FBSession.h +13 -14
- package/WebDriverAgentLib/Routing/FBSession.m +49 -46
- package/WebDriverAgentLib/Utilities/FBAlertsMonitor.m +3 -3
- package/WebDriverAgentLib/Utilities/FBCapabilities.h +20 -0
- package/WebDriverAgentLib/Utilities/FBCapabilities.m +1 -0
- package/WebDriverAgentLib/Utilities/FBKeyboard.m +6 -5
- package/WebDriverAgentLib/Utilities/FBMjpegServer.m +0 -1
- package/WebDriverAgentLib/Utilities/FBPasteboard.m +2 -2
- package/WebDriverAgentLib/Utilities/FBScreen.m +1 -2
- package/WebDriverAgentLib/Utilities/FBTVNavigationTracker.m +1 -2
- package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.h +0 -33
- package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m +2 -40
- package/WebDriverAgentLib/WebDriverAgentLib.h +0 -1
- package/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m +2 -3
- package/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m +0 -1
- package/WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.h +1 -3
- package/WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.m +5 -5
- package/WebDriverAgentTests/IntegrationTests/FBSafariAlertTests.m +1 -2
- package/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m +11 -10
- package/WebDriverAgentTests/IntegrationTests/FBTapTest.m +0 -1
- package/WebDriverAgentTests/IntegrationTests/FBW3CMultiTouchActionsIntegrationTests.m +0 -1
- package/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m +8 -8
- package/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m +5 -4
- package/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m +0 -1
- package/WebDriverAgentTests/UnitTests/Doubles/{FBApplicationDouble.h → XCUIApplicationDouble.h} +1 -1
- package/WebDriverAgentTests/UnitTests/Doubles/{FBApplicationDouble.m → XCUIApplicationDouble.m} +3 -3
- package/WebDriverAgentTests/UnitTests/FBSessionTests.m +3 -3
- package/package.json +2 -14
- package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/kazu.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/WebDriverAgent.xcodeproj/xcuserdata/kazu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -1342
- package/WebDriverAgentLib/FBApplication.h +0 -49
- package/WebDriverAgentLib/FBApplication.m +0 -185
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
#import "FBElementCommands.h"
|
|
11
11
|
|
|
12
|
-
#import "FBApplication.h"
|
|
13
12
|
#import "FBConfiguration.h"
|
|
14
13
|
#import "FBKeyboard.h"
|
|
15
14
|
#import "FBRoute.h"
|
|
@@ -18,7 +17,6 @@
|
|
|
18
17
|
#import "FBElementCache.h"
|
|
19
18
|
#import "FBErrorBuilder.h"
|
|
20
19
|
#import "FBSession.h"
|
|
21
|
-
#import "FBApplication.h"
|
|
22
20
|
#import "FBElementUtils.h"
|
|
23
21
|
#import "FBMacros.h"
|
|
24
22
|
#import "FBMathUtils.h"
|
|
@@ -76,24 +74,46 @@
|
|
|
76
74
|
[[FBRoute POST:@"/wda/element/:uuid/focuse"] respondWithTarget:self action:@selector(handleFocuse:)],
|
|
77
75
|
#else
|
|
78
76
|
[[FBRoute POST:@"/wda/element/:uuid/swipe"] respondWithTarget:self action:@selector(handleSwipe:)],
|
|
77
|
+
[[FBRoute POST:@"/wda/swipe"] respondWithTarget:self action:@selector(handleSwipe:)],
|
|
78
|
+
|
|
79
79
|
[[FBRoute POST:@"/wda/element/:uuid/pinch"] respondWithTarget:self action:@selector(handlePinch:)],
|
|
80
|
+
[[FBRoute POST:@"/wda/pinch"] respondWithTarget:self action:@selector(handlePinch:)],
|
|
81
|
+
|
|
80
82
|
[[FBRoute POST:@"/wda/element/:uuid/rotate"] respondWithTarget:self action:@selector(handleRotate:)],
|
|
83
|
+
[[FBRoute POST:@"/wda/rotate"] respondWithTarget:self action:@selector(handleRotate:)],
|
|
84
|
+
|
|
81
85
|
[[FBRoute POST:@"/wda/element/:uuid/doubleTap"] respondWithTarget:self action:@selector(handleDoubleTap:)],
|
|
86
|
+
[[FBRoute POST:@"/wda/doubleTap"] respondWithTarget:self action:@selector(handleDoubleTap:)],
|
|
87
|
+
|
|
82
88
|
[[FBRoute POST:@"/wda/element/:uuid/twoFingerTap"] respondWithTarget:self action:@selector(handleTwoFingerTap:)],
|
|
83
|
-
[[FBRoute POST:@"/wda/
|
|
89
|
+
[[FBRoute POST:@"/wda/twoFingerTap"] respondWithTarget:self action:@selector(handleTwoFingerTap:)],
|
|
90
|
+
|
|
91
|
+
[[FBRoute POST:@"/wda/element/:uuid/tapWithNumberOfTaps"] respondWithTarget:self
|
|
92
|
+
action:@selector(handleTapWithNumberOfTaps:)],
|
|
93
|
+
[[FBRoute POST:@"/wda/tapWithNumberOfTaps"] respondWithTarget:self
|
|
94
|
+
action:@selector(handleTapWithNumberOfTaps:)],
|
|
95
|
+
|
|
84
96
|
[[FBRoute POST:@"/wda/element/:uuid/touchAndHold"] respondWithTarget:self action:@selector(handleTouchAndHold:)],
|
|
97
|
+
[[FBRoute POST:@"/wda/touchAndHold"] respondWithTarget:self action:@selector(handleTouchAndHold:)],
|
|
98
|
+
|
|
85
99
|
[[FBRoute POST:@"/wda/element/:uuid/scroll"] respondWithTarget:self action:@selector(handleScroll:)],
|
|
100
|
+
[[FBRoute POST:@"/wda/scroll"] respondWithTarget:self action:@selector(handleScroll:)],
|
|
101
|
+
|
|
86
102
|
[[FBRoute POST:@"/wda/element/:uuid/scrollTo"] respondWithTarget:self action:@selector(handleScrollTo:)],
|
|
103
|
+
|
|
87
104
|
[[FBRoute POST:@"/wda/element/:uuid/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDrag:)],
|
|
105
|
+
[[FBRoute POST:@"/wda/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDrag:)],
|
|
106
|
+
|
|
88
107
|
[[FBRoute POST:@"/wda/element/:uuid/pressAndDragWithVelocity"] respondWithTarget:self action:@selector(handlePressAndDragWithVelocity:)],
|
|
89
|
-
[[FBRoute POST:@"/wda/element/:uuid/forceTouch"] respondWithTarget:self action:@selector(handleForceTouch:)],
|
|
90
|
-
[[FBRoute POST:@"/wda/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDragCoordinate:)],
|
|
91
108
|
[[FBRoute POST:@"/wda/pressAndDragWithVelocity"] respondWithTarget:self action:@selector(handlePressAndDragCoordinateWithVelocity:)],
|
|
92
|
-
|
|
93
|
-
[[FBRoute POST:@"/wda/
|
|
94
|
-
[[FBRoute POST:@"/wda/doubleTap"] respondWithTarget:self action:@selector(handleDoubleTapCoordinate:)],
|
|
95
|
-
[[FBRoute POST:@"/wda/pickerwheel/:uuid/select"] respondWithTarget:self action:@selector(handleWheelSelect:)],
|
|
109
|
+
|
|
110
|
+
[[FBRoute POST:@"/wda/element/:uuid/forceTouch"] respondWithTarget:self action:@selector(handleForceTouch:)],
|
|
96
111
|
[[FBRoute POST:@"/wda/forceTouch"] respondWithTarget:self action:@selector(handleForceTouch:)],
|
|
112
|
+
|
|
113
|
+
[[FBRoute POST:@"/wda/element/:uuid/tap"] respondWithTarget:self action:@selector(handleTap:)],
|
|
114
|
+
[[FBRoute POST:@"/wda/tap"] respondWithTarget:self action:@selector(handleTap:)],
|
|
115
|
+
|
|
116
|
+
[[FBRoute POST:@"/wda/pickerwheel/:uuid/select"] respondWithTarget:self action:@selector(handleWheelSelect:)],
|
|
97
117
|
#endif
|
|
98
118
|
[[FBRoute POST:@"/wda/keys"] respondWithTarget:self action:@selector(handleKeys:)],
|
|
99
119
|
];
|
|
@@ -287,38 +307,30 @@
|
|
|
287
307
|
#else
|
|
288
308
|
+ (id<FBResponsePayload>)handleDoubleTap:(FBRouteRequest *)request
|
|
289
309
|
{
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
{
|
|
298
|
-
CGVector offset = CGVectorMake([request.arguments[@"x"] doubleValue],
|
|
299
|
-
[request.arguments[@"y"] doubleValue]);
|
|
300
|
-
XCUICoordinate *doubleTapCoordinate = [self.class gestureCoordinateWithOffset:offset
|
|
301
|
-
element:request.session.activeApplication];
|
|
302
|
-
[doubleTapCoordinate doubleTap];
|
|
310
|
+
NSError *error;
|
|
311
|
+
id target = [self targetWithXyCoordinatesFromRequest:request error:&error];
|
|
312
|
+
if (nil == target) {
|
|
313
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.localizedDescription
|
|
314
|
+
traceback:nil]);
|
|
315
|
+
}
|
|
316
|
+
[target doubleTap];
|
|
303
317
|
return FBResponseWithOK();
|
|
304
318
|
}
|
|
305
319
|
|
|
306
320
|
+ (id<FBResponsePayload>)handleTwoFingerTap:(FBRouteRequest *)request
|
|
307
321
|
{
|
|
308
|
-
|
|
309
|
-
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
322
|
+
XCUIElement *element = [self targetFromRequest:request];
|
|
310
323
|
[element twoFingerTap];
|
|
311
324
|
return FBResponseWithOK();
|
|
312
325
|
}
|
|
313
326
|
|
|
314
327
|
+ (id<FBResponsePayload>)handleTapWithNumberOfTaps:(FBRouteRequest *)request
|
|
315
328
|
{
|
|
316
|
-
FBElementCache *elementCache = request.session.elementCache;
|
|
317
329
|
if (nil == request.arguments[@"numberOfTaps"] || nil == request.arguments[@"numberOfTouches"]) {
|
|
318
330
|
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:@"Both 'numberOfTaps' and 'numberOfTouches' arguments must be provided"
|
|
319
331
|
traceback:nil]);
|
|
320
332
|
}
|
|
321
|
-
XCUIElement *element = [
|
|
333
|
+
XCUIElement *element = [self targetFromRequest:request];
|
|
322
334
|
[element tapWithNumberOfTaps:[request.arguments[@"numberOfTaps"] integerValue]
|
|
323
335
|
numberOfTouches:[request.arguments[@"numberOfTouches"] integerValue]];
|
|
324
336
|
return FBResponseWithOK();
|
|
@@ -326,26 +338,20 @@
|
|
|
326
338
|
|
|
327
339
|
+ (id<FBResponsePayload>)handleTouchAndHold:(FBRouteRequest *)request
|
|
328
340
|
{
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
{
|
|
337
|
-
CGVector offset = CGVectorMake([request.arguments[@"x"] doubleValue],
|
|
338
|
-
[request.arguments[@"y"] doubleValue]);
|
|
339
|
-
XCUICoordinate *pressCoordinate = [self.class gestureCoordinateWithOffset:offset
|
|
340
|
-
element:request.session.activeApplication];
|
|
341
|
-
[pressCoordinate pressForDuration:[request.arguments[@"duration"] doubleValue]];
|
|
341
|
+
NSError *error;
|
|
342
|
+
id target = [self targetWithXyCoordinatesFromRequest:request error:&error];
|
|
343
|
+
if (nil == target) {
|
|
344
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.localizedDescription
|
|
345
|
+
traceback:nil]);
|
|
346
|
+
}
|
|
347
|
+
[target pressForDuration:[request.arguments[@"duration"] doubleValue]];
|
|
342
348
|
return FBResponseWithOK();
|
|
343
349
|
}
|
|
344
350
|
|
|
345
351
|
+ (id<FBResponsePayload>)handlePressAndDragWithVelocity:(FBRouteRequest *)request
|
|
346
352
|
{
|
|
347
353
|
FBElementCache *elementCache = request.session.elementCache;
|
|
348
|
-
XCUIElement *element = [
|
|
354
|
+
XCUIElement *element = [self targetFromRequest:request];
|
|
349
355
|
if (![element respondsToSelector:@selector(pressForDuration:thenDragToElement:withVelocity:thenHoldForDuration:)]) {
|
|
350
356
|
return FBResponseWithStatus([FBCommandStatus unsupportedOperationErrorWithMessage:@"This method is only supported in Xcode 12 and above"
|
|
351
357
|
traceback:nil]);
|
|
@@ -381,8 +387,7 @@
|
|
|
381
387
|
|
|
382
388
|
+ (id<FBResponsePayload>)handleScroll:(FBRouteRequest *)request
|
|
383
389
|
{
|
|
384
|
-
|
|
385
|
-
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
390
|
+
XCUIElement *element = [self targetFromRequest:request];
|
|
386
391
|
// Using presence of arguments as a way to convey control flow seems like a pretty bad idea but it's
|
|
387
392
|
// what ios-driver did and sadly, we must copy them.
|
|
388
393
|
NSString *const name = request.arguments[@"name"];
|
|
@@ -442,33 +447,18 @@
|
|
|
442
447
|
traceback:nil]);
|
|
443
448
|
}
|
|
444
449
|
|
|
445
|
-
+ (id<FBResponsePayload>)handleDragCoordinate:(FBRouteRequest *)request
|
|
446
|
-
{
|
|
447
|
-
FBSession *session = request.session;
|
|
448
|
-
CGVector startOffset = CGVectorMake([request.arguments[@"fromX"] doubleValue],
|
|
449
|
-
[request.arguments[@"fromY"] doubleValue]);
|
|
450
|
-
XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithOffset:startOffset
|
|
451
|
-
element:session.activeApplication];
|
|
452
|
-
CGVector endOffset = CGVectorMake([request.arguments[@"toX"] doubleValue],
|
|
453
|
-
[request.arguments[@"toY"] doubleValue]);
|
|
454
|
-
XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithOffset:endOffset
|
|
455
|
-
element:session.activeApplication];
|
|
456
|
-
NSTimeInterval duration = [request.arguments[@"duration"] doubleValue];
|
|
457
|
-
[startCoordinate pressForDuration:duration thenDragToCoordinate:endCoordinate];
|
|
458
|
-
return FBResponseWithOK();
|
|
459
|
-
}
|
|
460
|
-
|
|
461
450
|
+ (id<FBResponsePayload>)handleDrag:(FBRouteRequest *)request
|
|
462
451
|
{
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
452
|
+
NSString *elementUdid = (NSString *)request.parameters[@"uuid"];
|
|
453
|
+
XCUIElement *target = nil == elementUdid
|
|
454
|
+
? request.session.activeApplication
|
|
455
|
+
: [request.session.elementCache elementForUUID:elementUdid];
|
|
466
456
|
CGVector startOffset = CGVectorMake([request.arguments[@"fromX"] doubleValue],
|
|
467
457
|
[request.arguments[@"fromY"] doubleValue]);
|
|
468
|
-
XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithOffset:startOffset element:
|
|
458
|
+
XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithOffset:startOffset element:target];
|
|
469
459
|
CGVector endOffset = CGVectorMake([request.arguments[@"toX"] doubleValue],
|
|
470
460
|
[request.arguments[@"toY"] doubleValue]);
|
|
471
|
-
XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithOffset:endOffset element:
|
|
461
|
+
XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithOffset:endOffset element:target];
|
|
472
462
|
NSTimeInterval duration = [request.arguments[@"duration"] doubleValue];
|
|
473
463
|
[startCoordinate pressForDuration:duration thenDragToCoordinate:endCoordinate];
|
|
474
464
|
return FBResponseWithOK();
|
|
@@ -476,39 +466,41 @@
|
|
|
476
466
|
|
|
477
467
|
+ (id<FBResponsePayload>)handleSwipe:(FBRouteRequest *)request
|
|
478
468
|
{
|
|
479
|
-
FBElementCache *elementCache = request.session.elementCache;
|
|
480
|
-
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
481
469
|
NSString *const direction = request.arguments[@"direction"];
|
|
482
470
|
if (!direction) {
|
|
483
471
|
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:@"Missing 'direction' parameter" traceback:nil]);
|
|
484
472
|
}
|
|
485
473
|
NSArray<NSString *> *supportedDirections = @[@"up", @"down", @"left", @"right"];
|
|
486
474
|
if (![supportedDirections containsObject:direction.lowercaseString]) {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
475
|
+
NSString *message = [NSString stringWithFormat:@"Unsupported swipe direction '%@'. Only the following directions are supported: %@", direction, supportedDirections];
|
|
476
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:message
|
|
477
|
+
traceback:nil]);
|
|
490
478
|
}
|
|
491
|
-
|
|
479
|
+
NSError *error;
|
|
480
|
+
id target = [self targetWithXyCoordinatesFromRequest:request error:&error];
|
|
481
|
+
if (nil == target) {
|
|
482
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.localizedDescription
|
|
483
|
+
traceback:nil]);
|
|
484
|
+
}
|
|
485
|
+
[target fb_swipeWithDirection:direction velocity:request.arguments[@"velocity"]];
|
|
492
486
|
return FBResponseWithOK();
|
|
493
487
|
}
|
|
494
488
|
|
|
495
489
|
+ (id<FBResponsePayload>)handleTap:(FBRouteRequest *)request
|
|
496
490
|
{
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
[tapCoordinate tap];
|
|
491
|
+
NSError *error;
|
|
492
|
+
id target = [self targetWithXyCoordinatesFromRequest:request error:&error];
|
|
493
|
+
if (nil == target) {
|
|
494
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.localizedDescription
|
|
495
|
+
traceback:nil]);
|
|
496
|
+
}
|
|
497
|
+
[target tap];
|
|
505
498
|
return FBResponseWithOK();
|
|
506
499
|
}
|
|
507
500
|
|
|
508
501
|
+ (id<FBResponsePayload>)handlePinch:(FBRouteRequest *)request
|
|
509
502
|
{
|
|
510
|
-
|
|
511
|
-
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
503
|
+
XCUIElement *element = [self targetFromRequest:request];
|
|
512
504
|
CGFloat scale = (CGFloat)[request.arguments[@"scale"] doubleValue];
|
|
513
505
|
CGFloat velocity = (CGFloat)[request.arguments[@"velocity"] doubleValue];
|
|
514
506
|
[element pinchWithScale:scale velocity:velocity];
|
|
@@ -517,8 +509,7 @@
|
|
|
517
509
|
|
|
518
510
|
+ (id<FBResponsePayload>)handleRotate:(FBRouteRequest *)request
|
|
519
511
|
{
|
|
520
|
-
|
|
521
|
-
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
512
|
+
XCUIElement *element = [self targetFromRequest:request];
|
|
522
513
|
CGFloat rotation = (CGFloat)[request.arguments[@"rotation"] doubleValue];
|
|
523
514
|
CGFloat velocity = (CGFloat)[request.arguments[@"velocity"] doubleValue];
|
|
524
515
|
[element rotate:rotation withVelocity:velocity];
|
|
@@ -527,13 +518,7 @@
|
|
|
527
518
|
|
|
528
519
|
+ (id<FBResponsePayload>)handleForceTouch:(FBRouteRequest *)request
|
|
529
520
|
{
|
|
530
|
-
XCUIElement *element =
|
|
531
|
-
if (nil == request.parameters[@"uuid"]) {
|
|
532
|
-
element = [FBApplication fb_activeApplication];
|
|
533
|
-
} else {
|
|
534
|
-
FBElementCache *elementCache = request.session.elementCache;
|
|
535
|
-
element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
536
|
-
}
|
|
521
|
+
XCUIElement *element = [self targetFromRequest:request];
|
|
537
522
|
NSNumber *pressure = request.arguments[@"pressure"];
|
|
538
523
|
NSNumber *duration = request.arguments[@"duration"];
|
|
539
524
|
NSNumber *x = request.arguments[@"x"];
|
|
@@ -567,7 +552,7 @@
|
|
|
567
552
|
|
|
568
553
|
+ (id<FBResponsePayload>)handleGetWindowSize:(FBRouteRequest *)request
|
|
569
554
|
{
|
|
570
|
-
XCUIApplication *app = request.session.activeApplication ?:
|
|
555
|
+
XCUIApplication *app = request.session.activeApplication ?: XCUIApplication.fb_activeApplication;
|
|
571
556
|
|
|
572
557
|
#if TARGET_OS_TV
|
|
573
558
|
CGSize screenSize = app.frame.size;
|
|
@@ -675,6 +660,45 @@ static const NSInteger DEFAULT_MAX_PICKER_ATTEMPTS = 25;
|
|
|
675
660
|
return [[element coordinateWithNormalizedOffset:CGVectorMake(0, 0)] coordinateWithOffset:offset];
|
|
676
661
|
}
|
|
677
662
|
|
|
663
|
+
/**
|
|
664
|
+
Returns either coordinates or the target element for the given request that expects 'x' and 'y' coordannates
|
|
665
|
+
|
|
666
|
+
@param request HTTP request object
|
|
667
|
+
@param error Error instance if any
|
|
668
|
+
@return Either XCUICoordinate or XCUIElement instance. nil if the input data is invalid
|
|
669
|
+
*/
|
|
670
|
+
+ (nullable id)targetWithXyCoordinatesFromRequest:(FBRouteRequest *)request error:(NSError **)error
|
|
671
|
+
{
|
|
672
|
+
NSNumber *x = request.arguments[@"x"];
|
|
673
|
+
NSNumber *y = request.arguments[@"y"];
|
|
674
|
+
if (nil == x && nil == y) {
|
|
675
|
+
return [self targetFromRequest:request];
|
|
676
|
+
}
|
|
677
|
+
if ((nil == x && nil != y) || (nil != x && nil == y)) {
|
|
678
|
+
[[[FBErrorBuilder alloc]
|
|
679
|
+
withDescription:@"Both x and y coordinates must be provided"]
|
|
680
|
+
buildError:error];
|
|
681
|
+
return nil;
|
|
682
|
+
}
|
|
683
|
+
return [self gestureCoordinateWithOffset:CGVectorMake(x.doubleValue, y.doubleValue)
|
|
684
|
+
element:[self targetFromRequest:request]];
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
Returns the target element for the given request
|
|
689
|
+
|
|
690
|
+
@param request HTTP request object
|
|
691
|
+
@return Matching XCUIElement instance
|
|
692
|
+
*/
|
|
693
|
+
+ (XCUIElement *)targetFromRequest:(FBRouteRequest *)request
|
|
694
|
+
{
|
|
695
|
+
FBElementCache *elementCache = request.session.elementCache;
|
|
696
|
+
NSString *elementUuid = (NSString *)request.parameters[@"uuid"];
|
|
697
|
+
return nil == elementUuid
|
|
698
|
+
? request.session.activeApplication
|
|
699
|
+
: [elementCache elementForUUID:elementUuid];
|
|
700
|
+
}
|
|
701
|
+
|
|
678
702
|
#endif
|
|
679
703
|
|
|
680
704
|
@end
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
#import "FBRouteRequest.h"
|
|
13
13
|
#import "FBMacros.h"
|
|
14
14
|
#import "FBSession.h"
|
|
15
|
-
#import "
|
|
15
|
+
#import "XCUIApplication.h"
|
|
16
|
+
#import "XCUIApplication+FBHelpers.h"
|
|
16
17
|
#import "XCUIDevice.h"
|
|
17
18
|
|
|
18
19
|
extern const struct FBWDOrientationValues {
|
|
@@ -55,14 +56,14 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
|
|
|
55
56
|
|
|
56
57
|
+ (id<FBResponsePayload>)handleGetOrientation:(FBRouteRequest *)request
|
|
57
58
|
{
|
|
58
|
-
|
|
59
|
+
XCUIApplication *application = request.session.activeApplication ?: XCUIApplication.fb_activeApplication;
|
|
59
60
|
NSString *orientation = [self.class interfaceOrientationForApplication:application];
|
|
60
61
|
return FBResponseWithObject([[self _wdOrientationsMapping] objectForKey:orientation]);
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
+ (id<FBResponsePayload>)handleSetOrientation:(FBRouteRequest *)request
|
|
64
65
|
{
|
|
65
|
-
|
|
66
|
+
XCUIApplication *application = request.session.activeApplication ?: XCUIApplication.fb_activeApplication;
|
|
66
67
|
if ([self.class setDeviceOrientation:request.arguments[@"orientation"] forApplication:application]) {
|
|
67
68
|
return FBResponseWithOK();
|
|
68
69
|
}
|
|
@@ -73,7 +74,7 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
|
|
|
73
74
|
+ (id<FBResponsePayload>)handleGetRotation:(FBRouteRequest *)request
|
|
74
75
|
{
|
|
75
76
|
XCUIDevice *device = [XCUIDevice sharedDevice];
|
|
76
|
-
|
|
77
|
+
XCUIApplication *application = request.session.activeApplication ?: XCUIApplication.fb_activeApplication;
|
|
77
78
|
UIInterfaceOrientation orientation = application.interfaceOrientation;
|
|
78
79
|
return FBResponseWithObject(device.fb_rotationMapping[@(orientation)]);
|
|
79
80
|
}
|
|
@@ -101,7 +102,7 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
|
|
|
101
102
|
traceback:nil]);
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
XCUIApplication *application = request.session.activeApplication ?: XCUIApplication.fb_activeApplication;
|
|
105
106
|
if (![self.class setDeviceRotation:request.arguments forApplication:application]) {
|
|
106
107
|
NSString *errMessage = [
|
|
107
108
|
NSString stringWithFormat:@"The current rotation cannot be set to %@. Make sure the %@ application supports it",
|
|
@@ -116,7 +117,7 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
|
|
|
116
117
|
|
|
117
118
|
#pragma mark - Helpers
|
|
118
119
|
|
|
119
|
-
+ (NSString *)interfaceOrientationForApplication:(
|
|
120
|
+
+ (NSString *)interfaceOrientationForApplication:(XCUIApplication *)application
|
|
120
121
|
{
|
|
121
122
|
NSNumber *orientation = @(application.interfaceOrientation);
|
|
122
123
|
NSSet *keys = [[self _orientationsMapping] keysOfEntriesPassingTest:^BOOL(id key, NSNumber *obj, BOOL *stop) {
|
|
@@ -128,12 +129,12 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
|
|
|
128
129
|
return keys.anyObject;
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
+ (BOOL)setDeviceRotation:(NSDictionary *)rotationObj forApplication:(
|
|
132
|
+
+ (BOOL)setDeviceRotation:(NSDictionary *)rotationObj forApplication:(XCUIApplication *)application
|
|
132
133
|
{
|
|
133
134
|
return [[XCUIDevice sharedDevice] fb_setDeviceRotation:rotationObj];
|
|
134
135
|
}
|
|
135
136
|
|
|
136
|
-
+ (BOOL)setDeviceOrientation:(NSString *)orientation forApplication:(
|
|
137
|
+
+ (BOOL)setDeviceOrientation:(NSString *)orientation forApplication:(XCUIApplication *)application
|
|
137
138
|
{
|
|
138
139
|
NSNumber *orientationValue = [[self _orientationsMapping] objectForKey:[orientation uppercaseString]];
|
|
139
140
|
if (orientationValue == nil) {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
#import "FBSessionCommands.h"
|
|
11
11
|
|
|
12
|
-
#import "FBApplication.h"
|
|
13
12
|
#import "FBCapabilities.h"
|
|
14
13
|
#import "FBConfiguration.h"
|
|
15
14
|
#import "FBLogger.h"
|
|
@@ -17,7 +16,6 @@
|
|
|
17
16
|
#import "FBRouteRequest.h"
|
|
18
17
|
#import "FBSession.h"
|
|
19
18
|
#import "FBSettings.h"
|
|
20
|
-
#import "FBApplication.h"
|
|
21
19
|
#import "FBRuntimeUtils.h"
|
|
22
20
|
#import "FBActiveAppDetectionPoint.h"
|
|
23
21
|
#import "FBXCodeCompatibility.h"
|
|
@@ -138,28 +136,63 @@
|
|
|
138
136
|
}
|
|
139
137
|
|
|
140
138
|
NSString *bundleID = capabilities[FB_CAP_BUNDLE_ID];
|
|
141
|
-
|
|
139
|
+
NSString *initialUrl = capabilities[FB_CAP_INITIAL_URL];
|
|
140
|
+
XCUIApplication *app = nil;
|
|
141
|
+
BOOL didOpenInitialUrl = NO;
|
|
142
142
|
if (bundleID != nil) {
|
|
143
|
-
app = [[
|
|
143
|
+
app = [[XCUIApplication alloc] initWithBundleIdentifier:bundleID];
|
|
144
144
|
BOOL forceAppLaunch = YES;
|
|
145
145
|
if (nil != capabilities[FB_CAP_FORCE_APP_LAUNCH]) {
|
|
146
146
|
forceAppLaunch = [capabilities[FB_CAP_FORCE_APP_LAUNCH] boolValue];
|
|
147
147
|
}
|
|
148
|
-
|
|
149
|
-
BOOL isAppRunning = appState >=
|
|
148
|
+
XCUIApplicationState appState = app.state;
|
|
149
|
+
BOOL isAppRunning = appState >= XCUIApplicationStateRunningBackground;
|
|
150
150
|
if (!isAppRunning || (isAppRunning && forceAppLaunch)) {
|
|
151
151
|
app.fb_shouldWaitForQuiescence = nil == capabilities[FB_CAP_SHOULD_WAIT_FOR_QUIESCENCE]
|
|
152
152
|
|| [capabilities[FB_CAP_SHOULD_WAIT_FOR_QUIESCENCE] boolValue];
|
|
153
153
|
app.launchArguments = (NSArray<NSString *> *)capabilities[FB_CAP_ARGUMENTS] ?: @[];
|
|
154
154
|
app.launchEnvironment = (NSDictionary <NSString *, NSString *> *)capabilities[FB_CAP_ENVIRNOMENT] ?: @{};
|
|
155
|
-
|
|
155
|
+
if (nil != initialUrl) {
|
|
156
|
+
NSError *openError;
|
|
157
|
+
didOpenInitialUrl = [XCUIDevice.sharedDevice fb_openUrl:initialUrl
|
|
158
|
+
withApplication:bundleID
|
|
159
|
+
error:&openError];
|
|
160
|
+
if (!didOpenInitialUrl) {
|
|
161
|
+
NSString *errorMsg = [NSString stringWithFormat:@"Cannot open the URL %@ in %@ application. Original error: %@",
|
|
162
|
+
initialUrl, bundleID, openError.description];
|
|
163
|
+
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:errorMsg traceback:nil]);
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
[app launch];
|
|
167
|
+
}
|
|
156
168
|
if (![app running]) {
|
|
157
169
|
NSString *errorMsg = [NSString stringWithFormat:@"Cannot launch %@ application. Make sure the correct bundle identifier has been provided in capabilities and check the device log for possible crash report occurrences", bundleID];
|
|
158
170
|
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:errorMsg
|
|
159
171
|
traceback:nil]);
|
|
160
172
|
}
|
|
161
|
-
} else if (appState
|
|
162
|
-
|
|
173
|
+
} else if (appState == XCUIApplicationStateRunningBackground && !forceAppLaunch) {
|
|
174
|
+
if (nil != initialUrl) {
|
|
175
|
+
NSError *openError;
|
|
176
|
+
didOpenInitialUrl = [XCUIDevice.sharedDevice fb_openUrl:initialUrl
|
|
177
|
+
withApplication:bundleID
|
|
178
|
+
error:&openError];
|
|
179
|
+
if (!didOpenInitialUrl) {
|
|
180
|
+
NSString *errorMsg = [NSString stringWithFormat:@"Cannot open the URL %@ in %@ application. Original error: %@",
|
|
181
|
+
initialUrl, bundleID, openError.description];
|
|
182
|
+
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:errorMsg traceback:nil]);
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
[app activate];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (nil != initialUrl && nil == bundleID) {
|
|
191
|
+
NSError *openError;
|
|
192
|
+
if (![XCUIDevice.sharedDevice fb_openUrl:initialUrl error:&openError]) {
|
|
193
|
+
NSString *errorMsg = [NSString stringWithFormat:@"Cannot open the URL %@. Original error: %@",
|
|
194
|
+
initialUrl, openError.description];
|
|
195
|
+
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:errorMsg traceback:nil]);
|
|
163
196
|
}
|
|
164
197
|
}
|
|
165
198
|
|
|
@@ -265,7 +298,7 @@
|
|
|
265
298
|
|
|
266
299
|
+ (id<FBResponsePayload>)handleGetHealthCheck:(FBRouteRequest *)request
|
|
267
300
|
{
|
|
268
|
-
if (![[XCUIDevice sharedDevice] fb_healthCheckWithApplication:[
|
|
301
|
+
if (![[XCUIDevice sharedDevice] fb_healthCheckWithApplication:[XCUIApplication fb_activeApplication]]) {
|
|
269
302
|
return FBResponseWithUnknownErrorFormat(@"Health check failed");
|
|
270
303
|
}
|
|
271
304
|
return FBResponseWithOK();
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
#import "FBAlert.h"
|
|
11
11
|
|
|
12
|
-
#import "FBApplication.h"
|
|
13
12
|
#import "FBConfiguration.h"
|
|
14
13
|
#import "FBErrorBuilder.h"
|
|
15
14
|
#import "FBLogger.h"
|
|
16
15
|
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
17
16
|
#import "FBXCodeCompatibility.h"
|
|
17
|
+
#import "XCUIApplication.h"
|
|
18
18
|
#import "XCUIApplication+FBAlert.h"
|
|
19
19
|
#import "XCUIElement+FBClassChain.h"
|
|
20
20
|
#import "XCUIElement+FBTyping.h"
|
|
@@ -263,8 +263,8 @@
|
|
|
263
263
|
if (nil == self.element) {
|
|
264
264
|
self.element = self.application.fb_alertElement;
|
|
265
265
|
if (nil == self.element) {
|
|
266
|
-
|
|
267
|
-
for (
|
|
266
|
+
XCUIApplication *systemApp = XCUIApplication.fb_systemApplication;
|
|
267
|
+
for (XCUIApplication *activeApp in XCUIApplication.fb_activeApplications) {
|
|
268
268
|
if (systemApp.processID == activeApp.processID) {
|
|
269
269
|
self.element = activeApp.fb_alertElement;
|
|
270
270
|
break;
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
#import <Foundation/Foundation.h>
|
|
11
11
|
|
|
12
|
-
@class FBApplication;
|
|
13
12
|
@class FBElementCache;
|
|
13
|
+
@class XCUIApplication;
|
|
14
14
|
|
|
15
15
|
NS_ASSUME_NONNULL_BEGIN
|
|
16
16
|
|
|
@@ -20,16 +20,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
20
20
|
@interface FBSession : NSObject
|
|
21
21
|
|
|
22
22
|
/*! Application tested during that session */
|
|
23
|
-
@property (nonatomic,
|
|
23
|
+
@property (nonatomic, readonly) XCUIApplication *activeApplication;
|
|
24
24
|
|
|
25
25
|
/*! Session's identifier */
|
|
26
|
-
@property (nonatomic,
|
|
26
|
+
@property (nonatomic, readonly) NSString *identifier;
|
|
27
27
|
|
|
28
28
|
/*! Element cache related to that session */
|
|
29
|
-
@property (nonatomic,
|
|
29
|
+
@property (nonatomic, readonly) FBElementCache *elementCache;
|
|
30
30
|
|
|
31
31
|
/*! The identifier of the active application */
|
|
32
|
-
@property (nonatomic
|
|
32
|
+
@property (nonatomic) NSString *defaultActiveApplication;
|
|
33
33
|
|
|
34
34
|
/*! The action to apply to unexpected alerts. Either "accept"/"dismiss" or nil/empty string (by default) to do nothing */
|
|
35
35
|
@property (nonatomic, nullable) NSString *defaultAlertAction;
|
|
@@ -57,7 +57,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
57
57
|
@param application The application that we want to create session for
|
|
58
58
|
@return new session
|
|
59
59
|
*/
|
|
60
|
-
+ (instancetype)initWithApplication:(nullable
|
|
60
|
+
+ (instancetype)initWithApplication:(nullable XCUIApplication *)application;
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
Creates and saves new session for application with default alert handling behaviour
|
|
@@ -66,7 +66,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
66
66
|
@param defaultAlertAction The default reaction to on-screen alert. Either 'accept' or 'dismiss'
|
|
67
67
|
@return new session
|
|
68
68
|
*/
|
|
69
|
-
+ (instancetype)initWithApplication:(nullable
|
|
69
|
+
+ (instancetype)initWithApplication:(nullable XCUIApplication *)application
|
|
70
|
+
defaultAlertAction:(NSString *)defaultAlertAction;
|
|
70
71
|
|
|
71
72
|
/**
|
|
72
73
|
Kills application associated with that session and removes session
|
|
@@ -82,12 +83,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
82
83
|
@param arguments The optional array of application command line arguments. The arguments are going to be applied if the application was not running before.
|
|
83
84
|
@param environment The optional dictionary of environment variables for the application, which is going to be executed. The environment variables are going to be applied if the application was not running before.
|
|
84
85
|
@return The application instance
|
|
85
|
-
@throws FBApplicationMethodNotSupportedException if the method is not supported with the current XCTest SDK
|
|
86
86
|
*/
|
|
87
|
-
- (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
- (XCUIApplication *)launchApplicationWithBundleId:(NSString *)bundleIdentifier
|
|
88
|
+
shouldWaitForQuiescence:(nullable NSNumber *)shouldWaitForQuiescence
|
|
89
|
+
arguments:(nullable NSArray<NSString *> *)arguments
|
|
90
|
+
environment:(nullable NSDictionary <NSString *, NSString *> *)environment;
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
Activate an application with given bundle identifier in scope of current session.
|
|
@@ -95,9 +95,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
95
95
|
|
|
96
96
|
@param bundleIdentifier Valid bundle identifier of the application to be activated
|
|
97
97
|
@return The application instance
|
|
98
|
-
@throws FBApplicationMethodNotSupportedException if the method is not supported with the current XCTest SDK
|
|
99
98
|
*/
|
|
100
|
-
- (
|
|
99
|
+
- (XCUIApplication *)activateApplicationWithBundleId:(NSString *)bundleIdentifier;
|
|
101
100
|
|
|
102
101
|
/**
|
|
103
102
|
Terminate an application with the given bundle id. The application should be previously
|