Commit ad19ec7e authored by Justin Cohen's avatar Justin Cohen Committed by Commit Bot

[ios] Add support for safe_mode_egtests in EG2.

Update matchers to not use GREYMatchers anymore
Remove -testInvocations call for iOS 10.2
Add support for shared EarlGreyScopedBlockSwizzler.
Add helper util to call -presentSafeMode.

Bug: 987646
Change-Id: I783e84af095b87f84d2502c14a308dc41a6eef54
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1863950Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Commit-Queue: Justin Cohen <justincohen@chromium.org>
Auto-Submit: Justin Cohen <justincohen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707070}
parent 2dd1593f
...@@ -30,12 +30,14 @@ source_set("safe_mode") { ...@@ -30,12 +30,14 @@ source_set("safe_mode") {
source_set("eg_tests") { source_set("eg_tests") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
defines = [ "CHROME_EARL_GREY_1" ]
testonly = true testonly = true
sources = [ sources = [
"safe_mode_egtest.mm", "safe_mode_egtest.mm",
] ]
deps = [ deps = [
":safe_mode", ":safe_mode",
":test_support",
"//base", "//base",
"//ios/chrome/app:app_internal", "//ios/chrome/app:app_internal",
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
...@@ -44,10 +46,77 @@ source_set("eg_tests") { ...@@ -44,10 +46,77 @@ source_set("eg_tests") {
"//ios/chrome/test/app:test_support", "//ios/chrome/test/app:test_support",
"//ios/chrome/test/base", "//ios/chrome/test/base",
"//ios/chrome/test/earl_grey:test_support", "//ios/chrome/test/earl_grey:test_support",
"//ios/testing/earl_grey:earl_grey_support",
"//ios/third_party/earl_grey:earl_grey+link", "//ios/third_party/earl_grey:earl_grey+link",
] ]
} }
source_set("test_support") {
defines = [ "CHROME_EARL_GREY_1" ]
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"safe_mode_app_interface.h",
"safe_mode_app_interface.mm",
]
deps = [
":safe_mode",
"//ios/chrome/test/app:test_support",
]
}
source_set("eg_app_support+eg2") {
defines = [ "CHROME_EARL_GREY_2" ]
configs += [
"//build/config/compiler:enable_arc",
"//build/config/ios:xctest_config",
]
testonly = true
sources = [
"safe_mode_app_interface.h",
"safe_mode_app_interface.mm",
]
deps = [
":safe_mode",
"//ios/chrome/test/app:test_support",
]
}
source_set("eg_test_support+eg2") {
defines = [ "CHROME_EARL_GREY_2" ]
configs += [
"//build/config/compiler:enable_arc",
"//build/config/ios:xctest_config",
]
testonly = true
sources = [
"safe_mode_app_interface.h",
]
}
source_set("eg2_tests") {
defines = [ "CHROME_EARL_GREY_2" ]
configs += [
"//build/config/compiler:enable_arc",
"//build/config/ios:xctest_config",
]
testonly = true
sources = [
"safe_mode_egtest.mm",
]
deps = [
":eg_test_support+eg2",
"//base:base",
"//ios/chrome/app/strings:ios_chromium_strings_grit",
"//ios/chrome/test/base:base",
"//ios/chrome/test/earl_grey:eg_test_support+eg2",
"//ios/testing/earl_grey:eg_test_support+eg2",
"//ios/third_party/earl_grey2:test_lib",
]
libs = [ "UIKit.framework" ]
}
source_set("unit_tests") { source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
testonly = true testonly = true
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_SAFE_MODE_SAFE_MODE_APP_INTERFACE_H_
#define IOS_CHROME_BROWSER_UI_SAFE_MODE_SAFE_MODE_APP_INTERFACE_H_
#import <UIKit/UIKit.h>
// EarlGreyScopedBlockSwizzlerAppInterface contains the app-side
// implementation for helpers. These helpers are compiled into
// the app binary and can be called from either app or test code.
@interface SafeModeAppInterface : NSObject
// Presents the SafeModeViewController UI.
+ (void)presentSafeMode;
@end
#endif // IOS_CHROME_BROWSER_UI_SAFE_MODE_SAFE_MODE_APP_INTERFACE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/chrome/browser/ui/safe_mode/safe_mode_app_interface.h"
#import "ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation SafeModeAppInterface
+ (void)presentSafeMode {
SafeModeViewController* safeModeController =
[[SafeModeViewController alloc] initWithDelegate:nil];
[chrome_test_util::GetActiveViewController()
presentViewController:safeModeController
animated:NO
completion:nil];
}
@end
...@@ -2,61 +2,61 @@ ...@@ -2,61 +2,61 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#import <EarlGrey/EarlGrey.h> #include "base/feature_list.h"
#import <XCTest/XCTest.h>
#include "base/ios/ios_util.h" #include "base/ios/ios_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#import "ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.h" #include "ios/chrome/browser/ui/safe_mode/safe_mode_app_interface.h"
#include "ios/chrome/browser/ui/util/ui_util.h"
#include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_chromium_strings.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#import "ios/chrome/test/base/scoped_block_swizzler.h" #import "ios/chrome/test/base/scoped_block_swizzler.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler.h"
#import "ios/testing/earl_grey/app_launch_manager.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
#if defined(CHROME_EARL_GREY_2)
GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(SafeModeAppInterface)
#endif // defined(CHROME_EARL_GREY_2)
using chrome_test_util::ButtonWithAccessibilityLabel;
namespace { namespace {
// Verifies that |message| is displayed. // Verifies that |message| is displayed.
void AssertMessageOnPage(NSString* message) { void AssertMessageOnPage(NSString* message) {
id<GREYMatcher> messageMatcher = [GREYMatchers matcherForText:message]; id<GREYMatcher> messageMatcher =
grey_allOf(grey_text(message), grey_kindOfClass([UILabel class]),
grey_sufficientlyVisible(), nil);
[[EarlGrey selectElementWithMatcher:messageMatcher] [[EarlGrey selectElementWithMatcher:messageMatcher]
assertWithMatcher:grey_notNil()]; assertWithMatcher:grey_notNil()];
} }
// Verifies that |message| is not displayed. // Verifies that |message| is not displayed.
void AssertMessageNotOnPage(NSString* message) { void AssertMessageNotOnPage(NSString* message) {
id<GREYMatcher> messageMatcher = [GREYMatchers matcherForText:message]; id<GREYMatcher> messageMatcher =
grey_allOf(grey_text(message), grey_kindOfClass([UILabel class]),
grey_sufficientlyVisible(), nil);
[[EarlGrey selectElementWithMatcher:messageMatcher] [[EarlGrey selectElementWithMatcher:messageMatcher]
assertWithMatcher:grey_nil()]; assertWithMatcher:grey_nil()];
} }
// Verifies that the button to reload chrome is displayed. // Verifies that the button to reload chrome is displayed.
void AssertTryAgainButtonOnPage() { void AssertTryAgainButtonOnPage() {
NSString* tryAgain = id<GREYMatcher> tryAgainMatcher = ButtonWithAccessibilityLabel(
NSLocalizedString(@"IDS_IOS_SAFE_MODE_RELOAD_CHROME", @""); NSLocalizedString(@"IDS_IOS_SAFE_MODE_RELOAD_CHROME", @""));
// This is uppercased to match MDC button label convention.
NSString* tryAgainPrimaryAction =
[tryAgain uppercaseStringWithLocale:[NSLocale currentLocale]];
id<GREYMatcher> tryAgainMatcher =
[GREYMatchers matcherForButtonTitle:tryAgainPrimaryAction];
[[EarlGrey selectElementWithMatcher:tryAgainMatcher] [[EarlGrey selectElementWithMatcher:tryAgainMatcher]
assertWithMatcher:grey_notNil()]; assertWithMatcher:grey_notNil()];
} }
} // namespace } // namespace
// Expose internal class methods for swizzling.
@interface SafeModeViewController (Testing)
+ (BOOL)detectedThirdPartyMods;
+ (BOOL)hasReportToUpload;
- (NSArray*)startupCrashModules;
@end
// Tests the display of Safe Mode Controller under different error states of // Tests the display of Safe Mode Controller under different error states of
// jailbroken-ness and whether a crash dump was saved. // jailbroken-ness and whether a crash dump was saved.
...@@ -65,33 +65,18 @@ void AssertTryAgainButtonOnPage() { ...@@ -65,33 +65,18 @@ void AssertTryAgainButtonOnPage() {
@implementation SafeModeTestCase @implementation SafeModeTestCase
// Per crbug.com/845186, Disable flakey iPad Retina tests that are limited
// to iOS 10.2.
+ (NSArray*)testInvocations {
#if TARGET_IPHONE_SIMULATOR
if ([ChromeEarlGrey isIPadIdiom] && !base::ios::IsRunningOnOrLater(10, 3, 0))
return @[];
#endif // TARGET_IPHONE_SIMULATOR
return [super testInvocations];
}
// Tests that Safe Mode crash upload screen is displayed when there are crash // Tests that Safe Mode crash upload screen is displayed when there are crash
// reports to upload. // reports to upload.
- (void)testSafeModeSendingCrashReport { - (void)testSafeModeSendingCrashReport {
// Mocks the +hasReportToUpload method by swizzling to return positively that // Mocks the +hasReportToUpload method by swizzling to return positively that
// there are crash reports to upload. // there are crash reports to upload.
ScopedBlockSwizzler hasReport([SafeModeViewController class], // TODO(crbug.com/1015272): Consider moving from swizzling to a delegate.
@selector(hasReportToUpload), ^{ EarlGreyScopedBlockSwizzler hasReport(@"SafeModeViewController",
return YES; @"hasReportToUpload", ^{
}); return YES;
});
// Instantiates a Safe Mode controller and displays it. [SafeModeAppInterface presentSafeMode];
SafeModeViewController* safeModeController =
[[SafeModeViewController alloc] initWithDelegate:nil];
[chrome_test_util::GetActiveViewController()
presentViewController:safeModeController
animated:NO
completion:nil];
// Verifies screen content that shows that crash report is being uploaded. // Verifies screen content that shows that crash report is being uploaded.
AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @"")); AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @""));
AssertMessageOnPage( AssertMessageOnPage(
...@@ -106,23 +91,17 @@ void AssertTryAgainButtonOnPage() { ...@@ -106,23 +91,17 @@ void AssertTryAgainButtonOnPage() {
- (void)testSafeModeDetectedThirdPartyMods { - (void)testSafeModeDetectedThirdPartyMods {
// Mocks the +detectedThirdPartyMods method by swizzling to return positively // Mocks the +detectedThirdPartyMods method by swizzling to return positively
// that device appears to be jailbroken and contains third party mods. // that device appears to be jailbroken and contains third party mods.
ScopedBlockSwizzler thirdParty([SafeModeViewController class], // TODO(crbug.com/1015272): Consider moving from swizzling to a delegate.
@selector(detectedThirdPartyMods), ^{ EarlGreyScopedBlockSwizzler thirdParty(@"SafeModeViewController",
return YES; @"detectedThirdPartyMods", ^{
}); return YES;
});
// Returns an empty list to simulate no known mods detected. // Returns an empty list to simulate no known mods detected.
ScopedBlockSwizzler badModules([SafeModeViewController class], EarlGreyScopedBlockSwizzler badModules(@"SafeModeViewController",
@selector(startupCrashModules), ^{ @"startupCrashModules", ^{
return @[]; return @[];
}); });
[SafeModeAppInterface presentSafeMode];
// Instantiates a Safe Mode controller and displays it.
SafeModeViewController* safeModeController =
[[SafeModeViewController alloc] initWithDelegate:nil];
[chrome_test_util::GetActiveViewController()
presentViewController:safeModeController
animated:NO
completion:nil];
// Verifies screen content that does not show crash report being uploaded. // Verifies screen content that does not show crash report being uploaded.
// When devices are jailbroken, the crash reports are not very useful. // When devices are jailbroken, the crash reports are not very useful.
AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @"")); AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @""));
...@@ -139,27 +118,22 @@ void AssertTryAgainButtonOnPage() { ...@@ -139,27 +118,22 @@ void AssertTryAgainButtonOnPage() {
- (void)testSafeModeBothThirdPartyModsAndHasReport { - (void)testSafeModeBothThirdPartyModsAndHasReport {
// Mocks the +detectedThirdPartyMods method by swizzling to return positively // Mocks the +detectedThirdPartyMods method by swizzling to return positively
// that device appears to be jailbroken and contains third party mods. // that device appears to be jailbroken and contains third party mods.
ScopedBlockSwizzler thirdParty([SafeModeViewController class], // TODO(crbug.com/1015272): Consider moving from swizzling to a delegate.
@selector(detectedThirdPartyMods), ^{ EarlGreyScopedBlockSwizzler thirdParty(@"SafeModeViewController",
return YES; @"detectedThirdPartyMods", ^{
}); return YES;
});
// Mocked list of bad jailbroken mods. These will be checked later. // Mocked list of bad jailbroken mods. These will be checked later.
NSArray* badModulesList = @[ @"iAmBad", @"MJackson" ]; NSArray* badModulesList = @[ @"iAmBad", @"MJackson" ];
ScopedBlockSwizzler badModules([SafeModeViewController class], EarlGreyScopedBlockSwizzler badModules(@"SafeModeViewController",
@selector(startupCrashModules), ^{ @"startupCrashModules", ^{
return badModulesList; return badModulesList;
}); });
ScopedBlockSwizzler hasReport([SafeModeViewController class], EarlGreyScopedBlockSwizzler hasReport(@"SafeModeViewController",
@selector(hasReportToUpload), ^{ @"hasReportToUpload", ^{
return YES; return YES;
}); });
// Instantiates a Safe Mode controller and displays it. [SafeModeAppInterface presentSafeMode];
SafeModeViewController* safeModeController =
[[SafeModeViewController alloc] initWithDelegate:nil];
[chrome_test_util::GetActiveViewController()
presentViewController:safeModeController
animated:NO
completion:nil];
// Verifies screen content that does not show crash report being uploaded. // Verifies screen content that does not show crash report being uploaded.
// When devices are jailbroken, the crash reports are not very useful. // When devices are jailbroken, the crash reports are not very useful.
AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @"")); AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @""));
......
...@@ -212,6 +212,10 @@ source_set("test_support") { ...@@ -212,6 +212,10 @@ source_set("test_support") {
"chrome_test_case.mm", "chrome_test_case.mm",
"chrome_test_case_app_interface.h", "chrome_test_case_app_interface.h",
"chrome_test_case_app_interface.mm", "chrome_test_case_app_interface.mm",
"earl_grey_scoped_block_swizzler.h",
"earl_grey_scoped_block_swizzler.mm",
"earl_grey_scoped_block_swizzler_app_interface.h",
"earl_grey_scoped_block_swizzler_app_interface.mm",
"hardware_keyboard_util.h", "hardware_keyboard_util.h",
"hardware_keyboard_util.mm", "hardware_keyboard_util.mm",
"scoped_block_popups_pref.h", "scoped_block_popups_pref.h",
...@@ -248,6 +252,8 @@ source_set("test_support") { ...@@ -248,6 +252,8 @@ source_set("test_support") {
"//ios/chrome/browser/ui/payments:payments_ui", "//ios/chrome/browser/ui/payments:payments_ui",
"//ios/chrome/browser/ui/popup_menu:constants", "//ios/chrome/browser/ui/popup_menu:constants",
"//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants", "//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants",
"//ios/chrome/browser/ui/safe_mode",
"//ios/chrome/browser/ui/safe_mode:test_support",
"//ios/chrome/browser/ui/settings:settings", "//ios/chrome/browser/ui/settings:settings",
"//ios/chrome/browser/ui/settings/autofill", "//ios/chrome/browser/ui/settings/autofill",
"//ios/chrome/browser/ui/settings/autofill:feature_flags", "//ios/chrome/browser/ui/settings/autofill:feature_flags",
...@@ -267,6 +273,7 @@ source_set("test_support") { ...@@ -267,6 +273,7 @@ source_set("test_support") {
"//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util",
"//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/browser/web:tab_id_tab_helper",
"//ios/chrome/test/app:test_support", "//ios/chrome/test/app:test_support",
"//ios/chrome/test/base",
"//ios/testing:verify_custom_webkit", "//ios/testing:verify_custom_webkit",
"//ios/testing/earl_grey:earl_grey_support", "//ios/testing/earl_grey:earl_grey_support",
"//ios/third_party/material_components_ios", "//ios/third_party/material_components_ios",
...@@ -329,6 +336,8 @@ source_set("eg_app_support+eg2") { ...@@ -329,6 +336,8 @@ source_set("eg_app_support+eg2") {
"chrome_matchers_app_interface.mm", "chrome_matchers_app_interface.mm",
"chrome_test_case_app_interface.h", "chrome_test_case_app_interface.h",
"chrome_test_case_app_interface.mm", "chrome_test_case_app_interface.mm",
"earl_grey_scoped_block_swizzler_app_interface.h",
"earl_grey_scoped_block_swizzler_app_interface.mm",
"hardware_keyboard_util.h", "hardware_keyboard_util.h",
"hardware_keyboard_util.mm", "hardware_keyboard_util.mm",
] ]
...@@ -360,6 +369,8 @@ source_set("eg_app_support+eg2") { ...@@ -360,6 +369,8 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/browser/ui/payments:payments_ui", "//ios/chrome/browser/ui/payments:payments_ui",
"//ios/chrome/browser/ui/popup_menu:constants", "//ios/chrome/browser/ui/popup_menu:constants",
"//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants", "//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants",
"//ios/chrome/browser/ui/safe_mode",
"//ios/chrome/browser/ui/safe_mode:eg_app_support+eg2",
"//ios/chrome/browser/ui/settings:settings", "//ios/chrome/browser/ui/settings:settings",
"//ios/chrome/browser/ui/settings/autofill", "//ios/chrome/browser/ui/settings/autofill",
"//ios/chrome/browser/ui/settings/autofill:feature_flags", "//ios/chrome/browser/ui/settings/autofill:feature_flags",
...@@ -377,6 +388,7 @@ source_set("eg_app_support+eg2") { ...@@ -377,6 +388,7 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util",
"//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/browser/web:tab_id_tab_helper",
"//ios/chrome/test/app:test_support", "//ios/chrome/test/app:test_support",
"//ios/chrome/test/base",
"//ios/testing:nserror_support", "//ios/testing:nserror_support",
"//ios/testing:verify_custom_webkit", "//ios/testing:verify_custom_webkit",
"//ios/testing/earl_grey:eg_app_support+eg2", "//ios/testing/earl_grey:eg_app_support+eg2",
...@@ -422,6 +434,9 @@ source_set("eg_test_support+eg2") { ...@@ -422,6 +434,9 @@ source_set("eg_test_support+eg2") {
"chrome_test_case.h", "chrome_test_case.h",
"chrome_test_case.mm", "chrome_test_case.mm",
"chrome_test_case_app_interface.h", "chrome_test_case_app_interface.h",
"earl_grey_scoped_block_swizzler.h",
"earl_grey_scoped_block_swizzler.mm",
"earl_grey_scoped_block_swizzler_app_interface.h",
"scoped_block_popups_pref.h", "scoped_block_popups_pref.h",
"scoped_block_popups_pref.mm", "scoped_block_popups_pref.mm",
] ]
...@@ -435,6 +450,7 @@ source_set("eg_test_support+eg2") { ...@@ -435,6 +450,7 @@ source_set("eg_test_support+eg2") {
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
"//ios/chrome/browser/ui/popup_menu:constants", "//ios/chrome/browser/ui/popup_menu:constants",
"//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants", "//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants",
"//ios/chrome/browser/ui/safe_mode:eg_test_support+eg2",
"//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants", "//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants",
"//ios/chrome/browser/ui/tab_grid/grid:grid_ui_constants", "//ios/chrome/browser/ui/tab_grid/grid:grid_ui_constants",
"//ios/testing:http_server_bundle_data", "//ios/testing:http_server_bundle_data",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_TEST_EARL_GREY_EARL_GREY_SCOPED_BLOCK_SWIZZLER_H_
#define IOS_CHROME_TEST_EARL_GREY_EARL_GREY_SCOPED_BLOCK_SWIZZLER_H_
#import <UIKit/UIKit.h>
#include "base/macros.h"
// Helper class that wraps ScopedBlockSwizzler for use in EG1 and EG2 tests.
class EarlGreyScopedBlockSwizzler {
public:
// Constructs a new ScopedBlockSwizzler via the
// EarlGreyScopedBlockSwizzlerAppInterface interface.
EarlGreyScopedBlockSwizzler(NSString* target, NSString* selector, id block);
// Destroys the ScopedBlockSwizzler object via the
// EarlGreyScopedBlockSwizzlerAppInterface interface.
virtual ~EarlGreyScopedBlockSwizzler();
private:
// id used to track creation and destruction of swizzled block.
int unique_id_ = 0;
DISALLOW_COPY_AND_ASSIGN(EarlGreyScopedBlockSwizzler);
};
#endif // IOS_CHROME_TEST_EARL_GREY_EARL_GREY_SCOPED_BLOCK_SWIZZLER_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler.h"
#include "ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler_app_interface.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#if defined(CHROME_EARL_GREY_2)
GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(EarlGreyScopedBlockSwizzlerAppInterface)
#endif // defined(CHROME_EARL_GREY_2)
EarlGreyScopedBlockSwizzler::EarlGreyScopedBlockSwizzler(NSString* target,
NSString* selector,
id block)
: unique_id_([EarlGreyScopedBlockSwizzlerAppInterface
createScopedBlockSwizzlerForTarget:target
withSelector:selector
withBlock:block]) {}
EarlGreyScopedBlockSwizzler::~EarlGreyScopedBlockSwizzler() {
[EarlGreyScopedBlockSwizzlerAppInterface
deleteScopedBlockSwizzlerForID:unique_id_];
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_TEST_EARL_GREY_EARL_GREY_SCOPED_BLOCK_SWIZZLER_APP_INTERFACE_H_
#define IOS_CHROME_TEST_EARL_GREY_EARL_GREY_SCOPED_BLOCK_SWIZZLER_APP_INTERFACE_H_
#import <UIKit/UIKit.h>
// EarlGreyScopedBlockSwizzlerAppInterface contains the app-side
// implementation for helpers. These helpers are compiled into
// the app binary and can be called from either app or test code.
@interface EarlGreyScopedBlockSwizzlerAppInterface : NSObject
// Creates and retains a ScopedBlockSwizzler. Returns a unique id to be used
// to delete that ScopedBlockSwizzler.
+ (int)createScopedBlockSwizzlerForTarget:(NSString*)target
withSelector:(NSString*)selector
withBlock:(id)block;
// Deletes a ScopedBlockSwizzler based on it's unique id.
+ (void)deleteScopedBlockSwizzlerForID:(int)uniqueID;
@end
#endif // IOS_CHROME_TEST_EARL_GREY_EARL_GREY_SCOPED_BLOCK_SWIZZLER_APP_INTERFACE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/chrome/test/earl_grey/earl_grey_scoped_block_swizzler_app_interface.h"
#include <map>
#include "base/logging.h"
#include "ios/chrome/test/base/scoped_block_swizzler.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface EarlGreyScopedBlockSwizzlerHelper : NSObject {
// Unique IDs used with an EG2 safe basic type that can be used to later
// delete the ScopedBlockSwizzler.
int _swizzledIDs;
// Map of ScopedBlockSwizzler-ed objects, with a tracking int.
std::map<int, std::unique_ptr<ScopedBlockSwizzler>> _map;
}
// Inserts and removes from |map|.
- (int)insertScopedBlockSwizzler:(std::unique_ptr<ScopedBlockSwizzler>)swizzler;
- (void)removeScopedBlockSwizzler:(int)uniqueID;
@end
@implementation EarlGreyScopedBlockSwizzlerHelper
- (instancetype)init {
if ((self = [super init])) {
_swizzledIDs = 0;
}
return self;
}
+ (instancetype)sharedInstance {
static EarlGreyScopedBlockSwizzlerHelper* instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[EarlGreyScopedBlockSwizzlerHelper alloc] init];
});
return instance;
}
- (int)insertScopedBlockSwizzler:
(std::unique_ptr<ScopedBlockSwizzler>)swizzler {
_map[++_swizzledIDs] = std::move(swizzler);
return _swizzledIDs;
}
- (void)removeScopedBlockSwizzler:(int)uniqueID {
DCHECK(_map[uniqueID]);
_map.erase(uniqueID);
}
@end
@implementation EarlGreyScopedBlockSwizzlerAppInterface
+ (int)createScopedBlockSwizzlerForTarget:(NSString*)targetString
withSelector:(NSString*)selectorString
withBlock:(id)block {
Class target = NSClassFromString(targetString);
SEL selector = NSSelectorFromString(selectorString);
auto helper = [EarlGreyScopedBlockSwizzlerHelper sharedInstance];
auto swizzler =
std::make_unique<ScopedBlockSwizzler>(target, selector, block);
return [helper insertScopedBlockSwizzler:std::move(swizzler)];
}
+ (void)deleteScopedBlockSwizzlerForID:(int)uniqueID {
auto helper = [EarlGreyScopedBlockSwizzlerHelper sharedInstance];
[helper removeScopedBlockSwizzler:uniqueID];
}
@end
...@@ -57,6 +57,7 @@ chrome_ios_eg2_test("ios_chrome_ui_eg2tests_module") { ...@@ -57,6 +57,7 @@ chrome_ios_eg2_test("ios_chrome_ui_eg2tests_module") {
"//ios/chrome/browser/ui/open_in:eg2_tests", "//ios/chrome/browser/ui/open_in:eg2_tests",
"//ios/chrome/browser/ui/page_info:eg2_tests", "//ios/chrome/browser/ui/page_info:eg2_tests",
"//ios/chrome/browser/ui/sad_tab:eg2_tests", "//ios/chrome/browser/ui/sad_tab:eg2_tests",
"//ios/chrome/browser/ui/safe_mode:eg2_tests",
"//ios/chrome/browser/ui/settings/autofill:eg2_tests", "//ios/chrome/browser/ui/settings/autofill:eg2_tests",
"//ios/chrome/browser/ui/side_swipe:eg2_tests", "//ios/chrome/browser/ui/side_swipe:eg2_tests",
"//ios/chrome/browser/ui/tabs:eg2_tests", "//ios/chrome/browser/ui/tabs:eg2_tests",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment