| Index: chrome/browser/password_manager/password_manager_browsertest.cc
|
| diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
|
| index 4793dedd4f9ba260c4ba7a6d425eca316c934868..a3255123f1174d29dbcf4c4aef7f38a4ee3286ce 100644
|
| --- a/chrome/browser/password_manager/password_manager_browsertest.cc
|
| +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
|
| @@ -7,6 +7,7 @@
|
| #include "base/command_line.h"
|
| #include "base/metrics/histogram_samples.h"
|
| #include "base/metrics/statistics_recorder.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "chrome/browser/chrome_notification_types.h"
|
| #include "chrome/browser/infobars/infobar_service.h"
|
| #include "chrome/browser/password_manager/password_store_factory.h"
|
| @@ -173,23 +174,83 @@ class PasswordManagerBrowserTest : public InProcessBrowserTest {
|
| observer.Wait();
|
| }
|
|
|
| - // Executes |script| and uses the EXPECT macros to check the return value
|
| - // against |expected_return_value|.
|
| - void CheckScriptReturnValue(std::string& script, bool expected_return_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
|
| + // guarantees that once the real value matches the expected, the JavaScript
|
| + // event loop is spun to allow all other possible events to take place.
|
| + void WaitForElementValue(const std::string& element_id,
|
| + const std::string& expected_value);
|
| + // 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);
|
|
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(PasswordManagerBrowserTest);
|
| };
|
|
|
| -void PasswordManagerBrowserTest::CheckScriptReturnValue(
|
| - std::string& script,
|
| - bool expected_return_value) {
|
| - const std::string wrapped_script =
|
| - std::string("window.domAutomationController.send(") + script + ");";
|
| - bool return_value = !expected_return_value;
|
| +void PasswordManagerBrowserTest::WaitForElementValue(
|
| + const std::string& element_id,
|
| + const std::string& expected_value) {
|
| + enum ReturnCodes { // Possible results of the JavaScript code.
|
| + RETURN_CODE_OK,
|
| + RETURN_CODE_NO_ELEMENT,
|
| + RETURN_CODE_WRONG_VALUE,
|
| + RETURN_CODE_INVALID,
|
| + };
|
| + const std::string value_check_function = base::StringPrintf(
|
| + "function valueCheck() {"
|
| + " var element = document.getElementById('%s');"
|
| + " return element && element.value == '%s';"
|
| + "}",
|
| + element_id.c_str(),
|
| + expected_value.c_str());
|
| + const std::string script =
|
| + value_check_function +
|
| + base::StringPrintf(
|
| + "if (valueCheck()) {"
|
| + " /* Spin the event loop with setTimeout. */"
|
| + " setTimeout(window.domAutomationController.send(%d), 0);"
|
| + "} else {"
|
| + " var element = document.getElementById('%s');"
|
| + " if (!element)"
|
| + " window.domAutomationController.send(%d);"
|
| + " element.onchange = function() {"
|
| + " if (valueCheck()) {"
|
| + " /* Spin the event loop with setTimeout. */"
|
| + " setTimeout(window.domAutomationController.send(%d), 0);"
|
| + " } else {"
|
| + " window.domAutomationController.send(%d);"
|
| + " }"
|
| + " };"
|
| + "}",
|
| + RETURN_CODE_OK,
|
| + element_id.c_str(),
|
| + RETURN_CODE_NO_ELEMENT,
|
| + RETURN_CODE_OK,
|
| + RETURN_CODE_WRONG_VALUE);
|
| + int return_value = RETURN_CODE_INVALID;
|
| + ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
|
| + RenderViewHost(), script, &return_value));
|
| + EXPECT_EQ(RETURN_CODE_OK, return_value)
|
| + << "element_id = " << element_id
|
| + << ", expected_value = " << expected_value;
|
| +}
|
| +
|
| +void PasswordManagerBrowserTest::CheckElementValue(
|
| + const std::string& element_id,
|
| + const std::string& expected_value) {
|
| + const std::string value_check_script = base::StringPrintf(
|
| + "var element = document.getElementById('%s');"
|
| + "window.domAutomationController.send(element && element.value == '%s');",
|
| + element_id.c_str(),
|
| + expected_value.c_str());
|
| + bool return_value = false;
|
| ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
|
| - RenderViewHost(), wrapped_script, &return_value));
|
| - EXPECT_EQ(expected_return_value, return_value) << "script = " << script;
|
| + RenderViewHost(), value_check_script, &return_value));
|
| + EXPECT_TRUE(return_value) << "element_id = " << element_id
|
| + << ", expected_value = " << expected_value;
|
| }
|
|
|
| // Actual tests ---------------------------------------------------------------
|
| @@ -593,14 +654,7 @@ IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, DeleteFrameBeforeSubmit) {
|
| // The only thing we check here is that there is no use-after-free reported.
|
| }
|
|
|
| -// Disabled on Windows due to flakiness: http://crbug.com/346297
|
| -#if defined(OS_WIN)
|
| -#define MAYBE_PasswordValueAccessible DISABLED_PasswordValueAccessible
|
| -#else
|
| -#define MAYBE_PasswordValueAccessible PasswordValueAccessible
|
| -#endif
|
| -IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest,
|
| - MAYBE_PasswordValueAccessible) {
|
| +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, PasswordValueAccessible) {
|
| NavigateToFile("/password/form_and_link.html");
|
|
|
| // Click on a link to open a new tab, then switch back to the first one.
|
| @@ -626,18 +680,18 @@ IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest,
|
| NavigateToFile("/password/form_and_link.html");
|
| reload_observer.Wait();
|
|
|
| - // Check that while the username is immediately available, the password value
|
| - // needs a user interaction to show up.
|
| - std::string check_username =
|
| - "document.getElementById('username_field').value == 'temp'";
|
| - std::string check_password =
|
| - "document.getElementById('password_field').value == 'random'";
|
| - CheckScriptReturnValue(check_username, true);
|
| - CheckScriptReturnValue(check_password, false);
|
| - content::SimulateMouseClick(
|
| - WebContents(), 0, blink::WebMouseEvent::ButtonLeft);
|
| - CheckScriptReturnValue(check_username, true);
|
| - CheckScriptReturnValue(check_password, true);
|
| + // Wait until the username is filled, to make sure autofill kicked in.
|
| + WaitForElementValue("username_field", "temp");
|
| + // Now check that the password is not accessible yet.
|
| + CheckElementValue("password_field", "");
|
| + // Let the user interact with the page.
|
| + content::SimulateMouseClickAt(
|
| + WebContents(), 0, blink::WebMouseEvent::ButtonLeft, gfx::Point(1, 1));
|
| + // Wait until that interaction causes the password value to be revealed.
|
| + WaitForElementValue("password_field", "random");
|
| + // And check that after the side-effects of the interaction took place, the
|
| + // username value stays the same.
|
| + CheckElementValue("username_field", "temp");
|
| }
|
|
|
| // The following test is limited to Aura, because
|
|
|