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
// 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_
......@@ -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