From 5f93c76a08113d1beb6dd27458b0101fdc3ce366 Mon Sep 17 00:00:00 2001
From: "dhollowa@chromium.org"
 <dhollowa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Wed, 15 Dec 2010 00:05:47 +0000
Subject: [PATCH] Before starting translation reset cache in AutoFillManager.
 To call Reset() function, append Reset() virtual function in
 RenderViewHostDelegate::AutoFill and derive it from AutoFillManager.

BUG=58576
TEST= 1.launch English version Chrome 2. make sure autofill is enable and there is autofill data entry in settings 3.navigate to a non-English website e.g.: https://secure.fnac.pt/Account/Logon/LogonNewAccount.aspx?NID=-15&RNID=-15&PrevNID=0&pagepar=SID%3d22120814-4186-d926-4f7b-0dece96fade2|Origin%3dFnacAff|OrderInSession%3d1|TTL%3d070420110015|bl%3dHGAChead&PageRedir=https://www2.fnac.pt/Account/Profil/default.asp&PageAuth=yes&LogonType=ACCOUNT 4. when translation infobar show up, click "Translate" to translate to English 5. focus in "E-mail" field 6. press Down arrow 7. select the autofill data entry by double click on it 8. autofill data should be fill in all text boxes

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=69088

Review URL: http://codereview.chromium.org/5322001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69199 0039d316-1c4b-4281-b951-d872f2087c98
---
 .../browser/autofill/autofill_browsertest.cc  | 307 +++++++++++++-----
 chrome/browser/autofill/autofill_manager.h    |   4 +-
 .../chromeos/login/account_creation_view.cc   |   2 +
 .../browser/renderer_host/render_view_host.cc |   9 +
 .../renderer_host/render_view_host_delegate.h |   3 +
 chrome/chrome_tests.gypi                      |   2 +
 6 files changed, 236 insertions(+), 91 deletions(-)

diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index a14f5616277ef..0aad9de5fb9fc 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include <string>
 
+#include "base/utf_string_conversions.h"
 #include "app/keyboard_code_conversion.h"
 #include "base/basictypes.h"
 #include "base/ref_counted.h"
@@ -14,14 +15,53 @@
 #include "chrome/browser/autofill/personal_data_manager.h"
 #include "chrome/browser/net/predictor_api.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/renderer_host/mock_render_process_host.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
 #include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/translate/translate_infobar_delegate.h"
+#include "chrome/browser/translate/translate_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/common/net/test_url_fetcher_factory.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/translate_helper.h"
 #include "chrome/test/in_process_browser_test.h"
 #include "chrome/test/ui_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+static const char* kTestFormString =
+    "<form action=\"http://www.google.com/\" method=\"POST\">"
+    "<label for=\"firstname\">First name:</label>"
+    " <input type=\"text\" id=\"firstname\""
+    "        onFocus=\"domAutomationController.send(true)\""
+    " /><br />"
+    "<label for=\"lastname\">Last name:</label>"
+    " <input type=\"text\" id=\"lastname\" /><br />"
+    "<label for=\"address1\">Address line 1:</label>"
+    " <input type=\"text\" id=\"address1\" /><br />"
+    "<label for=\"address2\">Address line 2:</label>"
+    " <input type=\"text\" id=\"address2\" /><br />"
+    "<label for=\"city\">City:</label>"
+    " <input type=\"text\" id=\"city\" /><br />"
+    "<label for=\"state\">State:</label>"
+    " <select id=\"state\">"
+    " <option value=\"\" selected=\"yes\">--</option>"
+    " <option value=\"CA\">California</option>"
+    " <option value=\"TX\">Texas</option>"
+    " </select><br />"
+    "<label for=\"zip\">ZIP code:</label>"
+    " <input type=\"text\" id=\"zip\" /><br />"
+    "<label for=\"country\">Country:</label>"
+    " <select id=\"country\">"
+    " <option value=\"\" selected=\"yes\">--</option>"
+    " <option value=\"CA\">Canada</option>"
+    " <option value=\"US\">United States</option>"
+    " </select><br />"
+    "<label for=\"phone\">Phone number:</label>"
+    " <input type=\"text\" id=\"phone\" /><br />"
+    "</form>";
+
 class AutoFillTest : public InProcessBrowserTest {
  protected:
   AutoFillTest() {
@@ -56,100 +96,191 @@ class AutoFillTest : public InProcessBrowserTest {
         L"document.getElementById('" + field_name + L"').value);", &value));
     EXPECT_EQ(expected_value, value);
   }
