Add Uninstall API
Summary: Installing has a convenient API, so should Uninstalling. Reviewed By: migchez Differential Revision: D3151068 fb-gh-sync-id: b59af6b1cb83849d232d930e3c30a468b3d50258 fbshipit-source-id: b59af6b1cb83849d232d930e3c30a468b3d50258
This commit is contained in:
Родитель
7d3fc472ad
Коммит
75cddd62df
|
@ -9,19 +9,30 @@
|
|||
|
||||
#import <FBSimulatorControl/FBSimulatorInteraction.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class FBApplicationLaunchConfiguration;
|
||||
|
||||
@interface FBSimulatorInteraction (Applications)
|
||||
|
||||
/**
|
||||
Installs the given Application.
|
||||
Will Allways Succeed if the Application is a System Application.
|
||||
Will always succeed if the Application is a System Application.
|
||||
|
||||
@param application the Application to Install.
|
||||
@return the reciever, for chaining.
|
||||
*/
|
||||
- (instancetype)installApplication:(FBSimulatorApplication *)application;
|
||||
|
||||
/**
|
||||
Uninstalls the given Application.
|
||||
Will always fail if the Application is a System Application.
|
||||
|
||||
@param bundleID the Bundle ID of the application to uninstall.
|
||||
@return the reciever, for chaining.
|
||||
*/
|
||||
- (instancetype)uninstallApplicationWithBundleID:(NSString *)bundleID;
|
||||
|
||||
/**
|
||||
Launches the Application with the given Configuration.
|
||||
If the Application is determined to allready be running, the interaction will fail.
|
||||
|
@ -79,3 +90,5 @@
|
|||
- (instancetype)terminateLastLaunchedApplication;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
#import "FBSimulatorInteraction+Applications.h"
|
||||
|
||||
#import <CoreSimulator/SimDevice.h>
|
||||
|
||||
#import <FBControlCore/FBControlCore.h>
|
||||
|
||||
#import "FBProcessLaunchConfiguration+Helpers.h"
|
||||
|
@ -56,6 +54,40 @@
|
|||
}];
|
||||
}
|
||||
|
||||
- (instancetype)uninstallApplicationWithBundleID:(NSString *)bundleID
|
||||
{
|
||||
NSParameterAssert(bundleID);
|
||||
|
||||
return [self interactWithBootedSimulator:^ BOOL (NSError **error, FBSimulator *simulator) {
|
||||
// Confirm the app is suitable to be uninstalled.
|
||||
if ([simulator isSystemApplicationWithBundleID:bundleID error:nil]) {
|
||||
return [[[FBSimulatorError
|
||||
describeFormat:@"Can't uninstall '%@' as it is a system Application", bundleID]
|
||||
inSimulator:simulator]
|
||||
failBool:error];
|
||||
}
|
||||
NSError *innerError = nil;
|
||||
if (![simulator installedApplicationWithBundleID:bundleID error:&innerError]) {
|
||||
return [[[[FBSimulatorError
|
||||
describeFormat:@"Can't uninstall '%@' as it isn't installed", bundleID]
|
||||
causedBy:innerError]
|
||||
inSimulator:simulator]
|
||||
failBool:error];
|
||||
}
|
||||
// Kill the app if it's running
|
||||
[[simulator.interact terminateApplicationWithBundleID:bundleID] perform:nil];
|
||||
// Then uninstall for real.
|
||||
if (![simulator.simDeviceWrapper uninstallApplication:bundleID withOptions:nil error:&innerError]) {
|
||||
return [[[[FBSimulatorError
|
||||
describeFormat:@"Failed to uninstall '%@'", bundleID]
|
||||
causedBy:innerError]
|
||||
inSimulator:simulator]
|
||||
failBool:error];
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
}
|
||||
|
||||
- (instancetype)launchApplication:(FBApplicationLaunchConfiguration *)appLaunch
|
||||
{
|
||||
NSParameterAssert(appLaunch);
|
||||
|
|
|
@ -24,6 +24,7 @@ typedef void (^FBSimDeviceWrapperCallback)(void);
|
|||
Augments methods in CoreSimulator with:
|
||||
- More informative return values.
|
||||
- Implementations that are more resiliant to failure in CoreSimulator.
|
||||
- Annotations of the expected arguments and return types of CoreSimulator.
|
||||
*/
|
||||
@interface FBSimDeviceWrapper : NSObject
|
||||
|
||||
|
@ -79,6 +80,16 @@ typedef void (^FBSimDeviceWrapperCallback)(void);
|
|||
*/
|
||||
- (BOOL)installApplication:(NSURL *)appURL withOptions:(NSDictionary *)options error:(NSError **)error;
|
||||
|
||||
/**
|
||||
Uninstalls an Application on the Simulator.
|
||||
|
||||
@param bundleID the Bundle ID of the Application to uninstall.
|
||||
@param options the Options to use in the launch.
|
||||
@param error an error out for any error that occured.
|
||||
@return YES if the Application was installed successfully, NO otherwise.
|
||||
*/
|
||||
- (BOOL)uninstallApplication:(NSString *)bundleID withOptions:(NSDictionary *)options error:(NSError **)error;
|
||||
|
||||
/**
|
||||
Spawns an long-lived executable on the Simulator.
|
||||
The Task should not terminate in less than a few seconds, as Process Info will be obtained.
|
||||
|
|
|
@ -223,6 +223,12 @@
|
|||
return [self.simulator.device installApplication:appURL withOptions:options error:error];
|
||||
}
|
||||
|
||||
- (BOOL)uninstallApplication:(NSString *)bundleID withOptions:(NSDictionary *)options error:(NSError **)error
|
||||
{
|
||||
// The options don't appear to do much, simctl itself doesn't use them.
|
||||
return [self.simulator.device uninstallApplication:bundleID withOptions:nil error:error];
|
||||
}
|
||||
|
||||
- (FBProcessInfo *)spawnLongRunningWithPath:(NSString *)launchPath options:(NSDictionary *)options terminationHandler:(FBSimDeviceWrapperCallback)terminationHandler error:(NSError **)error
|
||||
{
|
||||
return [self processInfoForProcessIdentifier:[self.simulator.device spawnWithPath:launchPath options:options terminationHandler:terminationHandler error:error] error:error];
|
||||
|
|
|
@ -148,4 +148,16 @@
|
|||
[self testApplication:self.tableSearchApplication relaunches:self.tableSearchAppLaunch];
|
||||
}
|
||||
|
||||
- (void)testCanUninstallApplication
|
||||
{
|
||||
FBSimulator *simulator = [self obtainSimulator];
|
||||
FBSimulatorApplication *application = self.tableSearchApplication;
|
||||
FBApplicationLaunchConfiguration *launch = self.tableSearchAppLaunch;
|
||||
|
||||
[self.assert consumeAllNotifications];
|
||||
[self assertInteractionSuccessful:[[[simulator.interact bootSimulator:self.simulatorLaunchConfiguration] installApplication:application] launchApplication:launch]];
|
||||
[self assertLastLaunchedApplicationIsRunning:simulator];
|
||||
[self assertInteractionSuccessful:[simulator.interact uninstallApplicationWithBundleID:application.bundleID]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -86,6 +86,7 @@ public enum Action {
|
|||
case Shutdown
|
||||
case Tap(Double, Double)
|
||||
case Terminate(String)
|
||||
case Uninstall(String)
|
||||
case Upload([FBDiagnostic])
|
||||
}
|
||||
|
||||
|
@ -174,6 +175,8 @@ public func == (left: Action, right: Action) -> Bool {
|
|||
return leftX == rightX && leftY == rightY
|
||||
case (.Terminate(let leftBundleID), .Terminate(let rightBundleID)):
|
||||
return leftBundleID == rightBundleID
|
||||
case (.Uninstall(let leftBundleID), .Uninstall(let rightBundleID)):
|
||||
return leftBundleID == rightBundleID
|
||||
case (.Upload(let leftPaths), .Upload(let rightPaths)):
|
||||
return leftPaths == rightPaths
|
||||
default:
|
||||
|
|
|
@ -304,6 +304,7 @@ extension Action : Parsable {
|
|||
self.shutdownParser,
|
||||
self.tapParser,
|
||||
self.terminateParser,
|
||||
self.uninstallParser,
|
||||
self.uploadParser,
|
||||
])
|
||||
}}
|
||||
|
@ -430,6 +431,12 @@ extension Action : Parsable {
|
|||
.fmap { Action.Terminate($0) }
|
||||
}}
|
||||
|
||||
static var uninstallParser: Parser<Action> { get {
|
||||
return Parser
|
||||
.succeeded(EventName.Uninstall.rawValue, Parser<Any>.ofBundleID)
|
||||
.fmap { Action.Uninstall($0) }
|
||||
}}
|
||||
|
||||
static var uploadParser: Parser<Action> { get {
|
||||
return Parser
|
||||
.succeeded(
|
||||
|
|
|
@ -37,6 +37,7 @@ public enum EventName : String {
|
|||
case StateChange = "state"
|
||||
case Tap = "tap"
|
||||
case Terminate = "terminate"
|
||||
case Uninstall = "uninstall"
|
||||
case Upload = "upload"
|
||||
}
|
||||
|
||||
|
|
|
@ -259,6 +259,10 @@ private struct SimulatorRunner : Runner {
|
|||
return SimulatorInteraction(reporter, EventName.Record, bundleID) { interaction in
|
||||
interaction.terminateApplicationWithBundleID(bundleID)
|
||||
}
|
||||
case .Uninstall(let bundleID):
|
||||
return SimulatorInteraction(reporter, EventName.Uninstall, bundleID) { interaction in
|
||||
interaction.uninstallApplicationWithBundleID(bundleID)
|
||||
}
|
||||
case .Upload(let diagnostics):
|
||||
return UploadInteraction(reporter, diagnostics)
|
||||
default:
|
||||
|
|
|
@ -199,6 +199,7 @@ let validActions: [([String], Action)] = [
|
|||
(["shutdown"], Action.Shutdown),
|
||||
(["shutdown"], Action.Shutdown),
|
||||
(["terminate", "com.foo.bar"], Action.Terminate("com.foo.bar")),
|
||||
(["uninstall", "com.foo.bar"], Action.Uninstall("com.foo.bar")),
|
||||
(["upload", Fixtures.photoPath, Fixtures.videoPath], Action.Upload([Fixtures.photoDiagnostic, Fixtures.videoDiagnostic])),
|
||||
]
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче