Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ - (BOOL)fb_deactivateWithDuration:(NSTimeInterval)duration error:(NSError **)err
}
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:MAX(duration, .0)]];
[self activate];
#if !TARGET_OS_TV && !TARGET_OS_WATCH
Comment thread
mykola-mokhnach marked this conversation as resolved.
Outdated
// Wait for the system transition before the next command resolves element frames.
// App quiescence alone can miss it: https://github.com/appium/appium/issues/22857.
[XCUIApplication.fb_systemApplication fb_waitUntilStableWithTimeout:
FBConfiguration.sharedInstance.animationCoolOffTimeout];
#endif
return YES;
}

Expand Down
12 changes: 12 additions & 0 deletions packages/webdriveragent/WebDriverAgentLib/Routing/FBSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#import "FBXCTestDaemonsProxy.h"
#import "XCUIApplication+FBQuiescence.h"
#import "XCUIElement.h"
#import "XCUIElement+FBUtilities.h"

/*!
The intial value for the default application property.
Expand Down Expand Up @@ -475,7 +476,18 @@ - (XCUIApplication *)launchApplicationWithBundleId:(NSString *)bundleIdentifier
- (XCUIApplication *)activateApplicationWithBundleId:(NSString *)bundleIdentifier
{
XCUIApplication *app = [self makeApplicationWithBundleId:bundleIdentifier];
#if !TARGET_OS_TV && !TARGET_OS_WATCH
XCUIApplicationState previousState = app.state;
#endif
[app activate];
#if !TARGET_OS_TV && !TARGET_OS_WATCH
if (previousState == XCUIApplicationStateRunningBackground
|| previousState == XCUIApplicationStateRunningBackgroundSuspended) {
// Resolve subsequent element frames only after the system's resume transition.
[XCUIApplication.fb_systemApplication fb_waitUntilStableWithTimeout:
FBConfiguration.sharedInstance.animationCoolOffTimeout];
}
#endif
return app;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@
#import <XCTest/XCTest.h>

#import <mach/mach_time.h>
#import <math.h>

#import "FBIntegrationTestCase.h"
#import "FBElement.h"
#import "FBSession.h"
#import "FBMacros.h"
#import "FBTestMacros.h"
#import "XCUIApplication.h"
#import "XCUIApplication+FBHelpers.h"
#import "XCUIElement+FBIsVisible.h"
#import "FBXCodeCompatibility.h"
#import "FBConfiguration.h"
#import "FBScreen.h"
#import "FBRunLoopSpinner.h"
#import "XCUIDevice+FBHinge.h"

void calculateMaxTreeDepth(NSDictionary *tree, NSNumber *currentDepth, NSNumber** maxDepth) {
if (nil == maxDepth) {
Expand Down Expand Up @@ -83,6 +89,75 @@ - (void)testDeactivateApplication
XCTAssertTrue(self.testedApplication.buttons[@"Alerts"].exists);
}

- (void)testInputAfterDeactivate
{
[self verifyInputAfterBackgroundUsingSession:NO];
}

- (void)testInputAfterSessionActivate
{
[self verifyInputAfterBackgroundUsingSession:YES];
}

- (void)verifyInputAfterBackgroundUsingSession:(BOOL)useSession
{
XCUIDevice *device = XCUIDevice.sharedDevice;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we skip this test in CI?

BOOL canFold = NO;
#if TARGET_OS_SIMULATOR
canFold = device.fb_canAttemptSimulatedHingeAngleInjection;
#endif
NSNumber *originalAngle = canFold ? [device fb_getSimulatedHingeAngle:nil] : nil;
NSNumber *originalDisplay = FBConfiguration.sharedInstance.currentDisplayId;
if (canFold) {
XCTAssertNotNil(originalAngle);
}
BOOL (^setAngleAndWait)(NSNumber *) = ^BOOL(NSNumber *angle) {
if (![device fb_setSimulatedHingeAngle:angle.doubleValue error:nil]) {
return NO;
}
return [[[FBRunLoopSpinner new] timeout:5] spinUntilTrue:^BOOL{
NSNumber *reading = [device fb_getSimulatedHingeAngle:nil];
return nil != reading && fabs(reading.doubleValue - angle.doubleValue) < 1;
}];
};
@try {
for (NSNumber *angle in (canFold ? @[@0, @90, @180] : @[@0])) {
if (canFold) {
XCTAssertTrue(setAngleAndWait(angle), @"Hinge did not reach %@ degrees", angle);
for (NSDictionary *screen in [FBScreen screensWithError:nil]) {
if ([screen[@"isMain"] boolValue] == (angle.intValue == 0)) {
FBConfiguration.sharedInstance.currentDisplayId = screen[@"displayId"];
}
}
}
for (NSNumber *duration in @[@0, @2]) {
[self launchApplication];
NSError *error = nil;
if (useSession) {
XCTAssertTrue([device fb_goToHomescreenWithError:&error]);
XCTAssertTrue([[[FBRunLoopSpinner new] timeout:5] spinUntilTrue:^BOOL{
return self.testedApplication.state != XCUIApplicationStateRunningForeground;
}]);
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:duration.doubleValue]];
FBSession *session = [FBSession initWithApplication:self.testedApplication];
[session activateApplicationWithBundleId:self.testedApplication.bundleID];
Comment thread
KazuCocoa marked this conversation as resolved.
Outdated
} else {
XCTAssertTrue([self.testedApplication fb_deactivateWithDuration:duration.doubleValue error:&error]);
}
XCTAssertNil(error);
// Existence/foreground checks alone miss lost input. Do not add a
// delay or retry: this first tap must actually open the alerts page.
[self.testedApplication.buttons[@"Alerts"] tap];
XCTAssertTrue([self.testedApplication.buttons[FBShowAlertButtonName] waitForExistenceWithTimeout:2]);
}
}
} @finally {
BOOL restored = nil == originalAngle || setAngleAndWait(originalAngle);
FBConfiguration.sharedInstance.currentDisplayId = originalDisplay;
XCTAssertTrue(restored, @"Hinge did not return to %@ degrees", originalAngle);
}
}

- (void)testActiveApplication
{
XCUIApplication *systemApp = XCUIApplication.fb_systemApplication;
Expand Down
Loading