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" ]
}
......@@ -2,34 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <EarlGrey/EarlGrey.h>
#import <EarlGrey/GREYKeyboard.h>
#include "base/ios/ios_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#import "base/test/ios/wait_util.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/password_form.h"
#include "components/autofill/ios/browser/autofill_switches.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/browser/ui/autofill/manual_fill/all_password_coordinator.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/settings/password/passwords_table_view_controller.h"
#import "ios/chrome/browser/ui/util/ui_util.h"
#import "ios/chrome/browser/ui/autofill/autofill_app_interface.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#import "ios/chrome/test/earl_grey/chrome_actions.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/web/public/test/earl_grey/web_view_matchers.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#include "ios/web/public/test/element_selector.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/gurl.h"
......@@ -38,8 +20,30 @@
#error "This file requires ARC support."
#endif
#if defined(CHROME_EARL_GREY_2)
// TODO(crbug.com/1015113): The EG2 macro is breaking indexing for some reason
// without the trailing semicolon. For now, disable the extra semi warning
// so Xcode indexing works for the egtest.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi"
GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(AutofillAppInterface);
#pragma clang diagnostic pop
#endif // defined(CHROME_EARL_GREY_2)
using chrome_test_util::CancelButton;
using chrome_test_util::ManualFallbackKeyboardIconMatcher;
using chrome_test_util::ManualFallbackPasswordIconMatcher;
using chrome_test_util::ManualFallbackPasswordTableViewMatcher;
using chrome_test_util::ManualFallbackPasswordSearchBarMatcher;
using chrome_test_util::ManualFallbackManagePasswordsMatcher;
using chrome_test_util::ManualFallbackOtherPasswordsMatcher;
using chrome_test_util::ManualFallbackOtherPasswordsDismissMatcher;
using chrome_test_util::ManualFallbackPasswordButtonMatcher;
using chrome_test_util::ManualFallbackPasswordTableViewWindowMatcher;
using chrome_test_util::NavigationBarDoneButton;
using chrome_test_util::NavigationBarCancelButton;
using chrome_test_util::SettingsPasswordMatcher;
using chrome_test_util::SettingsPasswordSearchMatcher;
using chrome_test_util::StaticTextWithAccessibilityLabelId;
using chrome_test_util::TapWebElementWithId;
using chrome_test_util::TapWebElementWithIdInFrame;
......@@ -50,196 +54,29 @@ const char kFormElementUsername[] = "username";
const char kFormElementPassword[] = "password";
const char kExampleUsername[] = "concrete username";
const char kExamplePassword[] = "concrete password";
const char kFormHTMLFile[] = "/username_password_field_form.html";
const char kIFrameHTMLFile[] = "/iframe_form.html";
// Returns a matcher for the password icon in the keyboard accessory bar.
id<GREYMatcher> PasswordIconMatcher() {
return grey_accessibilityID(
manual_fill::AccessoryPasswordAccessibilityIdentifier);
}
id<GREYMatcher> KeyboardIconMatcher() {
return grey_accessibilityID(
manual_fill::AccessoryKeyboardAccessibilityIdentifier);
}
// Returns a matcher for the password table view in manual fallback.
id<GREYMatcher> PasswordTableViewMatcher() {
return grey_accessibilityID(
manual_fill::kPasswordTableViewAccessibilityIdentifier);
}
// Returns a matcher for the password search bar in manual fallback.
id<GREYMatcher> PasswordSearchBarMatcher() {
return grey_accessibilityID(
manual_fill::kPasswordSearchBarAccessibilityIdentifier);
}
// Returns a matcher for the button to open password settings in manual
// fallback.
id<GREYMatcher> ManagePasswordsMatcher() {
return grey_accessibilityID(
manual_fill::ManagePasswordsAccessibilityIdentifier);
}
// Returns a matcher for the button to open all passwords in manual fallback.
id<GREYMatcher> OtherPasswordsMatcher() {
return grey_accessibilityID(
manual_fill::OtherPasswordsAccessibilityIdentifier);
}
id<GREYMatcher> OtherPasswordsDismissMatcher() {
return grey_accessibilityID(
manual_fill::kPasswordDoneButtonAccessibilityIdentifier);
}
// TODO(crbug.com/1016367): Remove the guard once ExecuteJavaScript is updated
// to compile on EG2.
#if defined(CHROME_EARL_GREY_1)
const char kIFrameHTMLFile[] = "/iframe_form.html";
#endif // CHROME_EARL_GREY_1
// Returns a matcher for the example username in the list.
id<GREYMatcher> UsernameButtonMatcher() {
return grey_buttonTitle(base::SysUTF8ToNSString(kExampleUsername));
}
// Returns a matcher for the example password in the list.
id<GREYMatcher> PasswordButtonMatcher() {
return grey_buttonTitle(kMaskedPasswordTitle);
}
// Returns a matcher for the password settings collection view.
id<GREYMatcher> PasswordSettingsMatcher() {
return grey_accessibilityID(kPasswordsTableViewId);
}
// Returns a matcher for the search bar in password settings.
id<GREYMatcher> PasswordSettingsSearchMatcher() {
return grey_accessibilityID(kPasswordsSearchBarId);
}
// Matcher for the not secure website alert.
id<GREYMatcher> NotSecureWebsiteAlert() {
return StaticTextWithAccessibilityLabelId(
IDS_IOS_MANUAL_FALLBACK_NOT_SECURE_TITLE);
}
// Returns a matcher for the PasswordTableView window.
id<GREYMatcher> PasswordTableViewWindowMatcher() {
id<GREYMatcher> classMatcher = grey_kindOfClass([UIWindow class]);
id<GREYMatcher> parentMatcher = grey_descendant(PasswordTableViewMatcher());
return grey_allOf(classMatcher, parentMatcher, nil);
}
// Returns the matcher for an enabled cancel button in a navigation bar.
id<GREYMatcher> NavigationBarCancelMatcher() {
return grey_allOf(
grey_ancestor(grey_kindOfClass([UINavigationBar class])), CancelButton(),
grey_not(grey_accessibilityTrait(UIAccessibilityTraitNotEnabled)), nil);
}
// 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);
bool responded = base::test::ios::WaitUntilConditionOrTimeout(1.0, ^bool {
return !AreObtainedReset();
});
GREYAssert(responded, @"Obtaining fillable items took too long.");
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;
}
GREYFail(@"Stored form was not found in the PasswordStore results.");
}
// 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 storefor 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;
GREYAssert(consumer.GetStoreResults().empty(),
@"PasswordStore was not cleared.");
}
// TODO(crbug.com/1016367): Remove the guard once ExecuteJavaScript is updated
// to compile on EG2.
#if defined(CHROME_EARL_GREY_1)
// Polls the JavaScript query |java_script_condition| until the returned
// |boolValue| is YES with a kWaitForActionTimeout timeout.
BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
......@@ -254,6 +91,7 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
[GREYCondition conditionWithName:condition_name block:verify_block];
return [condition waitWithTimeout:timeout];
}
#endif // CHROME_EARL_GREY_1
} // namespace
......@@ -269,13 +107,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
const GURL URL = self.testServer->GetURL(kFormHTMLFile);
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"hello!"];
SaveExamplePasswordForm();
[AutofillAppInterface saveExamplePasswordForm];
}
- (void)tearDown {
ClearPasswordStore();
[EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait
errorOrNil:nil];
[AutofillAppInterface clearPasswordStore];
[super tearDown];
}
......@@ -286,11 +122,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
......@@ -302,11 +138,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the password controller contains the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:ManagePasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()]
assertWithMatcher:grey_interactable()];
}
......@@ -317,15 +153,15 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:ManagePasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()]
performAction:grey_tap()];
// Verify the password settings opened.
[[EarlGrey selectElementWithMatcher:PasswordSettingsMatcher()]
[[EarlGrey selectElementWithMatcher:SettingsPasswordMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
......@@ -337,35 +173,35 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the status of the icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_not(grey_userInteractionEnabled())];
// Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:ManagePasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()]
performAction:grey_tap()];
// Verify the password settings opened.
[[EarlGrey selectElementWithMatcher:PasswordSettingsMatcher()]
[[EarlGrey selectElementWithMatcher:SettingsPasswordMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap Cancel Button.
[[EarlGrey selectElementWithMatcher:NavigationBarCancelMatcher()]
[[EarlGrey selectElementWithMatcher:NavigationBarCancelButton()]
performAction:grey_tap()];
// Verify the status of the icons.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()];
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())];
// Verify the keyboard is not cover by the password view.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
}
......@@ -376,15 +212,16 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
performAction:grey_tap()];
// Verify the use other passwords opened.
[[EarlGrey selectElementWithMatcher:OtherPasswordsDismissMatcher()]
[[EarlGrey
selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
......@@ -396,19 +233,20 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the status of the icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_not(grey_userInteractionEnabled())];
// Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
performAction:grey_tap()];
// Verify the use other passwords opened.
[[EarlGrey selectElementWithMatcher:OtherPasswordsDismissMatcher()]
[[EarlGrey
selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap Cancel Button.
......@@ -416,15 +254,15 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:grey_tap()];
// Verify the status of the icons.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()];
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())];
// Verify the keyboard is not cover by the password view.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
}
......@@ -435,20 +273,21 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:ManagePasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()]
performAction:grey_tap()];
// Tap the password search.
[[EarlGrey selectElementWithMatcher:PasswordSettingsSearchMatcher()]
[[EarlGrey selectElementWithMatcher:SettingsPasswordSearchMatcher()]
performAction:grey_tap()];
// Verify keyboard is shown without the password controller.
GREYAssertTrue([GREYKeyboard isKeyboardShown], @"Keyboard Should be Shown");
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
}
......@@ -461,17 +300,18 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Tap the "Other Passwords..." action.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
performAction:grey_tap()];
// Tap the password search.
[[EarlGrey selectElementWithMatcher:PasswordSearchBarMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordSearchBarMatcher()]
performAction:grey_tap()];
GREYAssertTrue([GREYKeyboard isKeyboardShown], @"Keyboard Should be Shown");
GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// Select a username.
[[EarlGrey selectElementWithMatcher:UsernameButtonMatcher()]
......@@ -479,17 +319,13 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
// Wait for the password list to disappear. Using the search bar, since the
// popover doesn't have it.
[[EarlGrey selectElementWithMatcher:PasswordSearchBarMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordSearchBarMatcher()]
assertWithMatcher:grey_notVisible()];
// Only on iOS 11.3 it is certain that on iPhones the keyboard is back. On iOS
// 11.0-11.2, it varies by device and version.
if ([GREYKeyboard isKeyboardShown]) {
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
}
// Tests that the Password View Controller is resumed after dismissing "Other
......@@ -501,30 +337,27 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Tap the "Other Passwords..." action.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
performAction:grey_tap()];
// Dismiss the Other Passwords view.
[[EarlGrey selectElementWithMatcher:OtherPasswordsDismissMatcher()]
[[EarlGrey
selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()]
performAction:grey_tap()];
// Wait for the password list to disappear. Using the search bar, since the
// popover doesn't have it.
[[EarlGrey selectElementWithMatcher:PasswordSearchBarMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordSearchBarMatcher()]
assertWithMatcher:grey_notVisible()];
// Only on iOS 11.3 it is certain that on iPhones the keyboard is back. On iOS
// 11.0-11.2, it varies by device and version.
if ([GREYKeyboard isKeyboardShown]) {
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
}
// Tests that the Password View Controller is dismissed when tapping the
......@@ -539,22 +372,22 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap on the keyboard icon.
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
performAction:grey_tap()];
// Verify the password controller table view and the password icon is NOT
// visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_notVisible()];
}
......@@ -569,27 +402,28 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap on a point outside of the popover.
// The way EarlGrey taps doesn't go through the window hierarchy. Because of
// this, the tap needs to be done in the same window as the popover.
[[EarlGrey selectElementWithMatcher:PasswordTableViewWindowMatcher()]
[[EarlGrey
selectElementWithMatcher:ManualFallbackPasswordTableViewWindowMatcher()]
performAction:grey_tapAtPoint(CGPointMake(0, 0))];
// Verify the password controller table view is not visible and the password
// icon is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_interactable()];
// Verify the interaction status of the password icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()];
}
......@@ -606,21 +440,21 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
performAction:grey_typeText(@"text")];
// Verify the password controller table view and the password icon is NOT
// visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_notVisible()];
}
......@@ -632,11 +466,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the "Manage Passwords..." is on screen.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap the second element.
......@@ -644,11 +478,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementPassword)];
// Try to scroll.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)];
// Verify the "Manage Passwords..." is on screen.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
......@@ -659,46 +493,46 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
errorOrNil:nil];
[ChromeEarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
error:nil];
// Verify the password controller table view is still visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
// TODO(crbug.com/1016367): Remove the guard of this test when ExecuteJavaScript
// util is updated for EG2.
#if defined(CHROME_EARL_GREY_1)
// Tests that content is injected in iframe messaging.
- (void)testPasswordControllerSupportsIFrameMessaging {
// Iframe messaging is not supported on iOS < 11.3.
if (!base::ios::IsRunningOnOrLater(11, 3, 0)) {
EARL_GREY_TEST_SKIPPED(@"Skipped for iOS < 11.3");
}
const GURL URL = self.testServer->GetURL(kIFrameHTMLFile);
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"iFrame"];
SaveLocalPasswordForm(URL);
NSString* URLString = base::SysUTF8ToNSString(URL.spec());
[AutofillAppInterface savePasswordFormForURLSpec:URLString];
// Bring up the keyboard.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:TapWebElementWithIdInFrame(kFormElementUsername, 0)];
// Wait for the accessory icon to appear.
[GREYKeyboard waitForKeyboardToAppear];
GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Select a username.
......@@ -712,30 +546,34 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
kFormElementUsername, kExampleUsername];
XCTAssertTrue(WaitForJavaScriptCondition(javaScriptCondition));
}
#endif // CHROME_EARL_GREY_1
// Tests that an alert is shown when trying to fill a password in an unsecure
// field.
- (void)testPasswordControllerPresentsUnsecureAlert {
const GURL URL = self.testServer->GetURL(kFormHTMLFile);
SaveLocalPasswordForm(URL);
// Only Objc objects can cross the EDO portal.
NSString* URLString = base::SysUTF8ToNSString(URL.spec());
[AutofillAppInterface savePasswordFormForURLSpec:URLString];
// Bring up the keyboard.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:TapWebElementWithId(kFormElementUsername)];
// Wait for the accessory icon to appear.
[GREYKeyboard waitForKeyboardToAppear];
GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()];
// Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Select a password.
[[EarlGrey selectElementWithMatcher:PasswordButtonMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordButtonMatcher()]
performAction:grey_tap()];
// Look for the alert.
......@@ -745,28 +583,29 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
// Tests that the password icon is hidden when no passwords are available.
- (void)testPasswordIconIsNotVisibleWhenPasswordStoreEmpty {
ClearPasswordStore();
[AutofillAppInterface clearPasswordStore];
// Bring up the keyboard.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:TapWebElementWithId(kFormElementUsername)];
// Wait for the keyboard to appear.
[GREYKeyboard waitForKeyboardToAppear];
GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// Assert the password icon is not visible.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_notVisible()];
// Store one password.
SaveExamplePasswordForm();
[AutofillAppInterface saveExamplePasswordForm];
// Tap another field to trigger form activity.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:TapWebElementWithId(kFormElementPassword)];
// Assert the password icon is visible now.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
......
......@@ -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