初始化提交
This commit is contained in:
188
WebDriverAgentTests/IntegrationTests/FBAlertTests.m
Normal file
188
WebDriverAgentTests/IntegrationTests/FBAlertTests.m
Normal file
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import <WebDriverAgentLib/FBAlert.h>
|
||||
|
||||
#import "FBConfiguration.h"
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBMacros.h"
|
||||
|
||||
@interface FBAlertTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBAlertTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAlertsPage];
|
||||
[FBConfiguration disableApplicationUIInterruptionsHandling];
|
||||
});
|
||||
[self clearAlert];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self clearAlert];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)showApplicationAlert
|
||||
{
|
||||
[self.testedApplication.buttons[FBShowAlertButtonName] tap];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count != 0);
|
||||
}
|
||||
|
||||
- (void)showApplicationSheet
|
||||
{
|
||||
[self.testedApplication.buttons[FBShowSheetAlertButtonName] tap];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.sheets.count != 0);
|
||||
}
|
||||
|
||||
- (void)testAlertPresence
|
||||
{
|
||||
FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
|
||||
XCTAssertFalse(alert.isPresent);
|
||||
[self showApplicationAlert];
|
||||
XCTAssertTrue(alert.isPresent);
|
||||
}
|
||||
|
||||
- (void)testAlertText
|
||||
{
|
||||
FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
|
||||
XCTAssertNil(alert.text);
|
||||
[self showApplicationAlert];
|
||||
XCTAssertTrue([alert.text containsString:@"Magic"]);
|
||||
XCTAssertTrue([alert.text containsString:@"Should read"]);
|
||||
}
|
||||
|
||||
- (void)testAlertLabels
|
||||
{
|
||||
FBAlert* alert = [FBAlert alertWithApplication:self.testedApplication];
|
||||
XCTAssertNil(alert.buttonLabels);
|
||||
[self showApplicationAlert];
|
||||
XCTAssertNotNil(alert.buttonLabels);
|
||||
XCTAssertEqual(1, alert.buttonLabels.count);
|
||||
XCTAssertEqualObjects(@"Will do", alert.buttonLabels[0]);
|
||||
}
|
||||
|
||||
- (void)testClickAlertButton
|
||||
{
|
||||
FBAlert* alert = [FBAlert alertWithApplication:self.testedApplication];
|
||||
XCTAssertFalse([alert clickAlertButton:@"Invalid" error:nil]);
|
||||
[self showApplicationAlert];
|
||||
XCTAssertFalse([alert clickAlertButton:@"Invalid" error:nil]);
|
||||
FBAssertWaitTillBecomesTrue(alert.isPresent);
|
||||
XCTAssertTrue([alert clickAlertButton:@"Will do" error:nil]);
|
||||
FBAssertWaitTillBecomesTrue(!alert.isPresent);
|
||||
}
|
||||
|
||||
- (void)testAcceptingAlert
|
||||
{
|
||||
NSError *error;
|
||||
[self showApplicationAlert];
|
||||
XCTAssertTrue([[FBAlert alertWithApplication:self.testedApplication] acceptWithError:&error]);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testAcceptingAlertWithCustomLocator
|
||||
{
|
||||
NSError *error;
|
||||
[self showApplicationAlert];
|
||||
[FBConfiguration setAcceptAlertButtonSelector:@"**/XCUIElementTypeButton[-1]"];
|
||||
@try {
|
||||
XCTAssertTrue([[FBAlert alertWithApplication:self.testedApplication] acceptWithError:&error]);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
|
||||
XCTAssertNil(error);
|
||||
} @finally {
|
||||
[FBConfiguration setAcceptAlertButtonSelector:@""];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testDismissingAlert
|
||||
{
|
||||
NSError *error;
|
||||
[self showApplicationAlert];
|
||||
XCTAssertTrue([[FBAlert alertWithApplication:self.testedApplication] dismissWithError:&error]);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testDismissingAlertWithCustomLocator
|
||||
{
|
||||
NSError *error;
|
||||
[self showApplicationAlert];
|
||||
[FBConfiguration setDismissAlertButtonSelector:@"**/XCUIElementTypeButton[-1]"];
|
||||
@try {
|
||||
XCTAssertTrue([[FBAlert alertWithApplication:self.testedApplication] dismissWithError:&error]);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
|
||||
XCTAssertNil(error);
|
||||
} @finally {
|
||||
[FBConfiguration setDismissAlertButtonSelector:@""];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testAlertElement
|
||||
{
|
||||
[self showApplicationAlert];
|
||||
XCUIElement *alertElement = [FBAlert alertWithApplication:self.testedApplication].alertElement;
|
||||
XCTAssertTrue(alertElement.exists);
|
||||
XCTAssertTrue(alertElement.elementType == XCUIElementTypeAlert);
|
||||
}
|
||||
|
||||
- (void)testNotificationAlert
|
||||
{
|
||||
FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
|
||||
XCTAssertNil(alert.text);
|
||||
[self.testedApplication.buttons[@"Create Notification Alert"] tap];
|
||||
FBAssertWaitTillBecomesTrue(alert.isPresent);
|
||||
|
||||
XCTAssertTrue([alert.text containsString:@"Would Like to Send You Notifications"]);
|
||||
XCTAssertTrue([alert.text containsString:@"Notifications may include"]);
|
||||
}
|
||||
|
||||
// This test case depends on the local app permission state.
|
||||
- (void)testCameraRollAlert
|
||||
{
|
||||
FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
|
||||
XCTAssertNil(alert.text);
|
||||
|
||||
[self.testedApplication.buttons[@"Create Camera Roll Alert"] tap];
|
||||
FBAssertWaitTillBecomesTrue(alert.isPresent);
|
||||
|
||||
// "Would Like to Access Your Photos" or "Would Like to Access Your Photo Library" displayes on the alert button.
|
||||
XCTAssertTrue([alert.text containsString:@"Would Like to Access Your Photo"]);
|
||||
// iOS 15 has different UI flow
|
||||
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
|
||||
[[FBAlert alertWithApplication:self.testedApplication] dismissWithError:nil];
|
||||
// CI env could take longer time to show up the button, thus it needs to wait a bit.
|
||||
XCTAssertTrue([self.testedApplication.buttons[@"Cancel"] waitForExistenceWithTimeout:30.0]);
|
||||
[self.testedApplication.buttons[@"Cancel"] tap];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testGPSAccessAlert
|
||||
{
|
||||
FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
|
||||
XCTAssertNil(alert.text);
|
||||
|
||||
[self.testedApplication.buttons[@"Create GPS access Alert"] tap];
|
||||
FBAssertWaitTillBecomesTrue(alert.isPresent);
|
||||
|
||||
XCTAssertTrue([alert.text containsString:@"location"]);
|
||||
XCTAssertTrue([alert.text containsString:@"Yo Yo"]);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBSession.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIElement+FBUtilities.h"
|
||||
|
||||
|
||||
@interface FBAutoAlertsHandlerTests : FBIntegrationTestCase
|
||||
@property (nonatomic) FBSession *session;
|
||||
@end
|
||||
|
||||
|
||||
@implementation FBAutoAlertsHandlerTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
[self launchApplication];
|
||||
[self goToAlertsPage];
|
||||
|
||||
[self clearAlert];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self clearAlert];
|
||||
|
||||
if (self.session) {
|
||||
[self.session kill];
|
||||
}
|
||||
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
// The test is flaky on slow Travis CI
|
||||
- (void)disabled_testAutoAcceptingOfAlerts
|
||||
{
|
||||
self.session = [FBSession
|
||||
initWithApplication:XCUIApplication.fb_activeApplication
|
||||
defaultAlertAction:@"accept"];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
[self.testedApplication.buttons[FBShowAlertButtonName] tap];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
|
||||
}
|
||||
}
|
||||
|
||||
// The test is flaky on slow Travis CI
|
||||
- (void)disabled_testAutoDismissingOfAlerts
|
||||
{
|
||||
self.session = [FBSession
|
||||
initWithApplication:XCUIApplication.fb_activeApplication
|
||||
defaultAlertAction:@"dismiss"];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
[self.testedApplication.buttons[FBShowAlertButtonName] tap];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
38
WebDriverAgentTests/IntegrationTests/FBConfigurationTests.m
Normal file
38
WebDriverAgentTests/IntegrationTests/FBConfigurationTests.m
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "FBIntegrationTestCase.h"
|
||||
|
||||
#import "FBConfiguration.h"
|
||||
#import "FBRuntimeUtils.h"
|
||||
|
||||
@interface FBConfigurationTests : FBIntegrationTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBConfigurationTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
}
|
||||
|
||||
- (void)testReduceMotion
|
||||
{
|
||||
BOOL defaultReduceMotionEnabled = [FBConfiguration reduceMotionEnabled];
|
||||
|
||||
[FBConfiguration setReduceMotionEnabled:YES];
|
||||
XCTAssertTrue([FBConfiguration reduceMotionEnabled]);
|
||||
|
||||
[FBConfiguration setReduceMotionEnabled:defaultReduceMotionEnabled];
|
||||
XCTAssertEqual([FBConfiguration reduceMotionEnabled], defaultReduceMotionEnabled);
|
||||
}
|
||||
|
||||
@end
|
||||
250
WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m
Normal file
250
WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m
Normal file
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBFindElementCommands.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
#import "XCUIElement+FBAccessibility.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
#import "XCUIElement+FBWebDriverAttributes.h"
|
||||
|
||||
@interface FBElementAttributeTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBElementAttributeTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testElementAccessibilityAttributes
|
||||
{
|
||||
// "Button" is accessibility element, and therefore isn't accessibility container
|
||||
XCUIElement *buttonElement = self.testedApplication.buttons[@"Button"];
|
||||
XCTAssertTrue(buttonElement.exists);
|
||||
XCTAssertTrue(buttonElement.fb_isAccessibilityElement);
|
||||
XCTAssertFalse(buttonElement.isWDAccessibilityContainer);
|
||||
}
|
||||
|
||||
- (void)testContainerAccessibilityAttributes
|
||||
{
|
||||
// "not_accessible" isn't accessibility element, but contains accessibility elements, so it is accessibility container
|
||||
XCUIElement *inaccessibleButtonElement = self.testedApplication.buttons[@"not_accessible"];
|
||||
XCTAssertTrue(inaccessibleButtonElement.exists);
|
||||
XCTAssertFalse(inaccessibleButtonElement.fb_isAccessibilityElement);
|
||||
// FIXME: Xcode 11 environment returns false even if iOS 12
|
||||
// We must fix here to XCTAssertTrue if Xcode version will return the value properly
|
||||
XCTAssertFalse(inaccessibleButtonElement.isWDAccessibilityContainer);
|
||||
}
|
||||
|
||||
- (void)testIgnoredAccessibilityAttributes
|
||||
{
|
||||
// Images are neither accessibility elements nor contain them, so both checks should fail
|
||||
XCUIElement *imageElement = self.testedApplication.images.allElementsBoundByIndex.firstObject;
|
||||
XCTAssertTrue(imageElement.exists);
|
||||
XCTAssertFalse(imageElement.fb_isAccessibilityElement);
|
||||
XCTAssertFalse(imageElement.isWDAccessibilityContainer);
|
||||
}
|
||||
|
||||
- (void)testButtonAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.buttons[@"Button"];
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeButton");
|
||||
XCTAssertEqualObjects(element.wdName, @"Button");
|
||||
XCTAssertEqualObjects(element.wdLabel, @"Button");
|
||||
XCTAssertNil(element.wdValue);
|
||||
XCTAssertFalse(element.wdSelected);
|
||||
XCTAssertTrue(element.fb_isVisible);
|
||||
[element tap];
|
||||
XCTAssertTrue(element.wdValue.boolValue);
|
||||
XCTAssertTrue(element.wdSelected);
|
||||
}
|
||||
|
||||
- (void)testLabelAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.staticTexts[@"Label"];
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeStaticText");
|
||||
XCTAssertEqualObjects(element.wdName, @"Label");
|
||||
XCTAssertEqualObjects(element.wdLabel, @"Label");
|
||||
XCTAssertEqualObjects(element.wdValue, @"Label");
|
||||
}
|
||||
|
||||
- (void)testIndexAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.buttons[@"Button"];
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqual(element.wdIndex, 2);
|
||||
XCUIElement *element2 = self.testedApplication;
|
||||
XCTAssertTrue(element2.exists);
|
||||
XCTAssertEqual(element2.wdIndex, 0);
|
||||
}
|
||||
|
||||
- (void)testAccessibilityTraits
|
||||
{
|
||||
XCUIElement *button = self.testedApplication.buttons.firstMatch;
|
||||
XCTAssertTrue(button.exists);
|
||||
NSArray *buttonTraits = [button.wdTraits componentsSeparatedByString:@", "];
|
||||
NSArray *expectedButtonTraits = @[@"Button"];
|
||||
XCTAssertEqual(buttonTraits.count, expectedButtonTraits.count, @"Button should have exactly 1 trait");
|
||||
XCTAssertEqualObjects(buttonTraits, expectedButtonTraits);
|
||||
XCTAssertEqualObjects(button.wdType, @"XCUIElementTypeButton");
|
||||
|
||||
XCUIElement *toggle = self.testedApplication.switches.firstMatch;
|
||||
XCTAssertTrue(toggle.exists);
|
||||
|
||||
// iOS 17.0 specific traits if available
|
||||
NSArray *toggleTraits = [toggle.wdTraits componentsSeparatedByString:@", "];
|
||||
NSArray *expectedToggleTraits;
|
||||
|
||||
#if __clang_major__ >= 16
|
||||
if (@available(iOS 17.0, *)) {
|
||||
expectedToggleTraits = @[@"ToggleButton", @"Button"];
|
||||
XCTAssertEqual(toggleTraits.count, 2, @"Toggle should have exactly 2 traits on iOS 17+");
|
||||
}
|
||||
#else
|
||||
expectedToggleTraits = @[@"Button"];
|
||||
XCTAssertEqual(toggleTraits.count, 1, @"Toggle should have exactly 1 trait on iOS < 17");
|
||||
#endif
|
||||
XCTAssertEqualObjects(toggleTraits, expectedToggleTraits);
|
||||
XCTAssertEqualObjects(toggle.wdType, @"XCUIElementTypeSwitch");
|
||||
|
||||
XCUIElement *slider = self.testedApplication.sliders.firstMatch;
|
||||
XCTAssertTrue(slider.exists);
|
||||
NSArray *sliderTraits = [slider.wdTraits componentsSeparatedByString:@", "];
|
||||
NSArray *expectedSliderTraits = @[@"Adjustable"];
|
||||
XCTAssertEqual(sliderTraits.count, expectedSliderTraits.count, @"Slider should have exactly 1 trait");
|
||||
XCTAssertEqualObjects(sliderTraits, expectedSliderTraits);
|
||||
XCTAssertEqualObjects(slider.wdType, @"XCUIElementTypeSlider");
|
||||
|
||||
XCUIElement *picker = self.testedApplication.pickerWheels.firstMatch;
|
||||
XCTAssertTrue(picker.exists);
|
||||
NSArray *pickerTraits = [picker.wdTraits componentsSeparatedByString:@", "];
|
||||
NSArray *expectedPickerTraits = @[@"Adjustable"];
|
||||
XCTAssertEqual(pickerTraits.count, expectedPickerTraits.count, @"Picker should have exactly 1 trait");
|
||||
XCTAssertEqualObjects(pickerTraits, expectedPickerTraits);
|
||||
XCTAssertEqualObjects(picker.wdType, @"XCUIElementTypePickerWheel");
|
||||
}
|
||||
|
||||
- (void)testTextFieldAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.textFields[@"Value"];
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeTextField");
|
||||
XCTAssertNil(element.wdName);
|
||||
XCTAssertEqualObjects(element.wdLabel, @"");
|
||||
XCTAssertEqualObjects(element.wdValue, @"Value");
|
||||
}
|
||||
|
||||
- (void)testTextFieldWithAccessibilityIdentifiersAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.textFields[@"aIdentifier"];
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeTextField");
|
||||
XCTAssertEqualObjects(element.wdName, @"aIdentifier");
|
||||
XCTAssertEqualObjects(element.wdLabel, @"aLabel");
|
||||
XCTAssertEqualObjects(element.wdValue, @"Value2");
|
||||
}
|
||||
|
||||
- (void)testSegmentedControlAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.segmentedControls.element;
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeSegmentedControl");
|
||||
XCTAssertNil(element.wdName);
|
||||
XCTAssertNil(element.wdLabel);
|
||||
XCTAssertNil(element.wdValue);
|
||||
}
|
||||
|
||||
- (void)testSliderAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.sliders.element;
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeSlider");
|
||||
XCTAssertNil(element.wdName);
|
||||
XCTAssertNil(element.wdLabel);
|
||||
XCTAssertTrue([element.wdValue containsString:@"50"]);
|
||||
|
||||
NSNumber *minValue = element.wdMinValue;
|
||||
NSNumber *maxValue = element.wdMaxValue;
|
||||
|
||||
XCTAssertNotNil(minValue, @"Slider minValue should not be nil");
|
||||
XCTAssertNotNil(maxValue, @"Slider maxValue should not be nil");
|
||||
|
||||
XCTAssertEqualObjects(minValue, @0);
|
||||
XCTAssertEqualObjects(maxValue, @1);
|
||||
}
|
||||
|
||||
|
||||
- (void)testActivityIndicatorAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.activityIndicators.element;
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeActivityIndicator");
|
||||
XCTAssertEqualObjects(element.wdName, @"Progress halted");
|
||||
XCTAssertEqualObjects(element.wdLabel, @"Progress halted");
|
||||
XCTAssertEqualObjects(element.wdValue, @"0");
|
||||
}
|
||||
|
||||
- (void)testSwitchAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.switches.element;
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeSwitch");
|
||||
XCTAssertNil(element.wdName);
|
||||
XCTAssertNil(element.wdLabel);
|
||||
XCTAssertNil(element.wdPlaceholderValue);
|
||||
XCTAssertEqualObjects(element.wdValue, @"1");
|
||||
XCTAssertFalse(element.wdSelected);
|
||||
XCTAssertEqual(element.wdHittable, element.hittable);
|
||||
[element tap];
|
||||
XCTAssertEqualObjects(element.wdValue, @"0");
|
||||
XCTAssertFalse(element.wdSelected);
|
||||
}
|
||||
|
||||
- (void)testPickerWheelAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.pickerWheels[@"Today"];
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypePickerWheel");
|
||||
XCTAssertNil(element.wdName);
|
||||
XCTAssertNil(element.wdLabel);
|
||||
XCTAssertEqualObjects(element.wdValue, @"Today");
|
||||
}
|
||||
|
||||
- (void)testPageIndicatorAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.pageIndicators.element;
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypePageIndicator");
|
||||
XCTAssertNil(element.wdName);
|
||||
XCTAssertNil(element.wdLabel);
|
||||
XCTAssertEqualObjects(element.wdValue, @"page 1 of 3");
|
||||
}
|
||||
|
||||
- (void)testTextViewAttributes
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.textViews.element;
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypeTextView");
|
||||
XCTAssertNil(element.wdName);
|
||||
XCTAssertNil(element.wdLabel);
|
||||
XCTAssertEqualObjects(element.wdValue, @"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901");
|
||||
}
|
||||
|
||||
@end
|
||||
127
WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m
Normal file
127
WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIElement+FBWebDriverAttributes.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
#import "XCUIElement+FBSwiping.h"
|
||||
|
||||
@interface FBElementSwipingTests : FBIntegrationTestCase
|
||||
@property (nonatomic, strong) XCUIElement *scrollView;
|
||||
- (void)openScrollView;
|
||||
@end
|
||||
|
||||
@implementation FBElementSwipingTests
|
||||
|
||||
- (void)openScrollView
|
||||
{
|
||||
[self launchApplication];
|
||||
[self goToScrollPageWithCells:YES];
|
||||
self.scrollView = [[self.testedApplication.query descendantsMatchingType:XCUIElementTypeAny] matchingIdentifier:@"scrollView"].element;
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
|
||||
[self openScrollView];
|
||||
} else {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self openScrollView];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
|
||||
// Move to top page once to reset the scroll place
|
||||
// since iOS 15 seems cannot handle cell visibility well when the view keps the view
|
||||
[self.testedApplication terminate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testSwipeUp
|
||||
{
|
||||
[self.scrollView fb_swipeWithDirection:@"up" velocity:nil];
|
||||
FBAssertInvisibleCell(@"0");
|
||||
}
|
||||
|
||||
- (void)testSwipeDown
|
||||
{
|
||||
[self.scrollView fb_swipeWithDirection:@"up" velocity:nil];
|
||||
FBAssertInvisibleCell(@"0");
|
||||
[self.scrollView fb_swipeWithDirection:@"down" velocity:nil];
|
||||
FBAssertVisibleCell(@"0");
|
||||
}
|
||||
|
||||
- (void)testSwipeDownWithVelocity
|
||||
{
|
||||
if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
||||
XCTSkip(@"Failed on Azure Pipeline. Local run succeeded.");
|
||||
}
|
||||
[self.scrollView fb_swipeWithDirection:@"up" velocity:@2500];
|
||||
FBAssertInvisibleCell(@"0");
|
||||
[self.scrollView fb_swipeWithDirection:@"down" velocity:@3000];
|
||||
FBAssertVisibleCell(@"0");
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface FBElementSwipingApplicationTests : FBIntegrationTestCase
|
||||
@property (nonatomic, strong) XCUIElement *scrollView;
|
||||
- (void)openScrollView;
|
||||
@end
|
||||
|
||||
@implementation FBElementSwipingApplicationTests
|
||||
|
||||
- (void)openScrollView
|
||||
{
|
||||
[self launchApplication];
|
||||
[self goToScrollPageWithCells:YES];
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self openScrollView];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testSwipeUp
|
||||
{
|
||||
[self.testedApplication fb_swipeWithDirection:@"up" velocity:nil];
|
||||
FBAssertInvisibleCell(@"0");
|
||||
}
|
||||
|
||||
- (void)testSwipeDown
|
||||
{
|
||||
[self.testedApplication fb_swipeWithDirection:@"up" velocity:nil];
|
||||
FBAssertInvisibleCell(@"0");
|
||||
[self.testedApplication fb_swipeWithDirection:@"down" velocity:nil];
|
||||
FBAssertVisibleCell(@"0");
|
||||
}
|
||||
|
||||
- (void)testSwipeDownWithVelocity
|
||||
{
|
||||
if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
||||
XCTSkip(@"Failed on Azure Pipeline. Local run succeeded.");
|
||||
}
|
||||
[self.testedApplication fb_swipeWithDirection:@"up" velocity:@2500];
|
||||
FBAssertInvisibleCell(@"0");
|
||||
[self.testedApplication fb_swipeWithDirection:@"down" velocity:@2500];
|
||||
FBAssertVisibleCell(@"0");
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
|
||||
@interface FBElementVisibilityTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBElementVisibilityTests
|
||||
|
||||
- (void)testSpringBoardIcons
|
||||
{
|
||||
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
||||
return;
|
||||
}
|
||||
[self launchApplication];
|
||||
[self goToSpringBoardFirstPage];
|
||||
|
||||
// Check Icons on first screen
|
||||
// Note: Calender app exits 2 (an app icon + a widget) exist on the home screen
|
||||
// on iOS 15+. The firstMatch is for it.
|
||||
XCTAssertTrue(self.springboard.icons[@"Calendar"].firstMatch.fb_isVisible);
|
||||
XCTAssertTrue(self.springboard.icons[@"Reminders"].fb_isVisible);
|
||||
|
||||
// Check Icons on second screen screen
|
||||
XCTAssertFalse(self.springboard.icons[@"IntegrationApp"].firstMatch.fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)testSpringBoardSubfolder
|
||||
{
|
||||
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad
|
||||
|| SYSTEM_VERSION_GREATER_THAN(@"12.0")) {
|
||||
return;
|
||||
}
|
||||
[self launchApplication];
|
||||
[self goToSpringBoardExtras];
|
||||
XCTAssertFalse(self.springboard.icons[@"Extras"].otherElements[@"Contacts"].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)disabled_testIconsFromSearchDashboard
|
||||
{
|
||||
// This test causes:
|
||||
// Failure fetching attributes for element <XCAccessibilityElement: 0x60800044dd10> Device element: Error Domain=XCTDaemonErrorDomain Code=13 "Value for attribute 5017 is an error." UserInfo={NSLocalizedDescription=Value for attribute 5017 is an error.}
|
||||
[self launchApplication];
|
||||
[self goToSpringBoardDashboard];
|
||||
XCTAssertFalse(self.springboard.icons[@"Reminders"].fb_isVisible);
|
||||
XCTAssertFalse([[[self.springboard descendantsMatchingType:XCUIElementTypeIcon]
|
||||
matchingIdentifier:@"IntegrationApp"]
|
||||
firstMatch].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)testTableViewCells
|
||||
{
|
||||
[self launchApplication];
|
||||
[self goToScrollPageWithCells:YES];
|
||||
for (int i = 0 ; i < 10 ; i++) {
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.cells.allElementsBoundByIndex[i].fb_isVisible);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts.allElementsBoundByIndex[i].fb_isVisible);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBFailureProofTestCase.h"
|
||||
#import "FBExceptionHandler.h"
|
||||
|
||||
@interface FBFailureProofTestCaseTests : FBFailureProofTestCase
|
||||
@end
|
||||
|
||||
@implementation FBFailureProofTestCaseTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[[XCUIApplication new] launch];
|
||||
}
|
||||
|
||||
- (void)testPreventElementSearchFailure
|
||||
{
|
||||
[[XCUIApplication new].buttons[@"kaboom"] tap];
|
||||
}
|
||||
|
||||
- (void)testInactiveAppSearch
|
||||
{
|
||||
[[XCUIDevice sharedDevice] pressButton:XCUIDeviceButtonHome];
|
||||
[[XCUIApplication new].buttons[@"kaboom"] tap];
|
||||
}
|
||||
|
||||
- (void)testPreventAssertFailure
|
||||
{
|
||||
XCTAssertNotNil(nil);
|
||||
}
|
||||
|
||||
@end
|
||||
85
WebDriverAgentTests/IntegrationTests/FBForceTouchTests.m
Normal file
85
WebDriverAgentTests/IntegrationTests/FBForceTouchTests.m
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
|
||||
#import "FBMacros.h"
|
||||
#import "FBElementCache.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIDevice.h"
|
||||
#import "XCUIDevice+FBRotation.h"
|
||||
#import "XCUIElement+FBForceTouch.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
|
||||
@interface FBForceTouchTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
// It is recommnded to verify these tests with different iOS versions
|
||||
|
||||
@implementation FBForceTouchTests
|
||||
|
||||
- (void)verifyForceTapWithOrientation:(UIDeviceOrientation)orientation
|
||||
{
|
||||
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation];
|
||||
NSError *error;
|
||||
XCTAssertTrue(self.testedApplication.alerts.count == 0);
|
||||
[self.testedApplication.buttons[FBShowAlertForceTouchButtonName] fb_forceTouchCoordinate:nil
|
||||
pressure:nil
|
||||
duration:nil
|
||||
error:&error];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count > 0);
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAlertsPage];
|
||||
});
|
||||
[self clearAlert];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self clearAlert];
|
||||
[self resetOrientation];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testForceTap
|
||||
{
|
||||
if (![XCUIDevice sharedDevice].supportsPressureInteraction) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self verifyForceTapWithOrientation:UIDeviceOrientationPortrait];
|
||||
}
|
||||
|
||||
- (void)testForceTapInLandscapeLeft
|
||||
{
|
||||
if (![XCUIDevice sharedDevice].supportsPressureInteraction) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self verifyForceTapWithOrientation:UIDeviceOrientationLandscapeLeft];
|
||||
}
|
||||
|
||||
- (void)testForceTapInLandscapeRight
|
||||
{
|
||||
if (![XCUIDevice sharedDevice].supportsPressureInteraction) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self verifyForceTapWithOrientation:UIDeviceOrientationLandscapeRight];
|
||||
}
|
||||
|
||||
@end
|
||||
82
WebDriverAgentTests/IntegrationTests/FBImageProcessorTests.m
Normal file
82
WebDriverAgentTests/IntegrationTests/FBImageProcessorTests.m
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBImageProcessor.h"
|
||||
#import "FBIntegrationTestCase.h"
|
||||
|
||||
|
||||
@interface FBImageProcessorTests : FBIntegrationTestCase
|
||||
|
||||
@property (nonatomic) NSData *originalImage;
|
||||
@property (nonatomic) CGSize originalSize;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FBImageProcessorTests
|
||||
|
||||
- (void)setUp {
|
||||
XCUIApplication *app = [[XCUIApplication alloc] init];
|
||||
[app launch];
|
||||
XCUIScreenshot *screenshot = app.screenshot;
|
||||
self.originalImage = UIImageJPEGRepresentation(screenshot.image, 1.0);
|
||||
self.originalSize = [FBImageProcessorTests scaledSizeFromImage:screenshot.image];
|
||||
}
|
||||
|
||||
- (void)testScaling {
|
||||
CGFloat halfScale = 0.5;
|
||||
CGSize expectedHalfScaleSize = [FBImageProcessorTests sizeFromSize:self.originalSize scalingFactor:0.5];
|
||||
[self scaleImageWithFactor:halfScale
|
||||
expectedSize:expectedHalfScaleSize];
|
||||
|
||||
// 0 is the smalles scaling factor we accept
|
||||
CGFloat minScale = 0.0;
|
||||
CGSize expectedMinScaleSize = [FBImageProcessorTests sizeFromSize:self.originalSize scalingFactor:0.01];
|
||||
[self scaleImageWithFactor:minScale
|
||||
expectedSize:expectedMinScaleSize];
|
||||
|
||||
// For scaling factors above 100 we don't perform any scaling and just return the unmodified image
|
||||
[self scaleImageWithFactor:1.0
|
||||
expectedSize:self.originalSize];
|
||||
[self scaleImageWithFactor:2.0
|
||||
expectedSize:self.originalSize];
|
||||
}
|
||||
|
||||
- (void)scaleImageWithFactor:(CGFloat)scalingFactor expectedSize:(CGSize)excpectedSize {
|
||||
FBImageProcessor *scaler = [[FBImageProcessor alloc] init];
|
||||
|
||||
id expScaled = [self expectationWithDescription:@"Receive scaled image"];
|
||||
|
||||
[scaler submitImageData:self.originalImage
|
||||
scalingFactor:scalingFactor
|
||||
completionHandler:^(NSData *scaled) {
|
||||
UIImage *scaledImage = [UIImage imageWithData:scaled];
|
||||
CGSize scaledSize = [FBImageProcessorTests scaledSizeFromImage:scaledImage];
|
||||
|
||||
XCTAssertEqualWithAccuracy(scaledSize.width, excpectedSize.width, 1.0);
|
||||
XCTAssertEqualWithAccuracy(scaledSize.height, excpectedSize.height, 1.0);
|
||||
|
||||
[expScaled fulfill];
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[expScaled]
|
||||
timeout:0.5];
|
||||
|
||||
}
|
||||
|
||||
+ (CGSize)scaledSizeFromImage:(UIImage *)image {
|
||||
return CGSizeMake(image.size.width * image.scale, image.size.height * image.scale);
|
||||
}
|
||||
|
||||
+ (CGSize)sizeFromSize:(CGSize)size scalingFactor:(CGFloat)scalingFactor {
|
||||
return CGSizeMake(round(size.width * scalingFactor), round(size.height * scalingFactor));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
76
WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.h
Normal file
76
WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
extern NSString *const FBShowAlertButtonName;
|
||||
extern NSString *const FBShowSheetAlertButtonName;
|
||||
extern NSString *const FBShowAlertForceTouchButtonName;
|
||||
extern NSString *const FBTouchesCountLabelIdentifier;
|
||||
extern NSString *const FBTapsCountLabelIdentifier;
|
||||
|
||||
/**
|
||||
XCTestCase helper class used for integration tests
|
||||
*/
|
||||
@interface FBIntegrationTestCase : XCTestCase
|
||||
@property (nonatomic, strong, readonly) XCUIApplication *testedApplication;
|
||||
@property (nonatomic, strong, readonly) XCUIApplication *springboard;
|
||||
|
||||
/**
|
||||
Launches application and resets side effects of testing like orientation etc.
|
||||
*/
|
||||
- (void)launchApplication;
|
||||
|
||||
/**
|
||||
Navigates integration app to attributes page
|
||||
*/
|
||||
- (void)goToAttributesPage;
|
||||
|
||||
/**
|
||||
Navigates integration app to alerts page
|
||||
*/
|
||||
- (void)goToAlertsPage;
|
||||
|
||||
/**
|
||||
Navigates integration app to touch page
|
||||
*/
|
||||
- (void)goToTouchPage;
|
||||
|
||||
/**
|
||||
Navigates to SpringBoard first page
|
||||
*/
|
||||
- (void)goToSpringBoardFirstPage;
|
||||
|
||||
/**
|
||||
Navigates to SpringBoard path with Extras folder
|
||||
*/
|
||||
- (void)goToSpringBoardExtras;
|
||||
|
||||
/**
|
||||
Navigates to SpringBoard's dashboard
|
||||
*/
|
||||
- (void)goToSpringBoardDashboard;
|
||||
|
||||
/**
|
||||
Navigates integration app to scrolling page
|
||||
@param showCells whether should navigate to view with cell or plain scrollview
|
||||
*/
|
||||
- (void)goToScrollPageWithCells:(BOOL)showCells;
|
||||
|
||||
/**
|
||||
Verifies no alerts are present on the page.
|
||||
If an alert exists then it is going to be dismissed.
|
||||
*/
|
||||
- (void)clearAlert;
|
||||
|
||||
/**
|
||||
Resets device orientation to portrait mode
|
||||
*/
|
||||
- (void)resetOrientation;
|
||||
|
||||
@end
|
||||
140
WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.m
Normal file
140
WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.m
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBAlert.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBConfiguration.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBRunLoopSpinner.h"
|
||||
#import "XCUIApplication+FBHelpers.h"
|
||||
#import "XCUIDevice+FBRotation.h"
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
#import "XCUIElement+FBUtilities.h"
|
||||
#import "XCTestConfiguration.h"
|
||||
|
||||
NSString *const FBShowAlertButtonName = @"Create App Alert";
|
||||
NSString *const FBShowSheetAlertButtonName = @"Create Sheet Alert";
|
||||
NSString *const FBShowAlertForceTouchButtonName = @"Create Alert (Force Touch)";
|
||||
NSString *const FBTouchesCountLabelIdentifier = @"numberOfTouchesLabel";
|
||||
NSString *const FBTapsCountLabelIdentifier = @"numberOfTapsLabel";
|
||||
|
||||
@interface FBIntegrationTestCase ()
|
||||
@property (nonatomic, strong) XCUIApplication *testedApplication;
|
||||
@property (nonatomic, strong) XCUIApplication *springboard;
|
||||
@end
|
||||
|
||||
@implementation FBIntegrationTestCase
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// Enable it to get extended XCTest logs printed into the console
|
||||
// [FBConfiguration enableXcTestDebugLogs];
|
||||
[super setUp];
|
||||
[FBConfiguration disableRemoteQueryEvaluation];
|
||||
[FBConfiguration disableAttributeKeyPathAnalysis];
|
||||
[FBConfiguration configureDefaultKeyboardPreferences];
|
||||
[FBConfiguration disableApplicationUIInterruptionsHandling];
|
||||
[FBConfiguration disableScreenshots];
|
||||
self.continueAfterFailure = NO;
|
||||
self.springboard = XCUIApplication.fb_systemApplication;
|
||||
self.testedApplication = [XCUIApplication new];
|
||||
}
|
||||
|
||||
- (void)resetOrientation
|
||||
{
|
||||
if ([XCUIDevice sharedDevice].orientation != UIDeviceOrientationPortrait) {
|
||||
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:UIDeviceOrientationPortrait];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)launchApplication
|
||||
{
|
||||
[self.testedApplication launch];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.buttons[@"Alerts"].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)goToAttributesPage
|
||||
{
|
||||
[self.testedApplication.buttons[@"Attributes"] tap];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.buttons[@"Button"].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)goToAlertsPage
|
||||
{
|
||||
[self.testedApplication.buttons[@"Alerts"] tap];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.buttons[FBShowAlertButtonName].fb_isVisible);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.buttons[FBShowSheetAlertButtonName].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)goToTouchPage
|
||||
{
|
||||
[self.testedApplication.buttons[@"Touch"] tap];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts[FBTouchesCountLabelIdentifier].fb_isVisible);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts[FBTapsCountLabelIdentifier].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)goToSpringBoardFirstPage
|
||||
{
|
||||
[[XCUIDevice sharedDevice] pressButton:XCUIDeviceButtonHome];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(XCUIApplication.fb_systemApplication.icons[@"Safari"].exists);
|
||||
[[XCUIDevice sharedDevice] pressButton:XCUIDeviceButtonHome];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(XCUIApplication.fb_systemApplication.icons[@"Calendar"].firstMatch.fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)goToSpringBoardExtras
|
||||
{
|
||||
[self goToSpringBoardFirstPage];
|
||||
[self.springboard swipeLeft];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.springboard.icons[@"Extras"].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)goToSpringBoardDashboard
|
||||
{
|
||||
[self goToSpringBoardFirstPage];
|
||||
[self.springboard swipeRight];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
NSPredicate *predicate =
|
||||
[NSPredicate predicateWithFormat:
|
||||
@"%K IN %@",
|
||||
FBStringify(XCUIElement, identifier),
|
||||
@[@"SBSearchEtceteraIsolatedView", @"SpotlightSearchField"]
|
||||
];
|
||||
FBAssertWaitTillBecomesTrue([[self.springboard descendantsMatchingType:XCUIElementTypeAny] elementMatchingPredicate:predicate].fb_isVisible);
|
||||
FBAssertWaitTillBecomesTrue(!self.springboard.icons[@"Calendar"].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)goToScrollPageWithCells:(BOOL)showCells
|
||||
{
|
||||
[self.testedApplication.buttons[@"Scrolling"] tap];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.buttons[@"TableView"].fb_isVisible);
|
||||
[self.testedApplication.buttons[showCells ? @"TableView": @"ScrollView"] tap];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts[@"3"].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)clearAlert
|
||||
{
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
[[FBAlert alertWithApplication:self.testedApplication] dismissWithError:nil];
|
||||
[self.testedApplication fb_waitUntilStable];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
|
||||
}
|
||||
|
||||
@end
|
||||
61
WebDriverAgentTests/IntegrationTests/FBKeyboardTests.m
Normal file
61
WebDriverAgentTests/IntegrationTests/FBKeyboardTests.m
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBMacros.h"
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBKeyboard.h"
|
||||
#import "FBRunLoopSpinner.h"
|
||||
#import "XCUIApplication+FBHelpers.h"
|
||||
|
||||
@interface FBKeyboardTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBKeyboardTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
}
|
||||
|
||||
- (void)testKeyboardDismissal
|
||||
{
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
[textField tap];
|
||||
|
||||
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
|
||||
// A workaround until find out to clear tutorial on iOS 15
|
||||
XCUIElement *textField = self.testedApplication.staticTexts[@"Continue"];
|
||||
if (textField.hittable) {
|
||||
[textField tap];
|
||||
}
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
XCTAssertTrue([FBKeyboard waitUntilVisibleForApplication:self.testedApplication timeout:1 error:&error]);
|
||||
XCTAssertNil(error);
|
||||
if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
||||
XCTAssertTrue([self.testedApplication fb_dismissKeyboardWithKeyNames:nil error:&error]);
|
||||
XCTAssertNil(error);
|
||||
} else {
|
||||
XCTAssertFalse([self.testedApplication fb_dismissKeyboardWithKeyNames:@[@"return"] error:&error]);
|
||||
XCTAssertNotNil(error);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testKeyboardPresenceVerification
|
||||
{
|
||||
NSError *error;
|
||||
XCTAssertFalse([FBKeyboard waitUntilVisibleForApplication:self.testedApplication timeout:1 error:&error]);
|
||||
XCTAssertNotNil(error);
|
||||
}
|
||||
|
||||
@end
|
||||
91
WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m
Normal file
91
WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "XCUIElement+FBTyping.h"
|
||||
#import "FBPasteboard.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
@interface FBPasteboardTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBPasteboardTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
}
|
||||
|
||||
- (void)testSetPasteboard
|
||||
{
|
||||
NSString *text = @"Happy pasting";
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
NSError *error;
|
||||
BOOL result = [FBPasteboard setData:(NSData *)[text dataUsingEncoding:NSUTF8StringEncoding]
|
||||
forType:@"plaintext"
|
||||
error:&error];
|
||||
XCTAssertTrue(result);
|
||||
XCTAssertNil(error);
|
||||
[textField tap];
|
||||
XCTAssertTrue([textField fb_clearTextWithError:&error]);
|
||||
[textField pressForDuration:2.0];
|
||||
XCUIElementQuery *pastItemsQuery = [[self.testedApplication descendantsMatchingType:XCUIElementTypeAny] matchingIdentifier:@"Paste"];
|
||||
if (![pastItemsQuery.firstMatch waitForExistenceWithTimeout:2.0]) {
|
||||
XCTFail(@"No matched element named 'Paste'");
|
||||
}
|
||||
XCUIElement *pasteItem = pastItemsQuery.firstMatch;
|
||||
XCTAssertNotNil(pasteItem);
|
||||
[pasteItem tap];
|
||||
FBAssertWaitTillBecomesTrue([textField.value isEqualToString:text]);
|
||||
}
|
||||
|
||||
- (void)testGetPasteboard
|
||||
{
|
||||
NSString *text = @"Happy copying";
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
NSError *error;
|
||||
XCTAssertTrue([textField fb_typeText:text shouldClear:NO error:&error]);
|
||||
[textField pressForDuration:2.0];
|
||||
XCUIElement *selectAllItem = [[self.testedApplication descendantsMatchingType:XCUIElementTypeAny]
|
||||
matchingIdentifier:@"Select All"].firstMatch;
|
||||
XCTAssertTrue([selectAllItem waitForExistenceWithTimeout:5]);
|
||||
[selectAllItem tap];
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"16.0")) {
|
||||
[textField pressForDuration:2.0];
|
||||
}
|
||||
XCUIElement *copyItem = [[self.testedApplication descendantsMatchingType:XCUIElementTypeAny]
|
||||
matchingIdentifier:@"Copy"].firstMatch;
|
||||
XCTAssertTrue([copyItem waitForExistenceWithTimeout:5]);
|
||||
[copyItem tap];
|
||||
FBWaitExact(1.0);
|
||||
NSData *result = [FBPasteboard dataForType:@"plaintext" error:&error];
|
||||
XCTAssertNil(error);
|
||||
XCTAssertEqualObjects(textField.value, [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
- (void)testUrlCopyPaste
|
||||
{
|
||||
NSString *urlString = @"http://appium.io?some=value";
|
||||
NSError *error;
|
||||
XCTAssertTrue([FBPasteboard setData:(NSData *)[urlString dataUsingEncoding:NSUTF8StringEncoding]
|
||||
forType:@"url"
|
||||
error:&error]);
|
||||
XCTAssertNil(error);
|
||||
NSData *result = [FBPasteboard dataForType:@"url" error:&error];
|
||||
XCTAssertNil(error);
|
||||
XCTAssertEqualObjects(urlString, [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "XCUIElement+FBPickerWheel.h"
|
||||
#import "XCUIElement+FBWebDriverAttributes.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
@interface FBPickerWheelSelectTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBPickerWheelSelectTests
|
||||
|
||||
static const CGFloat DEFAULT_OFFSET = (CGFloat)0.2;
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testSelectNextPickerValue
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.pickerWheels.allElementsBoundByIndex.firstObject;
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypePickerWheel");
|
||||
NSError *error;
|
||||
NSString *previousValue = element.wdValue;
|
||||
XCTAssertTrue([element fb_selectNextOptionWithOffset:DEFAULT_OFFSET error:&error]);
|
||||
XCTAssertNotEqualObjects(previousValue, element.wdValue);
|
||||
}
|
||||
|
||||
- (void)testSelectPreviousPickerValue
|
||||
{
|
||||
XCUIElement *element = [self.testedApplication.pickerWheels elementBoundByIndex:1];
|
||||
XCTAssertTrue(element.exists);
|
||||
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypePickerWheel");
|
||||
NSError *error;
|
||||
NSString *previousValue = element.wdValue;
|
||||
XCTAssertTrue([element fb_selectPreviousOptionWithOffset:DEFAULT_OFFSET error:&error]);
|
||||
XCTAssertNotEqualObjects(previousValue, element.wdValue);
|
||||
}
|
||||
|
||||
@end
|
||||
73
WebDriverAgentTests/IntegrationTests/FBSafariAlertTests.m
Normal file
73
WebDriverAgentTests/IntegrationTests/FBSafariAlertTests.m
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBSession.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
#import "XCUIElement+FBTyping.h"
|
||||
#import "FBAlert.h"
|
||||
#import "XCUIApplication+FBAlert.h"
|
||||
|
||||
|
||||
@interface FBSafariAlertIntegrationTests : FBIntegrationTestCase
|
||||
@property (nonatomic) FBSession *session;
|
||||
@property (nonatomic) XCUIApplication *safariApp;
|
||||
@end
|
||||
|
||||
|
||||
@implementation FBSafariAlertIntegrationTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
self.session = [FBSession initWithApplication:XCUIApplication.fb_activeApplication];
|
||||
[self.session launchApplicationWithBundleId:FB_SAFARI_BUNDLE_ID
|
||||
shouldWaitForQuiescence:nil
|
||||
arguments:nil
|
||||
environment:nil];
|
||||
self.safariApp = self.session.activeApplication;
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self.session terminateApplicationWithBundleId:FB_SAFARI_BUNDLE_ID];
|
||||
}
|
||||
|
||||
- (void)disabled_testCanHandleSafariInputPrompt
|
||||
{
|
||||
XCUIElement *urlInput = [[self.safariApp
|
||||
descendantsMatchingType:XCUIElementTypeTextField]
|
||||
matchingPredicate:[
|
||||
NSPredicate predicateWithFormat:@"label == 'Address' or label == 'URL'"
|
||||
]].firstMatch;
|
||||
if (!urlInput.exists) {
|
||||
[[[self.safariApp descendantsMatchingType:XCUIElementTypeButton] matchingPredicate:[
|
||||
NSPredicate predicateWithFormat:@"label == 'Address' or label == 'URL'"]].firstMatch tap];
|
||||
}
|
||||
XCTAssertTrue([urlInput fb_typeText:@"https://www.w3schools.com/js/tryit.asp?filename=tryjs_alert"
|
||||
shouldClear:YES
|
||||
error:nil]);
|
||||
[[[self.safariApp descendantsMatchingType:XCUIElementTypeButton] matchingIdentifier:@"Go"].firstMatch tap];
|
||||
XCUIElement *clickMeButton = [[self.safariApp descendantsMatchingType:XCUIElementTypeButton]
|
||||
matchingPredicate:[NSPredicate predicateWithFormat:@"label == 'Try it'"]].firstMatch;
|
||||
XCTAssertTrue([clickMeButton waitForExistenceWithTimeout:15.0]);
|
||||
[clickMeButton tap];
|
||||
FBAlert *alert = [FBAlert alertWithApplication:self.safariApp];
|
||||
FBAssertWaitTillBecomesTrue([alert.text isEqualToString:@"I am an alert box!"]);
|
||||
NSArray *buttonLabels = alert.buttonLabels;
|
||||
XCTAssertEqualObjects(buttonLabels.firstObject, @"Close");
|
||||
XCTAssertNotNil([self.safariApp fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Close']"
|
||||
shouldReturnAfterFirstMatch:YES].firstObject);
|
||||
XCTAssertTrue([alert acceptWithError:nil]);
|
||||
}
|
||||
|
||||
@end
|
||||
31
WebDriverAgentTests/IntegrationTests/FBScreenTests.m
Normal file
31
WebDriverAgentTests/IntegrationTests/FBScreenTests.m
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBScreen.h"
|
||||
|
||||
@interface FBScreenTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBScreenTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
}
|
||||
|
||||
- (void)testScreenScale
|
||||
{
|
||||
XCTAssertTrue([FBScreen scale] >= 2);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
126
WebDriverAgentTests/IntegrationTests/FBScrollingTests.m
Normal file
126
WebDriverAgentTests/IntegrationTests/FBScrollingTests.m
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBTestMacros.h"
|
||||
|
||||
#import "FBMacros.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
#import "XCUIElement+FBScrolling.h"
|
||||
#import "XCUIElement+FBClassChain.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
|
||||
@interface FBScrollingTests : FBIntegrationTestCase
|
||||
@property (nonatomic, strong) XCUIElement *scrollView;
|
||||
@end
|
||||
|
||||
@implementation FBScrollingTests
|
||||
|
||||
+ (BOOL)shouldShowCells
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
[self goToScrollPageWithCells:YES];
|
||||
self.scrollView = [[self.testedApplication.query descendantsMatchingType:XCUIElementTypeAny] matchingIdentifier:@"scrollView"].element;
|
||||
}
|
||||
|
||||
- (void)testCellVisibility
|
||||
{
|
||||
FBAssertVisibleCell(@"0");
|
||||
FBAssertVisibleCell(@"10");
|
||||
XCUIElement *cell10 = FBCellElementWithLabel(@"10");
|
||||
XCTAssertEqual([cell10 isWDHittable], [cell10 isHittable]);
|
||||
FBAssertInvisibleCell(@"30");
|
||||
FBAssertInvisibleCell(@"50");
|
||||
XCUIElement *cell50 = FBCellElementWithLabel(@"50");
|
||||
XCTAssertEqual([cell50 isWDHittable], [cell50 isHittable]);
|
||||
}
|
||||
|
||||
- (void)testSimpleScroll
|
||||
{
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"16.0")) {
|
||||
// This test is unstable in CI env
|
||||
return;
|
||||
}
|
||||
|
||||
FBAssertVisibleCell(@"0");
|
||||
FBAssertVisibleCell(@"10");
|
||||
[self.scrollView fb_scrollDownByNormalizedDistance:1.0];
|
||||
FBAssertInvisibleCell(@"0");
|
||||
FBAssertInvisibleCell(@"10");
|
||||
XCTAssertTrue(self.testedApplication.staticTexts.count > 0);
|
||||
[self.scrollView fb_scrollUpByNormalizedDistance:1.0];
|
||||
FBAssertVisibleCell(@"0");
|
||||
FBAssertVisibleCell(@"10");
|
||||
}
|
||||
|
||||
- (void)testScrollToVisible
|
||||
{
|
||||
NSString *cellName = @"30";
|
||||
FBAssertInvisibleCell(cellName);
|
||||
NSError *error;
|
||||
XCTAssertTrue([FBCellElementWithLabel(cellName) fb_scrollToVisibleWithError:&error]);
|
||||
XCTAssertNil(error);
|
||||
FBAssertVisibleCell(cellName);
|
||||
}
|
||||
|
||||
- (void)testFarScrollToVisible
|
||||
{
|
||||
NSString *cellName = @"80";
|
||||
NSError *error;
|
||||
FBAssertInvisibleCell(cellName);
|
||||
XCTAssertTrue([FBCellElementWithLabel(cellName) fb_scrollToVisibleWithError:&error]);
|
||||
XCTAssertNil(error);
|
||||
FBAssertVisibleCell(cellName);
|
||||
}
|
||||
|
||||
- (void)testNativeFarScrollToVisible
|
||||
{
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"16.0")) {
|
||||
// This test is unstable in CI env
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *cellName = @"80";
|
||||
NSError *error;
|
||||
FBAssertInvisibleCell(cellName);
|
||||
XCTAssertTrue([FBCellElementWithLabel(cellName) fb_nativeScrollToVisibleWithError:&error]);
|
||||
XCTAssertNil(error);
|
||||
FBAssertVisibleCell(cellName);
|
||||
}
|
||||
|
||||
- (void)testAttributeWithNullScrollToVisible
|
||||
{
|
||||
NSError *error;
|
||||
NSArray<XCUIElement *> *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/XCUIElementTypeTable/XCUIElementTypeCell[60]" shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(queryMatches.count, 1);
|
||||
XCUIElement *element = queryMatches.firstObject;
|
||||
XCTAssertFalse(element.fb_isVisible);
|
||||
[element fb_scrollToVisibleWithError:&error];
|
||||
XCTAssertNil(error);
|
||||
XCTAssertTrue(element.fb_isVisible);
|
||||
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"16.0")) {
|
||||
// This test is unstable in CI env
|
||||
return;
|
||||
}
|
||||
|
||||
[element tap];
|
||||
XCTAssertTrue(element.wdSelected);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
133
WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m
Normal file
133
WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBExceptions.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBSession.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBUnattachedAppLauncher.h"
|
||||
#import "XCUIApplication+FBHelpers.h"
|
||||
#import "XCUIApplication.h"
|
||||
|
||||
@interface FBSession (Tests)
|
||||
|
||||
@end
|
||||
|
||||
@interface FBSessionIntegrationTests : FBIntegrationTestCase
|
||||
@property (nonatomic) FBSession *session;
|
||||
@end
|
||||
|
||||
|
||||
static NSString *const SETTINGS_BUNDLE_ID = @"com.apple.Preferences";
|
||||
|
||||
@implementation FBSessionIntegrationTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
XCUIApplication *app = [[XCUIApplication alloc] initWithBundleIdentifier:self.testedApplication.bundleID];
|
||||
self.session = [FBSession initWithApplication:app];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self.session kill];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testSettingsAppCanBeOpenedInScopeOfTheCurrentSession
|
||||
{
|
||||
XCUIApplication *testedApp = XCUIApplication.fb_activeApplication;
|
||||
[self.session launchApplicationWithBundleId:SETTINGS_BUNDLE_ID
|
||||
shouldWaitForQuiescence:nil
|
||||
arguments:nil
|
||||
environment:nil];
|
||||
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:SETTINGS_BUNDLE_ID]);
|
||||
XCTAssertEqual([self.session applicationStateWithBundleId:SETTINGS_BUNDLE_ID], 4);
|
||||
[self.session activateApplicationWithBundleId:testedApp.bundleID];
|
||||
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString: testedApp.bundleID]);
|
||||
XCTAssertEqual([self.session applicationStateWithBundleId:testedApp.bundleID], 4);
|
||||
}
|
||||
|
||||
- (void)testSettingsAppCanBeReopenedInScopeOfTheCurrentSession
|
||||
{
|
||||
XCUIApplication *systemApp = self.springboard;
|
||||
[self.session launchApplicationWithBundleId:SETTINGS_BUNDLE_ID
|
||||
shouldWaitForQuiescence:nil
|
||||
arguments:nil
|
||||
environment:nil];
|
||||
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:SETTINGS_BUNDLE_ID]);
|
||||
XCTAssertTrue([self.session terminateApplicationWithBundleId:SETTINGS_BUNDLE_ID]);
|
||||
FBAssertWaitTillBecomesTrue([systemApp.bundleID isEqualToString:self.session.activeApplication.bundleID]);
|
||||
[self.session launchApplicationWithBundleId:SETTINGS_BUNDLE_ID
|
||||
shouldWaitForQuiescence:nil
|
||||
arguments:nil
|
||||
environment:nil];
|
||||
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:SETTINGS_BUNDLE_ID]);
|
||||
}
|
||||
|
||||
- (void)testMainAppCanBeReactivatedInScopeOfTheCurrentSession
|
||||
{
|
||||
XCUIApplication *testedApp = XCUIApplication.fb_activeApplication;
|
||||
[self.session launchApplicationWithBundleId:SETTINGS_BUNDLE_ID
|
||||
shouldWaitForQuiescence:nil
|
||||
arguments:nil
|
||||
environment:nil];
|
||||
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:SETTINGS_BUNDLE_ID]);
|
||||
[self.session activateApplicationWithBundleId:testedApp.bundleID];
|
||||
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:testedApp.bundleID]);
|
||||
}
|
||||
|
||||
- (void)testMainAppCanBeRestartedInScopeOfTheCurrentSession
|
||||
{
|
||||
XCUIApplication *systemApp = self.springboard;
|
||||
XCUIApplication *testedApp = [[XCUIApplication alloc] initWithBundleIdentifier:self.testedApplication.bundleID];
|
||||
[self.session terminateApplicationWithBundleId:testedApp.bundleID];
|
||||
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:systemApp.bundleID]);
|
||||
[self.session launchApplicationWithBundleId:testedApp.bundleID
|
||||
shouldWaitForQuiescence:nil
|
||||
arguments:nil
|
||||
environment:nil];
|
||||
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:testedApp.bundleID]);
|
||||
}
|
||||
|
||||
- (void)testLaunchUnattachedApp
|
||||
{
|
||||
[FBUnattachedAppLauncher launchAppWithBundleId:SETTINGS_BUNDLE_ID];
|
||||
[self.session kill];
|
||||
XCTAssertEqualObjects(SETTINGS_BUNDLE_ID, XCUIApplication.fb_activeApplication.bundleID);
|
||||
}
|
||||
|
||||
- (void)testAppWithInvalidBundleIDCannotBeStarted
|
||||
{
|
||||
XCUIApplication *testedApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"yolo"];
|
||||
@try {
|
||||
[testedApp launch];
|
||||
XCTFail(@"An exception is expected to be thrown");
|
||||
} @catch (NSException *exception) {
|
||||
XCTAssertEqualObjects(FBApplicationMissingException, exception.name);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testAppWithInvalidBundleIDCannotBeActivated
|
||||
{
|
||||
XCUIApplication *testedApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"yolo"];
|
||||
@try {
|
||||
[testedApp activate];
|
||||
XCTFail(@"An exception is expected to be thrown");
|
||||
} @catch (NSException *exception) {
|
||||
XCTAssertEqualObjects(FBApplicationMissingException, exception.name);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
103
WebDriverAgentTests/IntegrationTests/FBTapTest.m
Normal file
103
WebDriverAgentTests/IntegrationTests/FBTapTest.m
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
|
||||
#import "FBElementCache.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIDevice+FBRotation.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
|
||||
@interface FBTapTest : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
// It is recommnded to verify these tests with different iOS versions
|
||||
|
||||
@implementation FBTapTest
|
||||
|
||||
- (void)verifyTapWithOrientation:(UIDeviceOrientation)orientation
|
||||
{
|
||||
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation];
|
||||
[self.testedApplication.buttons[FBShowAlertButtonName] tap];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count > 0);
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// Launch the app everytime to ensure the orientation for each test.
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
[self goToAlertsPage];
|
||||
[self clearAlert];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self clearAlert];
|
||||
[self resetOrientation];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testTap
|
||||
{
|
||||
[self verifyTapWithOrientation:UIDeviceOrientationPortrait];
|
||||
}
|
||||
|
||||
- (void)testTapInLandscapeLeft
|
||||
{
|
||||
[self verifyTapWithOrientation:UIDeviceOrientationLandscapeLeft];
|
||||
}
|
||||
|
||||
- (void)testTapInLandscapeRight
|
||||
{
|
||||
|
||||
[self verifyTapWithOrientation:UIDeviceOrientationLandscapeRight];
|
||||
}
|
||||
|
||||
- (void)testTapInPortraitUpsideDown
|
||||
{
|
||||
if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
||||
XCTSkip(@"Failed on Azure Pipeline. Local run succeeded.");
|
||||
}
|
||||
[self verifyTapWithOrientation:UIDeviceOrientationPortraitUpsideDown];
|
||||
}
|
||||
|
||||
- (void)verifyTapByCoordinatesWithOrientation:(UIDeviceOrientation)orientation
|
||||
{
|
||||
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation];
|
||||
XCUIElement *dstButton = self.testedApplication.buttons[FBShowAlertButtonName];
|
||||
[[dstButton coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)] tap];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count > 0);
|
||||
}
|
||||
|
||||
- (void)testTapCoordinates
|
||||
{
|
||||
[self verifyTapByCoordinatesWithOrientation:UIDeviceOrientationPortrait];
|
||||
}
|
||||
|
||||
- (void)testTapCoordinatesInLandscapeLeft
|
||||
{
|
||||
[self verifyTapByCoordinatesWithOrientation:UIDeviceOrientationLandscapeLeft];
|
||||
}
|
||||
|
||||
- (void)testTapCoordinatesInLandscapeRight
|
||||
{
|
||||
[self verifyTapByCoordinatesWithOrientation:UIDeviceOrientationLandscapeRight];
|
||||
}
|
||||
|
||||
- (void)testTapCoordinatesInPortraitUpsideDown
|
||||
{
|
||||
if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
||||
XCTSkip(@"Failed on Azure Pipeline. Local run succeeded.");
|
||||
}
|
||||
[self verifyTapByCoordinatesWithOrientation:UIDeviceOrientationPortraitUpsideDown];
|
||||
}
|
||||
|
||||
@end
|
||||
33
WebDriverAgentTests/IntegrationTests/FBTestMacros.h
Normal file
33
WebDriverAgentTests/IntegrationTests/FBTestMacros.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <WebDriverAgentLib/FBRunLoopSpinner.h>
|
||||
|
||||
/**
|
||||
Macro used to wait till certain condition is true.
|
||||
If condition will not become true within default timeout (1m) it will fail running test
|
||||
*/
|
||||
#define FBAssertWaitTillBecomesTrue(condition) \
|
||||
({ \
|
||||
NSError *__error; \
|
||||
XCTAssertTrue([[[FBRunLoopSpinner new] \
|
||||
interval:1.0] \
|
||||
spinUntilTrue:^BOOL{ \
|
||||
return (condition); \
|
||||
}]); \
|
||||
XCTAssertNil(__error); \
|
||||
})
|
||||
|
||||
#define FBWaitExact(timeoutSeconds) \
|
||||
({ \
|
||||
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:(timeoutSeconds)]]; \
|
||||
})
|
||||
|
||||
#define FBCellElementWithLabel(label) ([self.testedApplication descendantsMatchingType:XCUIElementTypeAny][label])
|
||||
#define FBAssertVisibleCell(label) FBAssertWaitTillBecomesTrue(FBCellElementWithLabel(label).fb_isVisible)
|
||||
#define FBAssertInvisibleCell(label) FBAssertWaitTillBecomesTrue(!FBCellElementWithLabel(label).fb_isVisible)
|
||||
68
WebDriverAgentTests/IntegrationTests/FBTypingTest.m
Normal file
68
WebDriverAgentTests/IntegrationTests/FBTypingTest.m
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIElement+FBTyping.h"
|
||||
|
||||
@interface FBTypingTest : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBTypingTest
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
}
|
||||
|
||||
- (void)testTextTyping
|
||||
{
|
||||
NSString *text = @"Happy typing";
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
NSError *error;
|
||||
XCTAssertTrue([textField fb_typeText:text shouldClear:NO error:&error]);
|
||||
XCTAssertNil(error);
|
||||
XCTAssertEqualObjects(textField.value, text);
|
||||
}
|
||||
|
||||
- (void)testTextTypingOnFocusedElement
|
||||
{
|
||||
NSString *text = @"Happy typing";
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
[textField tap];
|
||||
XCTAssertTrue(textField.hasKeyboardFocus);
|
||||
NSError *error;
|
||||
XCTAssertTrue([textField fb_typeText:text shouldClear:NO error:&error]);
|
||||
XCTAssertNil(error);
|
||||
XCTAssertTrue([textField fb_typeText:text shouldClear:NO error:&error]);
|
||||
XCTAssertNil(error);
|
||||
NSString *expectedText = [NSString stringWithFormat:@"%@%@", text, text];
|
||||
XCTAssertEqualObjects(textField.value, expectedText);
|
||||
}
|
||||
|
||||
- (void)testTextClearing
|
||||
{
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
[textField tap];
|
||||
[textField typeText:@"Happy typing"];
|
||||
XCTAssertTrue([textField.value length] > 0);
|
||||
NSError *error;
|
||||
XCTAssertTrue([textField fb_clearTextWithError:&error]);
|
||||
XCTAssertNil(error);
|
||||
XCTAssertEqualObjects(textField.value, @"");
|
||||
XCTAssertTrue([textField fb_typeText:@"Happy typing" shouldClear:YES error:&error]);
|
||||
XCTAssertTrue([textField fb_typeText:@"Happy typing 2" shouldClear:YES error:&error]);
|
||||
XCTAssertEqualObjects(textField.value, @"Happy typing 2");
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
@end
|
||||
64
WebDriverAgentTests/IntegrationTests/FBVideoRecordingTests.m
Normal file
64
WebDriverAgentTests/IntegrationTests/FBVideoRecordingTests.m
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
|
||||
#import "FBConfiguration.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBScreenRecordingPromise.h"
|
||||
#import "FBScreenRecordingRequest.h"
|
||||
#import "FBScreenRecordingContainer.h"
|
||||
#import "FBXCTestDaemonsProxy.h"
|
||||
|
||||
@interface FBVideoRecordingTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBVideoRecordingTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"DisableDiagnosticScreenRecordings"];
|
||||
[super setUp];
|
||||
}
|
||||
|
||||
- (void)testStartingAndStoppingVideoRecording
|
||||
{
|
||||
XCTSkip(@"Failed on Azure Pipeline. Local run succeeded.");
|
||||
|
||||
// Video recording is only available since iOS 17
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"17.0")) {
|
||||
return;
|
||||
}
|
||||
|
||||
FBScreenRecordingRequest *recordingRequest = [[FBScreenRecordingRequest alloc] initWithFps:24
|
||||
codec:0];
|
||||
NSError *error;
|
||||
FBScreenRecordingPromise *promise = [FBXCTestDaemonsProxy startScreenRecordingWithRequest:recordingRequest
|
||||
error:&error];
|
||||
XCTAssertNotNil(promise);
|
||||
XCTAssertNotNil(promise.identifier);
|
||||
XCTAssertNil(error);
|
||||
|
||||
[FBScreenRecordingContainer.sharedInstance storeScreenRecordingPromise:promise
|
||||
fps:24
|
||||
codec:0];
|
||||
XCTAssertEqual(FBScreenRecordingContainer.sharedInstance.screenRecordingPromise, promise);
|
||||
|
||||
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.]];
|
||||
|
||||
BOOL isSuccessfull = [FBXCTestDaemonsProxy stopScreenRecordingWithUUID:promise.identifier error:&error];
|
||||
XCTAssertTrue(isSuccessfull);
|
||||
XCTAssertNil(error);
|
||||
|
||||
[FBScreenRecordingContainer.sharedInstance reset];
|
||||
XCTAssertNil(FBScreenRecordingContainer.sharedInstance.screenRecordingPromise);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIApplication+FBTouchAction.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIDevice+FBRotation.h"
|
||||
#import "FBRunLoopSpinner.h"
|
||||
|
||||
@interface FBW3CMultiTouchActionsIntegrationTests : FBIntegrationTestCase
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation FBW3CMultiTouchActionsIntegrationTests
|
||||
|
||||
- (void)verifyGesture:(NSArray<NSDictionary<NSString *, id> *> *)gesture orientation:(UIDeviceOrientation)orientation
|
||||
{
|
||||
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation];
|
||||
NSError *error;
|
||||
XCTAssertTrue([self.testedApplication fb_performW3CActions:gesture elementCache:nil error:&error]);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count > 0);
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAlertsPage];
|
||||
});
|
||||
[self clearAlert];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self clearAlert];
|
||||
[self resetOrientation];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testErroneousGestures
|
||||
{
|
||||
NSArray<NSArray<NSDictionary<NSString *, id> *> *> *invalidGestures =
|
||||
@[
|
||||
// One of the chains has duplicated id
|
||||
@[
|
||||
@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @1, @"y": @1},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @1, @"y": @1},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
for (NSArray<NSDictionary<NSString *, id> *> *invalidGesture in invalidGestures) {
|
||||
NSError *error;
|
||||
XCTAssertFalse([self.testedApplication fb_performW3CActions:invalidGesture elementCache:nil error:&error]);
|
||||
XCTAssertNotNil(error);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testSymmetricTwoFingersTap
|
||||
{
|
||||
XCUIElement *element = self.testedApplication.buttons[FBShowAlertButtonName];
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[
|
||||
@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"origin": element, @"x": @0, @"y": @0},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger2",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"origin": element, @"x": @0, @"y": @0},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
[self verifyGesture:gesture orientation:UIDeviceOrientationPortrait];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,491 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIDevice.h"
|
||||
#import "XCUIApplication+FBTouchAction.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIDevice+FBRotation.h"
|
||||
#import "FBRunLoopSpinner.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
@interface FBW3CTouchActionsIntegrationTestsPart1 : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@interface FBW3CTouchActionsIntegrationTestsPart2 : FBIntegrationTestCase
|
||||
@property (nonatomic) XCUIElement *pickerWheel;
|
||||
@end
|
||||
|
||||
|
||||
@implementation FBW3CTouchActionsIntegrationTestsPart1
|
||||
|
||||
- (void)verifyGesture:(NSArray<NSDictionary<NSString *, id> *> *)gesture orientation:(UIDeviceOrientation)orientation
|
||||
{
|
||||
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation];
|
||||
NSError *error;
|
||||
XCTAssertTrue([self.testedApplication fb_performW3CActions:gesture elementCache:nil error:&error]);
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count > 0);
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAlertsPage];
|
||||
});
|
||||
[self clearAlert];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self clearAlert];
|
||||
[self resetOrientation];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testErroneousGestures
|
||||
{
|
||||
NSArray<NSArray<NSDictionary<NSString *, id> *> *> *invalidGestures =
|
||||
@[
|
||||
// Empty chain
|
||||
@[],
|
||||
|
||||
// Chain element without 'actions' key
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element without type
|
||||
@[@{
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @100, @"y": @100},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element without id
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @100, @"y": @100},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element with empty id
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @100, @"y": @100},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element with unsupported type
|
||||
@[@{
|
||||
@"type": @"key",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @100, @"y": @100},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element with unsupported pointerType (default)
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @100, @"y": @100},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element with unsupported pointerType (non-default)
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"pen"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @100, @"y": @100},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element without action item type
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"duration": @0, @"x": @1, @"y": @1},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element with singe up action
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element containing action item without y coordinate
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @1},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element containing action item with an unknown type
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMoved", @"duration": @0, @"x": @1, @"y": @1},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element where action items start with an incorrect item
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @1, @"y": @1},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element where pointerMove action item does not contain coordinates
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element where pointerMove action item cannot use coordinates of the previous item
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"origin": @"pointer"},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element where action items contains negative duration
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @1, @"y": @1},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @-100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// Chain element where action items start with an incorrect one, because the correct one is canceled
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @1, @"y": @1},
|
||||
@{@"type": @"pointerCancel"},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @-100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
for (NSArray<NSDictionary<NSString *, id> *> *invalidGesture in invalidGestures) {
|
||||
NSError *error;
|
||||
XCTAssertFalse([self.testedApplication fb_performW3CActions:invalidGesture elementCache:nil error:&error]);
|
||||
XCTAssertNotNil(error);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testNothingDoesWithoutError
|
||||
{
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[],
|
||||
},
|
||||
];
|
||||
NSError *error;
|
||||
XCTAssertTrue([self.testedApplication fb_performW3CActions:gesture elementCache:nil error:&error]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testTap
|
||||
{
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"origin": self.testedApplication.buttons[FBShowAlertButtonName], @"x": @0, @"y": @0},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
[self verifyGesture:gesture orientation:UIDeviceOrientationPortrait];
|
||||
}
|
||||
|
||||
- (void)testDoubleTap
|
||||
{
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"origin": self.testedApplication.buttons[FBShowAlertButtonName]},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @50},
|
||||
@{@"type": @"pointerUp"},
|
||||
@{@"type": @"pause", @"duration": @200},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @50},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
[self verifyGesture:gesture orientation:UIDeviceOrientationLandscapeLeft];
|
||||
}
|
||||
|
||||
- (void)testLongPressWithCombinedPause
|
||||
{
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"origin": self.testedApplication.buttons[FBShowAlertButtonName], @"x": @5, @"y": @5},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @200},
|
||||
@{@"type": @"pause", @"duration": @200},
|
||||
@{@"type": @"pause", @"duration": @100},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
[self verifyGesture:gesture orientation:UIDeviceOrientationLandscapeRight];
|
||||
}
|
||||
|
||||
- (void)testLongPress
|
||||
{
|
||||
if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
||||
XCTSkip(@"Failed on Azure Pipeline. Local run succeeded.");
|
||||
}
|
||||
UIDeviceOrientation orientation = UIDeviceOrientationLandscapeLeft;
|
||||
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation];
|
||||
CGRect elementFrame = self.testedApplication.buttons[FBShowAlertButtonName].frame;
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @(elementFrame.origin.x + 1), @"y": @(elementFrame.origin.y + 1)},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @500},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
[self verifyGesture:gesture orientation:orientation];
|
||||
}
|
||||
|
||||
- (void)testForceTap
|
||||
{
|
||||
if (![XCUIDevice.sharedDevice supportsPressureInteraction]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"origin": self.testedApplication.buttons[FBShowAlertButtonName]},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pause", @"duration": @500},
|
||||
@{@"type": @"pointerDown", @"pressure": @1.0, @"width":@10, @"height":@10},
|
||||
@{@"type": @"pause", @"duration": @50},
|
||||
@{@"type": @"pointerDown", @"pressure": @1.0, @"width":@10, @"height":@10},
|
||||
@{@"type": @"pause", @"duration": @50},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
[self verifyGesture:gesture orientation:UIDeviceOrientationLandscapeLeft];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation FBW3CTouchActionsIntegrationTestsPart2
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
});
|
||||
self.pickerWheel = self.testedApplication.pickerWheels.allElementsBoundByIndex.firstObject;
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self resetOrientation];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)verifyPickerWheelPositionChangeWithGesture:(NSArray<NSDictionary<NSString *, id> *> *)gesture
|
||||
{
|
||||
NSString *previousValue = self.pickerWheel.value;
|
||||
NSError *error;
|
||||
XCTAssertTrue([self.testedApplication fb_performW3CActions:gesture elementCache:nil error:&error]);
|
||||
XCTAssertNil(error);
|
||||
XCTAssertTrue([[[[FBRunLoopSpinner new]
|
||||
timeout:2.0]
|
||||
timeoutErrorMessage:@"Picker wheel value has not been changed after 2 seconds timeout"]
|
||||
spinUntilTrue:^BOOL{
|
||||
return ![[self.pickerWheel fb_standardSnapshot].value isEqualToString:previousValue];
|
||||
}
|
||||
error:&error]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testSwipePickerWheelWithElementCoordinates
|
||||
{
|
||||
CGRect pickerFrame = self.pickerWheel.frame;
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"origin": self.pickerWheel, @"x": @0, @"y":@0},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pointerMove", @"duration": @100,@"width":@10, @"height":@10, @"pressure":@0.5, @"origin": self.pickerWheel, @"x": @0, @"y": @(pickerFrame.size.height / 2)},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
[self verifyPickerWheelPositionChangeWithGesture:gesture];
|
||||
}
|
||||
|
||||
- (void)testSwipePickerWheelWithRelativeCoordinates
|
||||
{
|
||||
CGRect pickerFrame = self.pickerWheel.frame;
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @100, @"origin": self.pickerWheel, @"x": @0, @"y": @0},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pointerMove", @"duration": @100, @"width":@10, @"height":@10, @"pressure":@0.5, @"origin": @"pointer", @"x": @0, @"y": @(-pickerFrame.size.height / 2)},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
[self verifyPickerWheelPositionChangeWithGesture:gesture];
|
||||
}
|
||||
|
||||
- (void)testSwipePickerWheelWithAbsoluteCoordinates
|
||||
{
|
||||
CGRect pickerFrame = self.pickerWheel.frame;
|
||||
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
||||
@[@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"finger1",
|
||||
@"parameters": @{@"pointerType": @"touch"},
|
||||
@"actions": @[
|
||||
@{@"type": @"pointerMove", @"duration": @0, @"x": @(pickerFrame.origin.x + pickerFrame.size.width / 2), @"y": @(pickerFrame.origin.y + pickerFrame.size.height / 2)},
|
||||
@{@"type": @"pointerDown"},
|
||||
@{@"type": @"pointerMove", @"duration": @100,@"width":@10, @"height":@10, @"pressure":@0.5, @"origin": @"pointer", @"x": @0, @"y": @(pickerFrame.size.height / 2)},
|
||||
@{@"type": @"pointerUp"},
|
||||
],
|
||||
},
|
||||
];
|
||||
[self verifyPickerWheelPositionChangeWithGesture:gesture];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
184
WebDriverAgentTests/IntegrationTests/FBW3CTypeActionsTests.m
Normal file
184
WebDriverAgentTests/IntegrationTests/FBW3CTypeActionsTests.m
Normal file
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIElement+FBTyping.h"
|
||||
#import "XCUIApplication+FBTouchAction.h"
|
||||
#import "XCUIElement+FBWebDriverAttributes.h"
|
||||
#import "FBRuntimeUtils.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
|
||||
@interface FBW3CTypeActionsTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation FBW3CTypeActionsTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
}
|
||||
|
||||
- (void)testErroneousGestures
|
||||
{
|
||||
if (![XCPointerEvent.class fb_areKeyEventsSupported]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray<NSArray<NSDictionary<NSString *, id> *> *> *invalidGestures =
|
||||
@[
|
||||
|
||||
// missing balance 1
|
||||
@[@{
|
||||
@"type": @"key",
|
||||
@"id": @"keyboard",
|
||||
@"actions": @[
|
||||
@{@"type": @"keyDown", @"value": @"h"},
|
||||
@{@"type": @"keyUp", @"value": @"k"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// missing balance 2
|
||||
@[@{
|
||||
@"type": @"key",
|
||||
@"id": @"keyboard",
|
||||
@"actions": @[
|
||||
@{@"type": @"keyDown", @"value": @"h"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// missing balance 3
|
||||
@[@{
|
||||
@"type": @"key",
|
||||
@"id": @"keyboard",
|
||||
@"actions": @[
|
||||
@{@"type": @"keyUp", @"value": @"h"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// missing key value
|
||||
@[@{
|
||||
@"type": @"key",
|
||||
@"id": @"keyboard",
|
||||
@"actions": @[
|
||||
@{@"type": @"keyUp"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// wrong key value
|
||||
@[@{
|
||||
@"type": @"key",
|
||||
@"id": @"keyboard",
|
||||
@"actions": @[
|
||||
@{@"type": @"keyUp", @"value": @500},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// missing duration value
|
||||
@[@{
|
||||
@"type": @"key",
|
||||
@"id": @"keyboard",
|
||||
@"actions": @[
|
||||
@{@"type": @"pause"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// wrong duration value
|
||||
@[@{
|
||||
@"type": @"key",
|
||||
@"id": @"keyboard",
|
||||
@"actions": @[
|
||||
@{@"type": @"duration", @"duration": @"bla"},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
for (NSArray<NSDictionary<NSString *, id> *> *invalidGesture in invalidGestures) {
|
||||
NSError *error;
|
||||
XCTAssertFalse([self.testedApplication fb_performW3CActions:invalidGesture elementCache:nil error:&error]);
|
||||
XCTAssertNotNil(error);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testTextTyping
|
||||
{
|
||||
if (![XCPointerEvent.class fb_areKeyEventsSupported]) {
|
||||
return;
|
||||
}
|
||||
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
[textField tap];
|
||||
NSArray<NSDictionary<NSString *, id> *> *typeAction =
|
||||
@[
|
||||
@{
|
||||
@"type": @"key",
|
||||
@"id": @"keyboard2",
|
||||
@"actions": @[
|
||||
@{@"type": @"pause", @"duration": @500},
|
||||
@{@"type": @"keyDown", @"value": @"🏀"},
|
||||
@{@"type": @"keyUp", @"value": @"🏀"},
|
||||
@{@"type": @"keyDown", @"value": @"N"},
|
||||
@{@"type": @"keyUp", @"value": @"N"},
|
||||
@{@"type": @"keyDown", @"value": @"B"},
|
||||
@{@"type": @"keyUp", @"value": @"B"},
|
||||
@{@"type": @"keyDown", @"value": @"A"},
|
||||
@{@"type": @"keyUp", @"value": @"A"},
|
||||
@{@"type": @"keyDown", @"value": @"a"},
|
||||
@{@"type": @"keyUp", @"value": @"a"},
|
||||
@{@"type": @"keyDown", @"value": [NSString stringWithFormat:@"%C", 0xE003]},
|
||||
@{@"type": @"keyUp", @"value": [NSString stringWithFormat:@"%C", 0xE003]},
|
||||
@{@"type": @"pause", @"duration": @500},
|
||||
],
|
||||
},
|
||||
];
|
||||
NSError *error;
|
||||
XCTAssertTrue([self.testedApplication fb_performW3CActions:typeAction
|
||||
elementCache:nil
|
||||
error:&error]);
|
||||
XCTAssertNil(error);
|
||||
XCTAssertEqualObjects(textField.wdValue, @"🏀NBA");
|
||||
}
|
||||
|
||||
- (void)testTextTypingWithEmptyActions
|
||||
{
|
||||
if (![XCPointerEvent.class fb_areKeyEventsSupported]) {
|
||||
return;
|
||||
}
|
||||
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
[textField tap];
|
||||
NSArray<NSDictionary<NSString *, id> *> *typeAction =
|
||||
@[
|
||||
@{
|
||||
@"type": @"pointer",
|
||||
@"id": @"touch",
|
||||
@"actions": @[],
|
||||
},
|
||||
];
|
||||
NSError *error;
|
||||
XCTAssertTrue([self.testedApplication fb_performW3CActions:typeAction
|
||||
elementCache:nil
|
||||
error:&error]);
|
||||
XCTAssertNil(error);
|
||||
XCTAssertEqualObjects(textField.value, @"");
|
||||
}
|
||||
|
||||
@end
|
||||
157
WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m
Normal file
157
WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBXPath.h"
|
||||
#import "FBXCAccessibilityElement.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
||||
#import "FBXMLGenerationOptions.h"
|
||||
#import "XCUIApplication.h"
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIElement+FBFind.h"
|
||||
#import "XCUIElement+FBUtilities.h"
|
||||
#import "XCUIElement+FBWebDriverAttributes.h"
|
||||
|
||||
|
||||
@interface FBXPathIntegrationTests : FBIntegrationTestCase
|
||||
@property (nonatomic, strong) XCUIElement *testedView;
|
||||
@end
|
||||
|
||||
@implementation FBXPathIntegrationTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
});
|
||||
self.testedView = self.testedApplication.otherElements[@"MainView"];
|
||||
XCTAssertTrue(self.testedView.exists);
|
||||
FBAssertWaitTillBecomesTrue(self.testedView.buttons.count > 0);
|
||||
}
|
||||
|
||||
- (id<FBXCElementSnapshot>)destinationSnapshot
|
||||
{
|
||||
XCUIElement *matchingElement = self.testedView.buttons.allElementsBoundByIndex.firstObject;
|
||||
id<FBXCElementSnapshot> snapshot = [matchingElement fb_customSnapshot];
|
||||
// Over iOS13, snapshot returns a child.
|
||||
// The purpose of here is return a single element to replace children with an empty array for testing.
|
||||
snapshot.children = @[];
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
- (void)testApplicationNodeXMLRepresentation
|
||||
{
|
||||
id<FBXCElementSnapshot> snapshot = [self.testedApplication fb_customSnapshot];
|
||||
snapshot.children = @[];
|
||||
FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];
|
||||
NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
|
||||
options:nil];
|
||||
int pid = [snapshot.accessibilityElement processIdentifier];
|
||||
XCTAssertNotNil(xmlStr);
|
||||
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" traits=\"%@\" processId=\"%d\" bundleId=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, wrappedSnapshot.wdTraits, pid, [self.testedApplication bundleID]];
|
||||
XCTAssertEqualObjects(xmlStr, expectedXml);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantXMLRepresentation
|
||||
{
|
||||
id<FBXCElementSnapshot> snapshot = self.destinationSnapshot;
|
||||
FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];
|
||||
NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
|
||||
options:nil];
|
||||
XCTAssertNotNil(xmlStr);
|
||||
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" traits=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, wrappedSnapshot.wdTraits];
|
||||
XCTAssertEqualObjects(xmlStr, expectedXml);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantXMLRepresentationWithScope
|
||||
{
|
||||
id<FBXCElementSnapshot> snapshot = self.destinationSnapshot;
|
||||
NSString *scope = @"AppiumAUT";
|
||||
FBXMLGenerationOptions *options = [[FBXMLGenerationOptions new] withScope:scope];
|
||||
FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];
|
||||
NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
|
||||
options:options];
|
||||
XCTAssertNotNil(xmlStr);
|
||||
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@>\n <%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" traits=\"%@\"/>\n</%@>\n", scope, wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, wrappedSnapshot.wdTraits, scope];
|
||||
XCTAssertEqualObjects(xmlStr, expectedXml);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantXMLRepresentationWithoutAttributes
|
||||
{
|
||||
id<FBXCElementSnapshot> snapshot = self.destinationSnapshot;
|
||||
FBXMLGenerationOptions *options = [[FBXMLGenerationOptions new]
|
||||
withExcludedAttributes:@[@"visible", @"enabled", @"index", @"blabla"]];
|
||||
FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];
|
||||
NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
|
||||
options:options];
|
||||
XCTAssertNotNil(xmlStr);
|
||||
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" traits=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdTraits];
|
||||
XCTAssertEqualObjects(xmlStr, expectedXml);
|
||||
}
|
||||
|
||||
- (void)testFindMatchesInElement
|
||||
{
|
||||
NSArray<id<FBXCElementSnapshot>> *matchingSnapshots = [FBXPath matchesWithRootElement:self.testedApplication forQuery:@"//XCUIElementTypeButton"];
|
||||
XCTAssertEqual([matchingSnapshots count], 5);
|
||||
for (id<FBXCElementSnapshot> element in matchingSnapshots) {
|
||||
XCTAssertTrue([[FBXCElementSnapshotWrapper ensureWrapped:element].wdType isEqualToString:@"XCUIElementTypeButton"]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testFindMatchesWithoutContextScopeLimit
|
||||
{
|
||||
XCUIElement *button = self.testedApplication.buttons.firstMatch;
|
||||
BOOL previousValue = FBConfiguration.limitXpathContextScope;
|
||||
FBConfiguration.limitXpathContextScope = NO;
|
||||
@try {
|
||||
NSArray *parentSnapshots = [FBXPath matchesWithRootElement:button forQuery:@".."];
|
||||
XCTAssertEqual(parentSnapshots.count, 1);
|
||||
XCTAssertEqualObjects(
|
||||
[FBXCElementSnapshotWrapper ensureWrapped:[parentSnapshots objectAtIndex:0]].wdLabel,
|
||||
@"MainView"
|
||||
);
|
||||
NSArray *elements = [button.application fb_filterDescendantsWithSnapshots:parentSnapshots onlyChildren:NO];
|
||||
XCTAssertEqual(elements.count, 1);
|
||||
XCTAssertEqualObjects(
|
||||
[[elements objectAtIndex:0] wdLabel],
|
||||
@"MainView"
|
||||
);
|
||||
NSArray *currentSnapshots = [FBXPath matchesWithRootElement:button forQuery:@"."];
|
||||
XCTAssertEqual(currentSnapshots.count, 1);
|
||||
XCTAssertEqualObjects(
|
||||
[FBXCElementSnapshotWrapper ensureWrapped:[currentSnapshots objectAtIndex:0]].wdType,
|
||||
@"XCUIElementTypeButton"
|
||||
);
|
||||
NSArray *currentElements = [button.application fb_filterDescendantsWithSnapshots:currentSnapshots onlyChildren:NO];
|
||||
XCTAssertEqual(currentElements.count, 1);
|
||||
XCTAssertEqualObjects(
|
||||
[[currentElements objectAtIndex:0] wdType],
|
||||
@"XCUIElementTypeButton"
|
||||
);
|
||||
} @finally {
|
||||
FBConfiguration.limitXpathContextScope = previousValue;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testFindMatchesInElementWithDotNotation
|
||||
{
|
||||
NSArray<id<FBXCElementSnapshot>> *matchingSnapshots = [FBXPath matchesWithRootElement:self.testedApplication forQuery:@".//XCUIElementTypeButton"];
|
||||
XCTAssertEqual([matchingSnapshots count], 5);
|
||||
for (id<FBXCElementSnapshot> element in matchingSnapshots) {
|
||||
XCTAssertTrue([[FBXCElementSnapshotWrapper ensureWrapped:element].wdType isEqualToString:@"XCUIElementTypeButton"]);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
24
WebDriverAgentTests/IntegrationTests/Info.plist
Normal file
24
WebDriverAgentTests/IntegrationTests/Info.plist
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.facebook.wda.integrationTests</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
#import "XCUIElement+FBUtilities.h"
|
||||
#import "XCUIElement+FBWebDriverAttributes.h"
|
||||
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
@interface XCElementSnapshotHelperTests : FBIntegrationTestCase
|
||||
@property (nonatomic, strong) XCUIElement *testedView;
|
||||
@end
|
||||
|
||||
@implementation XCElementSnapshotHelperTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
});
|
||||
self.testedView = self.testedApplication.otherElements[@"MainView"];
|
||||
XCTAssertTrue(self.testedView.exists);
|
||||
}
|
||||
|
||||
- (void)testDescendantsMatchingType
|
||||
{
|
||||
NSSet<NSString *> *expectedLabels = [NSSet setWithArray:@[
|
||||
@"Alerts",
|
||||
@"Attributes",
|
||||
@"Scrolling",
|
||||
@"Deadlock app",
|
||||
@"Touch",
|
||||
]];
|
||||
NSArray<id<FBXCElementSnapshot>> *matchingSnapshots = [[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[self.testedView fb_customSnapshot]]
|
||||
fb_descendantsMatchingType:XCUIElementTypeButton];
|
||||
XCTAssertEqual(matchingSnapshots.count, expectedLabels.count);
|
||||
NSArray<NSString *> *labels = [matchingSnapshots valueForKeyPath:@"@distinctUnionOfObjects.label"];
|
||||
XCTAssertEqualObjects([NSSet setWithArray:labels], expectedLabels);
|
||||
|
||||
NSArray<NSNumber *> *types = [matchingSnapshots valueForKeyPath:@"@distinctUnionOfObjects.elementType"];
|
||||
XCTAssertEqual(types.count, 1, @"matchingSnapshots should contain only one type");
|
||||
XCTAssertEqualObjects(types.lastObject, @(XCUIElementTypeButton), @"matchingSnapshots should contain only one type");
|
||||
}
|
||||
|
||||
- (void)testParentMatchingType
|
||||
{
|
||||
XCUIElement *button = self.testedApplication.buttons[@"Alerts"];
|
||||
FBAssertWaitTillBecomesTrue(button.exists);
|
||||
id<FBXCElementSnapshot> windowSnapshot = [[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[self.testedView fb_customSnapshot]]
|
||||
fb_parentMatchingType:XCUIElementTypeWindow];
|
||||
XCTAssertNotNil(windowSnapshot);
|
||||
XCTAssertEqual(windowSnapshot.elementType, XCUIElementTypeWindow);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface XCElementSnapshotHelperTests_AttributePage : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCElementSnapshotHelperTests_AttributePage
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testParentMatchingOneOfTypes
|
||||
{
|
||||
XCUIElement *todayPickerWheel = self.testedApplication.pickerWheels[@"Today"];
|
||||
FBAssertWaitTillBecomesTrue(todayPickerWheel.exists);
|
||||
id<FBXCElementSnapshot> datePicker = [[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[todayPickerWheel fb_customSnapshot]]
|
||||
fb_parentMatchingOneOfTypes:@[@(XCUIElementTypeDatePicker), @(XCUIElementTypeWindow)]];
|
||||
XCTAssertNotNil(datePicker);
|
||||
XCTAssertEqual(datePicker.elementType, XCUIElementTypeDatePicker);
|
||||
}
|
||||
|
||||
- (void)testParentMatchingOneOfTypesWithXCUIElementTypeAny
|
||||
{
|
||||
XCUIElement *todayPickerWheel = self.testedApplication.pickerWheels[@"Today"];
|
||||
FBAssertWaitTillBecomesTrue(todayPickerWheel.exists);
|
||||
id<FBXCElementSnapshot> otherSnapshot =[[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[todayPickerWheel fb_customSnapshot]]
|
||||
fb_parentMatchingOneOfTypes:@[@(XCUIElementTypeAny)]];
|
||||
XCTAssertNotNil(otherSnapshot);
|
||||
}
|
||||
|
||||
- (void)testParentMatchingOneOfTypesWithAbsentParents
|
||||
{
|
||||
XCUIElement *todayPickerWheel = self.testedApplication.pickerWheels[@"Today"];
|
||||
FBAssertWaitTillBecomesTrue(todayPickerWheel.exists);
|
||||
id<FBXCElementSnapshot> otherSnapshot = [[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[todayPickerWheel fb_customSnapshot]]
|
||||
fb_parentMatchingOneOfTypes:@[@(XCUIElementTypeTab), @(XCUIElementTypeLink)]];
|
||||
XCTAssertNil(otherSnapshot);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface XCElementSnapshotHelperTests_ScrollView : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCElementSnapshotHelperTests_ScrollView
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToScrollPageWithCells:false];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testParentMatchingOneOfTypesWithFilter
|
||||
{
|
||||
XCUIElement *threeStaticText = self.testedApplication.staticTexts[@"3"];
|
||||
FBAssertWaitTillBecomesTrue(threeStaticText.exists);
|
||||
NSArray *acceptedParents = @[
|
||||
@(XCUIElementTypeScrollView),
|
||||
@(XCUIElementTypeCollectionView),
|
||||
@(XCUIElementTypeTable),
|
||||
];
|
||||
id<FBXCElementSnapshot> scrollView = [[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[threeStaticText fb_customSnapshot]]
|
||||
fb_parentMatchingOneOfTypes:acceptedParents
|
||||
filter:^BOOL(id<FBXCElementSnapshot> snapshot) {
|
||||
return [[FBXCElementSnapshotWrapper ensureWrapped:snapshot] isWDVisible];
|
||||
}];
|
||||
XCTAssertEqualObjects(scrollView.identifier, @"scrollView");
|
||||
}
|
||||
|
||||
- (void)testParentMatchingOneOfTypesWithFilterRetruningNo
|
||||
{
|
||||
XCUIElement *threeStaticText = self.testedApplication.staticTexts[@"3"];
|
||||
FBAssertWaitTillBecomesTrue(threeStaticText.exists);
|
||||
NSArray *acceptedParents = @[
|
||||
@(XCUIElementTypeScrollView),
|
||||
@(XCUIElementTypeCollectionView),
|
||||
@(XCUIElementTypeTable),
|
||||
];
|
||||
id<FBXCElementSnapshot> scrollView = [[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[threeStaticText fb_customSnapshot]]
|
||||
fb_parentMatchingOneOfTypes:acceptedParents
|
||||
filter:^BOOL(id<FBXCElementSnapshot> snapshot) {
|
||||
return NO;
|
||||
}];
|
||||
XCTAssertNil(scrollView);
|
||||
}
|
||||
|
||||
- (void)testDescendantsCellSnapshots
|
||||
{
|
||||
XCUIElement *scrollView = self.testedApplication.scrollViews[@"scrollView"];
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts[@"3"].fb_isVisible);
|
||||
NSArray *cells = [[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[scrollView fb_customSnapshot]]
|
||||
fb_descendantsCellSnapshots];
|
||||
XCTAssertGreaterThanOrEqual(cells.count, 10);
|
||||
id<FBXCElementSnapshot> element = cells.firstObject;
|
||||
XCTAssertEqualObjects(element.label, @"0");
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface XCElementSnapshotHelperTests_ScrollViewCells : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCElementSnapshotHelperTests_ScrollViewCells
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToScrollPageWithCells:true];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testParentCellSnapshot
|
||||
{
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts[@"3"].fb_isVisible);
|
||||
XCUIElement *threeStaticText = self.testedApplication.staticTexts[@"3"];
|
||||
id<FBXCElementSnapshot> xcuiElementCell = [[FBXCElementSnapshotWrapper ensureWrapped:
|
||||
[threeStaticText fb_customSnapshot]]
|
||||
fb_parentCellSnapshot];
|
||||
XCTAssertEqual(xcuiElementCell.elementType, 75);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIElement+FBUtilities.h"
|
||||
|
||||
@interface XCElementSnapshotHitPoint : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCElementSnapshotHitPoint
|
||||
|
||||
- (void)testAccessibilityActivationPoint
|
||||
{
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
XCUIElement *dstBtn = self.testedApplication.buttons[@"not_accessible"];
|
||||
CGPoint hitPoint = [FBXCElementSnapshotWrapper
|
||||
ensureWrapped:[dstBtn fb_standardSnapshot]].fb_hitPoint.CGPointValue;
|
||||
XCTAssertTrue(hitPoint.x > 0 && hitPoint.y > 0);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import <mach/mach_time.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBElement.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIApplication.h"
|
||||
#import "XCUIApplication+FBHelpers.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
void calculateMaxTreeDepth(NSDictionary *tree, NSNumber *currentDepth, NSNumber** maxDepth) {
|
||||
if (nil == maxDepth) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray *children = tree[@"children"];
|
||||
if (nil == children || 0 == children.count) {
|
||||
return;
|
||||
}
|
||||
for (NSDictionary *child in children) {
|
||||
if (currentDepth.integerValue > [*maxDepth integerValue]) {
|
||||
*maxDepth = currentDepth;
|
||||
}
|
||||
calculateMaxTreeDepth(child, @(currentDepth.integerValue + 1), maxDepth);
|
||||
}
|
||||
}
|
||||
|
||||
@interface XCUIApplicationHelperTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCUIApplicationHelperTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
}
|
||||
|
||||
- (void)testQueringSpringboard
|
||||
{
|
||||
[self goToSpringBoardFirstPage];
|
||||
XCTAssertTrue(XCUIApplication.fb_systemApplication.icons[@"Safari"].exists);
|
||||
XCTAssertTrue(XCUIApplication.fb_systemApplication.icons[@"Calendar"].firstMatch.exists);
|
||||
}
|
||||
|
||||
- (void)testApplicationTree
|
||||
{
|
||||
NSDictionary *tree = self.testedApplication.fb_tree;
|
||||
XCTAssertNotNil(tree);
|
||||
NSNumber *maxDepth;
|
||||
calculateMaxTreeDepth(tree, @0, &maxDepth);
|
||||
XCTAssertGreaterThan(maxDepth.integerValue, 3);
|
||||
XCTAssertNotNil(self.testedApplication.fb_accessibilityTree);
|
||||
}
|
||||
|
||||
- (void)testApplicationTreeAttributesFiltering
|
||||
{
|
||||
NSDictionary *applicationTree = [self.testedApplication fb_tree:[NSSet setWithArray:@[@"visible"]]];
|
||||
XCTAssertNotNil(applicationTree);
|
||||
XCTAssertNil([applicationTree objectForKey:@"isVisible"], @"'isVisible' key should not be present in the application tree");
|
||||
}
|
||||
|
||||
- (void)testDeactivateApplication
|
||||
{
|
||||
NSError *error;
|
||||
uint64_t timeStarted = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW);
|
||||
NSTimeInterval backgroundDuration = 5.0;
|
||||
XCTAssertTrue([self.testedApplication fb_deactivateWithDuration:backgroundDuration error:&error]);
|
||||
NSTimeInterval timeElapsed = (clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) - timeStarted) / NSEC_PER_SEC;
|
||||
XCTAssertNil(error);
|
||||
XCTAssertEqualWithAccuracy(timeElapsed, backgroundDuration, 3.0);
|
||||
XCTAssertTrue(self.testedApplication.buttons[@"Alerts"].exists);
|
||||
}
|
||||
|
||||
- (void)testActiveApplication
|
||||
{
|
||||
XCUIApplication *systemApp = XCUIApplication.fb_systemApplication;
|
||||
XCTAssertTrue([XCUIApplication fb_activeApplication].buttons[@"Alerts"].fb_isVisible);
|
||||
[self goToSpringBoardFirstPage];
|
||||
XCTAssertEqualObjects([XCUIApplication fb_activeApplication].bundleID, systemApp.bundleID);
|
||||
XCTAssertTrue(systemApp.icons[@"Safari"].fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)testActiveElement
|
||||
{
|
||||
[self goToAttributesPage];
|
||||
XCTAssertNil(self.testedApplication.fb_activeElement);
|
||||
XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
|
||||
[textField tap];
|
||||
FBAssertWaitTillBecomesTrue(nil != self.testedApplication.fb_activeElement);
|
||||
XCTAssertEqualObjects(((id<FBElement>)self.testedApplication.fb_activeElement).wdUID,
|
||||
((id<FBElement>)textField).wdUID);
|
||||
}
|
||||
|
||||
- (void)testActiveApplicationsInfo
|
||||
{
|
||||
NSArray *appsInfo = [XCUIApplication fb_activeAppsInfo];
|
||||
XCTAssertTrue(appsInfo.count > 0);
|
||||
BOOL isAppActive = NO;
|
||||
for (NSDictionary *appInfo in appsInfo) {
|
||||
if ([appInfo[@"bundleId"] isEqualToString:self.testedApplication.bundleID]) {
|
||||
isAppActive = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XCTAssertTrue(isAppActive);
|
||||
}
|
||||
|
||||
- (void)testTestmanagerdVersion
|
||||
{
|
||||
XCTAssertGreaterThan(FBTestmanagerdVersion(), 0);
|
||||
}
|
||||
|
||||
- (void)testAccessbilityAudit
|
||||
{
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"17.0")) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
NSArray *auditIssues1 = [XCUIApplication.fb_activeApplication fb_performAccessibilityAuditWithAuditTypes:~0UL
|
||||
error:&error];
|
||||
XCTAssertNotNil(auditIssues1);
|
||||
XCTAssertNil(error);
|
||||
|
||||
NSMutableSet *set = [NSMutableSet new];
|
||||
[set addObject:@"XCUIAccessibilityAuditTypeAll"];
|
||||
NSArray *auditIssues2 = [XCUIApplication.fb_activeApplication fb_performAccessibilityAuditWithAuditTypesSet:set.copy
|
||||
error:&error];
|
||||
// 'elementDescription' is not in this list because it could have
|
||||
// different object id's debug description in XCTest.
|
||||
NSArray *checkKeys = @[
|
||||
@"auditType",
|
||||
@"compactDescription",
|
||||
@"detailedDescription",
|
||||
@"element",
|
||||
@"elementAttributes"
|
||||
];
|
||||
|
||||
XCTAssertEqual([auditIssues1 count], [auditIssues2 count]);
|
||||
for (int i = 1; i < [auditIssues1 count]; i++) {
|
||||
for (NSString *k in checkKeys) {
|
||||
XCTAssertEqualObjects(
|
||||
[auditIssues1[i] objectForKey:k],
|
||||
[auditIssues2[i] objectForKey:k]
|
||||
);
|
||||
}
|
||||
}
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "XCUIDevice+FBHealthCheck.h"
|
||||
#import "XCUIElement.h"
|
||||
|
||||
@interface XCUIDeviceHealthCheckTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCUIDeviceHealthCheckTests
|
||||
|
||||
- (void)testHealthCheck
|
||||
{
|
||||
[self launchApplication];
|
||||
XCTAssertTrue(self.testedApplication.exists);
|
||||
XCTAssertTrue([[XCUIDevice sharedDevice] fb_healthCheckWithApplication:self.testedApplication]);
|
||||
}
|
||||
|
||||
@end
|
||||
220
WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m
Normal file
220
WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBImageUtils.h"
|
||||
#import "FBMacros.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIApplication.h"
|
||||
#import "XCUIApplication+FBHelpers.h"
|
||||
#import "XCUIDevice+FBHelpers.h"
|
||||
#import "XCUIDevice+FBRotation.h"
|
||||
#import "XCUIScreen.h"
|
||||
|
||||
@interface XCUIDeviceHelperTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCUIDeviceHelperTests
|
||||
|
||||
- (void)restorePortraitOrientation
|
||||
{
|
||||
if ([XCUIDevice sharedDevice].orientation != UIDeviceOrientationPortrait) {
|
||||
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:UIDeviceOrientationPortrait];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
[self restorePortraitOrientation];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self restorePortraitOrientation];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testScreenshot
|
||||
{
|
||||
NSError *error = nil;
|
||||
NSData *screenshotData = [[XCUIDevice sharedDevice] fb_screenshotWithError:&error];
|
||||
XCTAssertNotNil(screenshotData);
|
||||
XCTAssertNil(error);
|
||||
XCTAssertTrue(FBIsPngImage(screenshotData));
|
||||
|
||||
UIImage *screenshot = [UIImage imageWithData:screenshotData];
|
||||
XCTAssertNotNil(screenshot);
|
||||
|
||||
XCUIScreen *mainScreen = XCUIScreen.mainScreen;
|
||||
UIImage *screenshotExact = ((XCUIScreenshot *)mainScreen.screenshot).image;
|
||||
XCTAssertEqualWithAccuracy(screenshotExact.size.height * mainScreen.scale,
|
||||
screenshot.size.height,
|
||||
FLT_EPSILON);
|
||||
XCTAssertEqualWithAccuracy(screenshotExact.size.width * mainScreen.scale,
|
||||
screenshot.size.width,
|
||||
FLT_EPSILON);
|
||||
}
|
||||
|
||||
- (void)testLandscapeScreenshot
|
||||
{
|
||||
XCTAssertTrue([[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:UIDeviceOrientationLandscapeLeft]);
|
||||
NSError *error = nil;
|
||||
NSData *screenshotData = [[XCUIDevice sharedDevice] fb_screenshotWithError:&error];
|
||||
XCTAssertNotNil(screenshotData);
|
||||
XCTAssertTrue(FBIsPngImage(screenshotData));
|
||||
XCTAssertNil(error);
|
||||
|
||||
UIImage *screenshot = [UIImage imageWithData:screenshotData];
|
||||
XCTAssertNotNil(screenshot);
|
||||
XCTAssertTrue(screenshot.size.width > screenshot.size.height);
|
||||
|
||||
XCUIScreen *mainScreen = XCUIScreen.mainScreen;
|
||||
UIImage *screenshotExact = ((XCUIScreenshot *)mainScreen.screenshot).image;
|
||||
CGSize realMainScreenSize = screenshotExact.size.height > screenshot.size.width
|
||||
? CGSizeMake(screenshotExact.size.height * mainScreen.scale, screenshotExact.size.width * mainScreen.scale)
|
||||
: CGSizeMake(screenshotExact.size.width * mainScreen.scale, screenshotExact.size.height * mainScreen.scale);
|
||||
XCTAssertEqualWithAccuracy(realMainScreenSize.height, screenshot.size.height, FLT_EPSILON);
|
||||
XCTAssertEqualWithAccuracy(realMainScreenSize.width, screenshot.size.width, FLT_EPSILON);
|
||||
}
|
||||
|
||||
- (void)testWifiAddress
|
||||
{
|
||||
NSString *adderss = [XCUIDevice sharedDevice].fb_wifiIPAddress;
|
||||
if (!adderss) {
|
||||
return;
|
||||
}
|
||||
NSRange range = [adderss rangeOfString:@"^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})" options:NSRegularExpressionSearch];
|
||||
XCTAssertTrue(range.location != NSNotFound);
|
||||
}
|
||||
|
||||
- (void)testGoToHomeScreen
|
||||
{
|
||||
NSError *error;
|
||||
XCTAssertTrue([[XCUIDevice sharedDevice] fb_goToHomescreenWithError:&error]);
|
||||
XCTAssertNil(error);
|
||||
FBAssertWaitTillBecomesTrue([XCUIApplication fb_activeApplication].icons[@"Safari"].exists);
|
||||
}
|
||||
|
||||
- (void)testLockUnlockScreen
|
||||
{
|
||||
XCTAssertFalse([[XCUIDevice sharedDevice] fb_isScreenLocked]);
|
||||
NSError *error;
|
||||
XCTAssertTrue([[XCUIDevice sharedDevice] fb_lockScreen:&error]);
|
||||
XCTAssertTrue([[XCUIDevice sharedDevice] fb_isScreenLocked]);
|
||||
XCTAssertNil(error);
|
||||
XCTAssertTrue([[XCUIDevice sharedDevice] fb_unlockScreen:&error]);
|
||||
XCTAssertFalse([[XCUIDevice sharedDevice] fb_isScreenLocked]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testUrlSchemeActivation
|
||||
{
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"16.4")) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
XCTAssertTrue([XCUIDevice.sharedDevice fb_openUrl:@"https://apple.com" error:&error]);
|
||||
FBAssertWaitTillBecomesTrue([XCUIApplication.fb_activeApplication.bundleID isEqualToString:@"com.apple.mobilesafari"]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testUrlSchemeActivationWithApp
|
||||
{
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"16.4")) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
XCTAssertTrue([XCUIDevice.sharedDevice fb_openUrl:@"https://apple.com"
|
||||
withApplication:@"com.apple.mobilesafari"
|
||||
error:&error]);
|
||||
FBAssertWaitTillBecomesTrue([XCUIApplication.fb_activeApplication.bundleID isEqualToString:@"com.apple.mobilesafari"]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (void)testSimulatedLocationSetup
|
||||
{
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"16.4")) {
|
||||
return;
|
||||
}
|
||||
|
||||
CLLocation *simulatedLocation = [[CLLocation alloc] initWithLatitude:50 longitude:50];
|
||||
NSError *error;
|
||||
XCTAssertTrue([XCUIDevice.sharedDevice fb_setSimulatedLocation:simulatedLocation error:&error]);
|
||||
XCTAssertNil(error);
|
||||
CLLocation *currentLocation = [XCUIDevice.sharedDevice fb_getSimulatedLocation:&error];
|
||||
XCTAssertNil(error);
|
||||
XCTAssertNotNil(currentLocation);
|
||||
XCTAssertEqualWithAccuracy(simulatedLocation.coordinate.latitude, currentLocation.coordinate.latitude, 0.1);
|
||||
XCTAssertEqualWithAccuracy(simulatedLocation.coordinate.longitude, currentLocation.coordinate.longitude, 0.1);
|
||||
XCTAssertTrue([XCUIDevice.sharedDevice fb_clearSimulatedLocation:&error]);
|
||||
XCTAssertNil(error);
|
||||
currentLocation = [XCUIDevice.sharedDevice fb_getSimulatedLocation:&error];
|
||||
XCTAssertNil(error);
|
||||
XCTAssertNotEqualWithAccuracy(simulatedLocation.coordinate.latitude, currentLocation.coordinate.latitude, 0.1);
|
||||
XCTAssertNotEqualWithAccuracy(simulatedLocation.coordinate.longitude, currentLocation.coordinate.longitude, 0.1);
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)testPressingUnsupportedButton
|
||||
{
|
||||
NSError *error;
|
||||
NSNumber *duration = nil;
|
||||
XCTAssertFalse([XCUIDevice.sharedDevice fb_pressButton:@"volumeUpp"
|
||||
forDuration:duration
|
||||
error:&error]);
|
||||
XCTAssertNotNil(error);
|
||||
}
|
||||
|
||||
- (void)testPressingSupportedButton
|
||||
{
|
||||
NSError *error;
|
||||
XCTAssertTrue([XCUIDevice.sharedDevice fb_pressButton:@"home"
|
||||
forDuration:nil
|
||||
error:&error]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testPressingSupportedButtonNumber
|
||||
{
|
||||
NSError *error;
|
||||
XCTAssertTrue([XCUIDevice.sharedDevice fb_pressButton:@"home"
|
||||
forDuration:[NSNumber numberWithDouble:1.0]
|
||||
error:&error]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testLongPressHomeButton
|
||||
{
|
||||
NSError *error;
|
||||
// kHIDPage_Consumer = 0x0C
|
||||
// kHIDUsage_Csmr_Menu = 0x40
|
||||
XCTAssertTrue([XCUIDevice.sharedDevice fb_performIOHIDEventWithPage:0x0C
|
||||
usage:0x40
|
||||
duration:1.0
|
||||
error:&error]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
- (void)testAppearance
|
||||
{
|
||||
if (SYSTEM_VERSION_LESS_THAN(@"15.0")) {
|
||||
return;
|
||||
}
|
||||
NSError *error;
|
||||
XCTAssertTrue([XCUIDevice.sharedDevice fb_setAppearance:FBUIInterfaceAppearanceDark error:&error]);
|
||||
XCTAssertNil(error);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "XCUIDevice+FBRotation.h"
|
||||
|
||||
@interface XCUIDeviceRotationTests : FBIntegrationTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation XCUIDeviceRotationTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[self resetOrientation];
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testLandscapeRightOrientation
|
||||
{
|
||||
BOOL success = [[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:UIDeviceOrientationLandscapeRight];
|
||||
XCTAssertTrue(success, @"Device should support LandscapeRight");
|
||||
// Device rotation gives opposite interface rotation
|
||||
XCTAssertTrue(self.testedApplication.staticTexts[@"LandscapeLeft"].exists);
|
||||
}
|
||||
|
||||
- (void)testLandscapeLeftOrientation
|
||||
{
|
||||
BOOL success = [[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:UIDeviceOrientationLandscapeLeft];
|
||||
XCTAssertTrue(success, @"Device should support LandscapeLeft");
|
||||
// Device rotation gives opposite interface rotation
|
||||
XCTAssertTrue(self.testedApplication.staticTexts[@"LandscapeRight"].exists);
|
||||
}
|
||||
|
||||
- (void)testLandscapeRightRotation
|
||||
{
|
||||
BOOL success = [[XCUIDevice sharedDevice] fb_setDeviceRotation:@{
|
||||
@"x" : @(0),
|
||||
@"y" : @(0),
|
||||
@"z" : @(90)
|
||||
}];
|
||||
XCTAssertTrue(success, @"Device should support LandscapeRight");
|
||||
// Device rotation gives opposite interface rotation
|
||||
XCTAssertTrue(self.testedApplication.staticTexts[@"LandscapeLeft"].exists);
|
||||
}
|
||||
|
||||
- (void)testLandscapeLeftRotation
|
||||
{
|
||||
BOOL success = [[XCUIDevice sharedDevice] fb_setDeviceRotation:@{
|
||||
@"x" : @(0),
|
||||
@"y" : @(0),
|
||||
@"z" : @(270)
|
||||
}];
|
||||
XCTAssertTrue(success, @"Device should support LandscapeLeft");
|
||||
// Device rotation gives opposite interface rotation
|
||||
XCTAssertTrue(self.testedApplication.staticTexts[@"LandscapeRight"].exists);
|
||||
}
|
||||
|
||||
- (void)testRotationTiltRotation
|
||||
{
|
||||
UIDeviceOrientation currentRotation = [XCUIDevice sharedDevice].orientation;
|
||||
BOOL success = [[XCUIDevice sharedDevice] fb_setDeviceRotation:@{
|
||||
@"x" : @(15),
|
||||
@"y" : @(0),
|
||||
@"z" : @(0)}
|
||||
];
|
||||
XCTAssertFalse(success, @"Device should not support tilt");
|
||||
XCTAssertEqual(currentRotation, [XCUIDevice sharedDevice].orientation, @"Device doesnt support tilt, should be at previous orientation");
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIElement+FBWebDriverAttributes.h"
|
||||
#import "XCUIElement+FBFind.h"
|
||||
#import "FBElementUtils.h"
|
||||
#import "FBConfiguration.h"
|
||||
#import "FBResponsePayload.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
@interface XCUIElementAttributesTests : FBIntegrationTestCase
|
||||
@property (nonatomic, strong) XCUIElement *matchingElement;
|
||||
@end
|
||||
|
||||
@implementation XCUIElementAttributesTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
});
|
||||
XCUIElement *testedView = self.testedApplication.otherElements[@"MainView"];
|
||||
FBAssertWaitTillBecomesTrue(testedView.exists);
|
||||
self.matchingElement = [[testedView fb_descendantsMatchingIdentifier:@"Alerts" shouldReturnAfterFirstMatch:YES] firstObject];
|
||||
XCTAssertNotNil(self.matchingElement);
|
||||
}
|
||||
|
||||
- (void)verifyGettingAttributeWithShortcut:(NSString *)shortcutName expectedValue:(id)expectedValue
|
||||
{
|
||||
NSString *fullAttributeName = [NSString stringWithFormat:@"wd%@", [NSString stringWithFormat:@"%@%@", [[shortcutName substringToIndex:1] uppercaseString], [shortcutName substringFromIndex:1]]];
|
||||
id actualValue = [self.matchingElement fb_valueForWDAttributeName:fullAttributeName];
|
||||
id actualShortcutValue = [self.matchingElement fb_valueForWDAttributeName:shortcutName];
|
||||
if (nil == expectedValue) {
|
||||
XCTAssertNil(actualValue);
|
||||
XCTAssertNil(actualShortcutValue);
|
||||
return;
|
||||
}
|
||||
if ([actualValue isKindOfClass:NSString.class]) {
|
||||
XCTAssertTrue([actualValue isEqualToString:expectedValue]);
|
||||
XCTAssertTrue([actualShortcutValue isEqualToString:expectedValue]);
|
||||
} else if ([actualValue isKindOfClass:NSNumber.class]) {
|
||||
XCTAssertTrue([actualValue isEqualToNumber:expectedValue]);
|
||||
XCTAssertTrue([actualShortcutValue isEqualToNumber:expectedValue]);
|
||||
} else {
|
||||
XCTAssertEqual(actualValue, expectedValue);
|
||||
XCTAssertEqual(actualShortcutValue, expectedValue);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testGetNameAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"name" expectedValue:self.matchingElement.wdName];
|
||||
}
|
||||
|
||||
- (void)testGetValueAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"value" expectedValue:self.matchingElement.wdValue];
|
||||
}
|
||||
|
||||
- (void)testGetLabelAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"label" expectedValue:self.matchingElement.wdLabel];
|
||||
}
|
||||
|
||||
- (void)testGetTypeAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"type" expectedValue:self.matchingElement.wdType];
|
||||
}
|
||||
|
||||
- (void)testGetRectAttribute
|
||||
{
|
||||
NSString *shortcutName = @"rect";
|
||||
for (NSString *key in @[@"x", @"y", @"width", @"height"]) {
|
||||
NSNumber *actualValue = [self.matchingElement fb_valueForWDAttributeName:[FBElementUtils wdAttributeNameForAttributeName:shortcutName]][key];
|
||||
NSNumber *actualShortcutValue = [self.matchingElement fb_valueForWDAttributeName:shortcutName][key];
|
||||
NSNumber *expectedValue = self.matchingElement.wdRect[key];
|
||||
XCTAssertTrue([actualValue isEqualToNumber:expectedValue]);
|
||||
XCTAssertTrue([actualShortcutValue isEqualToNumber:expectedValue]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testGetEnabledAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"enabled" expectedValue:[NSNumber numberWithBool:self.matchingElement.wdEnabled]];
|
||||
}
|
||||
|
||||
- (void)testGetAccessibleAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"accessible" expectedValue:[NSNumber numberWithBool:self.matchingElement.wdAccessible]];
|
||||
}
|
||||
|
||||
- (void)testGetUidAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"UID" expectedValue:self.matchingElement.wdUID];
|
||||
}
|
||||
|
||||
- (void)testGetVisibleAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"visible" expectedValue:[NSNumber numberWithBool:self.matchingElement.wdVisible]];
|
||||
}
|
||||
|
||||
- (void)testGetAccessibilityContainerAttribute
|
||||
{
|
||||
[self verifyGettingAttributeWithShortcut:@"accessibilityContainer" expectedValue:[NSNumber numberWithBool:self.matchingElement.wdAccessibilityContainer]];
|
||||
}
|
||||
|
||||
- (void)testGetInvalidAttribute
|
||||
{
|
||||
XCTAssertThrowsSpecificNamed([self verifyGettingAttributeWithShortcut:@"invalid" expectedValue:@"blabla"], NSException, FBUnknownAttributeException);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface XCUIElementFBFindTests_CompactResponses : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
|
||||
@implementation XCUIElementFBFindTests_CompactResponses
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testCompactResponseYes
|
||||
{
|
||||
XCUIElement *alertsButton = self.testedApplication.buttons[@"Alerts"];
|
||||
NSDictionary *fields = FBDictionaryResponseWithElement(alertsButton, YES);
|
||||
XCTAssertNotNil(fields[@"ELEMENT"]);
|
||||
XCTAssertNotNil(fields[@"element-6066-11e4-a52e-4f735466cecf"]);
|
||||
XCTAssertEqual(fields.count, 2);
|
||||
}
|
||||
|
||||
- (void)testCompactResponseNo
|
||||
{
|
||||
XCUIElement *alertsButton = self.testedApplication.buttons[@"Alerts"];
|
||||
NSDictionary *fields = FBDictionaryResponseWithElement(alertsButton, NO);
|
||||
XCTAssertNotNil(fields[@"ELEMENT"]);
|
||||
XCTAssertNotNil(fields[@"element-6066-11e4-a52e-4f735466cecf"]);
|
||||
XCTAssertEqualObjects(fields[@"type"], @"XCUIElementTypeButton");
|
||||
XCTAssertEqualObjects(fields[@"label"], @"Alerts");
|
||||
XCTAssertEqual(fields.count, 4);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface XCUIElementFBFindTests_ResponseFields : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCUIElementFBFindTests_ResponseFields
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testCompactResponseYesWithResponseAttributesSet
|
||||
{
|
||||
[FBConfiguration setElementResponseAttributes:@"name,text,enabled"];
|
||||
XCUIElement *alertsButton = self.testedApplication.buttons[@"Alerts"];
|
||||
NSDictionary *fields = FBDictionaryResponseWithElement(alertsButton, YES);
|
||||
XCTAssertNotNil(fields[@"ELEMENT"]);
|
||||
XCTAssertNotNil(fields[@"element-6066-11e4-a52e-4f735466cecf"]);
|
||||
XCTAssertEqual(fields.count, 2);
|
||||
}
|
||||
|
||||
- (void)testCompactResponseNoWithResponseAttributesSet
|
||||
{
|
||||
[FBConfiguration setElementResponseAttributes:@"name,text,enabled"];
|
||||
XCUIElement *alertsButton = self.testedApplication.buttons[@"Alerts"];
|
||||
NSDictionary *fields = FBDictionaryResponseWithElement(alertsButton, NO);
|
||||
XCTAssertNotNil(fields[@"ELEMENT"]);
|
||||
XCTAssertNotNil(fields[@"element-6066-11e4-a52e-4f735466cecf"]);
|
||||
XCTAssertEqualObjects(fields[@"name"], @"XCUIElementTypeButton");
|
||||
XCTAssertEqualObjects(fields[@"text"], @"Alerts");
|
||||
XCTAssertEqualObjects(fields[@"enabled"], @(YES));
|
||||
XCTAssertEqual(fields.count, 5);
|
||||
}
|
||||
|
||||
- (void)testInvalidAttribute
|
||||
{
|
||||
[FBConfiguration setElementResponseAttributes:@"invalid_field,name"];
|
||||
XCUIElement *alertsButton = self.testedApplication.buttons[@"Alerts"];
|
||||
NSDictionary *fields = FBDictionaryResponseWithElement(alertsButton, NO);
|
||||
XCTAssertNotNil(fields[@"ELEMENT"]);
|
||||
XCTAssertNotNil(fields[@"element-6066-11e4-a52e-4f735466cecf"]);
|
||||
XCTAssertEqualObjects(fields[@"name"], @"XCUIElementTypeButton");
|
||||
XCTAssertEqual(fields.count, 3);
|
||||
}
|
||||
|
||||
- (void)testKnownAttributes
|
||||
{
|
||||
[FBConfiguration setElementResponseAttributes:@"name,type,label,text,rect,enabled,displayed,selected"];
|
||||
XCUIElement *alertsButton = self.testedApplication.buttons[@"Alerts"];
|
||||
NSDictionary *fields = FBDictionaryResponseWithElement(alertsButton, NO);
|
||||
XCTAssertNotNil(fields[@"ELEMENT"]);
|
||||
XCTAssertNotNil(fields[@"element-6066-11e4-a52e-4f735466cecf"]);
|
||||
XCTAssertEqualObjects(fields[@"name"], @"XCUIElementTypeButton");
|
||||
XCTAssertEqualObjects(fields[@"type"], @"XCUIElementTypeButton");
|
||||
XCTAssertEqualObjects(fields[@"label"], @"Alerts");
|
||||
XCTAssertEqualObjects(fields[@"text"], @"Alerts");
|
||||
XCTAssertTrue(matchesRegex([fields[@"rect"] description], @"\\{\\s*height = [0-9]+;\\s*width = [0-9]+;\\s*x = [0-9]+;\\s*y = [0-9]+;\\s*\\}"));
|
||||
XCTAssertEqualObjects(fields[@"enabled"], @(YES));
|
||||
XCTAssertEqualObjects(fields[@"displayed"], @(YES));
|
||||
XCTAssertEqualObjects(fields[@"selected"], @(NO));
|
||||
XCTAssertEqual(fields.count, 10);
|
||||
}
|
||||
|
||||
- (void)testArbitraryAttributes
|
||||
{
|
||||
[FBConfiguration setElementResponseAttributes:@"attribute/name,attribute/value"];
|
||||
XCUIElement *alertsButton = self.testedApplication.buttons[@"Alerts"];
|
||||
NSDictionary *fields = FBDictionaryResponseWithElement(alertsButton, NO);
|
||||
XCTAssertNotNil(fields[@"ELEMENT"]);
|
||||
XCTAssertNotNil(fields[@"element-6066-11e4-a52e-4f735466cecf"]);
|
||||
XCTAssertEqualObjects(fields[@"attribute/name"], @"Alerts");
|
||||
XCTAssertEqualObjects(fields[@"attribute/value"], [NSNull null]);
|
||||
XCTAssertEqual(fields.count, 4);
|
||||
}
|
||||
|
||||
static BOOL matchesRegex(NSString *target, NSString *pattern) {
|
||||
if (!target)
|
||||
return NO;
|
||||
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:NULL];
|
||||
return [regex numberOfMatchesInString:target options:0 range:NSMakeRange(0, target.length)] == 1;
|
||||
}
|
||||
|
||||
@end
|
||||
472
WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m
Normal file
472
WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m
Normal file
@@ -0,0 +1,472 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBElementUtils.h"
|
||||
#import "FBExceptions.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "XCUIElement.h"
|
||||
#import "XCUIElement+FBFind.h"
|
||||
#import "XCUIElement+FBUID.h"
|
||||
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
||||
#import "XCUIElement+FBIsVisible.h"
|
||||
#import "XCUIElement+FBClassChain.h"
|
||||
#import "XCUIElement+FBResolve.h"
|
||||
#import "FBXPath.h"
|
||||
#import "FBXCodeCompatibility.h"
|
||||
|
||||
@interface XCUIElementFBFindTests : FBIntegrationTestCase
|
||||
@property (nonatomic, strong) XCUIElement *testedView;
|
||||
@end
|
||||
|
||||
@implementation XCUIElementFBFindTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
});
|
||||
self.testedView = self.testedApplication.otherElements[@"MainView"];
|
||||
FBAssertWaitTillBecomesTrue(self.testedView.exists);
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithClassName
|
||||
{
|
||||
NSSet<NSString *> *expectedLabels = [NSSet setWithArray:@[
|
||||
@"Alerts",
|
||||
@"Attributes",
|
||||
@"Scrolling",
|
||||
@"Deadlock app",
|
||||
@"Touch",
|
||||
]];
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingClassName:@"XCUIElementTypeButton"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, expectedLabels.count);
|
||||
NSArray<NSString *> *labels = [matchingSnapshots valueForKeyPath:@"@distinctUnionOfObjects.label"];
|
||||
XCTAssertEqualObjects([NSSet setWithArray:labels], expectedLabels);
|
||||
|
||||
NSArray<NSNumber *> *types = [matchingSnapshots valueForKeyPath:@"@distinctUnionOfObjects.elementType"];
|
||||
XCTAssertEqual(types.count, 1, @"matchingSnapshots should contain only one type");
|
||||
XCTAssertEqualObjects(types.lastObject, @(XCUIElementTypeButton), @"matchingSnapshots should contain only one type");
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithClassName
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingClassName:@"XCUIElementTypeButton"
|
||||
shouldReturnAfterFirstMatch:YES];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithIdentifier
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
int snapshotsCount = 2;
|
||||
XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
|
||||
XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
|
||||
NSArray<XCUIElement *> *selfElementsById = [matchingSnapshots.lastObject fb_descendantsMatchingIdentifier:@"Alerts" shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(selfElementsById.count, 1);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithIdentifier
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts"
|
||||
shouldReturnAfterFirstMatch:YES];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
|
||||
}
|
||||
|
||||
- (void)testStableInstance
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts"
|
||||
shouldReturnAfterFirstMatch:YES];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
for (XCUIElement *el in @[
|
||||
matchingSnapshots.lastObject,
|
||||
[matchingSnapshots.lastObject fb_stableInstanceWithUid:[matchingSnapshots.lastObject fb_uid]]
|
||||
]) {
|
||||
XCTAssertEqual(el.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(el.label, @"Alerts");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithMissingIdentifier
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"blabla" shouldReturnAfterFirstMatch:YES];
|
||||
XCTAssertEqual(matchingSnapshots.count, 0);
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithXPathQuery
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Alerts']"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
|
||||
}
|
||||
|
||||
- (void)testSelfWithXPathQuery
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeApplication"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeApplication);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithXPathQuery
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@hittable='true']"
|
||||
shouldReturnAfterFirstMatch:YES];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCUIElement *matchingSnapshot = [matchingSnapshots firstObject];
|
||||
XCTAssertNotNil(matchingSnapshot);
|
||||
XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(matchingSnapshot.label, @"Alerts");
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithXPathQueryNoMatches
|
||||
{
|
||||
XCUIElement *matchingSnapshot = [[self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButtonnn"
|
||||
shouldReturnAfterFirstMatch:YES] firstObject];
|
||||
XCTAssertNil(matchingSnapshot);
|
||||
}
|
||||
|
||||
- (void)testSingleLastDescendantWithXPathQuery
|
||||
{
|
||||
XCUIElement *matchingSnapshot = [[self.testedView fb_descendantsMatchingXPathQuery:@"(//XCUIElementTypeButton)[last()]"
|
||||
shouldReturnAfterFirstMatch:YES] firstObject];
|
||||
XCTAssertNotNil(matchingSnapshot);
|
||||
XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton);
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithXPathQueryNoMatches
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Alerts1']"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 0);
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithComplexXPathQuery
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//*[@label='Scrolling']/preceding::*[boolean(string(@label))]"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
int snapshotsCount = 6;
|
||||
XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithWrongXPathQuery
|
||||
{
|
||||
XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingXPathQuery:@"//*[blabla(@label, Scrolling')]"
|
||||
shouldReturnAfterFirstMatch:NO],
|
||||
NSException, FBInvalidXPathException);
|
||||
}
|
||||
|
||||
- (void)testFirstDescendantWithWrongXPathQuery
|
||||
{
|
||||
XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingXPathQuery:@"//*[blabla(@label, Scrolling')]"
|
||||
shouldReturnAfterFirstMatch:YES],
|
||||
NSException, FBInvalidXPathException);
|
||||
}
|
||||
|
||||
- (void)testVisibleDescendantWithXPathQuery
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@name='Alerts' and @enabled='true' and @visible='true']" shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertTrue(matchingSnapshots.lastObject.isEnabled);
|
||||
XCTAssertTrue(matchingSnapshots.lastObject.fb_isVisible);
|
||||
XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithPredicateString
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"label = 'Alerts'"];
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingPredicate:predicate
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
int snapshotsCount = 2;
|
||||
XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
|
||||
XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
|
||||
NSPredicate *selfPredicate = [NSPredicate predicateWithFormat:@"label == 'Alerts'"];
|
||||
NSArray<XCUIElement *> *selfElementsByPredicate = [matchingSnapshots.lastObject fb_descendantsMatchingPredicate:selfPredicate
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(selfElementsByPredicate.count, 1);
|
||||
}
|
||||
|
||||
- (void)testSelfWithPredicateString
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == 'XCUIElementTypeApplication'"];
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingPredicate:predicate
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeApplication);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithPredicateString
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type = 'XCUIElementTypeButton'"];
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingPredicate:predicate shouldReturnAfterFirstMatch:YES];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithPredicateStringByIndex
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == 'XCUIElementTypeButton' AND index == 2"];
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingPredicate:predicate shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithPropertyStrict
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label"
|
||||
value:@"Alert"
|
||||
partialSearch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 0);
|
||||
matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label" value:@"Alerts" partialSearch:NO];
|
||||
int snapshotsCount = 2;
|
||||
XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
|
||||
XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
|
||||
}
|
||||
|
||||
- (void)testGlobalWithPropertyStrict
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingProperty:@"label"
|
||||
value:@"Alert"
|
||||
partialSearch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 0);
|
||||
matchingSnapshots = [self.testedApplication fb_descendantsMatchingProperty:@"label" value:@"Alerts" partialSearch:NO];
|
||||
int snapshotsCount = 2;
|
||||
XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
|
||||
XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithPropertyPartial
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label"
|
||||
value:@"Alerts"
|
||||
partialSearch:NO];
|
||||
int snapshotsCount = 2;
|
||||
XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
|
||||
XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithClassChain
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots;
|
||||
NSString *queryString =@"XCUIElementTypeWindow/XCUIElementTypeOther/**/XCUIElementTypeButton";
|
||||
matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 5); // /XCUIElementTypeButton
|
||||
for (XCUIElement *matchingSnapshot in matchingSnapshots) {
|
||||
XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithClassChainWithIndex
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots;
|
||||
// iPhone
|
||||
NSString *queryString = @"XCUIElementTypeWindow/*/*/*/*[2]/*/*/XCUIElementTypeButton";
|
||||
matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
if (matchingSnapshots.count == 0) {
|
||||
// iPad
|
||||
queryString = @"XCUIElementTypeWindow/*/*/*/*/*[2]/*/*/XCUIElementTypeButton";
|
||||
matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
}
|
||||
XCTAssertEqual(matchingSnapshots.count, 5); // /XCUIElementTypeButton
|
||||
for (XCUIElement *matchingSnapshot in matchingSnapshots) {
|
||||
XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithClassChainAndPredicates
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots;
|
||||
NSString *queryString = @"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]";
|
||||
matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 2);
|
||||
XCTAssertEqualObjects([matchingSnapshots firstObject].label, @"Alerts");
|
||||
XCTAssertEqualObjects([matchingSnapshots lastObject].label, @"Attributes");
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithIndirectClassChainAndPredicates
|
||||
{
|
||||
NSString *queryString = @"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]";
|
||||
NSArray<XCUIElement *> *simpleQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:queryString
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
NSArray<XCUIElement *> *deepQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(simpleQueryMatches.count, deepQueryMatches.count);
|
||||
XCTAssertEqualObjects([simpleQueryMatches firstObject].label, [deepQueryMatches firstObject].label);
|
||||
XCTAssertEqualObjects([simpleQueryMatches lastObject].label, [deepQueryMatches lastObject].label);
|
||||
}
|
||||
|
||||
- (void)testClassChainWithDescendantPredicate
|
||||
{
|
||||
NSArray<XCUIElement *> *simpleQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/*/*[1]"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
NSArray<XCUIElement *> *predicateQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/*/*[$type == 'XCUIElementTypeButton' AND label BEGINSWITH 'A'$]"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(simpleQueryMatches.count, predicateQueryMatches.count);
|
||||
XCTAssertEqual([simpleQueryMatches firstObject].elementType, [predicateQueryMatches firstObject].elementType);
|
||||
XCTAssertEqual([simpleQueryMatches lastObject].elementType, [predicateQueryMatches lastObject].elementType);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithComplexIndirectClassChain
|
||||
{
|
||||
NSArray<XCUIElement *> *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/*/XCUIElementTypeButton[2]"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(queryMatches.count, 1);
|
||||
XCTAssertEqual(queryMatches.lastObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertEqualObjects(queryMatches.lastObject.label, @"Deadlock app");
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithComplexIndirectClassChainAndZeroMatches
|
||||
{
|
||||
NSArray<XCUIElement *> *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/*/XCUIElementTypeWindow"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(queryMatches.count, 0);
|
||||
}
|
||||
|
||||
- (void)testDescendantsWithClassChainAndPredicatesAndIndexes
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots;
|
||||
NSString *queryString = @"XCUIElementTypeWindow[`name != 'bla'`]/**/XCUIElementTypeButton[`label BEGINSWITH \"A\"`][1]";
|
||||
matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqualObjects([matchingSnapshots firstObject].label, @"Alerts");
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithClassChain
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton"
|
||||
shouldReturnAfterFirstMatch:YES];
|
||||
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertTrue([matchingSnapshots.lastObject.label isEqualToString:@"Alerts"]);
|
||||
}
|
||||
|
||||
- (void)testSingleDescendantWithClassChainAndNegativeIndex
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots;
|
||||
matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton[-1]"
|
||||
shouldReturnAfterFirstMatch:YES];
|
||||
|
||||
XCTAssertEqual(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
|
||||
XCTAssertTrue([matchingSnapshots.lastObject.label isEqualToString:@"Touch"]);
|
||||
|
||||
matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton[-10]"
|
||||
shouldReturnAfterFirstMatch:YES];
|
||||
XCTAssertEqual(matchingSnapshots.count, 0);
|
||||
}
|
||||
|
||||
- (void)testInvalidQueryWithClassChain
|
||||
{
|
||||
XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingClassChain:@"NoXCUIElementTypePrefix"
|
||||
shouldReturnAfterFirstMatch:YES],
|
||||
NSException, FBClassChainQueryParseException);
|
||||
}
|
||||
|
||||
- (void)testHandleInvalidQueryWithClassChainAsNoElementWithoutError
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView
|
||||
fb_descendantsMatchingClassChain:@"XCUIElementTypeBlabla"
|
||||
shouldReturnAfterFirstMatch:YES];
|
||||
XCTAssertEqual(matchingSnapshots.count, 0);
|
||||
}
|
||||
|
||||
- (void)testClassChainWithInvalidPredicate
|
||||
{
|
||||
XCTAssertThrowsSpecificNamed([self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow[`bla != 'bla'`]"
|
||||
shouldReturnAfterFirstMatch:NO],
|
||||
NSException, FBUnknownAttributeException);;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface XCUIElementFBFindTests_AttributesPage : FBIntegrationTestCase
|
||||
@end
|
||||
@implementation XCUIElementFBFindTests_AttributesPage
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToAttributesPage];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testNestedQueryWithClassChain
|
||||
{
|
||||
NSString *queryString = @"XCUIElementTypePicker";
|
||||
FBAssertWaitTillBecomesTrue(self.testedApplication.buttons[@"Button"].fb_isVisible);
|
||||
XCUIElement *datePicker = [self.testedApplication
|
||||
descendantsMatchingType:XCUIElementTypeDatePicker].allElementsBoundByIndex.firstObject;
|
||||
NSArray<XCUIElement *> *matches = [datePicker fb_descendantsMatchingClassChain:queryString
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertEqual(matches.count, 1);
|
||||
|
||||
XCUIElementType expectedType = XCUIElementTypePicker;
|
||||
XCTAssertEqual([matches firstObject].elementType, expectedType);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface XCUIElementFBFindTests_ScrollPage : FBIntegrationTestCase
|
||||
@end
|
||||
@implementation XCUIElementFBFindTests_ScrollPage
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self launchApplication];
|
||||
[self goToScrollPageWithCells:YES];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)testInvisibleDescendantWithXPathQuery
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeStaticText[@visible='false']"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertGreaterThan(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeStaticText);
|
||||
XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible);
|
||||
}
|
||||
|
||||
- (void)testNonHittableDescendantWithXPathQuery
|
||||
{
|
||||
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeStaticText[@hittable='false']"
|
||||
shouldReturnAfterFirstMatch:NO];
|
||||
XCTAssertGreaterThan(matchingSnapshots.count, 1);
|
||||
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeStaticText);
|
||||
XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "XCTest/XCUIElementTypes.h"
|
||||
|
||||
#import "FBIntegrationTestCase.h"
|
||||
#import "FBTestMacros.h"
|
||||
#import "FBElement.h"
|
||||
#import "FBElementUtils.h"
|
||||
#import "FBXCElementSnapshot.h"
|
||||
#import "XCUIElement+FBUtilities.h"
|
||||
|
||||
@interface XCUIElementHelperIntegrationTests : FBIntegrationTestCase
|
||||
@end
|
||||
|
||||
@implementation XCUIElementHelperIntegrationTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
[self launchApplication];
|
||||
[self goToAlertsPage];
|
||||
}
|
||||
|
||||
- (void)testDescendantsFiltering
|
||||
{
|
||||
NSArray<XCUIElement *> *buttons = self.testedApplication.buttons.allElementsBoundByIndex;
|
||||
XCTAssertTrue(buttons.count > 0);
|
||||
NSArray<XCUIElement *> *windows = self.testedApplication.windows.allElementsBoundByIndex;
|
||||
XCTAssertTrue(windows.count > 0);
|
||||
|
||||
NSMutableArray<XCUIElement *> *allElements = [NSMutableArray array];
|
||||
[allElements addObjectsFromArray:buttons];
|
||||
[allElements addObjectsFromArray:windows];
|
||||
|
||||
NSMutableArray<id<FBXCElementSnapshot>> *buttonSnapshots = [NSMutableArray array];
|
||||
[buttonSnapshots addObject:[buttons.firstObject fb_customSnapshot]];
|
||||
|
||||
NSArray<XCUIElement *> *result = [self.testedApplication fb_filterDescendantsWithSnapshots:buttonSnapshots
|
||||
onlyChildren:NO];
|
||||
XCTAssertEqual(1, result.count);
|
||||
XCTAssertEqual([result.firstObject elementType], XCUIElementTypeButton);
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user