autofill_browsertest.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <string> 6 7#include "base/utf_string_conversions.h" 8#include "base/basictypes.h" 9#include "base/ref_counted.h" 10#include "base/scoped_ptr.h" 11#include "base/string16.h" 12#include "chrome/browser/autofill/autofill_common_test.h" 13#include "chrome/browser/autofill/autofill_profile.h" 14#include "chrome/browser/autofill/personal_data_manager.h" 15#include "chrome/browser/net/predictor_api.h" 16#include "chrome/browser/profiles/profile.h" 17#include "chrome/browser/renderer_host/mock_render_process_host.h" 18#include "chrome/browser/renderer_host/render_view_host.h" 19#include "chrome/browser/tab_contents/tab_contents.h" 20#include "chrome/browser/translate/translate_infobar_delegate.h" 21#include "chrome/browser/translate/translate_manager.h" 22#include "chrome/browser/ui/browser.h" 23#include "chrome/browser/ui/browser_window.h" 24#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 25#include "chrome/common/net/test_url_fetcher_factory.h" 26#include "chrome/common/render_messages.h" 27#include "chrome/renderer/translate_helper.h" 28#include "chrome/test/in_process_browser_test.h" 29#include "chrome/test/ui_test_utils.h" 30#include "testing/gtest/include/gtest/gtest.h" 31#include "ui/base/keycodes/keyboard_codes.h" 32 33static const char* kDataURIPrefix = "data:text/html;charset=utf-8,"; 34static const char* kTestFormString = 35 "<form action=\"http://www.example.com/\" method=\"POST\">" 36 "<label for=\"firstname\">First name:</label>" 37 " <input type=\"text\" id=\"firstname\"" 38 " onFocus=\"domAutomationController.send(true)\"" 39 " /><br />" 40 "<label for=\"lastname\">Last name:</label>" 41 " <input type=\"text\" id=\"lastname\" /><br />" 42 "<label for=\"address1\">Address line 1:</label>" 43 " <input type=\"text\" id=\"address1\" /><br />" 44 "<label for=\"address2\">Address line 2:</label>" 45 " <input type=\"text\" id=\"address2\" /><br />" 46 "<label for=\"city\">City:</label>" 47 " <input type=\"text\" id=\"city\" /><br />" 48 "<label for=\"state\">State:</label>" 49 " <select id=\"state\">" 50 " <option value=\"\" selected=\"yes\">--</option>" 51 " <option value=\"CA\">California</option>" 52 " <option value=\"TX\">Texas</option>" 53 " </select><br />" 54 "<label for=\"zip\">ZIP code:</label>" 55 " <input type=\"text\" id=\"zip\" /><br />" 56 "<label for=\"country\">Country:</label>" 57 " <select id=\"country\">" 58 " <option value=\"\" selected=\"yes\">--</option>" 59 " <option value=\"CA\">Canada</option>" 60 " <option value=\"US\">United States</option>" 61 " </select><br />" 62 "<label for=\"phone\">Phone number:</label>" 63 " <input type=\"text\" id=\"phone\" /><br />" 64 "</form>"; 65 66class AutoFillTest : public InProcessBrowserTest { 67 protected: 68 AutoFillTest() { 69 set_show_window(true); 70 EnableDOMAutomation(); 71 } 72 73 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 74 URLFetcher::set_factory(&url_fetcher_factory_); 75 } 76 77 void CreateTestProfile() { 78 autofill_test::DisableSystemServices(browser()->profile()); 79 80 AutoFillProfile profile; 81 autofill_test::SetProfileInfo( 82 &profile, "Office Space", "Milton", "C.", "Waddams", 83 "red.swingline@initech.com", "Initech", "4120 Freidrich Lane", 84 "Basement", "Austin", "Texas", "78744", "United States", "5125551234", 85 "5125550000"); 86 87 PersonalDataManager* personal_data_manager = 88 browser()->profile()->GetPersonalDataManager(); 89 ASSERT_TRUE(personal_data_manager); 90 91 std::vector<AutoFillProfile> profiles(1, profile); 92 personal_data_manager->SetProfiles(&profiles); 93 } 94 95 void ExpectFieldValue(const std::wstring& field_name, 96 const std::string& expected_value) { 97 std::string value; 98 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( 99 browser()->GetSelectedTabContents()->render_view_host(), L"", 100 L"window.domAutomationController.send(" 101 L"document.getElementById('" + field_name + L"').value);", &value)); 102 EXPECT_EQ(expected_value, value); 103 } 104 105 RenderViewHost* render_view_host() { 106 return browser()->GetSelectedTabContents()->render_view_host(); 107 } 108 109 void SimulateURLFetch(bool success) { 110 TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 111 ASSERT_TRUE(fetcher); 112 net::URLRequestStatus status; 113 status.set_status(success ? net::URLRequestStatus::SUCCESS : 114 net::URLRequestStatus::FAILED); 115 116 std::string script = " var google = {};" 117 "google.translate = (function() {" 118 " return {" 119 " TranslateService: function() {" 120 " return {" 121 " isAvailable : function() {" 122 " return true;" 123 " }," 124 " restore : function() {" 125 " return;" 126 " }," 127 " getDetectedLanguage : function() {" 128 " return \"ja\";" 129 " }," 130 " translatePage : function(originalLang, targetLang," 131 " onTranslateProgress) {" 132 " document.getElementsByTagName(\"body\")[0].innerHTML = '" + 133 std::string(kTestFormString) + 134 " ';" 135 " onTranslateProgress(100, true, false);" 136 " }" 137 " };" 138 " }" 139 " };" 140 "})();"; 141 142 fetcher->delegate()->OnURLFetchComplete(fetcher, fetcher->original_url(), 143 status, success ? 200 : 500, 144 ResponseCookies(), 145 script); 146 } 147 148 void FocusFirstNameField() { 149 ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(), 150 VIEW_ID_TAB_CONTAINER)); 151 ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), 152 VIEW_ID_TAB_CONTAINER_FOCUS_VIEW)); 153 154 bool result = false; 155 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( 156 render_view_host(), L"", 157 L"document.getElementById('firstname').focus();", &result)); 158 ASSERT_TRUE(result); 159 } 160 161 void ExpectFilledTestForm() { 162 ExpectFieldValue(L"firstname", "Milton"); 163 ExpectFieldValue(L"lastname", "Waddams"); 164 ExpectFieldValue(L"address1", "4120 Freidrich Lane"); 165 ExpectFieldValue(L"address2", "Basement"); 166 ExpectFieldValue(L"city", "Austin"); 167 ExpectFieldValue(L"state", "TX"); 168 ExpectFieldValue(L"zip", "78744"); 169 ExpectFieldValue(L"country", "US"); 170 ExpectFieldValue(L"phone", "5125551234"); 171 } 172 173 void TryBasicFormFill() { 174 FocusFirstNameField(); 175 176 // Start filling the first name field with "M" and wait for the popup to be 177 // shown. 178 ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 179 browser(), ui::VKEY_M, false, true, false, false, 180 NotificationType::AUTOFILL_DID_SHOW_SUGGESTIONS, 181 Source<RenderViewHost>(render_view_host()))); 182 183 // Press the down arrow to select the suggestion and preview the autofilled 184 // form. 185 ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 186 browser(), ui::VKEY_DOWN, false, false, false, false, 187 NotificationType::AUTOFILL_DID_FILL_FORM_DATA, 188 Source<RenderViewHost>(render_view_host()))); 189 190 // The previewed values should not be accessible to JavaScript. 191 ExpectFieldValue(L"firstname", "M"); 192 ExpectFieldValue(L"lastname", ""); 193 ExpectFieldValue(L"address1", ""); 194 ExpectFieldValue(L"address2", ""); 195 ExpectFieldValue(L"city", ""); 196 ExpectFieldValue(L"state", ""); 197 ExpectFieldValue(L"zip", ""); 198 ExpectFieldValue(L"country", ""); 199 ExpectFieldValue(L"phone", ""); 200 // TODO(isherman): It would be nice to test that the previewed values are 201 // displayed: http://crbug.com/57220 202 203 // Press Enter to accept the autofill suggestions. 204 ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 205 browser(), ui::VKEY_RETURN, false, false, false, false, 206 NotificationType::AUTOFILL_DID_FILL_FORM_DATA, 207 Source<RenderViewHost>(render_view_host()))); 208 209 // The form should be filled. 210 ExpectFilledTestForm(); 211 } 212 213 private: 214 TestURLFetcherFactory url_fetcher_factory_; 215}; 216 217// Test that basic form fill is working. 218IN_PROC_BROWSER_TEST_F(AutoFillTest, BasicFormFill) { 219 CreateTestProfile(); 220 221 // Load the test page. 222 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 223 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 224 GURL(std::string(kDataURIPrefix) + kTestFormString))); 225 226 // Invoke AutoFill. 227 TryBasicFormFill(); 228} 229 230// Test that form filling can be initiated by pressing the down arrow. 231IN_PROC_BROWSER_TEST_F(AutoFillTest, AutoFillViaDownArrow) { 232 CreateTestProfile(); 233 234 // Load the test page. 235 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 236 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 237 GURL(std::string(kDataURIPrefix) + kTestFormString))); 238 239 // Focus a fillable field. 240 FocusFirstNameField(); 241 242 // Press the down arrow to initiate AutoFill and wait for the popup to be 243 // shown. 244 ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 245 browser(), ui::VKEY_DOWN, false, false, false, false, 246 NotificationType::AUTOFILL_DID_SHOW_SUGGESTIONS, 247 Source<RenderViewHost>(render_view_host()))); 248 249 // Press the down arrow to select the suggestion and preview the autofilled 250 // form. 251 ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 252 browser(), ui::VKEY_DOWN, false, false, false, false, 253 NotificationType::AUTOFILL_DID_FILL_FORM_DATA, 254 Source<RenderViewHost>(render_view_host()))); 255 256 // Press Enter to accept the autofill suggestions. 257 ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 258 browser(), ui::VKEY_RETURN, false, false, false, false, 259 NotificationType::AUTOFILL_DID_FILL_FORM_DATA, 260 Source<RenderViewHost>(render_view_host()))); 261 262 // The form should be filled. 263 ExpectFilledTestForm(); 264} 265 266// Test that form filling works after reloading the current page. 267// This test brought to you by http://crbug.com/69204 268IN_PROC_BROWSER_TEST_F(AutoFillTest, AutoFillAfterReload) { 269 CreateTestProfile(); 270 271 // Load the test page. 272 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 273 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 274 GURL(std::string(kDataURIPrefix) + kTestFormString))); 275 276 // Reload the page. 277 NavigationController* controller = 278 &browser()->GetSelectedTabContentsWrapper()->tab_contents()->controller(); 279 controller->Reload(false); 280 ui_test_utils::WaitForLoadStop(controller); 281 282 // Invoke AutoFill. 283 TryBasicFormFill(); 284} 285 286// Test that autofill works after page translation. 287IN_PROC_BROWSER_TEST_F(AutoFillTest, AutoFillAfterTranslate) { 288 CreateTestProfile(); 289 290 GURL url(std::string(kDataURIPrefix) + 291 "<form action=\"http://www.example.com/\" method=\"POST\">" 292 "<label for=\"fn\">なまえ</label>" 293 " <input type=\"text\" id=\"fn\"" 294 " onFocus=\"domAutomationController.send(true)\"" 295 " /><br />" 296 "<label for=\"ln\">みょうじ</label>" 297 " <input type=\"text\" id=\"ln\" /><br />" 298 "<label for=\"a1\">Address line 1:</label>" 299 " <input type=\"text\" id=\"a1\" /><br />" 300 "<label for=\"a2\">Address line 2:</label>" 301 " <input type=\"text\" id=\"a2\" /><br />" 302 "<label for=\"ci\">City:</label>" 303 " <input type=\"text\" id=\"ci\" /><br />" 304 "<label for=\"st\">State:</label>" 305 " <select id=\"st\">" 306 " <option value=\"\" selected=\"yes\">--</option>" 307 " <option value=\"CA\">California</option>" 308 " <option value=\"TX\">Texas</option>" 309 " </select><br />" 310 "<label for=\"z\">ZIP code:</label>" 311 " <input type=\"text\" id=\"z\" /><br />" 312 "<label for=\"co\">Country:</label>" 313 " <select id=\"co\">" 314 " <option value=\"\" selected=\"yes\">--</option>" 315 " <option value=\"CA\">Canada</option>" 316 " <option value=\"US\">United States</option>" 317 " </select><br />" 318 "<label for=\"ph\">Phone number:</label>" 319 " <input type=\"text\" id=\"ph\" /><br />" 320 "</form>"); 321 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 322 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); 323 324 // Get translation bar. 325 int page_id = browser()->GetSelectedTabContents()->controller(). 326 GetLastCommittedEntry()->page_id(); 327 render_view_host()->OnMessageReceived(ViewHostMsg_PageContents( 328 0, url, page_id, ASCIIToUTF16("test"), "ja", true)); 329 TranslateInfoBarDelegate* infobar = browser()->GetSelectedTabContents()-> 330 GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate(); 331 332 ASSERT_TRUE(infobar != NULL); 333 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); 334 335 // Simulate translation button press. 336 infobar->Translate(); 337 338 // Simulate the translate script being retrieved. 339 // Pass fake google.translate lib as the translate script. 340 SimulateURLFetch(true); 341 342 // Simulate translation to kick onTranslateElementLoad. 343 // But right now, the call stucks here. 344 // Once click the text field, it starts again. 345 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( 346 render_view_host(), L"", 347 L"cr.googleTranslate.onTranslateElementLoad();")); 348 349 // Simulate the render notifying the translation has been done. 350 ui_test_utils::WaitForNotification(NotificationType::PAGE_TRANSLATED); 351 352 TryBasicFormFill(); 353} 354