This source file includes following definitions.
- SimulateOnFillPasswordForm
- SetUp
- TearDown
- UpdateOriginForHTML
- UpdateUsernameAndPasswordElements
- ClearUsernameAndPasswordFields
- SimulateUsernameChangeForElement
- LayoutMainFrame
- SimulateUsernameChange
- ExpectNoSuggestionsPopup
- SimulateKeyDownEvent
- CheckTextFieldsStateForElements
- CheckTextFieldsState
- CheckTextFieldsDOMState
- CheckUsernameSelection
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/test/base/chrome_render_view_test.h"
#include "components/autofill/content/common/autofill_messages.h"
#include "components/autofill/content/renderer/autofill_agent.h"
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "components/autofill/content/renderer/password_autofill_agent.h"
#include "components/autofill/content/renderer/test_password_autofill_agent.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/password_autofill_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebFormElement.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebInputElement.h"
#include "third_party/WebKit/public/web/WebNode.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "ui/events/keycodes/keyboard_codes.h"
using autofill::PasswordForm;
using base::ASCIIToUTF16;
using base::UTF16ToUTF8;
using blink::WebDocument;
using blink::WebElement;
using blink::WebFrame;
using blink::WebInputElement;
using blink::WebString;
using blink::WebView;
namespace {
const char kUsernameName[] = "username";
const char kPasswordName[] = "password";
const char kAliceUsername[] = "alice";
const char kAlicePassword[] = "password";
const char kBobUsername[] = "bob";
const char kBobPassword[] = "secret";
const char kCarolUsername[] = "Carol";
const char kCarolPassword[] = "test";
const char kCarolAlternateUsername[] = "RealCarolUsername";
const char kFormHTML[] =
"<FORM name='LoginTestForm' action='http://www.bidule.com'>"
" <INPUT type='text' id='username'/>"
" <INPUT type='password' id='password'/>"
" <INPUT type='submit' value='Login'/>"
"</FORM>";
const char kVisibleFormHTML[] =
"<head> <style> form {display: inline;} </style> </head>"
"<body>"
" <form>"
" <div>"
" <input type='password' id='password'/>"
" </div>"
" </form>"
"</body>";
const char kEmptyFormHTML[] =
"<head> <style> form {display: inline;} </style> </head>"
"<body> <form> </form> </body>";
const char kNonVisibleFormHTML[] =
"<head> <style> form {display: none;} </style> </head>"
"<body>"
" <form>"
" <div>"
" <input type='password' id='password'/>"
" </div>"
" </form>"
"</body>";
const char kEmptyWebpage[] =
"<html>"
" <head>"
" </head>"
" <body>"
" </body>"
"</html>";
const char kRedirectionWebpage[] =
"<html>"
" <head>"
" <meta http-equiv='Content-Type' content='text/html'>"
" <title>Redirection page</title>"
" <script></script>"
" </head>"
" <body>"
" <script type='text/javascript'>"
" function test(){}"
" </script>"
" </body>"
"</html>";
const char kSimpleWebpage[] =
"<html>"
" <head>"
" <meta charset='utf-8' />"
" <title>Title</title>"
" </head>"
" <body>"
" <form name='LoginTestForm'>"
" <input type='text' id='username'/>"
" <input type='password' id='password'/>"
" <input type='submit' value='Login'/>"
" </form>"
" </body>"
"</html>";
const char kWebpageWithDynamicContent[] =
"<html>"
" <head>"
" <meta charset='utf-8' />"
" <title>Title</title>"
" </head>"
" <body>"
" <script type='text/javascript'>"
" function addParagraph() {"
" var p = document.createElement('p');"
" document.body.appendChild(p);"
" }"
" window.onload = addParagraph;"
" </script>"
" </body>"
"</html>";
const char kJavaScriptClick[] =
"var event = new MouseEvent('click', {"
" 'view': window,"
" 'bubbles': true,"
" 'cancelable': true"
"});"
"var form = document.getElementById('myform1');"
"form.dispatchEvent(event);"
"console.log('clicked!');";
const char kOnChangeDetectionScript[] =
"<script>"
" usernameOnchangeCalled = false;"
" passwordOnchangeCalled = false;"
" document.getElementById('username').onchange = function() {"
" usernameOnchangeCalled = true;"
" };"
" document.getElementById('password').onchange = function() {"
" passwordOnchangeCalled = true;"
" };"
"</script>";
}
namespace autofill {
class PasswordAutofillAgentTest : public ChromeRenderViewTest {
public:
PasswordAutofillAgentTest() {
}
void SimulateOnFillPasswordForm(
const PasswordFormFillData& fill_data) {
AutofillMsg_FillPasswordForm msg(0, fill_data);
password_autofill_->OnMessageReceived(msg);
}
virtual void SetUp() {
ChromeRenderViewTest::SetUp();
username1_ = ASCIIToUTF16(kAliceUsername);
password1_ = ASCIIToUTF16(kAlicePassword);
username2_ = ASCIIToUTF16(kBobUsername);
password2_ = ASCIIToUTF16(kBobPassword);
username3_ = ASCIIToUTF16(kCarolUsername);
password3_ = ASCIIToUTF16(kCarolPassword);
alternate_username3_ = ASCIIToUTF16(kCarolAlternateUsername);
FormFieldData username_field;
username_field.name = ASCIIToUTF16(kUsernameName);
username_field.value = username1_;
fill_data_.basic_data.fields.push_back(username_field);
FormFieldData password_field;
password_field.name = ASCIIToUTF16(kPasswordName);
password_field.value = password1_;
password_field.form_control_type = "password";
fill_data_.basic_data.fields.push_back(password_field);
PasswordAndRealm password2;
password2.password = password2_;
fill_data_.additional_logins[username2_] = password2;
PasswordAndRealm password3;
password3.password = password3_;
fill_data_.additional_logins[username3_] = password3;
UsernamesCollectionKey key;
key.username = username3_;
key.password = password3_;
key.realm = "google.com";
fill_data_.other_possible_usernames[key].push_back(alternate_username3_);
UpdateOriginForHTML(kFormHTML);
fill_data_.basic_data.action = GURL("http://www.bidule.com");
LoadHTML(kFormHTML);
UpdateUsernameAndPasswordElements();
}
virtual void TearDown() {
username_element_.reset();
password_element_.reset();
ChromeRenderViewTest::TearDown();
}
void UpdateOriginForHTML(const std::string& html) {
std::string origin = "data:text/html;charset=utf-8," + html;
fill_data_.basic_data.origin = GURL(origin);
}
void UpdateUsernameAndPasswordElements() {
WebDocument document = GetMainFrame()->document();
WebElement element =
document.getElementById(WebString::fromUTF8(kUsernameName));
ASSERT_FALSE(element.isNull());
username_element_ = element.to<blink::WebInputElement>();
element = document.getElementById(WebString::fromUTF8(kPasswordName));
ASSERT_FALSE(element.isNull());
password_element_ = element.to<blink::WebInputElement>();
}
void ClearUsernameAndPasswordFields() {
username_element_.setValue("");
username_element_.setAutofilled(false);
password_element_.setValue("");
password_element_.setAutofilled(false);
}
void SimulateUsernameChangeForElement(const std::string& username,
bool move_caret_to_end,
WebFrame* input_frame,
WebInputElement& username_input) {
username_input.setValue(WebString::fromUTF8(username));
while (!username_input.focused())
input_frame->document().frame()->view()->advanceFocus(false);
if (move_caret_to_end)
username_input.setSelectionRange(username.length(), username.length());
autofill_agent_->textFieldDidChange(username_input);
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this)));
base::MessageLoop::current()->RunUntilIdle();
}
void LayoutMainFrame() {
GetMainFrame()->view()->layout();
}
void SimulateUsernameChange(const std::string& username,
bool move_caret_to_end) {
SimulateUsernameChangeForElement(username, move_caret_to_end,
GetMainFrame(), username_element_);
}
void ExpectNoSuggestionsPopup() {
if (!ShouldIgnoreAutocompleteOffForPasswordFields()) {
EXPECT_TRUE(autofill_agent_->password_autofill_agent_->ShowSuggestions(
username_element_));
EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_ShowPasswordSuggestions::ID));
}
}
void SimulateKeyDownEvent(const WebInputElement& element,
ui::KeyboardCode key_code) {
blink::WebKeyboardEvent key_event;
key_event.windowsKeyCode = key_code;
autofill_agent_->textFieldDidReceiveKeyDown(element, key_event);
}
void CheckTextFieldsStateForElements(const WebInputElement& username_element,
const std::string& username,
bool username_autofilled,
const WebInputElement& password_element,
const std::string& password,
bool password_autofilled,
bool checkSuggestedValue = true) {
EXPECT_EQ(username,
static_cast<std::string>(username_element.value().utf8()));
EXPECT_EQ(username_autofilled, username_element.isAutofilled());
EXPECT_EQ(password,
static_cast<std::string>(
checkSuggestedValue ? password_element.suggestedValue().utf8()
: password_element.value().utf8()));
EXPECT_EQ(password_autofilled, password_element.isAutofilled());
}
void CheckTextFieldsState(const std::string& username,
bool username_autofilled,
const std::string& password,
bool password_autofilled) {
CheckTextFieldsStateForElements(username_element_, username,
username_autofilled, password_element_,
password, password_autofilled);
}
void CheckTextFieldsDOMState(const std::string& username,
bool username_autofilled,
const std::string& password,
bool password_autofilled) {
CheckTextFieldsStateForElements(username_element_,
username,
username_autofilled,
password_element_,
password,
password_autofilled,
false);
}
void CheckUsernameSelection(int start, int end) {
EXPECT_EQ(start, username_element_.selectionStart());
EXPECT_EQ(end, username_element_.selectionEnd());
}
base::string16 username1_;
base::string16 username2_;
base::string16 username3_;
base::string16 password1_;
base::string16 password2_;
base::string16 password3_;
base::string16 alternate_username3_;
PasswordFormFillData fill_data_;
WebInputElement username_element_;
WebInputElement password_element_;
private:
DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgentTest);
};
TEST_F(PasswordAutofillAgentTest, InitialAutocomplete) {
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
}
TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
const char kEmptyActionFormHTML[] =
"<FORM name='LoginTestForm'>"
" <INPUT type='text' id='username'/>"
" <INPUT type='password' id='password'/>"
" <INPUT type='submit' value='Login'/>"
"</FORM>";
LoadHTML(kEmptyActionFormHTML);
WebDocument document = GetMainFrame()->document();
WebElement element =
document.getElementById(WebString::fromUTF8(kUsernameName));
ASSERT_FALSE(element.isNull());
username_element_ = element.to<blink::WebInputElement>();
element = document.getElementById(WebString::fromUTF8(kPasswordName));
ASSERT_FALSE(element.isNull());
password_element_ = element.to<blink::WebInputElement>();
UpdateOriginForHTML(kEmptyActionFormHTML);
fill_data_.basic_data.action = fill_data_.basic_data.origin;
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
}
TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) {
password_element_.setAttribute(WebString::fromUTF8("readonly"),
WebString::fromUTF8("true"));
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(std::string(), false, std::string(), false);
}
TEST_F(PasswordAutofillAgentTest,
AutocompletePasswordForReadonlyUsernameMatched) {
username_element_.setValue(username3_);
username_element_.setAttribute(WebString::fromUTF8("readonly"),
WebString::fromUTF8("true"));
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(UTF16ToUTF8(username3_), false,
UTF16ToUTF8(password3_), true);
}
TEST_F(PasswordAutofillAgentTest,
NoAutocompletePasswordForReadonlyUsernameUnmatched) {
username_element_.setValue(WebString::fromUTF8(""));
username_element_.setAttribute(WebString::fromUTF8("readonly"),
WebString::fromUTF8("true"));
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(std::string(), false, std::string(), false);
}
TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) {
username_element_.setValue(WebString::fromUTF8("bogus"));
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState("bogus", false, std::string(), false);
}
TEST_F(PasswordAutofillAgentTest, NoPartialMatchForPrefilledUsername) {
username_element_.setValue(WebString::fromUTF8("ali"));
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState("ali", false, std::string(), false);
}
TEST_F(PasswordAutofillAgentTest, InputWithNoForms) {
const char kNoFormInputs[] =
"<input type='text' id='username'/>"
"<input type='password' id='password'/>";
LoadHTML(kNoFormInputs);
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(std::string(), false, std::string(), false);
}
TEST_F(PasswordAutofillAgentTest, NoAutocompleteForTextFieldPasswords) {
const char kTextFieldPasswordFormHTML[] =
"<FORM name='LoginTestForm' action='http://www.bidule.com'>"
" <INPUT type='text' id='username'/>"
" <INPUT type='text' id='password'/>"
" <INPUT type='submit' value='Login'/>"
"</FORM>";
LoadHTML(kTextFieldPasswordFormHTML);
WebDocument document = GetMainFrame()->document();
WebElement element =
document.getElementById(WebString::fromUTF8(kUsernameName));
ASSERT_FALSE(element.isNull());
username_element_ = element.to<blink::WebInputElement>();
element = document.getElementById(WebString::fromUTF8(kPasswordName));
ASSERT_FALSE(element.isNull());
password_element_ = element.to<blink::WebInputElement>();
UpdateOriginForHTML(kTextFieldPasswordFormHTML);
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(std::string(), false, std::string(), false);
}
TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) {
const char kPasswordFieldUsernameFormHTML[] =
"<FORM name='LoginTestForm' action='http://www.bidule.com'>"
" <INPUT type='password' id='username'/>"
" <INPUT type='password' id='password'/>"
" <INPUT type='submit' value='Login'/>"
"</FORM>";
LoadHTML(kPasswordFieldUsernameFormHTML);
WebDocument document = GetMainFrame()->document();
WebElement element =
document.getElementById(WebString::fromUTF8(kUsernameName));
ASSERT_FALSE(element.isNull());
username_element_ = element.to<blink::WebInputElement>();
element = document.getElementById(WebString::fromUTF8(kPasswordName));
ASSERT_FALSE(element.isNull());
password_element_ = element.to<blink::WebInputElement>();
UpdateOriginForHTML(kPasswordFieldUsernameFormHTML);
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(std::string(), false, std::string(), false);
}
TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForMatchingFilledField) {
username_element_.setValue(WebString::fromUTF8(kAliceUsername));
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
}
TEST_F(PasswordAutofillAgentTest, PasswordClearOnEdit) {
SimulateOnFillPasswordForm(fill_data_);
SimulateUsernameChange("alicia", true);
CheckTextFieldsState("alicia", false, std::string(), false);
}
TEST_F(PasswordAutofillAgentTest, WaitUsername) {
fill_data_.wait_for_username = true;
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(std::string(), false, std::string(), false);
SimulateUsernameChange("a", true);
CheckTextFieldsState("a", false, std::string(), false);
SimulateUsernameChange("al", true);
CheckTextFieldsState("al", false, std::string(), false);
SimulateUsernameChange(kAliceUsername, true);
CheckTextFieldsState(kAliceUsername, false, std::string(), false);
username_element_.setValue("a");
autofill_agent_->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("a", false, std::string(), false);
username_element_.setValue("al");
autofill_agent_->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("al", false, std::string(), false);
username_element_.setValue("alices");
autofill_agent_->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("alices", false, std::string(), false);
username_element_.setValue(ASCIIToUTF16(kAliceUsername));
autofill_agent_->textFieldDidEndEditing(username_element_);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
}
TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) {
SimulateOnFillPasswordForm(fill_data_);
ClearUsernameAndPasswordFields();
SimulateUsernameChange("a", true);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
CheckUsernameSelection(1, 5);
SimulateUsernameChange("al", true);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
CheckUsernameSelection(2, 5);
SimulateKeyDownEvent(username_element_, ui::VKEY_BACK);
SimulateUsernameChange("alic", true);
CheckTextFieldsState("alic", false, std::string(), false);
CheckUsernameSelection(4, 4);
SimulateKeyDownEvent(username_element_, ui::VKEY_A);
SimulateUsernameChange("alf", true);
CheckTextFieldsState("alf", false, std::string(), false);
CheckUsernameSelection(3, 3);
SimulateUsernameChange("b", true);
CheckTextFieldsState(kBobUsername, true, kBobPassword, true);
CheckUsernameSelection(1, 3);
SimulateUsernameChange("C", true);
CheckTextFieldsState(kCarolUsername, true, kCarolPassword, true);
CheckUsernameSelection(1, 5);
SimulateUsernameChange("c", true);
CheckTextFieldsState("c", false, std::string(), false);
CheckUsernameSelection(1, 1);
SimulateUsernameChange("R", true);
CheckTextFieldsState(kCarolAlternateUsername, true, kCarolPassword, true);
CheckUsernameSelection(1, 17);
}
TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
blink::WebVector<blink::WebFormElement> forms1, forms2, forms3;
blink::WebFrame* frame;
LoadHTML(kVisibleFormHTML);
frame = GetMainFrame();
frame->document().forms(forms1);
ASSERT_EQ(1u, forms1.size());
EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
LoadHTML(kEmptyFormHTML);
frame = GetMainFrame();
frame->document().forms(forms2);
ASSERT_EQ(1u, forms2.size());
EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
LoadHTML(kNonVisibleFormHTML);
frame = GetMainFrame();
frame->document().forms(forms3);
ASSERT_EQ(1u, forms3.size());
EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
}
TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
render_thread_->sink().ClearMessages();
LoadHTML(kVisibleFormHTML);
const IPC::Message* message = render_thread_->sink()
.GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
EXPECT_TRUE(message);
Tuple1<std::vector<autofill::PasswordForm> > param;
AutofillHostMsg_PasswordFormsRendered::Read(message, ¶m);
EXPECT_TRUE(param.a.size());
render_thread_->sink().ClearMessages();
LoadHTML(kEmptyFormHTML);
message = render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_PasswordFormsRendered::ID);
EXPECT_TRUE(message);
AutofillHostMsg_PasswordFormsRendered::Read(message, ¶m);
EXPECT_FALSE(param.a.size());
render_thread_->sink().ClearMessages();
LoadHTML(kNonVisibleFormHTML);
message = render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_PasswordFormsRendered::ID);
EXPECT_TRUE(message);
AutofillHostMsg_PasswordFormsRendered::Read(message, ¶m);
EXPECT_FALSE(param.a.size());
}
TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
render_thread_->sink().ClearMessages();
LoadHTML(kEmptyWebpage);
EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_PasswordFormsRendered::ID));
render_thread_->sink().ClearMessages();
LoadHTML(kRedirectionWebpage);
EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_PasswordFormsRendered::ID));
render_thread_->sink().ClearMessages();
LoadHTML(kSimpleWebpage);
EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_PasswordFormsRendered::ID));
render_thread_->sink().ClearMessages();
LoadHTML(kWebpageWithDynamicContent);
EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_PasswordFormsRendered::ID));
}
TEST_F(PasswordAutofillAgentTest, IframeNoFillTest) {
const char kIframeName[] = "iframe";
const char kWebpageWithIframeStart[] =
"<html>"
" <head>"
" <meta charset='utf-8' />"
" <title>Title</title>"
" </head>"
" <body>"
" <iframe name='iframe' src=\"";
const char kWebpageWithIframeEnd[] =
"\"></iframe>"
" </body>"
"</html>";
std::string origin("data:text/html;charset=utf-8,");
origin += kSimpleWebpage;
std::string page_html(kWebpageWithIframeStart);
page_html += origin;
page_html += kWebpageWithIframeEnd;
LoadHTML(page_html.c_str());
fill_data_.basic_data.origin = GURL(origin);
fill_data_.basic_data.action = GURL(origin);
SimulateOnFillPasswordForm(fill_data_);
WebFrame* iframe = GetMainFrame()->findChildByName(kIframeName);
ASSERT_TRUE(iframe);
WebDocument document = iframe->document();
WebElement username_element = document.getElementById(kUsernameName);
WebElement password_element = document.getElementById(kPasswordName);
ASSERT_FALSE(username_element.isNull());
ASSERT_FALSE(password_element.isNull());
WebInputElement username_input = username_element.to<WebInputElement>();
WebInputElement password_input = password_element.to<WebInputElement>();
ASSERT_FALSE(username_element.isNull());
CheckTextFieldsStateForElements(username_input, "", false,
password_input, "", false);
SimulateUsernameChangeForElement(kAliceUsername, true,
iframe, username_input);
CheckTextFieldsStateForElements(username_input, kAliceUsername, true,
password_input, kAlicePassword, true);
}
TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
SimulateElementClick(kUsernameName);
CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
}
TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) {
SimulateOnFillPasswordForm(fill_data_);
ExecuteJavaScript(kJavaScriptClick);
CheckTextFieldsDOMState(kAliceUsername, true, "", true);
}
TEST_F(PasswordAutofillAgentTest, SelectUsernameWithUsernameAutofillOff) {
SimulateOnFillPasswordForm(fill_data_);
username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
WebString::fromUTF8("off"));
SimulateUsernameChange(kAliceUsername, true);
ExpectNoSuggestionsPopup();
}
TEST_F(PasswordAutofillAgentTest,
SelectUnknownUsernameWithUsernameAutofillOff) {
SimulateOnFillPasswordForm(fill_data_);
username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
WebString::fromUTF8("off"));
SimulateUsernameChange("foo", true);
ExpectNoSuggestionsPopup();
}
TEST_F(PasswordAutofillAgentTest, SelectUsernameWithPasswordAutofillOff) {
SimulateOnFillPasswordForm(fill_data_);
password_element_.setAttribute(WebString::fromUTF8("autocomplete"),
WebString::fromUTF8("off"));
SimulateUsernameChange(kAliceUsername, true);
ExpectNoSuggestionsPopup();
}
TEST_F(PasswordAutofillAgentTest,
SelectUnknownUsernameWithPasswordAutofillOff) {
SimulateOnFillPasswordForm(fill_data_);
password_element_.setAttribute(WebString::fromUTF8("autocomplete"),
WebString::fromUTF8("off"));
SimulateUsernameChange("foo", true);
ExpectNoSuggestionsPopup();
}
TEST_F(PasswordAutofillAgentTest,
PasswordAutofillTriggersOnChangeEventsOnLoad) {
std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
LoadHTML(html.c_str());
UpdateOriginForHTML(html);
UpdateUsernameAndPasswordElements();
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
int username_onchange_called = -1;
int password_onchange_called = -1;
ASSERT_TRUE(
ExecuteJavaScriptAndReturnIntValue(
ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
&username_onchange_called));
EXPECT_EQ(1, username_onchange_called);
ASSERT_TRUE(
ExecuteJavaScriptAndReturnIntValue(
ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
&password_onchange_called));
SimulateElementClick(kUsernameName);
CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
ASSERT_TRUE(
ExecuteJavaScriptAndReturnIntValue(
ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
&password_onchange_called));
EXPECT_EQ(1, password_onchange_called);
}
TEST_F(PasswordAutofillAgentTest,
PasswordAutofillTriggersOnChangeEventsWaitForUsername) {
std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
LoadHTML(html.c_str());
UpdateOriginForHTML(html);
UpdateUsernameAndPasswordElements();
fill_data_.wait_for_username = true;
SimulateOnFillPasswordForm(fill_data_);
CheckTextFieldsState(std::string(), false, std::string(), false);
SimulateElementClick(kUsernameName);
username_element_.setValue(ASCIIToUTF16(kAliceUsername), true);
autofill_agent_->textFieldDidEndEditing(username_element_);
CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
int username_onchange_called = -1;
int password_onchange_called = -1;
ASSERT_TRUE(
ExecuteJavaScriptAndReturnIntValue(
ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
&username_onchange_called));
EXPECT_EQ(1, username_onchange_called);
ASSERT_TRUE(
ExecuteJavaScriptAndReturnIntValue(
ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
&password_onchange_called));
EXPECT_EQ(1, password_onchange_called);
}
}