Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions WebDriverAgentLib/FBApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (BOOL)fb_switchToSystemApplicationWithError:(NSError **)error;

/**
Returns the bundle indentifier of the system app (ususally Springboard)
*/
+ (NSString *)fb_systemApplicationBundleID;

/**
Checks if the app is installed on the device under test.
*/
- (BOOL)fb_isInstalled;

@end

NS_ASSUME_NONNULL_END
36 changes: 36 additions & 0 deletions WebDriverAgentLib/FBApplication.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@

#import "FBApplication.h"

#import "FBExceptions.h"
#import "FBXCAccessibilityElement.h"
#import "FBLogger.h"
#import "FBRunLoopSpinner.h"
#import "FBMacros.h"
#import "FBActiveAppDetectionPoint.h"
#import "FBXCodeCompatibility.h"
#import "FBXCTestDaemonsProxy.h"
#import "LSApplicationWorkspace.h"
#import "XCUIApplication.h"
#import "XCUIApplication+FBHelpers.h"
#import "XCUIApplicationImpl.h"
Expand Down Expand Up @@ -133,6 +135,16 @@ + (instancetype)fb_systemApplication
[[FBXCAXClientProxy.sharedClient systemApplication] processIdentifier]];
}

+ (NSString *)fb_systemApplicationBundleID
{
static dispatch_once_t onceToken;
static NSString *systemAppBundleID;
dispatch_once(&onceToken, ^{
systemAppBundleID = [[self.class fb_systemApplication] bundleID];
});
return systemAppBundleID;
}

+ (instancetype)applicationWithPID:(pid_t)processID
{
if ([NSProcessInfo processInfo].processIdentifier == processID) {
Expand All @@ -141,14 +153,33 @@ + (instancetype)applicationWithPID:(pid_t)processID
return (FBApplication *)[FBXCAXClientProxy.sharedClient monitoredApplicationWithProcessIdentifier:processID];
}

/**
https://github.com/appium/WebDriverAgent/issues/702
*/
- (void)fb_assertInstalledByAction:(NSString *)action
{
if (![self.bundleID isEqualToString:[self.class fb_systemApplicationBundleID]] && !self.fb_isInstalled) {
NSString *message = [NSString stringWithFormat:@"The application '%@' cannot be %@ because it is not installed on the device under test",
self.bundleID, action];
[[NSException exceptionWithName:FBApplicationMissingException reason:message userInfo:nil] raise];
}
}

- (void)launch
{
[self fb_assertInstalledByAction:@"launched"];
[super launch];
if (![self fb_waitForAppElement:APP_STATE_CHANGE_TIMEOUT]) {
[FBLogger logFmt:@"The application '%@' is not running in foreground after %.2f seconds", self.bundleID, APP_STATE_CHANGE_TIMEOUT];
}
}

- (void)activate
{
[self fb_assertInstalledByAction:@"activated"];
[super activate];
}

- (void)terminate
{
[super terminate];
Expand Down Expand Up @@ -181,4 +212,9 @@ + (BOOL)fb_switchToSystemApplicationWithError:(NSError **)error
error:error];
}

- (BOOL)fb_isInstalled
{
return [[LSApplicationWorkspace defaultWorkspace] applicationIsInstalled:self.bundleID];
}

@end
3 changes: 2 additions & 1 deletion WebDriverAgentLib/Routing/FBExceptionHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ - (void)handleException:(NSException *)exception forResponse:(RouteResponse *)re
commandStatus = [FBCommandStatus noSuchDriverErrorWithMessage:exception.reason
traceback:traceback];
} else if ([exception.name isEqualToString:FBInvalidArgumentException]
|| [exception.name isEqualToString:FBElementAttributeUnknownException]) {
|| [exception.name isEqualToString:FBElementAttributeUnknownException]
|| [exception.name isEqualToString:FBApplicationMissingException]) {
commandStatus = [FBCommandStatus invalidArgumentErrorWithMessage:exception.reason
traceback:traceback];
} else if ([exception.name isEqualToString:FBApplicationCrashedException]
Expand Down
3 changes: 3 additions & 0 deletions WebDriverAgentLib/Routing/FBExceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,7 @@ extern NSString *const FBClassChainQueryParseException;
/*! Exception used to notify about application crash */
extern NSString *const FBApplicationCrashedException;

/*! Exception used to notify about the application is not installed */
extern NSString *const FBApplicationMissingException;

NS_ASSUME_NONNULL_END
1 change: 1 addition & 0 deletions WebDriverAgentLib/Routing/FBExceptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
NSString *const FBXPathQueryEvaluationException = @"FBXPathQueryEvaluationException";
NSString *const FBClassChainQueryParseException = @"FBClassChainQueryParseException";
NSString *const FBApplicationCrashedException = @"FBApplicationCrashedException";
NSString *const FBApplicationMissingException = @"FBApplicationMissingException";
29 changes: 29 additions & 0 deletions WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#import "FBIntegrationTestCase.h"
#import "FBApplication.h"
#import "FBExceptions.h"
#import "FBMacros.h"
#import "FBSession.h"
#import "FBXCodeCompatibility.h"
Expand Down Expand Up @@ -100,6 +101,34 @@ - (void)testMainAppCanBeRestartedInScopeOfTheCurrentSession
FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:testedApp.bundleID]);
}

- (void)testAppWithInvalidBundleIDCannotBeStarted
{
FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"];
@try {
[testedApp launch];
XCTFail(@"An exception is expected to be thrown");
} @catch (NSException *exception) {
XCTAssertEqualObjects(FBApplicationMissingException, exception.name);
}
}

- (void)testAppWithInvalidBundleIDCannotBeActivated
{
FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"];
@try {
[testedApp activate];
XCTFail(@"An exception is expected to be thrown");
} @catch (NSException *exception) {
XCTAssertEqualObjects(FBApplicationMissingException, exception.name);
}
}

- (void)testAppWithInvalidBundleIDCannotBeTerminated
{
FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"];
[testedApp terminate];
}

- (void)testLaunchUnattachedApp
{
[FBUnattachedAppLauncher launchAppWithBundleId:SETTINGS_BUNDLE_ID];
Expand Down