Commit 6236efae authored by Robbie Gibson's avatar Robbie Gibson Committed by Commit Bot

[iOS] Migrate credential manager egtest to eg2

Before any conversion, the tests failed when run on the bots with other
tests. After conversion, the tests pass when run by themselves locally
in both EG1 and EG2. The tests fail on EG1 bots when submitting, and I
can't tell whether they pass on EG2 bots because I can't find these
bots. I'm submitting with them only disabled on EG1, with the hope that
the EG2 migration will fix the ordering issue.

Bug: 987646
Change-Id: I006671d67f02fb2263c60eee6b330e419f5dfd62
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1871880
Commit-Queue: Robbie Gibson <rkgibson@google.com>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarStepan Khapugin <stkhapugin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709014}
parent 0ae98f43
......@@ -207,6 +207,7 @@ source_set("unit_tests") {
}
source_set("eg_tests") {
defines = [ "CHROME_EARL_GREY_1" ]
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
......@@ -214,18 +215,10 @@ source_set("eg_tests") {
]
deps = [
":passwords",
":feature_flags",
":test_support",
"//base",
"//base/test:test_support",
"//components/autofill/core/common",
"//components/autofill/ios/browser",
"//components/keyed_service/core",
"//components/password_manager/core/browser",
"//components/password_manager/core/browser:test_support",
"//components/password_manager/core/common",
"//components/password_manager/ios",
"//components/prefs",
"//components/prefs:test_support",
"//ios/chrome/test/app:test_support",
"//ios/chrome/test/earl_grey:test_support",
"//ios/testing/earl_grey:earl_grey_support",
......@@ -236,3 +229,84 @@ source_set("eg_tests") {
"XCTest.framework",
]
}
source_set("eg2_tests") {
defines = [ "CHROME_EARL_GREY_2" ]
configs += [
"//build/config/compiler:enable_arc",
"//build/config/ios:xctest_config",
]
testonly = true
sources = [
"credential_manager_egtest.mm",
]
deps = [
":eg_test_support+eg2",
":feature_flags",
"//base",
"//base/test:test_support",
"//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/http_server",
]
libs = [ "UIKit.framework" ]
}
source_set("test_support") {
defines = [ "CHROME_EARL_GREY_1" ]
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"password_manager_app_interface.h",
"password_manager_app_interface.mm",
]
deps = [
":passwords",
"//base",
"//components/autofill/core/common",
"//components/keyed_service/core",
"//components/password_manager/core/browser",
"//components/password_manager/core/common",
"//ios/chrome/test/app:test_support",
"//ios/testing:nserror_support",
"//ios/web/public",
]
}
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 = [
"password_manager_app_interface.h",
"password_manager_app_interface.mm",
]
deps = [
":passwords",
"//base",
"//components/autofill/core/common",
"//components/keyed_service/core",
"//components/password_manager/core/browser",
"//components/password_manager/core/common",
"//ios/chrome/test/app:test_support",
"//ios/testing:nserror_support",
"//ios/web/public",
]
}
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 = [
"password_manager_app_interface.h",
]
}
......@@ -2,9 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/chrome/browser/passwords/credential_manager.h"
#import <EarlGrey/EarlGrey.h>
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
......@@ -14,17 +12,16 @@
#include "base/strings/utf_string_conversions.h"
#import "base/test/ios/wait_util.h"
#include "base/test/scoped_feature_list.h"
#include "components/keyed_service/core/service_access_type.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
#import "ios/chrome/browser/passwords/password_manager_app_interface.h"
#include "ios/chrome/browser/passwords/password_manager_features.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#import "ios/chrome/test/app/tab_test_util.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/testing/earl_grey/app_launch_manager.h"
#import "ios/testing/earl_grey/disabled_test_macros.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "ios/web/public/test/http_server/http_server.h"
#include "ios/web/public/test/http_server/http_server_util.h"
......@@ -32,6 +29,15 @@
#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(PasswordManagerAppInterface);
#endif // defined(CHROME_EARL_GREY_2)
namespace {
// Notification should be displayed for 3 seconds. 4 should be safe to check.
......@@ -64,6 +70,7 @@ std::unique_ptr<net::test_server::HttpResponse> StandardResponse(
- (void)setUp {
_featureList.InitAndEnableFeature(features::kCredentialManager);
[super setUp];
// Set up server.
......@@ -72,29 +79,19 @@ std::unique_ptr<net::test_server::HttpResponse> StandardResponse(
}
- (void)tearDown {
scoped_refptr<password_manager::PasswordStore> passwordStore =
IOSChromePasswordStoreFactory::GetForBrowserState(
chrome_test_util::GetOriginalBrowserState(),
ServiceAccessType::IMPLICIT_ACCESS)
.get();
// Remove Credentials stored during executing the test.
passwordStore->RemoveLoginsCreatedBetween(base::Time(), base::Time::Now(),
base::Closure());
[PasswordManagerAppInterface clearCredentials];
[super tearDown];
}
#pragma mark - Utils
// Sets preferences required for autosign-in to true.
- (void)setAutosigninPreferences {
chrome_test_util::SetBooleanUserPref(
chrome_test_util::GetOriginalBrowserState(),
password_manager::prefs::kWasAutoSignInFirstRunExperienceShown, true);
chrome_test_util::SetBooleanUserPref(
chrome_test_util::GetOriginalBrowserState(),
password_manager::prefs::kCredentialsEnableAutosignin, true);
- (void)launchAppForTestMethod {
[[AppLaunchManager sharedManager]
ensureAppLaunchedWithFeaturesEnabled:{features::kCredentialManager}
disabled:{}
forceRestart:NO];
}
#pragma mark - Utils
// Loads simple page on localhost and stores an example PasswordCredential.
- (void)loadSimplePageAndStoreACredential {
// Loads simple page. It is on localhost so it is considered a secure context.
......@@ -102,41 +99,29 @@ std::unique_ptr<net::test_server::HttpResponse> StandardResponse(
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"You are here."];
// Obtain a PasswordStore.
scoped_refptr<password_manager::PasswordStore> passwordStore =
IOSChromePasswordStoreFactory::GetForBrowserState(
chrome_test_util::GetOriginalBrowserState(),
ServiceAccessType::IMPLICIT_ACCESS)
.get();
GREYAssertTrue(passwordStore != nullptr,
@"PasswordStore is unexpectedly null for BrowserState");
// Store a PasswordForm representing a PasswordCredential.
autofill::PasswordForm passwordCredentialForm;
passwordCredentialForm.username_value =
base::ASCIIToUTF16("johndoe@example.com");
passwordCredentialForm.password_value = base::ASCIIToUTF16("ilovejanedoe123");
passwordCredentialForm.origin =
chrome_test_util::GetCurrentWebState()->GetLastCommittedURL().GetOrigin();
passwordCredentialForm.signon_realm = passwordCredentialForm.origin.spec();
passwordCredentialForm.scheme = autofill::PasswordForm::Scheme::kHtml;
passwordStore->AddLogin(passwordCredentialForm);
NSError* error = [PasswordManagerAppInterface
storeCredentialWithUsername:@"johndoe@example.com"
password:@"ilovejanedoe123"];
GREYAssertNil(error, error.localizedDescription);
}
#pragma mark - Tests
// Tests that notification saying "Signing is as ..." appears on auto sign-in.
- (void)testNotificationAppearsOnAutoSignIn {
// TODO(crbug.com/786960): re-enable when fixed.
// TODO(crbug.com/786960): re-enable when fixed. Tests may pass on EG2
#if defined(CHROME_EARL_GREY_1)
EARL_GREY_TEST_DISABLED(@"Fails on iOS 11.0.");
#endif
[self setAutosigninPreferences];
[PasswordManagerAppInterface setAutosigninPreferences];
[self loadSimplePageAndStoreACredential];
// Call get() from JavaScript.
NSError* error = nil;
NSString* result = chrome_test_util::ExecuteJavaScript(
@"typeof navigator.credentials.get({password: true})", &error);
NSString* result = [ChromeEarlGreyAppInterface
executeJavaScript:@"typeof navigator.credentials.get({password: true})"
error:&error];
GREYAssertTrue([result isEqual:@"object"],
@"Unexpected error occurred when executing JavaScript.");
GREYAssertTrue(!error,
......@@ -174,22 +159,18 @@ std::unique_ptr<net::test_server::HttpResponse> StandardResponse(
// Tests that when navigator.credentials.get() was called from inactive tab, the
// autosign-in notification appears once tab becomes active.
- (void)testNotificationAppearsWhenTabIsActive {
// TODO(crbug.com/786960): re-enable when fixed.
// TODO(crbug.com/786960): re-enable when fixed. Tests may pass on EG2
#if defined(CHROME_EARL_GREY_1)
EARL_GREY_TEST_DISABLED(@"Fails on iOS 11.0.");
[self setAutosigninPreferences];
#endif
[PasswordManagerAppInterface setAutosigninPreferences];
[self loadSimplePageAndStoreACredential];
// Get WebState before switching the tab.
web::WebState* webState = chrome_test_util::GetCurrentWebState();
// Open new tab.
[ChromeEarlGreyUI openNewTab];
[ChromeEarlGrey waitForMainTabCount:2];
// Execute JavaScript from inactive tab.
webState->ExecuteJavaScript(
base::UTF8ToUTF16("typeof navigator.credentials.get({password: true})"));
[PasswordManagerAppInterface getCredentialsInTabAtIndex:0];
// Matches the UILabel by its accessibilityLabel.
id<GREYMatcher> matcher = chrome_test_util::StaticTextWithAccessibilityLabel(
......
// 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_PASSWORDS_PASSWORD_MANAGER_APP_INTERFACE_H_
#define IOS_CHROME_BROWSER_PASSWORDS_PASSWORD_MANAGER_APP_INTERFACE_H_
#import <UIKit/UIKit.h>
@interface PasswordManagerAppInterface : NSObject
// Sets preferences required for autosign-in to true.
+ (void)setAutosigninPreferences;
// Stores a credential to the password store.
+ (NSError*)storeCredentialWithUsername:(NSString*)username
password:(NSString*)password;
// Clears any credentials that were stored during a test run.
+ (void)clearCredentials;
// Executes the javascript to fetch credentials in a background tab. There must
// be two tabs open before calling this method.
+ (void)getCredentialsInTabAtIndex:(int)index;
@end
#endif // IOS_CHROME_BROWSER_PASSWORDS_PASSWORD_MANAGER_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/passwords/password_manager_app_interface.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/common/password_form.h"
#include "components/keyed_service/core/service_access_type.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#import "ios/chrome/test/app/tab_test_util.h"
#import "ios/testing/nserror_util.h"
#import "ios/web/public/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation PasswordManagerAppInterface
+ (void)setAutosigninPreferences {
chrome_test_util::SetBooleanUserPref(
chrome_test_util::GetOriginalBrowserState(),
password_manager::prefs::kWasAutoSignInFirstRunExperienceShown, true);
chrome_test_util::SetBooleanUserPref(
chrome_test_util::GetOriginalBrowserState(),
password_manager::prefs::kCredentialsEnableAutosignin, true);
}
+ (NSError*)storeCredentialWithUsername:(NSString*)username
password:(NSString*)password {
// Obtain a PasswordStore.
scoped_refptr<password_manager::PasswordStore> passwordStore =
IOSChromePasswordStoreFactory::GetForBrowserState(
chrome_test_util::GetOriginalBrowserState(),
ServiceAccessType::IMPLICIT_ACCESS)
.get();
if (passwordStore == nullptr) {
return testing::NSErrorWithLocalizedDescription(
@"PasswordStore is unexpectedly null for BrowserState");
}
// Store a PasswordForm representing a PasswordCredential.
autofill::PasswordForm passwordCredentialForm;
passwordCredentialForm.username_value = base::SysNSStringToUTF16(username);
passwordCredentialForm.password_value = base::SysNSStringToUTF16(password);
passwordCredentialForm.origin =
chrome_test_util::GetCurrentWebState()->GetLastCommittedURL().GetOrigin();
passwordCredentialForm.signon_realm = passwordCredentialForm.origin.spec();
passwordCredentialForm.scheme = autofill::PasswordForm::Scheme::kHtml;
passwordStore->AddLogin(passwordCredentialForm);
return nil;
}
+ (void)clearCredentials {
scoped_refptr<password_manager::PasswordStore> passwordStore =
IOSChromePasswordStoreFactory::GetForBrowserState(
chrome_test_util::GetOriginalBrowserState(),
ServiceAccessType::IMPLICIT_ACCESS)
.get();
// Remove credentials stored during executing the test.
passwordStore->RemoveLoginsCreatedBetween(base::Time(), base::Time::Now(),
base::Closure());
}
+ (void)getCredentialsInTabAtIndex:(int)index {
// Get WebState for the original tab.
web::WebState* webState =
chrome_test_util::GetWebStateAtIndexInCurrentMode(index);
// Execute JavaScript from inactive tab.
webState->ExecuteJavaScript(
base::UTF8ToUTF16("typeof navigator.credentials.get({password: true})"));
}
@end
......@@ -237,6 +237,8 @@ source_set("test_support") {
"//ios/chrome/browser/autofill",
"//ios/chrome/browser/content_settings:content_settings",
"//ios/chrome/browser/ntp:features",
"//ios/chrome/browser/passwords",
"//ios/chrome/browser/passwords:test_support",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication:authentication",
"//ios/chrome/browser/ui/authentication/cells",
......@@ -363,6 +365,8 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/browser/content_settings:content_settings",
"//ios/chrome/browser/device_sharing:eg_app_support+eg2",
"//ios/chrome/browser/ntp:features",
"//ios/chrome/browser/passwords",
"//ios/chrome/browser/passwords:eg_app_support+eg2",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication/cells",
"//ios/chrome/browser/ui/autofill:eg_app_support+eg2",
......
......@@ -36,6 +36,7 @@ chrome_ios_eg2_test("ios_chrome_integration_eg2tests_module") {
deps = [
"//ios/chrome/browser/device_sharing:eg2_tests",
"//ios/chrome/browser/ntp_tiles:eg2_tests",
"//ios/chrome/browser/passwords:eg2_tests",
"//ios/chrome/browser/prerender: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