+
+  RenderViewHost* rvh() {
+    return browser()->GetSelectedTabContents()->render_view_host();
+  }
+
+  virtual void SetUp() {
+    URLFetcher::set_factory(&url_fetcher_factory_);
+    InProcessBrowserTest::SetUp();
+  }
+
+  void SimulateURLFetch(bool success) {
+    TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
+    ASSERT_TRUE(fetcher);
+    URLRequestStatus status;
+    status.set_status(success ? URLRequestStatus::SUCCESS :
+        URLRequestStatus::FAILED);
+
+    std::string script = " var google = {};"
+        "google.translate = (function() {"
+        "  return {"
+        "    TranslateService: function() {"
+        "      return {"
+        "        isAvailable : function() {"
+        "          return true;"
+        "        },"
+        "        restore : function() {"
+        "          return;"
+        "        },"
+        "        getDetectedLanguage : function() {"
+        "          return \"ja\";"
+        "        },"
+        "        translatePage : function(originalLang, targetLang,"
+        "                                 onTranslateProgress) {"
+        "          document.getElementsByTagName(\"body\")[0].innerHTML = '" +
+        std::string(kTestFormString) +
+        "              ';"
+        "          onTranslateProgress(100, true, false);"
+        "        }"
+        "      };"
+        "    }"
+        "  };"
+        "})();";
+
+    fetcher->delegate()->OnURLFetchComplete(fetcher, fetcher->original_url(),
+        status, success ? 200 : 500,
+        ResponseCookies(),
+        script);
+  }
+
+  void TryBasicFormFillWithMKey() {
+    ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(),
+                                                       VIEW_ID_TAB_CONTAINER));
+    ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(),
+                                             VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
+
+    bool result = false;
+    ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
+        rvh(), L"", L"document.getElementById('firstname').focus();", &result));
+    ASSERT_TRUE(result);
+    // Start filling the first name field with "M" and wait for the popup to be
+    // shown.
+    ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
+        browser(), app::VKEY_M, false, true, false, false,
+        NotificationType::AUTOFILL_DID_SHOW_SUGGESTIONS,
+        Source<RenderViewHost>(rvh())));
+
+    // Press the down arrow to select the suggestion and preview the autofilled
+    // form.
+    ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
+        browser(), app::VKEY_DOWN, false, false, false, false,
+        NotificationType::AUTOFILL_DID_FILL_FORM_DATA,
+        Source<RenderViewHost>(rvh())));
+
+    // The previewed values should not be accessible to JavaScript.
+    ExpectFieldValue(L"firstname", "M");
+    ExpectFieldValue(L"lastname", "");
+    ExpectFieldValue(L"address1", "");
+    ExpectFieldValue(L"address2", "");
+    ExpectFieldValue(L"city", "");
+    ExpectFieldValue(L"state", "");
+    ExpectFieldValue(L"zip", "");
+    ExpectFieldValue(L"country", "");
+    ExpectFieldValue(L"phone", "");
+    // TODO(isherman): It would be nice to test that the previewed values are
+    // displayed: http://crbug.com/57220
+
+    // Press Enter to accept the autofill suggestions.
+    ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
+        browser(), app::VKEY_RETURN, false, false, false, false,
+        NotificationType::AUTOFILL_DID_FILL_FORM_DATA,
+        Source<RenderViewHost>(rvh())));
+
+    // The form should be filled.
+    ExpectFieldValue(L"firstname", "Milton");
+    ExpectFieldValue(L"lastname", "Waddams");
+    ExpectFieldValue(L"address1", "4120 Freidrich Lane");
+    ExpectFieldValue(L"address2", "Basement");
+    ExpectFieldValue(L"city", "Austin");
+    ExpectFieldValue(L"state", "TX");
+    ExpectFieldValue(L"zip", "78744");
+    ExpectFieldValue(L"country", "US");
+    ExpectFieldValue(L"phone", "5125551234");
+
+  }
+
+ private:
+  TestURLFetcherFactory url_fetcher_factory_;
 };
 
 // Test that basic form fill is working.
 IN_PROC_BROWSER_TEST_F(AutoFillTest, BasicFormFill) {
   SetUpProfile();
 
+  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
+  ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
+      GURL("data:text/html;charset=utf-8," + std::string(kTestFormString))));
+
+  TryBasicFormFillWithMKey();
+}
+
+// Test that basic form fill is working.
+IN_PROC_BROWSER_TEST_F(AutoFillTest, TranslateAndFormFill) {
+  SetUpProfile();
+
+  GURL url("data:text/html;charset=utf-8,"
+              "<form action=\"http://www.google.com/\" method=\"POST\">"
+              "<label for=\"firstname\">なまえ</label>"
+              " <input type=\"text\" id=\"firstname\""
+              "        onFocus=\"domAutomationController.send(true)\""
+              " /><br />"
+              "<label for=\"lastname\">みょうじ</label>"
+              " <input type=\"text\" id=\"lastname\" /><br />"
+              "<label for=\"address1\">Address line 1:</label>"
+              " <input type=\"text\" id=\"address1\" /><br />"
+              "<label for=\"address2\">Address line 2:</label>"
+              " <input type=\"text\" id=\"address2\" /><br />"
+              "<label for=\"city\">City:</label>"
+              " <input type=\"text\" id=\"city\" /><br />"
+              "<label for=\"state\">State:</label>"
+              " <select id=\"state\">"
+              " <option value=\"\" selected=\"yes\">--</option>"
+              " <option value=\"CA\">California</option>"
+              " <option value=\"TX\">Texas</option>"
+              " </select><br />"
+              "<label for=\"zip\">ZIP code:</label>"
+              " <input type=\"text\" id=\"zip\" /><br />"
+              "<label for=\"country\">Country:</label>"
+              " <select id=\"country\">"
+              " <option value=\"\" selected=\"yes\">--</option>"
+              " <option value=\"CA\">Canada</option>"
+              " <option value=\"US\">United States</option>"
+              " </select><br />"
+              "<label for=\"phone\">Phone number:</label>"
+              " <input type=\"text\" id=\"phone\" /><br />"
+              "</form>");
   ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
   ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
-      browser(), GURL("data:text/html;charset=utf-8,"
-                      "<form action=\"http://www.google.com/\" method=\"POST\">"
-                      "<label for=\"firstname\">First name:</label>"
-                      " <input type=\"text\" id=\"firstname\""
-                      "        onFocus=\"domAutomationController.send(true)\""
-                      " /><br />"
-                      "<label for=\"lastname\">Last name:</label>"
-                      " <input type=\"text\" id=\"lastname\" /><br />"
-                      "<label for=\"address1\">Address line 1:</label>"
-                      " <input type=\"text\" id=\"address1\" /><br />"
-                      "<label for=\"address2\">Address line 2:</label>"
-                      " <input type=\"text\" id=\"address2\" /><br />"
-                      "<label for=\"city\">City:</label>"
-                      " <input type=\"text\" id=\"city\" /><br />"
-                      "<label for=\"state\">State:</label>"
-                      " <select id=\"state\">"
-                      " <option value=\"\" selected=\"yes\">--</option>"
-                      " <option value=\"CA\">California</option>"
-                      " <option value=\"TX\">Texas</option>"
-                      " </select><br />"
-                      "<label for=\"zip\">ZIP code:</label>"
-                      " <input type=\"text\" id=\"zip\" /><br />"
-                      "<label for=\"country\">Country:</label>"
-                      " <select id=\"country\">"
-                      " <option value=\"\" selected=\"yes\">--</option>"
-                      " <option value=\"CA\">Canada</option>"
-                      " <option value=\"US\">United States</option>"
-                      " </select><br />"
-                      "<label for=\"phone\">Phone number:</label>"
-                      " <input type=\"text\" id=\"phone\" /><br />"
-                      "</form>")));
-
-  ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(),
-                                                     VIEW_ID_TAB_CONTAINER));
-  ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(),
-                                           VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
-
-  RenderViewHost* render_view_host =
-      browser()->GetSelectedTabContents()->render_view_host();
-  bool result;
-  ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
-      render_view_host, L"", L"document.getElementById('firstname').focus();",
-      &result));
-  ASSERT_TRUE(result);
-
-  // Start filling the first name field with "M" and wait for the popup to be
-  // shown.
-  ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
-      browser(), app::VKEY_M, false, true, false, false,
-      NotificationType::AUTOFILL_DID_SHOW_SUGGESTIONS,
-      Source<RenderViewHost>(render_view_host)));
-
-  // Press the down arrow to select the suggestion and preview the autofilled
-  // form.
-  ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
-      browser(), app::VKEY_DOWN, false, false, false, false,
-      NotificationType::AUTOFILL_DID_FILL_FORM_DATA,
-      Source<RenderViewHost>(render_view_host)));
-
-  // The previewed values should not be accessible to JavaScript.
-  ExpectFieldValue(L"firstname", "M");
-  ExpectFieldValue(L"lastname", "");
-  ExpectFieldValue(L"address1", "");
-  ExpectFieldValue(L"address2", "");
-  ExpectFieldValue(L"city", "");
-  ExpectFieldValue(L"state", "");
-  ExpectFieldValue(L"zip", "");
-  ExpectFieldValue(L"country", "");
-  ExpectFieldValue(L"phone", "");
-  // TODO(isherman): It would be nice to test that the previewed values are
-  // displayed: http://crbug.com/57220
-
-  // Press Enter to accept the autofill suggestions.
-  ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
-      browser(), app::VKEY_RETURN, false, false, false, false,
-      NotificationType::AUTOFILL_DID_FILL_FORM_DATA,
-      Source<RenderViewHost>(render_view_host)));
-
-  // The form should be filled.
-  ExpectFieldValue(L"firstname", "Milton");
-  ExpectFieldValue(L"lastname", "Waddams");
-  ExpectFieldValue(L"address1", "4120 Freidrich Lane");
-  ExpectFieldValue(L"address2", "Basement");
-  ExpectFieldValue(L"city", "Austin");
-  ExpectFieldValue(L"state", "TX");
-  ExpectFieldValue(L"zip", "78744");
-  ExpectFieldValue(L"country", "US");
-  ExpectFieldValue(L"phone", "5125551234");
+      browser(), url));
+
+  // Get translation bar.
+  int page_id = browser()->GetSelectedTabContents()->controller().
+      GetLastCommittedEntry()->page_id();
+  rvh()->OnMessageReceived(ViewHostMsg_PageContents(0, url, page_id,
+      UTF8ToUTF16("test"), "ja", true));
+  TranslateInfoBarDelegate* infobar = browser()->GetSelectedTabContents()->
+      GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate();
+
+  ASSERT_TRUE(infobar != NULL);
+  EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type());
+
+  // Simulate press translation button.
+  infobar->Translate();
+
+  // Simulate the translate script being retrieved.
+  // Pass fake google.translate lib as the translate script.
+  SimulateURLFetch(true);
+
+  // Simulate translation to kick onTranslateElementLoad.
+  // But right now, the call stucks here.
+  // Once click the text field, it starts again.
+  ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
+      rvh(), L"", L"cr.googleTranslate.onTranslateElementLoad();"));
+
+  // Simulate the render notifying the translation has been done.
+  ui_test_utils::WaitForNotification(NotificationType::PAGE_TRANSLATED);
+
+  TryBasicFormFillWithMKey();
 }
diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h
index 791d171f8ff79..29e6b230d2616 100644
--- a/chrome/browser/autofill/autofill_manager.h
+++ b/chrome/browser/autofill/autofill_manager.h
@@ -57,14 +57,12 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill,
                                     const webkit_glue::FormField& field,
                                     int unique_id);
   virtual void ShowAutoFillDialog();
+  virtual void Reset();
 
   // Called by the AutoFillCCInfoBarDelegate when the user interacts with the
   // infobar.
   virtual void OnInfoBarClosed(bool should_save);
 
-  // Resets the stored form data.
-  virtual void Reset();
-
   // AutoFillDownloadManager::Observer implementation:
   virtual void OnLoadedAutoFillHeuristics(const std::string& heuristic_xml);
   virtual void OnUploadedAutoFillHeuristics(const std::string& form_signature);
diff --git a/chrome/browser/chromeos/login/account_creation_view.cc b/chrome/browser/chromeos/login/account_creation_view.cc
index a748155de892c..05c66b561dbbd 100644
--- a/chrome/browser/chromeos/login/account_creation_view.cc
+++ b/chrome/browser/chromeos/login/account_creation_view.cc
@@ -68,6 +68,8 @@ class AccountCreationTabContents : public WizardWebPageViewTabContents,
 
   virtual void ShowAutoFillDialog() {}
 
