Commit 369a7170 authored by Javier Ernesto Flores Robles's avatar Javier Ernesto Flores Robles Committed by Commit Bot

[iOS][MF][EG2] Migrate Password Tests

Add Autofill App Interface with the app code so EG2 can interact
with the app.
Move matchers to chrome matchers.
Create new EG2 tests and needed targets.

Bug: 1016368
Change-Id: If2256944612b3c7a6523dd3e1f9e36b79fc1d15b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1872058
Commit-Queue: Javier Ernesto Flores Robles <javierrobles@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarStepan Khapugin <stkhapugin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708935}
parent 1e10422e
......@@ -161,3 +161,55 @@ source_set("eg_tests") {
"XCTest.framework",
]
}
source_set("test_support") {
defines = [ "CHROME_EARL_GREY_1" ]
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"autofill_app_interface.h",
"autofill_app_interface.mm",
]
deps = [
"//base",
"//base/test:test_support",
"//components/keyed_service/core",
"//components/password_manager/core/browser",
"//ios/chrome/browser/passwords",
"//ios/chrome/test/app:test_support",
"//ios/testing/earl_grey:earl_grey_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 = [
"autofill_app_interface.h",
"autofill_app_interface.mm",
]
deps = [
"//base",
"//base/test:test_support",
"//components/keyed_service/core",
"//components/password_manager/core/browser",
"//ios/chrome/browser/passwords",
"//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 = [
"autofill_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.
#ifndef IOS_CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_APP_INTERFACE_H_
#define IOS_CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_APP_INTERFACE_H_
#import <Foundation/Foundation.h>
// AutofillAppInterface 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 AutofillAppInterface : NSObject
// Removes all credentials stored.
+ (void)clearPasswordStore;
// Saves an example form in the store.
+ (void)saveExamplePasswordForm;
// Saves an example form in the store for the passed URL spec.
+ (void)savePasswordFormForURLSpec:(NSString*)URLSpec;
@end
#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_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.
#import "ios/chrome/browser/ui/autofill/autofill_app_interface.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#import "base/test/ios/wait_util.h"
#include "components/keyed_service/core/service_access_type.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
#include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.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
namespace {
const char kExampleUsername[] = "concrete username";
const char kExamplePassword[] = "concrete password";
// Gets the current password store.
scoped_refptr<password_manager::PasswordStore> GetPasswordStore() {
// ServiceAccessType governs behaviour in Incognito: only modifications with
// EXPLICIT_ACCESS, which correspond to user's explicit gesture, succeed.
// This test does not deal with Incognito, and should not run in Incognito
// context. Therefore IMPLICIT_ACCESS is used to let the test fail if in
// Incognito context.
return IOSChromePasswordStoreFactory::GetForBrowserState(
chrome_test_util::GetOriginalBrowserState(),
ServiceAccessType::IMPLICIT_ACCESS);
}
// This class is used to obtain results from the PasswordStore and hence both
// check the success of store updates and ensure that store has finished
// processing.
class TestStoreConsumer : public password_manager::PasswordStoreConsumer {
public:
void OnGetPasswordStoreResults(
std::vector<std::unique_ptr<autofill::PasswordForm>> obtained) override {
obtained_ = std::move(obtained);
}
const std::vector<autofill::PasswordForm>& GetStoreResults() {
results_.clear();
ResetObtained();
GetPasswordStore()->GetAllLogins(this);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-result"
base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForFileOperationTimeout, ^bool {
return !AreObtainedReset();
});
#pragma clang diagnostic pop
AppendObtainedToResults();
return results_;
}
private:
// Puts |obtained_| in a known state not corresponding to any PasswordStore
// state.
void ResetObtained() {
obtained_.clear();
obtained_.emplace_back(nullptr);
}
// Returns true if |obtained_| are in the reset state.
bool AreObtainedReset() { return obtained_.size() == 1 && !obtained_[0]; }
void AppendObtainedToResults() {
for (const auto& source : obtained_) {
results_.emplace_back(*source);
}
ResetObtained();
}
// Temporary cache of obtained store results.
std::vector<std::unique_ptr<autofill::PasswordForm>> obtained_;
// Combination of fillable and blacklisted credentials from the store.
std::vector<autofill::PasswordForm> results_;
};
// Saves |form| to the password store and waits until the async processing is
// done.
void SaveToPasswordStore(const autofill::PasswordForm& form) {
GetPasswordStore()->AddLogin(form);
// When we retrieve the form from the store, |from_store| should be set.
autofill::PasswordForm expected_form = form;
expected_form.from_store = autofill::PasswordForm::Store::kProfileStore;
// Check the result and ensure PasswordStore processed this.
TestStoreConsumer consumer;
for (const auto& result : consumer.GetStoreResults()) {
if (result == expected_form)
return;
}
}
// Saves an example form in the store.
void SaveExamplePasswordForm() {
autofill::PasswordForm example;
example.username_value = base::ASCIIToUTF16(kExampleUsername);
example.password_value = base::ASCIIToUTF16(kExamplePassword);
example.origin = GURL("https://example.com/");
example.signon_realm = example.origin.spec();
SaveToPasswordStore(example);
}
// Saves an example form in the store for the passed URL.
void SaveLocalPasswordForm(const GURL& url) {
autofill::PasswordForm localForm;
localForm.username_value = base::ASCIIToUTF16(kExampleUsername);
localForm.password_value = base::ASCIIToUTF16(kExamplePassword);
localForm.origin = url;
localForm.signon_realm = localForm.origin.spec();
SaveToPasswordStore(localForm);
}
// Removes all credentials stored.
void ClearPasswordStore() {
GetPasswordStore()->RemoveLoginsCreatedBetween(base::Time(), base::Time(),
base::Closure());
TestStoreConsumer consumer;
}
} // namespace
@implementation AutofillAppInterface
+ (void)clearPasswordStore {
ClearPasswordStore();
}
+ (void)saveExamplePasswordForm {
SaveExamplePasswordForm();
}
+ (void)savePasswordFormForURLSpec:(NSString*)URLSpec {
SaveLocalPasswordForm(GURL(base::SysNSStringToUTF8(URLSpec)));
}
@end
......@@ -190,6 +190,7 @@ source_set("requesters") {
}
source_set("eg_tests") {
defines = [ "CHROME_EARL_GREY_1" ]
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
......@@ -210,11 +211,10 @@ source_set("eg_tests") {
"//components/autofill/core/common",
"//components/autofill/ios/browser",
"//components/keyed_service/core",
"//components/password_manager/core/browser",
"//ios/chrome/app/strings:ios_strings_grit",
"//ios/chrome/browser",
"//ios/chrome/browser/autofill",
"//ios/chrome/browser/passwords",
"//ios/chrome/browser/ui/autofill:test_support",
"//ios/chrome/browser/ui/settings",
"//ios/chrome/browser/ui/settings/autofill",
"//ios/chrome/browser/ui/settings/autofill:feature_flags",
......@@ -231,3 +231,28 @@ source_set("eg_tests") {
"//third_party/ocmock",
]
}
source_set("eg2_tests") {
defines = [ "CHROME_EARL_GREY_2" ]
configs += [
"//build/config/compiler:enable_arc",
"//build/config/ios:xctest_config",
]
testonly = true
sources = [
"password_view_controller_egtest.mm",
]
deps = [
"//base",
"//base/test:test_support",
"//ios/chrome/app/strings:ios_strings_grit",
"//ios/chrome/browser/ui/autofill:eg_test_support+eg2",
"//ios/chrome/test/earl_grey:eg_test_support+eg2",
"//ios/testing/earl_grey:eg_test_support+eg2",
"//ios/third_party/earl_grey2:test_lib",
"//ios/web/public/test:element_selector",
"//net:test_support",
"//url",
]
libs = [ "UIKit.framework" ]
}
......@@ -240,6 +240,8 @@ source_set("test_support") {
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication:authentication",
"//ios/chrome/browser/ui/authentication/cells",
"//ios/chrome/browser/ui/autofill/manual_fill",
"//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui",
"//ios/chrome/browser/ui/bookmarks:bookmarks_ui",
"//ios/chrome/browser/ui/collection_view/cells",
"//ios/chrome/browser/ui/commands:commands",
......@@ -261,6 +263,7 @@ source_set("test_support") {
"//ios/chrome/browser/ui/settings/clear_browsing_data",
"//ios/chrome/browser/ui/settings/credit_card_scanner",
"//ios/chrome/browser/ui/settings/google_services",
"//ios/chrome/browser/ui/settings/password",
"//ios/chrome/browser/ui/settings/sync",
"//ios/chrome/browser/ui/static_content",
"//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants",
......@@ -361,6 +364,9 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/browser/ntp:features",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication/cells",
"//ios/chrome/browser/ui/autofill:eg_app_support+eg2",
"//ios/chrome/browser/ui/autofill/manual_fill",
"//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui",
"//ios/chrome/browser/ui/bookmarks:bookmarks_ui",
"//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant",
"//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui",
......@@ -380,6 +386,7 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/browser/ui/settings/clear_browsing_data",
"//ios/chrome/browser/ui/settings/credit_card_scanner",
"//ios/chrome/browser/ui/settings/google_services",
"//ios/chrome/browser/ui/settings/password",
"//ios/chrome/browser/ui/settings/sync",
"//ios/chrome/browser/ui/static_content",
"//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants",
......
......@@ -59,6 +59,9 @@ id<GREYMatcher> PrimaryToolbar();
// Returns matcher for a cancel button.
id<GREYMatcher> CancelButton();
// Returns the matcher for an enabled cancel button in a navigation bar.
id<GREYMatcher> NavigationBarCancelButton();
// Returns matcher for a close button.
id<GREYMatcher> CloseButton();
......@@ -364,6 +367,43 @@ id<GREYMatcher> TabGridOtherDevicesPanelButton();
// Returns the GREYMatcher for the button to close the cell at |index| in the
// tab grid.
id<GREYMatcher> TabGridCloseButtonForCellAtIndex(unsigned int index);
}
// Returns a matcher for the password settings collection view.
id<GREYMatcher> SettingsPasswordMatcher();
// Returns a matcher for the search bar in password settings.
id<GREYMatcher> SettingsPasswordSearchMatcher();
#pragma mark - Manual Fallback
// Returns a matcher for the keyboard icon in the keyboard accessory bar.
id<GREYMatcher> ManualFallbackKeyboardIconMatcher();
// Returns a matcher for the password icon in the keyboard accessory bar.
id<GREYMatcher> ManualFallbackPasswordIconMatcher();
// Returns a matcher for the password table view in manual fallback.
id<GREYMatcher> ManualFallbackPasswordTableViewMatcher();
// Returns a matcher for the password search bar in manual fallback.
id<GREYMatcher> ManualFallbackPasswordSearchBarMatcher();
// Returns a matcher for the button to open password settings in manual
// fallback.
id<GREYMatcher> ManualFallbackManagePasswordsMatcher();
// Returns a matcher for the button to open all passwords in manual fallback.
id<GREYMatcher> ManualFallbackOtherPasswordsMatcher();
// Returns a matcher for the button to dismiss all passwords in manual fallback.
id<GREYMatcher> ManualFallbackOtherPasswordsDismissMatcher();
// Returns a matcher for the a password in the manual fallback list.
id<GREYMatcher> ManualFallbackPasswordButtonMatcher();
// Returns a matcher for the PasswordTableView window.
id<GREYMatcher> ManualFallbackPasswordTableViewWindowMatcher();
} // namespace chrome_test_util
#endif // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_H_
......@@ -73,6 +73,10 @@ id<GREYMatcher> CancelButton() {
return [ChromeMatchersAppInterface cancelButton];
}
id<GREYMatcher> NavigationBarCancelButton() {
return [ChromeMatchersAppInterface navigationBarCancelButton];
}
id<GREYMatcher> CloseButton() {
return [ChromeMatchersAppInterface closeButton];
}
......@@ -455,4 +459,52 @@ id<GREYMatcher> TabGridCloseButtonForCellAtIndex(unsigned int index) {
return [ChromeMatchersAppInterface tabGridCloseButtonForCellAtIndex:index];
}
id<GREYMatcher> SettingsPasswordMatcher() {
return [ChromeMatchersAppInterface settingsPasswordMatcher];
}
id<GREYMatcher> SettingsPasswordSearchMatcher() {
return [ChromeMatchersAppInterface settingsPasswordSearchMatcher];
}
#pragma mark - Manual Fallback
id<GREYMatcher> ManualFallbackKeyboardIconMatcher() {
return [ChromeMatchersAppInterface manualFallbackKeyboardIconMatcher];
}
id<GREYMatcher> ManualFallbackPasswordIconMatcher() {
return [ChromeMatchersAppInterface manualFallbackPasswordIconMatcher];
}
id<GREYMatcher> ManualFallbackPasswordTableViewMatcher() {
return [ChromeMatchersAppInterface manualFallbackPasswordTableViewMatcher];
}
id<GREYMatcher> ManualFallbackPasswordSearchBarMatcher() {
return [ChromeMatchersAppInterface manualFallbackPasswordSearchBarMatcher];
}
id<GREYMatcher> ManualFallbackManagePasswordsMatcher() {
return [ChromeMatchersAppInterface manualFallbackManagePasswordsMatcher];
}
id<GREYMatcher> ManualFallbackOtherPasswordsMatcher() {
return [ChromeMatchersAppInterface manualFallbackOtherPasswordsMatcher];
}
id<GREYMatcher> ManualFallbackOtherPasswordsDismissMatcher() {
return
[ChromeMatchersAppInterface manualFallbackOtherPasswordsDismissMatcher];
}
id<GREYMatcher> ManualFallbackPasswordButtonMatcher() {
return [ChromeMatchersAppInterface manualFallbackPasswordButtonMatcher];
}
id<GREYMatcher> ManualFallbackPasswordTableViewWindowMatcher() {
return
[ChromeMatchersAppInterface manualFallbackPasswordTableViewWindowMatcher];
}
} // namespace chrome_test_util
......@@ -62,6 +62,9 @@
// Returns matcher for a cancel button.
+ (id<GREYMatcher>)cancelButton;
// Returns the matcher for an enabled cancel button in a navigation bar.
+ (id<GREYMatcher>)navigationBarCancelButton;
// Returns matcher for a close button.
+ (id<GREYMatcher>)closeButton;
......@@ -370,6 +373,42 @@
// tab grid.
+ (id<GREYMatcher>)tabGridCloseButtonForCellAtIndex:(unsigned int)index;
// Returns a matcher for the password settings collection view.
+ (id<GREYMatcher>)settingsPasswordMatcher;
// Returns a matcher for the search bar in password settings.
+ (id<GREYMatcher>)settingsPasswordSearchMatcher;
#pragma mark - Manual Fallback
// Returns a matcher for the keyboard icon in the keyboard accessory bar.
+ (id<GREYMatcher>)manualFallbackKeyboardIconMatcher;
// Returns a matcher for the password icon in the keyboard accessory bar.
+ (id<GREYMatcher>)manualFallbackPasswordIconMatcher;
// Returns a matcher for the password table view in manual fallback.
+ (id<GREYMatcher>)manualFallbackPasswordTableViewMatcher;
// Returns a matcher for the password search bar in manual fallback.
+ (id<GREYMatcher>)manualFallbackPasswordSearchBarMatcher;
// Returns a matcher for the button to open password settings in manual
// fallback.
+ (id<GREYMatcher>)manualFallbackManagePasswordsMatcher;
// Returns a matcher for the button to open all passwords in manual fallback.
+ (id<GREYMatcher>)manualFallbackOtherPasswordsMatcher;
// Returns a matcher for the button to dismiss all passwords in manual fallback.
+ (id<GREYMatcher>)manualFallbackOtherPasswordsDismissMatcher;
// Returns a matcher for the a password in the manual fallback list.
+ (id<GREYMatcher>)manualFallbackPasswordButtonMatcher;
// Returns a matcher for the PasswordTableView window.
+ (id<GREYMatcher>)manualFallbackPasswordTableViewWindowMatcher;
@end
#endif // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_APP_INTERFACE_H_
......@@ -9,6 +9,10 @@
#include "components/strings/grit/components_strings.h"
#include "components/unified_consent/feature.h"
#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view.h"
#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h"
#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.h"
#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_mediator.h"
#import "ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_ui_constants.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h"
#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
......@@ -32,6 +36,7 @@
#import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h"
#import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/password/passwords_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/privacy_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/settings_table_view_controller.h"
#import "ios/chrome/browser/ui/static_content/static_html_view_controller.h"
......@@ -223,6 +228,13 @@ UIView* SubviewWithAccessibilityIdentifier(NSString* accessibility_id,
[ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(IDS_CANCEL)];
}
+ (id<GREYMatcher>)navigationBarCancelButton {
return grey_allOf(
grey_ancestor(grey_kindOfClass([UINavigationBar class])),
[self cancelButton],
grey_not(grey_accessibilityTrait(UIAccessibilityTraitNotEnabled)), nil);
}
+ (id<GREYMatcher>)closeButton {
return grey_allOf(
[ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(IDS_CLOSE)],
......@@ -721,4 +733,60 @@ UIView* SubviewWithAccessibilityIdentifier(NSString* accessibility_id,
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)settingsPasswordMatcher {
return grey_accessibilityID(kPasswordsTableViewId);
}
+ (id<GREYMatcher>)settingsPasswordSearchMatcher {
return grey_accessibilityID(kPasswordsSearchBarId);
}
#pragma mark - Manual Fallback
+ (id<GREYMatcher>)manualFallbackPasswordIconMatcher {
return grey_accessibilityID(
manual_fill::AccessoryPasswordAccessibilityIdentifier);
}
+ (id<GREYMatcher>)manualFallbackKeyboardIconMatcher {
return grey_accessibilityID(
manual_fill::AccessoryKeyboardAccessibilityIdentifier);
}
+ (id<GREYMatcher>)manualFallbackPasswordTableViewMatcher {
return grey_accessibilityID(
manual_fill::kPasswordTableViewAccessibilityIdentifier);
}
+ (id<GREYMatcher>)manualFallbackPasswordSearchBarMatcher {
return grey_accessibilityID(
manual_fill::kPasswordSearchBarAccessibilityIdentifier);
}
+ (id<GREYMatcher>)manualFallbackManagePasswordsMatcher {
return grey_accessibilityID(
manual_fill::ManagePasswordsAccessibilityIdentifier);
}
+ (id<GREYMatcher>)manualFallbackOtherPasswordsMatcher {
return grey_accessibilityID(
manual_fill::OtherPasswordsAccessibilityIdentifier);
}
+ (id<GREYMatcher>)manualFallbackOtherPasswordsDismissMatcher {
return grey_accessibilityID(
manual_fill::kPasswordDoneButtonAccessibilityIdentifier);
}
+ (id<GREYMatcher>)manualFallbackPasswordButtonMatcher {
return grey_buttonTitle(kMaskedPasswordTitle);
}
+ (id<GREYMatcher>)manualFallbackPasswordTableViewWindowMatcher {
id<GREYMatcher> classMatcher = grey_kindOfClass([UIWindow class]);
id<GREYMatcher> parentMatcher =
grey_descendant([self manualFallbackPasswordTableViewMatcher]);
return grey_allOf(classMatcher, parentMatcher, nil);
}
@end
......@@ -58,6 +58,7 @@ chrome_ios_eg2_test("ios_chrome_ui_eg2tests_module") {
deps = [
"//ios/chrome/browser/ui/activity_services:eg2_tests",
"//ios/chrome/browser/ui/autofill/manual_fill:eg2_tests",
"//ios/chrome/browser/ui/content_suggestions:eg2_tests",
"//ios/chrome/browser/ui/download:eg2_tests",
"//ios/chrome/browser/ui/integration_tests: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