Commit 6a3f8d9a authored by rouslan's avatar rouslan Committed by Commit bot

[autofill] Allow only a user gesture to trigger autofill.

If a script inserts text into an input field without a user gesture,
then do not show the autofill popup.

TEST=AutofillRendererTest.IgnoreNonUserGestureTextFieldChanges
BUG=353001

Review URL: https://codereview.chromium.org/1026493002

Cr-Commit-Position: refs/heads/master@{#327204}
parent 992492e6
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "third_party/WebKit/public/web/WebFormElement.h" #include "third_party/WebKit/public/web/WebFormElement.h"
#include "third_party/WebKit/public/web/WebInputElement.h" #include "third_party/WebKit/public/web/WebInputElement.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
using base::ASCIIToUTF16; using base::ASCIIToUTF16;
using blink::WebDocument; using blink::WebDocument;
...@@ -245,6 +246,31 @@ TEST_F(AutofillRendererTest, DynamicallyAddedUnownedFormElements) { ...@@ -245,6 +246,31 @@ TEST_F(AutofillRendererTest, DynamicallyAddedUnownedFormElements) {
EXPECT_FORM_FIELD_DATA_EQUALS(expected, forms[0].fields[8]); EXPECT_FORM_FIELD_DATA_EQUALS(expected, forms[0].fields[8]);
} }
TEST_F(AutofillRendererTest, IgnoreNonUserGestureTextFieldChanges) {
LoadHTML("<form method='post'>"
" <input type='text' id='full_name'/>"
"</form>");
blink::WebInputElement full_name =
GetMainFrame()->document().getElementById("full_name")
.to<blink::WebInputElement>();
while (!full_name.focused())
GetMainFrame()->view()->advanceFocus(false);
// Not a user gesture, so no IPC message to browser.
full_name.setValue("Alice", true);
GetMainFrame()->toWebLocalFrame()->autofillClient()->textFieldDidChange(
full_name);
base::MessageLoop::current()->RunUntilIdle();
ASSERT_EQ(nullptr, render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_TextFieldDidChange::ID));
// A user gesture will send a message to the browser.
SimulateUserInputChangeForElement(&full_name, "Alice");
ASSERT_NE(nullptr, render_thread_->sink().GetFirstMessageMatching(
AutofillHostMsg_TextFieldDidChange::ID));
}
class RequestAutocompleteRendererTest : public AutofillRendererTest { class RequestAutocompleteRendererTest : public AutofillRendererTest {
public: public:
RequestAutocompleteRendererTest() RequestAutocompleteRendererTest()
......
...@@ -297,40 +297,6 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest { ...@@ -297,40 +297,6 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest {
->textFieldDidEndEditing(input); ->textFieldDidEndEditing(input);
} }
void SimulateInputChangeForElement(const std::string& new_value,
bool move_caret_to_end,
WebFrame* input_frame,
WebInputElement& input,
bool is_user_input) {
input.setValue(WebString::fromUTF8(new_value), is_user_input);
// The field must have focus or AutofillAgent will think the
// change should be ignored.
while (!input.focused())
input_frame->document().frame()->view()->advanceFocus(false);
if (move_caret_to_end)
input.setSelectionRange(new_value.length(), new_value.length());
if (is_user_input) {
AutofillMsg_FirstUserGestureObservedInTab msg(0);
content::RenderFrame::FromWebFrame(input_frame)->OnMessageReceived(msg);
// Also pass the message to the testing object.
if (input_frame == GetMainFrame())
password_autofill_agent_->FirstUserGestureObserved();
}
input_frame->toWebLocalFrame()->autofillClient()->textFieldDidChange(input);
// Processing is delayed because of a Blink bug:
// https://bugs.webkit.org/show_bug.cgi?id=16976
// See PasswordAutofillAgent::TextDidChangeInTextField() for details.
// Autocomplete will trigger a style recalculation when we put up the next
// frame, but we don't want to wait that long. Instead, trigger a style
// recalcuation manually after TextFieldDidChangeImpl runs.
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this)));
base::MessageLoop::current()->RunUntilIdle();
}
void SimulateSuggestionChoice(WebInputElement& username_input) { void SimulateSuggestionChoice(WebInputElement& username_input) {
base::string16 username(base::ASCIIToUTF16(kAliceUsername)); base::string16 username(base::ASCIIToUTF16(kAliceUsername));
base::string16 password(base::ASCIIToUTF16(kAlicePassword)); base::string16 password(base::ASCIIToUTF16(kAlicePassword));
...@@ -353,26 +319,12 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest { ...@@ -353,26 +319,12 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest {
->OnMessageReceived(msg); ->OnMessageReceived(msg);
} }
void LayoutMainFrame() { void SimulateUsernameChange(const std::string& username) {
GetMainFrame()->view()->layout(); SimulateUserInputChangeForElement(&username_element_, username);
} }
void SimulateUsernameChange(const std::string& username, void SimulatePasswordChange(const std::string& password) {
bool move_caret_to_end, SimulateUserInputChangeForElement(&password_element_, password);
bool is_user_input = false) {
SimulateInputChangeForElement(username,
move_caret_to_end,
GetMainFrame(),
username_element_,
is_user_input);
}
void SimulateKeyDownEvent(const WebInputElement& element,
ui::KeyboardCode key_code) {
blink::WebKeyboardEvent key_event;
key_event.windowsKeyCode = key_code;
static_cast<blink::WebAutofillClient*>(autofill_agent_)
->textFieldDidReceiveKeyDown(element, key_event);
} }
void CheckTextFieldsStateForElements(const WebInputElement& username_element, void CheckTextFieldsStateForElements(const WebInputElement& username_element,
...@@ -688,7 +640,7 @@ TEST_F(PasswordAutofillAgentTest, PasswordClearOnEdit) { ...@@ -688,7 +640,7 @@ TEST_F(PasswordAutofillAgentTest, PasswordClearOnEdit) {
SimulateOnFillPasswordForm(fill_data_); SimulateOnFillPasswordForm(fill_data_);
// Simulate the user changing the username to some unknown username. // Simulate the user changing the username to some unknown username.
SimulateUsernameChange("alicia", true); SimulateUsernameChange("alicia");
// The password should have been cleared. // The password should have been cleared.
CheckTextFieldsState("alicia", false, std::string(), false); CheckTextFieldsState("alicia", false, std::string(), false);
...@@ -705,31 +657,31 @@ TEST_F(PasswordAutofillAgentTest, WaitUsername) { ...@@ -705,31 +657,31 @@ TEST_F(PasswordAutofillAgentTest, WaitUsername) {
CheckTextFieldsState(std::string(), false, std::string(), false); CheckTextFieldsState(std::string(), false, std::string(), false);
// No autocomplete should happen when text is entered in the username. // No autocomplete should happen when text is entered in the username.
SimulateUsernameChange("a", true); SimulateUsernameChange("a");
CheckTextFieldsState("a", false, std::string(), false); CheckTextFieldsState("a", false, std::string(), false);
SimulateUsernameChange("al", true); SimulateUsernameChange("al");
CheckTextFieldsState("al", false, std::string(), false); CheckTextFieldsState("al", false, std::string(), false);
SimulateUsernameChange(kAliceUsername, true); SimulateUsernameChange(kAliceUsername);
CheckTextFieldsState(kAliceUsername, false, std::string(), false); CheckTextFieldsState(kAliceUsername, false, std::string(), false);
// Autocomplete should happen only when the username textfield is blurred with // Autocomplete should happen only when the username textfield is blurred with
// a full match. // a full match.
username_element_.setValue("a"); SimulateUsernameChange("a");
static_cast<blink::WebAutofillClient*>(autofill_agent_) static_cast<blink::WebAutofillClient*>(autofill_agent_)
->textFieldDidEndEditing(username_element_); ->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("a", false, std::string(), false); CheckTextFieldsState("a", false, std::string(), false);
username_element_.setValue("al"); SimulateUsernameChange("al");
static_cast<blink::WebAutofillClient*>(autofill_agent_) static_cast<blink::WebAutofillClient*>(autofill_agent_)
->textFieldDidEndEditing(username_element_); ->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("al", false, std::string(), false); CheckTextFieldsState("al", false, std::string(), false);
username_element_.setValue("alices"); SimulateUsernameChange("alices");
static_cast<blink::WebAutofillClient*>(autofill_agent_) static_cast<blink::WebAutofillClient*>(autofill_agent_)
->textFieldDidEndEditing(username_element_); ->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("alices", false, std::string(), false); CheckTextFieldsState("alices", false, std::string(), false);
username_element_.setValue(ASCIIToUTF16(kAliceUsername)); SimulateUsernameChange(kAliceUsername);
static_cast<blink::WebAutofillClient*>(autofill_agent_) static_cast<blink::WebAutofillClient*>(autofill_agent_)
->textFieldDidEndEditing(username_element_); ->textFieldDidEndEditing(username_element_);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
} }
// Tests that inline autocompletion works properly. // Tests that inline autocompletion works properly.
...@@ -741,57 +693,55 @@ TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) { ...@@ -741,57 +693,55 @@ TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) {
// Simulate the user typing in the first letter of 'alice', a stored // Simulate the user typing in the first letter of 'alice', a stored
// username. // username.
SimulateUsernameChange("a", true); SimulateUsernameChange("a");
// Both the username and password text fields should reflect selection of the // Both the username and password text fields should reflect selection of the
// stored login. // stored login.
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
// And the selection should have been set to 'lice', the last 4 letters. // And the selection should have been set to 'lice', the last 4 letters.
CheckUsernameSelection(1, 5); CheckUsernameSelection(1, 5);
// Now the user types the next letter of the same username, 'l'. // Now the user types the next letter of the same username, 'l'.
SimulateUsernameChange("al", true); SimulateUserTypingASCIICharacter('l', true);
// Now the fields should have the same value, but the selection should have a // Now the fields should have the same value, but the selection should have a
// different start value. // different start value.
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
CheckUsernameSelection(2, 5); CheckUsernameSelection(2, 5);
// Test that deleting does not trigger autocomplete. // Test that backspace will erase the selection and will stop autocompletion.
SimulateKeyDownEvent(username_element_, ui::VKEY_BACK); SimulateUserTypingASCIICharacter(ui::VKEY_BACK, true);
SimulateUsernameChange("alic", true); CheckTextFieldsState("al", false, std::string(), false);
CheckTextFieldsState("alic", false, std::string(), false); CheckUsernameSelection(2, 2); // No selection.
CheckUsernameSelection(4, 4); // No selection.
// Reset the last pressed key to something other than backspace.
SimulateKeyDownEvent(username_element_, ui::VKEY_A);
// Now lets say the user goes astray from the stored username and types the // Now lets say the user goes astray from the stored username and types the
// letter 'f', spelling 'alf'. We don't know alf (that's just sad), so in // letter 'f', spelling 'alf'. We don't know alf (that's just sad), so in
// practice the username should no longer be 'alice' and the selected range // practice the username should no longer be 'alice' and the selected range
// should be empty. // should be empty.
SimulateUsernameChange("alf", true); SimulateUserTypingASCIICharacter('f', true);
CheckTextFieldsState("alf", false, std::string(), false); CheckTextFieldsState("alf", false, std::string(), false);
CheckUsernameSelection(3, 3); // No selection. CheckUsernameSelection(3, 3); // No selection.
// Ok, so now the user removes all the text and enters the letter 'b'. // Ok, so now the user removes all the text and enters the letter 'b'.
SimulateUsernameChange("b", true); SimulateUsernameChange("b");
// The username and password fields should match the 'bob' entry. // The username and password fields should match the 'bob' entry.
CheckTextFieldsState(kBobUsername, true, kBobPassword, true); CheckTextFieldsDOMState(kBobUsername, true, kBobPassword, true);
CheckUsernameSelection(1, 3); CheckUsernameSelection(1, 3);
// Then, the user again removes all the text and types an uppercase 'C'. // Then, the user again removes all the text and types an uppercase 'C'.
SimulateUsernameChange("C", true); SimulateUsernameChange("C");
// The username and password fields should match the 'Carol' entry. // The username and password fields should match the 'Carol' entry.
CheckTextFieldsState(kCarolUsername, true, kCarolPassword, true); CheckTextFieldsDOMState(kCarolUsername, true, kCarolPassword, true);
CheckUsernameSelection(1, 5); CheckUsernameSelection(1, 5);
// The user removes all the text and types a lowercase 'c'. We only // The user removes all the text and types a lowercase 'c'. We only
// want case-sensitive autocompletion, so the username and the selected range // want case-sensitive autocompletion, so the username and the selected range
// should be empty. // should be empty.
SimulateUsernameChange("c", true); SimulateUsernameChange("c");
CheckTextFieldsState("c", false, std::string(), false); CheckTextFieldsState("c", false, std::string(), false);
CheckUsernameSelection(1, 1); CheckUsernameSelection(1, 1);
// Check that we complete other_possible_usernames as well. // Check that we complete other_possible_usernames as well.
SimulateUsernameChange("R", true); SimulateUsernameChange("R");
CheckTextFieldsState(kCarolAlternateUsername, true, kCarolPassword, true); CheckTextFieldsDOMState(kCarolAlternateUsername, true, kCarolPassword, true);
CheckUsernameSelection(1, 17); CheckUsernameSelection(1, 17);
} }
...@@ -920,8 +870,9 @@ TEST_F(PasswordAutofillAgentTest, IframeNoFillTest) { ...@@ -920,8 +870,9 @@ TEST_F(PasswordAutofillAgentTest, IframeNoFillTest) {
// Simulate the user typing in the username in the iframe which should cause // Simulate the user typing in the username in the iframe which should cause
// an autofill. // an autofill.
SimulateInputChangeForElement( content::RenderFrame::FromWebFrame(iframe)
kAliceUsername, true, iframe, username_input, true); ->OnMessageReceived(AutofillMsg_FirstUserGestureObservedInTab(0));
SimulateUserInputChangeForElement(&username_input, kAliceUsername);
CheckTextFieldsStateForElements(username_input, CheckTextFieldsStateForElements(username_input,
kAliceUsername, kAliceUsername,
...@@ -1029,9 +980,9 @@ TEST_F(PasswordAutofillAgentTest, ...@@ -1029,9 +980,9 @@ TEST_F(PasswordAutofillAgentTest,
// set directly. // set directly.
SimulateElementClick(kUsernameName); SimulateElementClick(kUsernameName);
// Simulate the user entering her username and selecting the matching autofill // Simulate the user entering the first letter of her username and selecting
// from the dropdown. // the matching autofill from the dropdown.
SimulateUsernameChange(kAliceUsername, true, true); SimulateUsernameChange("a");
SimulateSuggestionChoice(username_element_); SimulateSuggestionChoice(username_element_);
// The username and password should now have been autocompleted. // The username and password should now have been autocompleted.
...@@ -1289,10 +1240,10 @@ TEST_F(PasswordAutofillAgentTest, ClearPreviewWithInlineAutocompletedUsername) { ...@@ -1289,10 +1240,10 @@ TEST_F(PasswordAutofillAgentTest, ClearPreviewWithInlineAutocompletedUsername) {
ClearUsernameAndPasswordFields(); ClearUsernameAndPasswordFields();
// Simulate the user typing in the first letter of 'alice', a stored username. // Simulate the user typing in the first letter of 'alice', a stored username.
SimulateUsernameChange("a", true); SimulateUsernameChange("a");
// Both the username and password text fields should reflect selection of the // Both the username and password text fields should reflect selection of the
// stored login. // stored login.
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true); CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
// The selection should have been set to 'lice', the last 4 letters. // The selection should have been set to 'lice', the last 4 letters.
CheckUsernameSelection(1, 5); CheckUsernameSelection(1, 5);
...@@ -1314,7 +1265,7 @@ TEST_F(PasswordAutofillAgentTest, ClearPreviewWithInlineAutocompletedUsername) { ...@@ -1314,7 +1265,7 @@ TEST_F(PasswordAutofillAgentTest, ClearPreviewWithInlineAutocompletedUsername) {
EXPECT_EQ(kAliceUsername, username_element_.value().utf8()); EXPECT_EQ(kAliceUsername, username_element_.value().utf8());
EXPECT_TRUE(username_element_.suggestedValue().isEmpty()); EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
EXPECT_TRUE(username_element_.isAutofilled()); EXPECT_TRUE(username_element_.isAutofilled());
EXPECT_TRUE(password_element_.value().isEmpty()); EXPECT_EQ(kAlicePassword, password_element_.value().utf8());
EXPECT_TRUE(password_element_.suggestedValue().isEmpty()); EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
EXPECT_TRUE(password_element_.isAutofilled()); EXPECT_TRUE(password_element_.isAutofilled());
CheckUsernameSelection(1, 5); CheckUsernameSelection(1, 5);
...@@ -1414,17 +1365,18 @@ TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) { ...@@ -1414,17 +1365,18 @@ TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) {
// Now simulate a user typing in an unrecognized username and then // Now simulate a user typing in an unrecognized username and then
// clicking on the username element. This should also produce a message with // clicking on the username element. This should also produce a message with
// all the usernames. // all the usernames.
SimulateUsernameChange("baz", true); SimulateUsernameChange("baz");
render_thread_->sink().ClearMessages(); render_thread_->sink().ClearMessages();
static_cast<PageClickListener*>(autofill_agent_) static_cast<PageClickListener*>(autofill_agent_)
->FormControlElementClicked(username_element_, true); ->FormControlElementClicked(username_element_, true);
CheckSuggestions("baz", true); CheckSuggestions("baz", true);
ClearUsernameAndPasswordFields();
// Now simulate a user typing in the first letter of the username and then // Now simulate a user typing in the first letter of the username and then
// clicking on the username element. While the typing of the first letter will // clicking on the username element. While the typing of the first letter will
// inline autocomplete, clicking on the element should still produce a full // inline autocomplete, clicking on the element should still produce a full
// suggestion list. // suggestion list.
SimulateUsernameChange("a", true); SimulateUsernameChange("a");
render_thread_->sink().ClearMessages(); render_thread_->sink().ClearMessages();
static_cast<PageClickListener*>(autofill_agent_) static_cast<PageClickListener*>(autofill_agent_)
->FormControlElementClicked(username_element_, true); ->FormControlElementClicked(username_element_, true);
...@@ -1520,10 +1472,8 @@ TEST_F(PasswordAutofillAgentTest, NoCredentialsOnPasswordClick) { ...@@ -1520,10 +1472,8 @@ TEST_F(PasswordAutofillAgentTest, NoCredentialsOnPasswordClick) {
// typed by the user. // typed by the user.
TEST_F(PasswordAutofillAgentTest, TEST_F(PasswordAutofillAgentTest,
RememberLastNonEmptyUsernameAndPasswordOnSubmit_ScriptCleared) { RememberLastNonEmptyUsernameAndPasswordOnSubmit_ScriptCleared) {
SimulateInputChangeForElement( SimulateUsernameChange("temp");
"temp", true, GetMainFrame(), username_element_, true); SimulatePasswordChange("random");
SimulateInputChangeForElement(
"random", true, GetMainFrame(), password_element_, true);
// Simulate that the username and the password value was cleared by the // Simulate that the username and the password value was cleared by the
// site's JavaScript before submit. // site's JavaScript before submit.
...@@ -1543,16 +1493,12 @@ TEST_F(PasswordAutofillAgentTest, ...@@ -1543,16 +1493,12 @@ TEST_F(PasswordAutofillAgentTest,
// remembered. // remembered.
TEST_F(PasswordAutofillAgentTest, TEST_F(PasswordAutofillAgentTest,
RememberLastNonEmptyUsernameAndPasswordOnSubmit_UserCleared) { RememberLastNonEmptyUsernameAndPasswordOnSubmit_UserCleared) {
SimulateInputChangeForElement( SimulateUsernameChange("temp");
"temp", true, GetMainFrame(), username_element_, true); SimulatePasswordChange("random");
SimulateInputChangeForElement(
"random", true, GetMainFrame(), password_element_, true);
// Simulate that the user actually cleared the username and password again. // Simulate that the user actually cleared the username and password again.
SimulateInputChangeForElement("", true, GetMainFrame(), username_element_, SimulateUsernameChange("");
true); SimulatePasswordChange("");
SimulateInputChangeForElement(
"", true, GetMainFrame(), password_element_, true);
static_cast<content::RenderFrameObserver*>(password_autofill_agent_) static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
->WillSubmitForm(username_element_.form()); ->WillSubmitForm(username_element_.form());
...@@ -1574,10 +1520,8 @@ TEST_F(PasswordAutofillAgentTest, ...@@ -1574,10 +1520,8 @@ TEST_F(PasswordAutofillAgentTest,
LoadHTML(kNewPasswordFormHTML); LoadHTML(kNewPasswordFormHTML);
UpdateUsernameAndPasswordElements(); UpdateUsernameAndPasswordElements();
SimulateInputChangeForElement( SimulateUsernameChange("temp");
"temp", true, GetMainFrame(), username_element_, true); SimulatePasswordChange("random");
SimulateInputChangeForElement(
"random", true, GetMainFrame(), password_element_, true);
// Simulate that the username and the password value was cleared by // Simulate that the username and the password value was cleared by
// the site's JavaScript before submit. // the site's JavaScript before submit.
...@@ -1602,22 +1546,14 @@ TEST_F(PasswordAutofillAgentTest, ...@@ -1602,22 +1546,14 @@ TEST_F(PasswordAutofillAgentTest,
fill_data_.wait_for_username = true; fill_data_.wait_for_username = true;
SimulateOnFillPasswordForm(fill_data_); SimulateOnFillPasswordForm(fill_data_);
// Simulate that the user typed her name to make the autofill work. // Simulate that the user typed her name to make the autofill work.
SimulateInputChangeForElement(kAliceUsername, SimulateUsernameChange(kAliceUsername);
/*move_caret_to_end=*/true,
GetMainFrame(),
username_element_,
/*is_user_input=*/true);
SimulateDidEndEditing(GetMainFrame(), username_element_); SimulateDidEndEditing(GetMainFrame(), username_element_);
const std::string old_username(username_element_.value().utf8()); const std::string old_username(username_element_.value().utf8());
const std::string old_password(password_element_.value().utf8()); const std::string old_password(password_element_.value().utf8());
const std::string new_password(old_password + "modify"); const std::string new_password(old_password + "modify");
// The user changes the password. // The user changes the password.
SimulateInputChangeForElement(new_password, SimulatePasswordChange(new_password);
/*move_caret_to_end=*/true,
GetMainFrame(),
password_element_,
/*is_user_input=*/true);
// The user switches back into the username field, but leaves that without // The user switches back into the username field, but leaves that without
// changes. // changes.
...@@ -1637,14 +1573,10 @@ TEST_F(PasswordAutofillAgentTest, ...@@ -1637,14 +1573,10 @@ TEST_F(PasswordAutofillAgentTest,
ClearUsernameAndPasswordFields(); ClearUsernameAndPasswordFields();
// The user enters a password // The user enters a password
SimulateInputChangeForElement("someOtherPassword", SimulatePasswordChange("someOtherPassword");
/*move_caret_to_end=*/true,
GetMainFrame(),
password_element_,
/*is_user_input=*/true);
// Simulate the user typing a stored username. // Simulate the user typing a stored username.
SimulateUsernameChange(kAliceUsername, true); SimulateUsernameChange(kAliceUsername);
// The autofileld password should replace the typed one. // The autofileld password should replace the typed one.
CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
} }
...@@ -1655,10 +1587,8 @@ TEST_F(PasswordAutofillAgentTest, ...@@ -1655,10 +1587,8 @@ TEST_F(PasswordAutofillAgentTest,
// typed by the user. // typed by the user.
TEST_F(PasswordAutofillAgentTest, TEST_F(PasswordAutofillAgentTest,
RememberLastTypedUsernameAndPasswordOnSubmit_ScriptChanged) { RememberLastTypedUsernameAndPasswordOnSubmit_ScriptChanged) {
SimulateInputChangeForElement("temp", true, GetMainFrame(), username_element_, SimulateUsernameChange("temp");
true); SimulatePasswordChange("random");
SimulateInputChangeForElement("random", true, GetMainFrame(),
password_element_, true);
// Simulate that the username and the password value was changed by the // Simulate that the username and the password value was changed by the
// site's JavaScript before submit. // site's JavaScript before submit.
...@@ -1705,10 +1635,8 @@ TEST_F( ...@@ -1705,10 +1635,8 @@ TEST_F(
RememberLastTypedAfterAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) { RememberLastTypedAfterAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
SimulateOnFillPasswordForm(fill_data_); SimulateOnFillPasswordForm(fill_data_);
SimulateInputChangeForElement("temp", true, GetMainFrame(), username_element_, SimulateUsernameChange("temp");
true); SimulatePasswordChange("random");
SimulateInputChangeForElement("random", true, GetMainFrame(),
password_element_, true);
// Simulate that the username and the password value was changed by the // Simulate that the username and the password value was changed by the
// site's JavaScript before submit. // site's JavaScript before submit.
...@@ -1728,12 +1656,10 @@ TEST_F( ...@@ -1728,12 +1656,10 @@ TEST_F(
// PasswordAutofillAgent should remember the username that was autofilled, // PasswordAutofillAgent should remember the username that was autofilled,
// not last typed. // not last typed.
TEST_F(PasswordAutofillAgentTest, RememberAutofilledUsername) { TEST_F(PasswordAutofillAgentTest, RememberAutofilledUsername) {
SimulateInputChangeForElement("Te", true, GetMainFrame(), username_element_, SimulateUsernameChange("Te");
true);
// Simulate that the username was changed by autofilling. // Simulate that the username was changed by autofilling.
username_element_.setValue(WebString("temp")); username_element_.setValue(WebString("temp"));
SimulateInputChangeForElement("random", true, GetMainFrame(), SimulatePasswordChange("random");
password_element_, true);
static_cast<content::RenderFrameObserver*>(password_autofill_agent_) static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
->WillSendSubmitEvent(username_element_.form()); ->WillSendSubmitEvent(username_element_.form());
...@@ -1878,12 +1804,9 @@ TEST_F(PasswordAutofillAgentTest, FindingUsernameWithoutAutofillPredictions) { ...@@ -1878,12 +1804,9 @@ TEST_F(PasswordAutofillAgentTest, FindingUsernameWithoutAutofillPredictions) {
LoadHTML(kFormHTMLWithTwoTextFields); LoadHTML(kFormHTMLWithTwoTextFields);
UpdateUsernameAndPasswordElements(); UpdateUsernameAndPasswordElements();
blink::WebInputElement email_element = GetInputElementByID(kEmailName); blink::WebInputElement email_element = GetInputElementByID(kEmailName);
SimulateInputChangeForElement("temp", true, GetMainFrame(), username_element_, SimulateUsernameChange("temp");
true); SimulateUserInputChangeForElement(&email_element, "temp@google.com");
SimulateInputChangeForElement("temp@google.com", true, GetMainFrame(), SimulatePasswordChange("random");
email_element, true);
SimulateInputChangeForElement("random", true, GetMainFrame(),
password_element_, true);
static_cast<content::RenderFrameObserver*>(password_autofill_agent_) static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
->WillSendSubmitEvent(username_element_.form()); ->WillSendSubmitEvent(username_element_.form());
static_cast<content::RenderFrameObserver*>(password_autofill_agent_) static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
...@@ -1900,13 +1823,9 @@ TEST_F(PasswordAutofillAgentTest, FindingUsernameWithAutofillPredictions) { ...@@ -1900,13 +1823,9 @@ TEST_F(PasswordAutofillAgentTest, FindingUsernameWithAutofillPredictions) {
LoadHTML(kFormHTMLWithTwoTextFields); LoadHTML(kFormHTMLWithTwoTextFields);
UpdateUsernameAndPasswordElements(); UpdateUsernameAndPasswordElements();
blink::WebInputElement email_element = GetInputElementByID(kEmailName); blink::WebInputElement email_element = GetInputElementByID(kEmailName);
SimulateInputChangeForElement("temp", true, GetMainFrame(), username_element_, SimulateUsernameChange("temp");
true); SimulateUserInputChangeForElement(&email_element, "temp@google.com");
SimulateInputChangeForElement("temp@google.com", true, GetMainFrame(), SimulatePasswordChange("random");
email_element, true);
SimulateInputChangeForElement("random", true, GetMainFrame(),
password_element_, true);
// Find FormData for visible password form. // Find FormData for visible password form.
blink::WebFormElement form_element = username_element_.form(); blink::WebFormElement form_element = username_element_.form();
FormData form_data; FormData form_data;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebWidget.h" #include "third_party/WebKit/public/web/WebWidget.h"
#include "ui/events/keycodes/keyboard_codes.h"
using blink::WebDocument; using blink::WebDocument;
using blink::WebElement; using blink::WebElement;
...@@ -309,29 +310,18 @@ TEST_F(PasswordGenerationAgentTest, EditingTest) { ...@@ -309,29 +310,18 @@ TEST_F(PasswordGenerationAgentTest, EditingTest) {
EXPECT_EQ(password, second_password_element.value()); EXPECT_EQ(password, second_password_element.value());
// After editing the first field they are still the same. // After editing the first field they are still the same.
base::string16 edited_password = base::ASCIIToUTF16("edited_password"); std::string edited_password_ascii = "edited_password";
first_password_element.setValue(edited_password); SimulateUserInputChangeForElement(&first_password_element,
// Cast to WebAutofillClient where textFieldDidChange() is public. edited_password_ascii);
static_cast<blink::WebAutofillClient*>(autofill_agent_)->textFieldDidChange( base::string16 edited_password = base::ASCIIToUTF16(edited_password_ascii);
first_password_element);
// textFieldDidChange posts a task, so we need to wait until it's been
// processed.
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(edited_password, first_password_element.value()); EXPECT_EQ(edited_password, first_password_element.value());
EXPECT_EQ(edited_password, second_password_element.value()); EXPECT_EQ(edited_password, second_password_element.value());
// Verify that password mirroring works correctly even when the password // Verify that password mirroring works correctly even when the password
// is deleted. // is deleted.
base::string16 empty_password; SimulateUserInputChangeForElement(&first_password_element, std::string());
first_password_element.setValue(empty_password); EXPECT_EQ(base::string16(), first_password_element.value());
// Cast to WebAutofillClient where textFieldDidChange() is public. EXPECT_EQ(base::string16(), second_password_element.value());
static_cast<blink::WebAutofillClient*>(autofill_agent_)->textFieldDidChange(
first_password_element);
// textFieldDidChange posts a task, so we need to wait until it's been
// processed.
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(empty_password, first_password_element.value());
EXPECT_EQ(empty_password, second_password_element.value());
} }
TEST_F(PasswordGenerationAgentTest, BlacklistedTest) { TEST_F(PasswordGenerationAgentTest, BlacklistedTest) {
...@@ -394,15 +384,9 @@ TEST_F(PasswordGenerationAgentTest, MaximumOfferSize) { ...@@ -394,15 +384,9 @@ TEST_F(PasswordGenerationAgentTest, MaximumOfferSize) {
WebInputElement first_password_element = element.to<WebInputElement>(); WebInputElement first_password_element = element.to<WebInputElement>();
// Make a password just under maximum offer size. // Make a password just under maximum offer size.
first_password_element.setValue( SimulateUserInputChangeForElement(
base::ASCIIToUTF16( &first_password_element,
std::string(password_generation_->kMaximumOfferSize - 1, 'a'))); std::string(password_generation_->kMaximumOfferSize - 1, 'a'));
// Cast to WebAutofillClient where textFieldDidChange() is public.
static_cast<blink::WebAutofillClient*>(autofill_agent_)->textFieldDidChange(
first_password_element);
// textFieldDidChange posts a task, so we need to wait until it's been
// processed.
base::MessageLoop::current()->RunUntilIdle();
// There should now be a message to show the UI. // There should now be a message to show the UI.
ASSERT_EQ(1u, password_generation_->messages().size()); ASSERT_EQ(1u, password_generation_->messages().size());
EXPECT_EQ(AutofillHostMsg_ShowPasswordGenerationPopup::ID, EXPECT_EQ(AutofillHostMsg_ShowPasswordGenerationPopup::ID,
...@@ -410,15 +394,8 @@ TEST_F(PasswordGenerationAgentTest, MaximumOfferSize) { ...@@ -410,15 +394,8 @@ TEST_F(PasswordGenerationAgentTest, MaximumOfferSize) {
password_generation_->clear_messages(); password_generation_->clear_messages();
// Simulate a user typing a password just over maximum offer size. // Simulate a user typing a password just over maximum offer size.
first_password_element.setValue( SimulateUserTypingASCIICharacter('a', false);
base::ASCIIToUTF16( SimulateUserTypingASCIICharacter('a', true);
std::string(password_generation_->kMaximumOfferSize + 1, 'a')));
// Cast to WebAutofillClient where textFieldDidChange() is public.
static_cast<blink::WebAutofillClient*>(autofill_agent_)->textFieldDidChange(
first_password_element);
// textFieldDidChange posts a task, so we need to wait until it's been
// processed.
base::MessageLoop::current()->RunUntilIdle();
// There should now be a message to hide the UI. // There should now be a message to hide the UI.
ASSERT_EQ(1u, password_generation_->messages().size()); ASSERT_EQ(1u, password_generation_->messages().size());
EXPECT_EQ(AutofillHostMsg_HidePasswordGenerationPopup::ID, EXPECT_EQ(AutofillHostMsg_HidePasswordGenerationPopup::ID,
...@@ -427,15 +404,7 @@ TEST_F(PasswordGenerationAgentTest, MaximumOfferSize) { ...@@ -427,15 +404,7 @@ TEST_F(PasswordGenerationAgentTest, MaximumOfferSize) {
// Simulate the user deleting characters. The generation popup should be shown // Simulate the user deleting characters. The generation popup should be shown
// again. // again.
first_password_element.setValue( SimulateUserTypingASCIICharacter(ui::VKEY_BACK, true);
base::ASCIIToUTF16(
std::string(password_generation_->kMaximumOfferSize, 'a')));
// Cast to WebAutofillClient where textFieldDidChange() is public.
static_cast<blink::WebAutofillClient*>(autofill_agent_)->textFieldDidChange(
first_password_element);
// textFieldDidChange posts a task, so we need to wait until it's been
// processed.
base::MessageLoop::current()->RunUntilIdle();
// There should now be a message to show the UI. // There should now be a message to show the UI.
ASSERT_EQ(1u, password_generation_->messages().size()); ASSERT_EQ(1u, password_generation_->messages().size());
EXPECT_EQ(AutofillHostMsg_ShowPasswordGenerationPopup::ID, EXPECT_EQ(AutofillHostMsg_ShowPasswordGenerationPopup::ID,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "components/autofill/content/renderer/autofill_agent.h" #include "components/autofill/content/renderer/autofill_agent.h"
#include "base/auto_reset.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
...@@ -43,6 +44,7 @@ ...@@ -43,6 +44,7 @@
#include "third_party/WebKit/public/web/WebNode.h" #include "third_party/WebKit/public/web/WebNode.h"
#include "third_party/WebKit/public/web/WebOptionElement.h" #include "third_party/WebKit/public/web/WebOptionElement.h"
#include "third_party/WebKit/public/web/WebTextAreaElement.h" #include "third_party/WebKit/public/web/WebTextAreaElement.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/WebView.h" #include "third_party/WebKit/public/web/WebView.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/events/keycodes/keyboard_codes.h" #include "ui/events/keycodes/keyboard_codes.h"
...@@ -62,6 +64,7 @@ using blink::WebNode; ...@@ -62,6 +64,7 @@ using blink::WebNode;
using blink::WebOptionElement; using blink::WebOptionElement;
using blink::WebString; using blink::WebString;
using blink::WebTextAreaElement; using blink::WebTextAreaElement;
using blink::WebUserGestureIndicator;
using blink::WebVector; using blink::WebVector;
namespace autofill { namespace autofill {
...@@ -149,7 +152,6 @@ AutofillAgent::AutofillAgent(content::RenderFrame* render_frame, ...@@ -149,7 +152,6 @@ AutofillAgent::AutofillAgent(content::RenderFrame* render_frame,
autofill_query_id_(0), autofill_query_id_(0),
was_query_node_autofilled_(false), was_query_node_autofilled_(false),
has_shown_autofill_popup_for_current_edit_(false), has_shown_autofill_popup_for_current_edit_(false),
did_set_node_text_(false),
ignore_text_changes_(false), ignore_text_changes_(false),
is_popup_possibly_visible_(false), is_popup_possibly_visible_(false),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
...@@ -378,15 +380,12 @@ void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) { ...@@ -378,15 +380,12 @@ void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) {
} }
void AutofillAgent::textFieldDidChange(const WebFormControlElement& element) { void AutofillAgent::textFieldDidChange(const WebFormControlElement& element) {
DCHECK(toWebInputElement(&element) || IsTextAreaElement(element));
if (ignore_text_changes_) if (ignore_text_changes_)
return; return;
DCHECK(toWebInputElement(&element) || IsTextAreaElement(element)); if (!WebUserGestureIndicator::isProcessingUserGesture())
if (did_set_node_text_) {
did_set_node_text_ = false;
return; return;
}
// We post a task for doing the Autofill as the caret position is not set // We post a task for doing the Autofill as the caret position is not set
// properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and
...@@ -714,7 +713,7 @@ void AutofillAgent::QueryAutofillSuggestions( ...@@ -714,7 +713,7 @@ void AutofillAgent::QueryAutofillSuggestions(
void AutofillAgent::FillFieldWithValue(const base::string16& value, void AutofillAgent::FillFieldWithValue(const base::string16& value,
WebInputElement* node) { WebInputElement* node) {
did_set_node_text_ = true; base::AutoReset<bool> auto_reset(&ignore_text_changes_, true);
node->setEditingValue(value.substr(0, node->maxLength())); node->setEditingValue(value.substr(0, node->maxLength()));
} }
......
...@@ -252,9 +252,6 @@ class AutofillAgent : public content::RenderFrameObserver, ...@@ -252,9 +252,6 @@ class AutofillAgent : public content::RenderFrameObserver,
// currently editing? Used to keep track of state for metrics logging. // currently editing? Used to keep track of state for metrics logging.
bool has_shown_autofill_popup_for_current_edit_; bool has_shown_autofill_popup_for_current_edit_;
// If true we just set the node text so we shouldn't show the popup.
bool did_set_node_text_;
// Whether or not to ignore text changes. Useful for when we're committing // Whether or not to ignore text changes. Useful for when we're committing
// a composition when we are defocusing the WebView and we don't want to // a composition when we are defocusing the WebView and we don't want to
// trigger an autofill popup to show. // trigger an autofill popup to show.
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "content/public/test/render_view_test.h" #include "content/public/test/render_view_test.h"
#include <cctype>
#include "base/run_loop.h" #include "base/run_loop.h"
#include "components/scheduler/renderer/renderer_scheduler.h" #include "components/scheduler/renderer/renderer_scheduler.h"
#include "content/common/dom_storage/dom_storage_types.h" #include "content/common/dom_storage/dom_storage_types.h"
...@@ -27,13 +29,16 @@ ...@@ -27,13 +29,16 @@
#include "content/test/test_content_client.h" #include "content/test/test_content_client.h"
#include "third_party/WebKit/public/platform/WebScreenInfo.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h" #include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebHistoryItem.h" #include "third_party/WebKit/public/web/WebHistoryItem.h"
#include "third_party/WebKit/public/web/WebInputElement.h"
#include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebInputEvent.h"
#include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebView.h" #include "third_party/WebKit/public/web/WebView.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
...@@ -49,6 +54,7 @@ using blink::WebString; ...@@ -49,6 +54,7 @@ using blink::WebString;
using blink::WebURLRequest; using blink::WebURLRequest;
namespace { namespace {
const int32 kOpenerId = -2; const int32 kOpenerId = -2;
const int32 kRouteId = 5; const int32 kRouteId = 5;
const int32 kMainFrameRouteId = 6; const int32 kMainFrameRouteId = 6;
...@@ -56,6 +62,32 @@ const int32 kNewWindowRouteId = 7; ...@@ -56,6 +62,32 @@ const int32 kNewWindowRouteId = 7;
const int32 kNewFrameRouteId = 10; const int32 kNewFrameRouteId = 10;
const int32 kSurfaceId = 42; const int32 kSurfaceId = 42;
// Converts |ascii_character| into |key_code| and returns true on success.
// Handles only the characters needed by tests.
bool GetWindowsKeyCode(char ascii_character, int* key_code) {
if (isalnum(ascii_character)) {
*key_code = base::ToUpperASCII(ascii_character);
return true;
}
switch (ascii_character) {
case '@':
*key_code = '2';
return true;
case '_':
*key_code = ui::VKEY_OEM_MINUS;
return true;
case '.':
*key_code = ui::VKEY_OEM_PERIOD;
return true;
case ui::VKEY_BACK:
*key_code = ui::VKEY_BACK;
return true;
default:
return false;
}
}
} // namespace } // namespace
namespace content { namespace content {
...@@ -395,6 +427,55 @@ void RenderViewTest::Resize(gfx::Size new_size, ...@@ -395,6 +427,55 @@ void RenderViewTest::Resize(gfx::Size new_size,
OnMessageReceived(*resize_message); OnMessageReceived(*resize_message);
} }
void RenderViewTest::SimulateUserTypingASCIICharacter(char ascii_character,
bool flush_message_loop) {
blink::WebKeyboardEvent event;
event.text[0] = ascii_character;
ASSERT_TRUE(GetWindowsKeyCode(ascii_character, &event.windowsKeyCode));
if (isupper(ascii_character) || ascii_character == '@' ||
ascii_character == '_') {
event.modifiers = blink::WebKeyboardEvent::ShiftKey;
}
event.type = blink::WebKeyboardEvent::RawKeyDown;
SendWebKeyboardEvent(event);
event.type = blink::WebKeyboardEvent::Char;
SendWebKeyboardEvent(event);
event.type = blink::WebKeyboardEvent::KeyUp;
SendWebKeyboardEvent(event);
if (flush_message_loop) {
// Processing is delayed because of a Blink bug:
// https://bugs.webkit.org/show_bug.cgi?id=16976 See
// PasswordAutofillAgent::TextDidChangeInTextField() for details.
base::MessageLoop::current()->RunUntilIdle();
}
}
void RenderViewTest::SimulateUserInputChangeForElement(
blink::WebInputElement* input,
const std::string& new_value) {
ASSERT_TRUE(base::IsStringASCII(new_value));
while (!input->focused())
input->document().frame()->view()->advanceFocus(false);
size_t previous_length = input->value().length();
for (size_t i = 0; i < previous_length; ++i)
SimulateUserTypingASCIICharacter(ui::VKEY_BACK, false);
EXPECT_TRUE(input->value().utf8().empty());
for (size_t i = 0; i < new_value.size(); ++i)
SimulateUserTypingASCIICharacter(new_value[i], false);
// Compare only beginning, because autocomplete may have filled out the
// form.
EXPECT_EQ(new_value, input->value().utf8().substr(0, new_value.length()));
base::MessageLoop::current()->RunUntilIdle();
}
bool RenderViewTest::OnMessageReceived(const IPC::Message& msg) { bool RenderViewTest::OnMessageReceived(const IPC::Message& msg) {
RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
return impl->OnMessageReceived(msg); return impl->OnMessageReceived(msg);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
struct ViewMsg_Resize_Params; struct ViewMsg_Resize_Params;
namespace blink { namespace blink {
class WebInputElement;
class WebWidget; class WebWidget;
} }
...@@ -99,7 +100,7 @@ class RenderViewTest : public testing::Test { ...@@ -99,7 +100,7 @@ class RenderViewTest : public testing::Test {
void SendWebKeyboardEvent(const blink::WebKeyboardEvent& key_event); void SendWebKeyboardEvent(const blink::WebKeyboardEvent& key_event);
// Send a raw mouse event to the renderer. // Send a raw mouse event to the renderer.
void SendWebMouseEvent(const blink::WebMouseEvent& key_event); void SendWebMouseEvent(const blink::WebMouseEvent& mouse_event);
// Returns the bounds (coordinates and size) of the element with id // Returns the bounds (coordinates and size) of the element with id
// |element_id|. Returns an empty rect if such an element was not found. // |element_id|. Returns an empty rect if such an element was not found.
...@@ -130,6 +131,18 @@ class RenderViewTest : public testing::Test { ...@@ -130,6 +131,18 @@ class RenderViewTest : public testing::Test {
gfx::Rect resizer_rect, gfx::Rect resizer_rect,
bool is_fullscreen); bool is_fullscreen);
// Simulates typing the |ascii_character| into this render view. Also accepts
// ui::VKEY_BACK for backspace. Will flush the message loop if
// |flush_message_loop| is true.
void SimulateUserTypingASCIICharacter(char ascii_character,
bool flush_message_loop);
// Simulates user focusing |input|, erasing all text, and typing the
// |new_value| instead. Will process input events for autofill. This is a user
// gesture.
void SimulateUserInputChangeForElement(blink::WebInputElement* input,
const std::string& new_value);
// These are all methods from RenderViewImpl that we expose to testing code. // These are all methods from RenderViewImpl that we expose to testing code.
bool OnMessageReceived(const IPC::Message& msg); bool OnMessageReceived(const IPC::Message& msg);
void DidNavigateWithinPage(blink::WebLocalFrame* frame, void DidNavigateWithinPage(blink::WebLocalFrame* frame,
......
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