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") { ...@@ -161,3 +161,55 @@ source_set("eg_tests") {
"XCTest.framework", "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") { ...@@ -190,6 +190,7 @@ source_set("requesters") {
} }
source_set("eg_tests") { source_set("eg_tests") {
defines = [ "CHROME_EARL_GREY_1" ]
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
testonly = true testonly = true
sources = [ sources = [
...@@ -210,11 +211,10 @@ source_set("eg_tests") { ...@@ -210,11 +211,10 @@ source_set("eg_tests") {
"//components/autofill/core/common", "//components/autofill/core/common",
"//components/autofill/ios/browser", "//components/autofill/ios/browser",
"//components/keyed_service/core", "//components/keyed_service/core",
"//components/password_manager/core/browser",
"//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/app/strings:ios_strings_grit",
"//ios/chrome/browser", "//ios/chrome/browser",
"//ios/chrome/browser/autofill", "//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",
"//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",
...@@ -231,3 +231,28 @@ source_set("eg_tests") { ...@@ -231,3 +231,28 @@ source_set("eg_tests") {
"//third_party/ocmock", "//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 @@ ...@@ -2,34 +2,16 @@
// 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>
#import <EarlGrey/GREYKeyboard.h>
#include "base/ios/ios_util.h" #include "base/ios/ios_util.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#import "base/test/ios/wait_util.h" #import "base/test/ios/wait_util.h"
#include "components/autofill/core/common/autofill_features.h" #import "ios/chrome/browser/ui/autofill/autofill_app_interface.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"
#include "ios/chrome/grit/ios_strings.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_actions.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_matchers.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/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 "ios/web/public/test/element_selector.h"
#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -38,8 +20,30 @@ ...@@ -38,8 +20,30 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #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::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::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::StaticTextWithAccessibilityLabelId;
using chrome_test_util::TapWebElementWithId; using chrome_test_util::TapWebElementWithId;
using chrome_test_util::TapWebElementWithIdInFrame; using chrome_test_util::TapWebElementWithIdInFrame;
...@@ -50,196 +54,29 @@ const char kFormElementUsername[] = "username"; ...@@ -50,196 +54,29 @@ const char kFormElementUsername[] = "username";
const char kFormElementPassword[] = "password"; const char kFormElementPassword[] = "password";
const char kExampleUsername[] = "concrete username"; const char kExampleUsername[] = "concrete username";
const char kExamplePassword[] = "concrete password";
const char kFormHTMLFile[] = "/username_password_field_form.html"; 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() { // TODO(crbug.com/1016367): Remove the guard once ExecuteJavaScript is updated
return grey_accessibilityID( // to compile on EG2.
manual_fill::kPasswordDoneButtonAccessibilityIdentifier); #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. // Returns a matcher for the example username in the list.
id<GREYMatcher> UsernameButtonMatcher() { id<GREYMatcher> UsernameButtonMatcher() {
return grey_buttonTitle(base::SysUTF8ToNSString(kExampleUsername)); 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. // Matcher for the not secure website alert.
id<GREYMatcher> NotSecureWebsiteAlert() { id<GREYMatcher> NotSecureWebsiteAlert() {
return StaticTextWithAccessibilityLabelId( return StaticTextWithAccessibilityLabelId(
IDS_IOS_MANUAL_FALLBACK_NOT_SECURE_TITLE); IDS_IOS_MANUAL_FALLBACK_NOT_SECURE_TITLE);
} }
// Returns a matcher for the PasswordTableView window. // TODO(crbug.com/1016367): Remove the guard once ExecuteJavaScript is updated
id<GREYMatcher> PasswordTableViewWindowMatcher() { // to compile on EG2.
id<GREYMatcher> classMatcher = grey_kindOfClass([UIWindow class]); #if defined(CHROME_EARL_GREY_1)
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.");
}
// Polls the JavaScript query |java_script_condition| until the returned // Polls the JavaScript query |java_script_condition| until the returned
// |boolValue| is YES with a kWaitForActionTimeout timeout. // |boolValue| is YES with a kWaitForActionTimeout timeout.
BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
...@@ -254,6 +91,7 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -254,6 +91,7 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
[GREYCondition conditionWithName:condition_name block:verify_block]; [GREYCondition conditionWithName:condition_name block:verify_block];
return [condition waitWithTimeout:timeout]; return [condition waitWithTimeout:timeout];
} }
#endif // CHROME_EARL_GREY_1
} // namespace } // namespace
...@@ -269,13 +107,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -269,13 +107,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
const GURL URL = self.testServer->GetURL(kFormHTMLFile); const GURL URL = self.testServer->GetURL(kFormHTMLFile);
[ChromeEarlGrey loadURL:URL]; [ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"hello!"]; [ChromeEarlGrey waitForWebStateContainingText:"hello!"];
SaveExamplePasswordForm(); [AutofillAppInterface saveExamplePasswordForm];
} }
- (void)tearDown { - (void)tearDown {
ClearPasswordStore(); [AutofillAppInterface clearPasswordStore];
[EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait
errorOrNil:nil];
[super tearDown]; [super tearDown];
} }
...@@ -286,11 +122,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -286,11 +122,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller table view is visible. // Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
} }
...@@ -302,11 +138,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -302,11 +138,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller contains the "Manage Passwords..." action. // Verify the password controller contains the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:ManagePasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()]
assertWithMatcher:grey_interactable()]; assertWithMatcher:grey_interactable()];
} }
...@@ -317,15 +153,15 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -317,15 +153,15 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Tap the "Manage Passwords..." action. // Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:ManagePasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password settings opened. // Verify the password settings opened.
[[EarlGrey selectElementWithMatcher:PasswordSettingsMatcher()] [[EarlGrey selectElementWithMatcher:SettingsPasswordMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
} }
...@@ -337,35 +173,35 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -337,35 +173,35 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the status of the icon. // Verify the status of the icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_not(grey_userInteractionEnabled())]; assertWithMatcher:grey_not(grey_userInteractionEnabled())];
// Tap the "Manage Passwords..." action. // Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:ManagePasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password settings opened. // Verify the password settings opened.
[[EarlGrey selectElementWithMatcher:PasswordSettingsMatcher()] [[EarlGrey selectElementWithMatcher:SettingsPasswordMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
// Tap Cancel Button. // Tap Cancel Button.
[[EarlGrey selectElementWithMatcher:NavigationBarCancelMatcher()] [[EarlGrey selectElementWithMatcher:NavigationBarCancelButton()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the status of the icons. // Verify the status of the icons.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()]; assertWithMatcher:grey_userInteractionEnabled()];
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())]; assertWithMatcher:grey_not(grey_sufficientlyVisible())];
// Verify the keyboard is not cover by the password view. // Verify the keyboard is not cover by the password view.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
} }
...@@ -376,15 +212,16 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -376,15 +212,16 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Tap the "Manage Passwords..." action. // Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the use other passwords opened. // Verify the use other passwords opened.
[[EarlGrey selectElementWithMatcher:OtherPasswordsDismissMatcher()] [[EarlGrey
selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
} }
...@@ -396,19 +233,20 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -396,19 +233,20 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the status of the icon. // Verify the status of the icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_not(grey_userInteractionEnabled())]; assertWithMatcher:grey_not(grey_userInteractionEnabled())];
// Tap the "Manage Passwords..." action. // Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the use other passwords opened. // Verify the use other passwords opened.
[[EarlGrey selectElementWithMatcher:OtherPasswordsDismissMatcher()] [[EarlGrey
selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
// Tap Cancel Button. // Tap Cancel Button.
...@@ -416,15 +254,15 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -416,15 +254,15 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the status of the icons. // Verify the status of the icons.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()]; assertWithMatcher:grey_userInteractionEnabled()];
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())]; assertWithMatcher:grey_not(grey_sufficientlyVisible())];
// Verify the keyboard is not cover by the password view. // Verify the keyboard is not cover by the password view.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
} }
...@@ -435,20 +273,21 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -435,20 +273,21 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Tap the "Manage Passwords..." action. // Tap the "Manage Passwords..." action.
[[EarlGrey selectElementWithMatcher:ManagePasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackManagePasswordsMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Tap the password search. // Tap the password search.
[[EarlGrey selectElementWithMatcher:PasswordSettingsSearchMatcher()] [[EarlGrey selectElementWithMatcher:SettingsPasswordSearchMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify keyboard is shown without the password controller. // Verify keyboard is shown without the password controller.
GREYAssertTrue([GREYKeyboard isKeyboardShown], @"Keyboard Should be Shown"); GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] @"Keyboard Should be Shown");
[[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
} }
...@@ -461,17 +300,18 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -461,17 +300,18 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Tap the "Other Passwords..." action. // Tap the "Other Passwords..." action.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Tap the password search. // Tap the password search.
[[EarlGrey selectElementWithMatcher:PasswordSearchBarMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordSearchBarMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
GREYAssertTrue([GREYKeyboard isKeyboardShown], @"Keyboard Should be Shown"); GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// Select a username. // Select a username.
[[EarlGrey selectElementWithMatcher:UsernameButtonMatcher()] [[EarlGrey selectElementWithMatcher:UsernameButtonMatcher()]
...@@ -479,17 +319,13 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -479,17 +319,13 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
// Wait for the password list to disappear. Using the search bar, since the // Wait for the password list to disappear. Using the search bar, since the
// popover doesn't have it. // popover doesn't have it.
[[EarlGrey selectElementWithMatcher:PasswordSearchBarMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordSearchBarMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
// Only on iOS 11.3 it is certain that on iPhones the keyboard is back. On iOS [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
// 11.0-11.2, it varies by device and version. assertWithMatcher:grey_sufficientlyVisible()];
if ([GREYKeyboard isKeyboardShown]) { [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] assertWithMatcher:grey_sufficientlyVisible()];
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
} }
// Tests that the Password View Controller is resumed after dismissing "Other // Tests that the Password View Controller is resumed after dismissing "Other
...@@ -501,30 +337,27 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -501,30 +337,27 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Tap the "Other Passwords..." action. // Tap the "Other Passwords..." action.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Dismiss the Other Passwords view. // Dismiss the Other Passwords view.
[[EarlGrey selectElementWithMatcher:OtherPasswordsDismissMatcher()] [[EarlGrey
selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Wait for the password list to disappear. Using the search bar, since the // Wait for the password list to disappear. Using the search bar, since the
// popover doesn't have it. // popover doesn't have it.
[[EarlGrey selectElementWithMatcher:PasswordSearchBarMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordSearchBarMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
// Only on iOS 11.3 it is certain that on iPhones the keyboard is back. On iOS [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
// 11.0-11.2, it varies by device and version. assertWithMatcher:grey_sufficientlyVisible()];
if ([GREYKeyboard isKeyboardShown]) { [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] assertWithMatcher:grey_sufficientlyVisible()];
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
} }
// Tests that the Password View Controller is dismissed when tapping the // Tests that the Password View Controller is dismissed when tapping the
...@@ -539,22 +372,22 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -539,22 +372,22 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller table view is visible. // Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
// Tap on the keyboard icon. // Tap on the keyboard icon.
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller table view and the password icon is NOT // Verify the password controller table view and the password icon is NOT
// visible. // visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
} }
...@@ -569,27 +402,28 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -569,27 +402,28 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller table view is visible. // Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
// Tap on a point outside of the popover. // Tap on a point outside of the popover.
// The way EarlGrey taps doesn't go through the window hierarchy. Because of // 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. // 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))]; performAction:grey_tapAtPoint(CGPointMake(0, 0))];
// Verify the password controller table view is not visible and the password // Verify the password controller table view is not visible and the password
// icon is visible. // icon is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_interactable()]; assertWithMatcher:grey_interactable()];
// Verify the interaction status of the password icon. // Verify the interaction status of the password icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()]; assertWithMatcher:grey_userInteractionEnabled()];
} }
...@@ -606,21 +440,21 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -606,21 +440,21 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller table view is visible. // Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
performAction:grey_typeText(@"text")]; performAction:grey_typeText(@"text")];
// Verify the password controller table view and the password icon is NOT // Verify the password controller table view and the password icon is NOT
// visible. // visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
[[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
} }
...@@ -632,11 +466,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -632,11 +466,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the "Manage Passwords..." is on screen. // Verify the "Manage Passwords..." is on screen.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
// Tap the second element. // Tap the second element.
...@@ -644,11 +478,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -644,11 +478,11 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementPassword)]; performAction:TapWebElementWithId(kFormElementPassword)];
// Try to scroll. // Try to scroll.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)]; performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)];
// Verify the "Manage Passwords..." is on screen. // Verify the "Manage Passwords..." is on screen.
[[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
} }
...@@ -659,46 +493,46 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -659,46 +493,46 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller table view is visible. // Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
[EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft [ChromeEarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
errorOrNil:nil]; error:nil];
// Verify the password controller table view is still visible. // Verify the password controller table view is still visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; 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. // Tests that content is injected in iframe messaging.
- (void)testPasswordControllerSupportsIFrameMessaging { - (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); const GURL URL = self.testServer->GetURL(kIFrameHTMLFile);
[ChromeEarlGrey loadURL:URL]; [ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"iFrame"]; [ChromeEarlGrey waitForWebStateContainingText:"iFrame"];
SaveLocalPasswordForm(URL); NSString* URLString = base::SysUTF8ToNSString(URL.spec());
[AutofillAppInterface savePasswordFormForURLSpec:URLString];
// Bring up the keyboard. // Bring up the keyboard.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:TapWebElementWithIdInFrame(kFormElementUsername, 0)]; performAction:TapWebElementWithIdInFrame(kFormElementUsername, 0)];
// Wait for the accessory icon to appear. // Wait for the accessory icon to appear.
[GREYKeyboard waitForKeyboardToAppear]; GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller table view is visible. // Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
// Select a username. // Select a username.
...@@ -712,30 +546,34 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -712,30 +546,34 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
kFormElementUsername, kExampleUsername]; kFormElementUsername, kExampleUsername];
XCTAssertTrue(WaitForJavaScriptCondition(javaScriptCondition)); XCTAssertTrue(WaitForJavaScriptCondition(javaScriptCondition));
} }
#endif // CHROME_EARL_GREY_1
// Tests that an alert is shown when trying to fill a password in an unsecure // Tests that an alert is shown when trying to fill a password in an unsecure
// field. // field.
- (void)testPasswordControllerPresentsUnsecureAlert { - (void)testPasswordControllerPresentsUnsecureAlert {
const GURL URL = self.testServer->GetURL(kFormHTMLFile); 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. // Bring up the keyboard.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Wait for the accessory icon to appear. // Wait for the accessory icon to appear.
[GREYKeyboard waitForKeyboardToAppear]; GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// Tap on the passwords icon. // Tap on the passwords icon.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Verify the password controller table view is visible. // Verify the password controller table view is visible.
[[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
// Select a password. // Select a password.
[[EarlGrey selectElementWithMatcher:PasswordButtonMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordButtonMatcher()]
performAction:grey_tap()]; performAction:grey_tap()];
// Look for the alert. // Look for the alert.
...@@ -745,28 +583,29 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) { ...@@ -745,28 +583,29 @@ BOOL WaitForJavaScriptCondition(NSString* java_script_condition) {
// Tests that the password icon is hidden when no passwords are available. // Tests that the password icon is hidden when no passwords are available.
- (void)testPasswordIconIsNotVisibleWhenPasswordStoreEmpty { - (void)testPasswordIconIsNotVisibleWhenPasswordStoreEmpty {
ClearPasswordStore(); [AutofillAppInterface clearPasswordStore];
// Bring up the keyboard. // Bring up the keyboard.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:TapWebElementWithId(kFormElementUsername)]; performAction:TapWebElementWithId(kFormElementUsername)];
// Wait for the keyboard to appear. // Wait for the keyboard to appear.
[GREYKeyboard waitForKeyboardToAppear]; GREYAssertTrue([ChromeEarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// Assert the password icon is not visible. // Assert the password icon is not visible.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_notVisible()]; assertWithMatcher:grey_notVisible()];
// Store one password. // Store one password.
SaveExamplePasswordForm(); [AutofillAppInterface saveExamplePasswordForm];
// Tap another field to trigger form activity. // Tap another field to trigger form activity.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:TapWebElementWithId(kFormElementPassword)]; performAction:TapWebElementWithId(kFormElementPassword)];
// Assert the password icon is visible now. // Assert the password icon is visible now.
[[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()]; assertWithMatcher:grey_sufficientlyVisible()];
} }
......
...@@ -240,6 +240,8 @@ source_set("test_support") { ...@@ -240,6 +240,8 @@ source_set("test_support") {
"//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication:authentication", "//ios/chrome/browser/ui/authentication:authentication",
"//ios/chrome/browser/ui/authentication/cells", "//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/bookmarks:bookmarks_ui",
"//ios/chrome/browser/ui/collection_view/cells", "//ios/chrome/browser/ui/collection_view/cells",
"//ios/chrome/browser/ui/commands:commands", "//ios/chrome/browser/ui/commands:commands",
...@@ -261,6 +263,7 @@ source_set("test_support") { ...@@ -261,6 +263,7 @@ source_set("test_support") {
"//ios/chrome/browser/ui/settings/clear_browsing_data", "//ios/chrome/browser/ui/settings/clear_browsing_data",
"//ios/chrome/browser/ui/settings/credit_card_scanner", "//ios/chrome/browser/ui/settings/credit_card_scanner",
"//ios/chrome/browser/ui/settings/google_services", "//ios/chrome/browser/ui/settings/google_services",
"//ios/chrome/browser/ui/settings/password",
"//ios/chrome/browser/ui/settings/sync", "//ios/chrome/browser/ui/settings/sync",
"//ios/chrome/browser/ui/static_content", "//ios/chrome/browser/ui/static_content",
"//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants", "//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants",
...@@ -361,6 +364,9 @@ source_set("eg_app_support+eg2") { ...@@ -361,6 +364,9 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/browser/ntp:features", "//ios/chrome/browser/ntp:features",
"//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication/cells", "//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/bookmarks:bookmarks_ui",
"//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant", "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant",
"//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui", "//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui",
...@@ -380,6 +386,7 @@ source_set("eg_app_support+eg2") { ...@@ -380,6 +386,7 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/browser/ui/settings/clear_browsing_data", "//ios/chrome/browser/ui/settings/clear_browsing_data",
"//ios/chrome/browser/ui/settings/credit_card_scanner", "//ios/chrome/browser/ui/settings/credit_card_scanner",
"//ios/chrome/browser/ui/settings/google_services", "//ios/chrome/browser/ui/settings/google_services",
"//ios/chrome/browser/ui/settings/password",
"//ios/chrome/browser/ui/settings/sync", "//ios/chrome/browser/ui/settings/sync",
"//ios/chrome/browser/ui/static_content", "//ios/chrome/browser/ui/static_content",
"//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants", "//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants",
......
...@@ -59,6 +59,9 @@ id<GREYMatcher> PrimaryToolbar(); ...@@ -59,6 +59,9 @@ id<GREYMatcher> PrimaryToolbar();
// Returns matcher for a cancel button. // Returns matcher for a cancel button.
id<GREYMatcher> CancelButton(); id<GREYMatcher> CancelButton();
// Returns the matcher for an enabled cancel button in a navigation bar.
id<GREYMatcher> NavigationBarCancelButton();
// Returns matcher for a close button. // Returns matcher for a close button.
id<GREYMatcher> CloseButton(); id<GREYMatcher> CloseButton();
...@@ -364,6 +367,43 @@ id<GREYMatcher> TabGridOtherDevicesPanelButton(); ...@@ -364,6 +367,43 @@ id<GREYMatcher> TabGridOtherDevicesPanelButton();
// Returns the GREYMatcher for the button to close the cell at |index| in the // Returns the GREYMatcher for the button to close the cell at |index| in the
// tab grid. // tab grid.
id<GREYMatcher> TabGridCloseButtonForCellAtIndex(unsigned int index); 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_ #endif // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_H_
...@@ -73,6 +73,10 @@ id<GREYMatcher> CancelButton() { ...@@ -73,6 +73,10 @@ id<GREYMatcher> CancelButton() {
return [ChromeMatchersAppInterface cancelButton]; return [ChromeMatchersAppInterface cancelButton];
} }
id<GREYMatcher> NavigationBarCancelButton() {
return [ChromeMatchersAppInterface navigationBarCancelButton];
}
id<GREYMatcher> CloseButton() { id<GREYMatcher> CloseButton() {
return [ChromeMatchersAppInterface closeButton]; return [ChromeMatchersAppInterface closeButton];
} }
...@@ -455,4 +459,52 @@ id<GREYMatcher> TabGridCloseButtonForCellAtIndex(unsigned int index) { ...@@ -455,4 +459,52 @@ id<GREYMatcher> TabGridCloseButtonForCellAtIndex(unsigned int index) {
return [ChromeMatchersAppInterface tabGridCloseButtonForCellAtIndex: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 } // namespace chrome_test_util
...@@ -62,6 +62,9 @@ ...@@ -62,6 +62,9 @@
// Returns matcher for a cancel button. // Returns matcher for a cancel button.
+ (id<GREYMatcher>)cancelButton; + (id<GREYMatcher>)cancelButton;
// Returns the matcher for an enabled cancel button in a navigation bar.
+ (id<GREYMatcher>)navigationBarCancelButton;
// Returns matcher for a close button. // Returns matcher for a close button.
+ (id<GREYMatcher>)closeButton; + (id<GREYMatcher>)closeButton;
...@@ -370,6 +373,42 @@ ...@@ -370,6 +373,42 @@
// tab grid. // tab grid.
+ (id<GREYMatcher>)tabGridCloseButtonForCellAtIndex:(unsigned int)index; + (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 @end
#endif // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_APP_INTERFACE_H_ #endif // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_APP_INTERFACE_H_
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#include "components/unified_consent/feature.h" #include "components/unified_consent/feature.h"
#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view.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/bookmarks/bookmark_ui_constants.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h"
#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
...@@ -32,6 +36,7 @@ ...@@ -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/accounts_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.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/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/privacy_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/settings_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" #import "ios/chrome/browser/ui/static_content/static_html_view_controller.h"
...@@ -223,6 +228,13 @@ UIView* SubviewWithAccessibilityIdentifier(NSString* accessibility_id, ...@@ -223,6 +228,13 @@ UIView* SubviewWithAccessibilityIdentifier(NSString* accessibility_id,
[ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(IDS_CANCEL)]; [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 { + (id<GREYMatcher>)closeButton {
return grey_allOf( return grey_allOf(
[ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(IDS_CLOSE)], [ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(IDS_CLOSE)],
...@@ -721,4 +733,60 @@ UIView* SubviewWithAccessibilityIdentifier(NSString* accessibility_id, ...@@ -721,4 +733,60 @@ UIView* SubviewWithAccessibilityIdentifier(NSString* accessibility_id,
grey_sufficientlyVisible(), nil); 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 @end
...@@ -58,6 +58,7 @@ chrome_ios_eg2_test("ios_chrome_ui_eg2tests_module") { ...@@ -58,6 +58,7 @@ chrome_ios_eg2_test("ios_chrome_ui_eg2tests_module") {
deps = [ deps = [
"//ios/chrome/browser/ui/activity_services:eg2_tests", "//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/content_suggestions:eg2_tests",
"//ios/chrome/browser/ui/download:eg2_tests", "//ios/chrome/browser/ui/download:eg2_tests",
"//ios/chrome/browser/ui/integration_tests: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