blob: 0970c284c21c4db42ee2e6467e2ca6d7a5adc4ea [file] [log] [blame]
// Copyright 2015 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_TEST_BASE_H_
#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_MANAGER_TEST_BASE_H_
#include <memory>
#include "base/macros.h"
#include "base/run_loop.h"
#include "chrome/browser/ssl/cert_verifier_browser_test.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
#include "content/public/browser/web_contents_observer.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
namespace autofill {
struct PasswordForm;
}
class ManagePasswordsUIController;
class NavigationObserver : public content::WebContentsObserver {
public:
explicit NavigationObserver(content::WebContents* web_contents);
~NavigationObserver() override;
// Normally Wait() will not return until a main frame navigation occurs.
// If a path is set, Wait() will return after this path has been seen,
// regardless of the frame that navigated. Useful for multi-frame pages.
void SetPathToWaitFor(const std::string& path) { wait_for_path_ = path; }
// Normally Wait() will not return until a main frame navigation occurs.
// If quit_on_entry_committed is true Wait() will return on EntryCommited.
void set_quit_on_entry_committed(bool quit_on_entry_committed) {
quit_on_entry_committed_ = quit_on_entry_committed;
}
// Wait for navigation to succeed.
void Wait();
// Returns the RenderFrameHost that navigated.
content::RenderFrameHost* render_frame_host() { return render_frame_host_; }
// content::WebContentsObserver:
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) override;
private:
std::string wait_for_path_;
content::RenderFrameHost* render_frame_host_;
bool quit_on_entry_committed_;
base::RunLoop run_loop_;
DISALLOW_COPY_AND_ASSIGN(NavigationObserver);
};
// 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
// fallback or successful login.
bool IsSavePromptAvailable() const;
// Checks if the update prompt is being currently available due to either
// manual fallback or successful login.
bool IsUpdatePromptAvailable() const;
// Checks if the save prompt was shown automatically.
// |web_contents| must be the custom one returned by
// PasswordManagerBrowserTestBase.
bool IsSavePromptShownAutomatically() const;
// Checks if the update prompt was shown automatically.
// |web_contents| must be the custom one returned by
// PasswordManagerBrowserTestBase.
bool IsUpdatePromptShownAutomatically() const;
// Hide the currently open prompt.
void Hide() const;
// Expecting that the prompt is available, saves the password. At the end,
// checks that the prompt is no longer available afterwards.
void AcceptSavePrompt() const;
// Expecting that the prompt is shown, update |form| with the password from
// observed form. Checks that the prompt is no longer visible afterwards.
void AcceptUpdatePrompt(const autofill::PasswordForm& form) const;
// Returns once the account chooser pops up or it's already shown.
// |web_contents| must be the custom one returned by
// PasswordManagerBrowserTestBase.
void WaitForAccountChooser() const;
// Returns once the UI controller is in inactive state.
// |web_contents| must be the custom one returned by
// PasswordManagerBrowserTestBase.
void WaitForInactiveState() const;
// Returns once the UI controller is in the management state due to matching
// credentials autofilled.
// |web_contents| must be the custom one returned by
// PasswordManagerBrowserTestBase.
void WaitForManagementState() const;
// Returns once the save prompt pops up or it's already shown.
// |web_contents| must be the custom one returned by
// PasswordManagerBrowserTestBase.
void WaitForAutomaticSavePrompt() const;
// Returns once the fallback for saving becomes available.
// |web_contents| must be the custom one returned by
// PasswordManagerBrowserTestBase.
void WaitForFallbackForSaving() const;
private:
ManagePasswordsUIController* const passwords_ui_controller_;
DISALLOW_COPY_AND_ASSIGN(BubbleObserver);
};
class PasswordManagerBrowserTestBase : public CertVerifierBrowserTest {
public:
PasswordManagerBrowserTestBase();
~PasswordManagerBrowserTestBase() override;
// InProcessBrowserTest:
void SetUpOnMainThread() override;
void TearDownOnMainThread() override;
void TearDownInProcessBrowserTestFixture() override;
// Bring up a new Chrome tab set up with password manager test hooks.
// @param[in] browser the browser running the password manager test, upon
// which this function will perform the setup steps.
// @param[out] a new tab on the browser set up with password manager test
// hooks.
static void SetUpOnMainThreadAndGetNewTab(
Browser* browser,
content::WebContents** web_contents);
// Make sure that the password store associated with the given browser
// processed all the previous calls, calls executed on another thread.
static void WaitForPasswordStore(Browser* browser);
protected:
// Wrapper around ui_test_utils::NavigateToURL that waits until
// DidFinishLoad() fires. Normally this function returns after
// DidStopLoading(), which caused flakiness as the NavigationObserver
// would sometimes see the DidFinishLoad event from a previous navigation and
// return immediately.
void NavigateToFile(const std::string& path);
// 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
// guarantees that once the real value matches the expected, the JavaScript
// event loop is spun to allow all other possible events to take place.
// WARNING:
// - the function waits only for the first "onchange" event.
// - "onchange" event is triggered by autofill. However, if user's typing is
// simulated then the event is triggered only when control looses focus.
void WaitForElementValue(const std::string& element_id,
const std::string& expected_value);
// Same as above except the element |element_id| is in iframe |iframe_id|
void WaitForElementValue(const std::string& iframe_id,
const std::string& element_id,
const std::string& expected_value);
// Same as above except the element has index |element_index| in elements() of
// the form |form_id|.
void WaitForElementValue(const std::string& form_id,
size_t element_index,
const std::string& expected_value);
// Same as above except the element is selected with |element_selector| JS
// expression.
void WaitForJsElementValue(const std::string& element_selector,
const std::string& expected_value);
// Make sure that the password store processed all the previous calls which
// are executed on another thread.
void WaitForPasswordStore();
// Checks that the current "value" attribute of the HTML element with
// |element_id| is equal to |expected_value|.
void CheckElementValue(const std::string& element_id,
const std::string& expected_value);
// Same as above except the element |element_id| is in iframe |iframe_id|
void CheckElementValue(const std::string& iframe_id,
const std::string& element_id,
const std::string& expected_value);
// Synchronoulsy adds the given host to the list of valid HSTS hosts.
void AddHSTSHost(const std::string& host);
// Checks that |password_store| stores only one credential with |username| and
// |password|.
void CheckThatCredentialsStored(const std::string& username,
const std::string& password);
// Accessors
// Return the first created tab with a custom ManagePasswordsUIController.
content::WebContents* WebContents() const;
content::RenderFrameHost* RenderFrameHost() const;
net::EmbeddedTestServer& https_test_server() { return https_test_server_; }
private:
net::EmbeddedTestServer https_test_server_;
// A tab with some hooks injected.
content::WebContents* web_contents_;
DISALLOW_COPY_AND_ASSIGN(PasswordManagerBrowserTestBase);
};
#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_MANAGER_TEST_BASE_H_