+  virtual void Reset() {}
+
  private:
   AccountCreationViewDelegate* delegate_;
 
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index dc358b6944541..470b8baf482e2 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -2014,6 +2014,15 @@ void RenderViewHost::TranslatePage(int page_id,
                                    const std::string& translate_script,
                                    const std::string& source_lang,
                                    const std::string& target_lang) {
+  // Ideally we'd have a better way to uniquely identify form control elements,
+  // but we don't have that yet.  So before start translation, we clear the
+  // current form and re-parse it in AutoFillManager first to get the new
+  // labels.
+  RenderViewHostDelegate::AutoFill* autofill_delegate =
+      delegate_->GetAutoFillDelegate();
+  if (autofill_delegate)
+    autofill_delegate->Reset();
+
   Send(new ViewMsg_TranslatePage(routing_id(), page_id, translate_script,
                                  source_lang, target_lang));
 }
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index 89f7d94d4da90..043000ab8b618 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -589,6 +589,9 @@ class RenderViewHostDelegate {
     // AutoFill popup.
     virtual void ShowAutoFillDialog() = 0;
 
+    // Reset cache in AutoFillManager.
+    virtual void Reset() = 0;
+
    protected:
     virtual ~AutoFill() {}
   };
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 0f20285afc833..4b9116b06222c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -313,6 +313,8 @@
         'browser/ui/views/browser_keyboard_accessibility_test_win.cc',
         'browser/ui/views/find_bar_host_interactive_uitest.cc',
         'browser/ui/views/tabs/tab_dragging_test.cc',
+        'common/net/test_url_fetcher_factory.cc',
+        'common/net/test_url_fetcher_factory.h',
         'test/in_process_browser_test.cc',
         'test/in_process_browser_test.h',
         'test/interactive_ui/fast_shutdown_interactive_uitest.cc',
-- 
GitLab