Commit d7267e5d authored by Vasilii Sukhanov's avatar Vasilii Sukhanov Committed by Commit Bot

Reland: Change some password browser tests to produce user input.

Previous attempt: https://chromium-review.googlesource.com/c/chromium/src/+/1054675
This is a preparation CL for removing some code from PasswordAutofillAgent. Most of the tests in the file do not test the real behavior. We fill the username/password using JavaScript and it's a different code path from typing them manually.
The tests changed here are necessary to update. Let's land them first and observe if it introduces some flakiness before proceeding. They are interactive UI tests because actual typing is involved.

Bug: 842643
Change-Id: I81e8f444374012272433e514d12d398d850a15b9
Reviewed-on: https://chromium-review.googlesource.com/1059627
Commit-Queue: Vasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: default avatarVaclav Brozek <vabr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558789}
parent 7220276a
......@@ -255,8 +255,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
bubble_observer.AcceptSavePrompt();
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16("temp"),
base::ASCIIToUTF16("random"));
CheckThatCredentialsStored("temp", "random");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
......@@ -644,45 +643,6 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
EXPECT_TRUE(prompt_observer->IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
PromptForXHRWithoutOnSubmit) {
NavigateToFile("/password/password_xhr_submit.html");
// Verify that if XHR navigation occurs and the form is properly filled out,
// we try and save the password even though onsubmit hasn't been called.
NavigationObserver observer(WebContents());
std::unique_ptr<BubbleObserver> prompt_observer(
new BubbleObserver(WebContents()));
std::string fill_and_navigate =
"document.getElementById('username_field').value = 'temp';"
"document.getElementById('password_field').value = 'random';"
"send_xhr()";
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
observer.Wait();
EXPECT_TRUE(prompt_observer->IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
PromptForXHRWithNewPasswordsWithoutOnSubmit) {
NavigateToFile("/password/password_xhr_submit.html");
// Verify that if XHR navigation occurs and the form is properly filled out,
// we try and save the password even though onsubmit hasn't been called.
// Specifically verify that the password form saving new passwords is treated
// the same as a login form.
NavigationObserver observer(WebContents());
std::unique_ptr<BubbleObserver> prompt_observer(
new BubbleObserver(WebContents()));
std::string fill_and_navigate =
"document.getElementById('signup_username_field').value = 'temp';"
"document.getElementById('signup_password_field').value = 'random';"
"document.getElementById('confirmation_password_field').value = 'random';"
"send_xhr()";
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
observer.Wait();
EXPECT_TRUE(prompt_observer->IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
PromptForXHRSubmitWithoutNavigation) {
NavigateToFile("/password/password_xhr_submit.html");
......@@ -817,45 +777,6 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
EXPECT_TRUE(prompt_observer->IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
PromptForFetchWithoutOnSubmit) {
NavigateToFile("/password/password_fetch_submit.html");
// Verify that if Fetch navigation occurs and the form is properly filled out,
// we try and save the password even though onsubmit hasn't been called.
NavigationObserver observer(WebContents());
std::unique_ptr<BubbleObserver> prompt_observer(
new BubbleObserver(WebContents()));
std::string fill_and_navigate =
"document.getElementById('username_field').value = 'temp';"
"document.getElementById('password_field').value = 'random';"
"send_fetch()";
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
observer.Wait();
EXPECT_TRUE(prompt_observer->IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
PromptForFetchWithNewPasswordsWithoutOnSubmit) {
NavigateToFile("/password/password_fetch_submit.html");
// Verify that if Fetch navigation occurs and the form is properly filled out,
// we try and save the password even though onsubmit hasn't been called.
// Specifically verify that the password form saving new passwords is treated
// the same as a login form.
NavigationObserver observer(WebContents());
std::unique_ptr<BubbleObserver> prompt_observer(
new BubbleObserver(WebContents()));
std::string fill_and_navigate =
"document.getElementById('signup_username_field').value = 'temp';"
"document.getElementById('signup_password_field').value = 'random';"
"document.getElementById('confirmation_password_field').value = 'random';"
"send_fetch()";
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
observer.Wait();
EXPECT_TRUE(prompt_observer->IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
PromptForFetchSubmitWithoutNavigation) {
NavigateToFile("/password/password_fetch_submit.html");
......@@ -1133,8 +1054,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
// Check that credentials are stored.
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16("temp"),
base::ASCIIToUTF16("random"));
CheckThatCredentialsStored("temp", "random");
}
// Test for checking that no prompt is shown for URLs with file: scheme.
......@@ -1633,8 +1553,7 @@ IN_PROC_BROWSER_TEST_P(
// Wait for password store and check that credentials are stored.
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16("user"),
base::ASCIIToUTF16("password"));
CheckThatCredentialsStored("user", "password");
}
// Tests that after HTTP -> HTTPS migration the credential is autofilled.
......@@ -1759,15 +1678,6 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
EXPECT_FALSE(password_store->IsEmpty());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
AutofillSuggestionsForPasswordFormWithoutUsernameField) {
std::string submit =
"document.getElementById('password').value = 'mypassword';"
"document.getElementById('submit-button').click();";
VerifyPasswordIsSavedAndFilled("/password/form_with_only_password_field.html",
submit, "password", "mypassword");
}
// Test that if a form gets autofilled, then it gets autofilled on re-creation
// as well.
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
......@@ -2169,30 +2079,6 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
EXPECT_TRUE(prompt_observer->IsSavePromptShownAutomatically());
}
// Tests that if a site embeds the login and signup forms into one <form>, the
// login form still gets autofilled.
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
AutofillSuggestionsForLoginSignupForm) {
std::string submit =
"document.getElementById('username').value = 'myusername';"
"document.getElementById('password').value = 'mypassword';"
"document.getElementById('submit').click();";
VerifyPasswordIsSavedAndFilled("/password/login_signup_form.html",
submit, "password", "mypassword");
}
// Check that we can fill in cases where <base href> is set and the action of
// the form is not set. Regression test for https://crbug.com/360230.
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
BaseTagWithNoActionTest) {
std::string submit =
"document.getElementById('username_field').value = 'myusername';"
"document.getElementById('password_field').value = 'mypassword';"
"document.getElementById('submit_button').click();";
VerifyPasswordIsSavedAndFilled("/password/password_xhr_submit.html",
submit, "password_field", "mypassword");
}
// Check that a username and password are filled into forms in iframes
// that don't share the security origin with the main frame, but have PSL
// matched origins.
......@@ -2412,18 +2298,6 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
WaitForElementValue("iframe", "password_field", "pa55w0rd");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
NoFormElementTest) {
std::string submit =
"document.getElementById('username_field').value = 'myusername';"
"document.getElementById('password_field').value = 'mypassword';"
"send_xhr();";
VerifyPasswordIsSavedAndFilled("/password/no_form_element.html",
submit,
"password_field",
"mypassword");
}
// The password manager driver will kill processes when they try to access
// passwords of sites other than the site the process is dedicated to, under
// site isolation.
......@@ -2504,8 +2378,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
// Check that credentials are stored.
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16(""),
base::ASCIIToUTF16("new_pw"));
CheckThatCredentialsStored("", "new_pw");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
......@@ -2547,8 +2420,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
prompt_observer->AcceptUpdatePrompt(pending_credentials);
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16("temp"),
base::ASCIIToUTF16("new_pw"));
CheckThatCredentialsStored("temp", "new_pw");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
......@@ -2590,8 +2462,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
password_store->stored_passwords().begin()->second[0];
prompt_observer->AcceptUpdatePrompt(stored_form);
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16("temp"),
base::ASCIIToUTF16("new_pw"));
CheckThatCredentialsStored("temp", "new_pw");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
......@@ -2622,8 +2493,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
// The stored password "pw" was not overriden, so update prompt is not
// expected.
EXPECT_FALSE(prompt_observer->IsUpdatePromptShownAutomatically());
CheckThatCredentialsStored(base::ASCIIToUTF16("temp"),
base::ASCIIToUTF16("pw"));
CheckThatCredentialsStored("temp", "pw");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
......@@ -2668,8 +2538,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
base::ASCIIToUTF16("chg_new_password_wo_username_2"))));
bubble_observer.AcceptSavePrompt();
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16(""),
base::ASCIIToUTF16("pass1"));
CheckThatCredentialsStored("", "pass1");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
......@@ -2709,8 +2578,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
password_store->stored_passwords().begin()->second[0];
prompt_observer->AcceptUpdatePrompt(stored_form);
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16("temp"),
base::ASCIIToUTF16("new_pw"));
CheckThatCredentialsStored("temp", "new_pw");
}
// Test whether the password form with the username and password fields having
......@@ -3135,7 +3003,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
prompt_observer->AcceptSavePrompt();
WaitForPasswordStore();
CheckThatCredentialsStored(base::string16(), base::ASCIIToUTF16("pw"));
CheckThatCredentialsStored("", "pw");
}
// Tests that no bubble shown when a password form without username submitted
......@@ -3206,8 +3074,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
prompt_observer->AcceptUpdatePrompt(stored_form);
WaitForPasswordStore();
CheckThatCredentialsStored(base::ASCIIToUTF16("temp"),
base::ASCIIToUTF16("new_pw"));
CheckThatCredentialsStored("temp", "new_pw");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
......@@ -3258,19 +3125,6 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
EXPECT_TRUE(prompt_observer->IsSavePromptShownAutomatically());
}
// Tests that password suggestions still work if the fields have the
// "autocomplete" attribute set to off.
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithViewsFeature,
AutofillSuggestionsForPasswordFormWithAutocompleteOff) {
std::string submit =
"document.getElementById('username').value = 'temp';"
"document.getElementById('password').value = 'mypassword';"
"document.getElementById('submit').click();";
VerifyPasswordIsSavedAndFilled(
"/password/password_autocomplete_off_test.html", submit, "password",
"mypassword");
}
IN_PROC_BROWSER_TEST_P(
PasswordManagerBrowserTestWithViewsFeature,
SkipZeroClickNotToggledAfterSuccessfulSubmissionWithAPI) {
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/password_manager/password_manager_interactive_test_base.h"
#include "content/public/test/browser_test_utils.h"
#include "ui/events/keycodes/dom_us_layout_data.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
PasswordManagerInteractiveTestBase::PasswordManagerInteractiveTestBase() =
default;
PasswordManagerInteractiveTestBase::~PasswordManagerInteractiveTestBase() =
default;
void PasswordManagerInteractiveTestBase::FillElementWithValue(
const std::string& element_id,
const std::string& value) {
ASSERT_TRUE(content::ExecuteScript(
RenderFrameHost(),
base::StringPrintf("document.getElementById('%s').focus();",
element_id.c_str())));
for (base::char16 character : value) {
ui::DomKey dom_key = ui::DomKey::FromCharacter(character);
const ui::PrintableCodeEntry* code_entry = std::find_if(
std::begin(ui::kPrintableCodeMap), std::end(ui::kPrintableCodeMap),
[character](const ui::PrintableCodeEntry& entry) {
return entry.character[0] == character ||
entry.character[1] == character;
});
ASSERT_TRUE(code_entry != std::end(ui::kPrintableCodeMap));
bool shift = code_entry->character[1] == character;
ui::DomCode dom_code = code_entry->dom_code;
content::SimulateKeyPress(WebContents(), dom_key, dom_code,
ui::DomCodeToUsLayoutKeyboardCode(dom_code),
false, shift, false, false);
}
}
void PasswordManagerInteractiveTestBase::VerifyPasswordIsSavedAndFilled(
const std::string& filename,
const std::string& username_id,
const std::string& password_id,
const std::string& submission_script) {
EXPECT_FALSE(password_id.empty());
NavigateToFile(filename);
NavigationObserver observer(WebContents());
const char kUsername[] = "user";
const char kPassword[] = "123";
if (!username_id.empty())
FillElementWithValue(username_id, kUsername);
FillElementWithValue(password_id, kPassword);
ASSERT_TRUE(content::ExecuteScript(RenderFrameHost(), submission_script));
observer.Wait();
WaitForPasswordStore();
BubbleObserver(WebContents()).AcceptSavePrompt();
// Spin the message loop to make sure the password store had a chance to save
// the password.
WaitForPasswordStore();
CheckThatCredentialsStored(username_id.empty() ? "" : kUsername, kPassword);
NavigateToFile(filename);
// Let the user interact with the page, so that DOM gets modification events,
// needed for autofilling fields.
content::SimulateMouseClickAt(
WebContents(), 0, blink::WebMouseEvent::Button::kLeft, gfx::Point(1, 1));
// Wait until that interaction causes the password value to be revealed.
if (!username_id.empty())
WaitForElementValue(username_id, kUsername);
WaitForElementValue(password_id, kPassword);
}
// Copyright 2018 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 CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_MANAGER_INTERACTIVE_TEST_BASE_H_
#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_MANAGER_INTERACTIVE_TEST_BASE_H_
#include <string>
#include "chrome/browser/password_manager/password_manager_test_base.h"
class PasswordManagerInteractiveTestBase
: public PasswordManagerBrowserTestBase {
public:
PasswordManagerInteractiveTestBase();
~PasswordManagerInteractiveTestBase() override;
// Focuses an input element with id |element_id| in the main frame and
// emulates typing |value| into it.
void FillElementWithValue(const std::string& element_id,
const std::string& value);
// Navigates to |filename|, fills |username_id| and |password_id| if nonempty
// and runs |submission_script| to submit. The credential is then saved via
// the password prompt.
// Navigates back to |filename| and then verifies that the same elements are
// filled.
void VerifyPasswordIsSavedAndFilled(const std::string& filename,
const std::string& username_id,
const std::string& password_id,
const std::string& submission_script);
private:
DISALLOW_COPY_AND_ASSIGN(PasswordManagerInteractiveTestBase);
};
#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_MANAGER_INTERACTIVE_TEST_BASE_H_
......@@ -7,7 +7,7 @@
#include "base/feature_list.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/password_manager/password_manager_test_base.h"
#include "chrome/browser/password_manager/password_manager_interactive_test_base.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
......@@ -15,34 +15,10 @@
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/password_manager/core/browser/test_password_store.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "ui/events/keycodes/keyboard_codes.h"
namespace {
void SimulateUserTypingInField(content::WebContents* web_contents,
const std::string& field_id) {
std::string focus("document.getElementById('" + field_id + "').focus();");
ASSERT_TRUE(content::ExecuteScript(web_contents, focus));
content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('O'),
ui::DomCode::US_O, ui::VKEY_O, false, false, false,
false);
content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('R'),
ui::DomCode::US_R, ui::VKEY_R, false, false, false,
false);
content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('A'),
ui::DomCode::US_A, ui::VKEY_A, false, false, false,
false);
content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('R'),
ui::DomCode::US_R, ui::VKEY_R, false, false, false,
false);
content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('Y'),
ui::DomCode::US_Y, ui::VKEY_Y, false, false, false,
false);
}
// Erases all characters that have been typed by SimulateUserTypingInField.
// Erases all characters that have been typed into |field_id|.
void SimulateUserDeletingFieldContent(content::WebContents* web_contents,
const std::string& field_id) {
std::string focus("document.getElementById('" + field_id + "').focus();");
......@@ -66,7 +42,7 @@ namespace password_manager {
// - bool popup_views_enabled: whether feature AutofillExpandedPopupViews
// is enabled for testing.
class PasswordManagerBrowserTestWithConditionalPopupViews
: public PasswordManagerBrowserTestBase,
: public PasswordManagerInteractiveTestBase,
public ::testing::WithParamInterface<bool> {
public:
PasswordManagerBrowserTestWithConditionalPopupViews() = default;
......@@ -83,7 +59,7 @@ class PasswordManagerBrowserTestWithConditionalPopupViews
}
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
PasswordManagerBrowserTestBase::SetUp();
PasswordManagerInteractiveTestBase::SetUp();
}
private:
......@@ -115,15 +91,15 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
WaitForElementValue("username_field", "temp");
WaitForElementValue("password_field", "random");
// Change username and submit. This should add the characters "ORARY" to the
// Change username and submit. This should add the characters "orary" to the
// already autofilled username.
SimulateUserTypingInField(WebContents(), "username_field");
FillElementWithValue("username_field", "orary");
// Move the focus out of the inputs before waiting because WaitForElementValue
// uses "onchange" event. The event is triggered only when the control looses
// focus.
chrome::FocusLocationBar(browser());
WaitForElementValue("username_field", "tempORARY");
WaitForElementValue("username_field", "temporary");
NavigationObserver navigation_observer(WebContents());
BubbleObserver prompt_observer(WebContents());
......@@ -147,7 +123,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
EXPECT_EQ(2u, stored_passwords.begin()->second.size());
EXPECT_EQ(base::UTF8ToUTF16("temp"),
(stored_passwords.begin()->second)[0].username_value);
EXPECT_EQ(base::UTF8ToUTF16("tempORARY"),
EXPECT_EQ(base::UTF8ToUTF16("temporary"),
(stored_passwords.begin()->second)[1].username_value);
}
......@@ -155,9 +131,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
ManualFallbackForSaving) {
NavigateToFile("/password/password_form.html");
std::string focus("document.getElementById('password_field').focus();");
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), focus));
SimulateUserTypingInField(WebContents(), "password_field");
FillElementWithValue("password_field", "123");
BubbleObserver prompt_observer(WebContents());
prompt_observer.WaitForFallbackForSaving();
......@@ -176,7 +150,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
prompt_observer.AcceptSavePrompt();
WaitForPasswordStore();
CheckThatCredentialsStored(base::string16(), base::ASCIIToUTF16("ORARY"));
CheckThatCredentialsStored("", "123");
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
......@@ -184,9 +158,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
NavigateToFile("/password/password_form.html");
ManagePasswordsUIController::set_save_fallback_timeout_in_seconds(0);
std::string focus("document.getElementById('password_field').focus();");
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), focus));
SimulateUserTypingInField(WebContents(), "password_field");
FillElementWithValue("password_field", "123");
BubbleObserver prompt_observer(WebContents());
prompt_observer.WaitForFallbackForSaving();
......@@ -200,9 +172,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
ManualFallbackForSaving_HideIcon) {
NavigateToFile("/password/password_form.html");
std::string focus("document.getElementById('password_field').focus();");
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), focus));
SimulateUserTypingInField(WebContents(), "password_field");
FillElementWithValue("password_field", "123");
BubbleObserver prompt_observer(WebContents());
prompt_observer.WaitForFallbackForSaving();
......@@ -228,9 +198,7 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
NavigateToFile("/password/password_form.html");
std::string focus("document.getElementById('password_field').focus();");
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), focus));
SimulateUserTypingInField(WebContents(), "password_field");
FillElementWithValue("password_field", "123");
BubbleObserver prompt_observer(WebContents());
prompt_observer.WaitForFallbackForSaving();
......@@ -239,6 +207,111 @@ IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
prompt_observer.WaitForManagementState();
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
PromptForXHRWithoutOnSubmit) {
NavigateToFile("/password/password_xhr_submit.html");
// Verify that if XHR navigation occurs and the form is properly filled out,
// we try and save the password even though onsubmit hasn't been called.
FillElementWithValue("username_field", "user");
FillElementWithValue("password_field", "1234");
NavigationObserver observer(WebContents());
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), "send_xhr()"));
observer.Wait();
EXPECT_TRUE(BubbleObserver(WebContents()).IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
PromptForXHRWithNewPasswordsWithoutOnSubmit) {
NavigateToFile("/password/password_xhr_submit.html");
// Verify that if XHR navigation occurs and the form is properly filled out,
// we try and save the password even though onsubmit hasn't been called.
// Specifically verify that the password form saving new passwords is treated
// the same as a login form.
FillElementWithValue("signup_username_field", "user");
FillElementWithValue("signup_password_field", "1234");
FillElementWithValue("confirmation_password_field", "1234");
NavigationObserver observer(WebContents());
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), "send_xhr()"));
observer.Wait();
EXPECT_TRUE(BubbleObserver(WebContents()).IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
PromptForFetchWithoutOnSubmit) {
NavigateToFile("/password/password_fetch_submit.html");
// Verify that if Fetch navigation occurs and the form is properly filled out,
// we try and save the password even though onsubmit hasn't been called.
FillElementWithValue("username_field", "user");
FillElementWithValue("password_field", "1234");
NavigationObserver observer(WebContents());
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), "send_fetch()"));
observer.Wait();
EXPECT_TRUE(BubbleObserver(WebContents()).IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
PromptForFetchWithNewPasswordsWithoutOnSubmit) {
NavigateToFile("/password/password_fetch_submit.html");
// Verify that if Fetch navigation occurs and the form is properly filled out,
// we try and save the password even though onsubmit hasn't been called.
// Specifically verify that the password form saving new passwords is treated
// the same as a login form.
FillElementWithValue("signup_username_field", "user");
FillElementWithValue("signup_password_field", "1234");
FillElementWithValue("confirmation_password_field", "1234");
NavigationObserver observer(WebContents());
ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), "send_fetch()"));
observer.Wait();
EXPECT_TRUE(BubbleObserver(WebContents()).IsSavePromptShownAutomatically());
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
AutofillPasswordFormWithoutUsernameField) {
std::string submit = "document.getElementById('submit-button').click();";
VerifyPasswordIsSavedAndFilled("/password/form_with_only_password_field.html",
std::string(), "password", submit);
}
// Tests that if a site embeds the login and signup forms into one <form>, the
// login form still gets autofilled.
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
AutofillLoginSignupForm) {
std::string submit = "document.getElementById('submit').click();";
VerifyPasswordIsSavedAndFilled("/password/login_signup_form.html", "username",
"password", submit);
}
// Tests that password suggestions still work if the fields have the
// "autocomplete" attribute set to off.
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
AutofillPasswordFormWithAutocompleteOff) {
std::string submit = "document.getElementById('submit').click();";
VerifyPasswordIsSavedAndFilled(
"/password/password_autocomplete_off_test.html", "username", "password",
submit);
}
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
AutofillPasswordNoFormElement) {
VerifyPasswordIsSavedAndFilled("/password/no_form_element.html",
"username_field", "password_field",
"send_xhr();");
}
// Check that we can fill in cases where <base href> is set and the action of
// the form is not set. Regression test for https://crbug.com/360230.
IN_PROC_BROWSER_TEST_P(PasswordManagerBrowserTestWithConditionalPopupViews,
AutofillBaseTagWithNoActionTest) {
std::string submit = "document.getElementById('submit_button').click();";
VerifyPasswordIsSavedAndFilled("/password/password_xhr_submit.html",
"username_field", "password_field", submit);
}
INSTANTIATE_TEST_CASE_P(All,
PasswordManagerBrowserTestWithConditionalPopupViews,
/*popup_views_enabled=*/::testing::Bool());
......
......@@ -14,6 +14,7 @@
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/profiles/profile.h"
......@@ -486,42 +487,6 @@ void PasswordManagerBrowserTestBase::NavigateToFile(const std::string& path) {
observer.Wait();
}
void PasswordManagerBrowserTestBase::VerifyPasswordIsSavedAndFilled(
const std::string& filename,
const std::string& submission_script,
const std::string& expected_element,
const std::string& expected_value) {
password_manager::TestPasswordStore* password_store =
static_cast<password_manager::TestPasswordStore*>(
PasswordStoreFactory::GetForProfile(
browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS).get());
EXPECT_TRUE(password_store->IsEmpty());
NavigateToFile(filename);
NavigationObserver observer(WebContents());
ASSERT_TRUE(content::ExecuteScript(RenderFrameHost(), submission_script));
observer.Wait();
WaitForPasswordStore();
BubbleObserver(WebContents()).AcceptSavePrompt();
// Spin the message loop to make sure the password store had a chance to save
// the password.
WaitForPasswordStore();
ASSERT_FALSE(password_store->IsEmpty());
NavigateToFile(filename);
// Let the user interact with the page, so that DOM gets modification events,
// needed for autofilling fields.
content::SimulateMouseClickAt(
WebContents(), 0, blink::WebMouseEvent::Button::kLeft, gfx::Point(1, 1));
// Wait until that interaction causes the password value to be revealed.
WaitForElementValue(expected_element, expected_value);
}
void PasswordManagerBrowserTestBase::WaitForElementValue(
const std::string& element_id,
const std::string& expected_value) {
......@@ -688,8 +653,8 @@ void PasswordManagerBrowserTestBase::AddHSTSHost(const std::string& host) {
}
void PasswordManagerBrowserTestBase::CheckThatCredentialsStored(
const base::string16& username,
const base::string16& password) {
const std::string& username,
const std::string& password) {
scoped_refptr<password_manager::TestPasswordStore> password_store =
static_cast<password_manager::TestPasswordStore*>(
PasswordStoreFactory::GetForProfile(
......@@ -700,6 +665,6 @@ void PasswordManagerBrowserTestBase::CheckThatCredentialsStored(
auto& passwords_vector = passwords_map.begin()->second;
ASSERT_EQ(1u, passwords_vector.size());
const autofill::PasswordForm& form = passwords_vector[0];
EXPECT_EQ(username, form.username_value);
EXPECT_EQ(password, form.password_value);
EXPECT_EQ(base::ASCIIToUTF16(username), form.username_value);
EXPECT_EQ(base::ASCIIToUTF16(password), form.password_value);
}
......@@ -59,11 +59,12 @@ class NavigationObserver : public content::WebContentsObserver {
DISALLOW_COPY_AND_ASSIGN(NavigationObserver);
};
// Observes the save password prompt for a specified WebContents, keeps track of
// whether or not it is currently shown, and allows accepting saving passwords
// through it.
// Checks the save password prompt for a specified WebContents and allows
// accepting saving passwords through it.
class BubbleObserver {
public:
// The constructor doesn't start tracking |web_contents|. To check the status
// of the prompt one can even construct a temporary BubbleObserver.
explicit BubbleObserver(content::WebContents* web_contents);
// Checks if the save prompt is being currently available due to either manual
......@@ -146,14 +147,6 @@ class PasswordManagerBrowserTestBase : public CertVerifierBrowserTest {
// return immediately.
void NavigateToFile(const std::string& path);
// Navigates to |filename| and runs |submission_script| to submit. Navigates
// back to |filename| and then verifies that |expected_element| has
// |expected_value|.
void VerifyPasswordIsSavedAndFilled(const std::string& filename,
const std::string& submission_script,
const std::string& expected_element,
const std::string& expected_value);
// Waits until the "value" attribute of the HTML element with |element_id| is
// equal to |expected_value|. If the current value is not as expected, this
// waits until the "change" event is fired for the element. This also
......@@ -198,8 +191,8 @@ class PasswordManagerBrowserTestBase : public CertVerifierBrowserTest {
// Checks that |password_store| stores only one credential with |username| and
// |password|.
void CheckThatCredentialsStored(const base::string16& username,
const base::string16& password);
void CheckThatCredentialsStored(const std::string& username,
const std::string& password);
// Accessors
// Return the first created tab with a custom ManagePasswordsUIController.
......
......@@ -4602,6 +4602,8 @@ if (!is_android) {
"../browser/notifications/message_center_notifications_browsertest.cc",
"../browser/notifications/platform_notification_service_interactive_uitest.cc",
"../browser/password_manager/password_generation_interactive_uitest.cc",
"../browser/password_manager/password_manager_interactive_test_base.cc",
"../browser/password_manager/password_manager_interactive_test_base.h",
"../browser/password_manager/password_manager_interactive_uitest.cc",
"../browser/renderer_context_menu/render_view_context_menu_browsertest_util.cc",
"../browser/renderer_context_menu/render_view_context_menu_browsertest_util.h",
......
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