summaryrefslogtreecommitdiffstats
path: root/chrome/test
diff options
context:
space:
mode:
authordennisjeffrey@chromium.org <dennisjeffrey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-10 16:28:10 +0000
committerdennisjeffrey@chromium.org <dennisjeffrey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-10 16:28:10 +0000
commit535773382e9f47db97d83bcbe34cb4b89405cfba (patch)
tree3b4ed48a23562643ee94ef72505c1364c5e2eb7c /chrome/test
parent2136da4abd2aa67873010ee3a3294d7fdf1d2fe8 (diff)
downloadchromium_src-535773382e9f47db97d83bcbe34cb4b89405cfba.zip
chromium_src-535773382e9f47db97d83bcbe34cb4b89405cfba.tar.gz
chromium_src-535773382e9f47db97d83bcbe34cb4b89405cfba.tar.bz2
Fix for pyauto autofill flakiness when sending key events to populate a form.
This change should eliminate flakiness in a few pyauto autofill tests, which are now re-enabled. BUG=80190,80336 TEST=None Review URL: http://codereview.chromium.org/6929052 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84791 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test')
-rw-r--r--chrome/test/functional/PYAUTO_TESTS6
-rw-r--r--chrome/test/functional/autofill.py37
-rw-r--r--chrome/test/pyautolib/pyauto.py158
-rw-r--r--chrome/test/pyautolib/pyautolib.h2
4 files changed, 155 insertions, 48 deletions
diff --git a/chrome/test/functional/PYAUTO_TESTS b/chrome/test/functional/PYAUTO_TESTS
index 2f6c94d..f106e29 100644
--- a/chrome/test/functional/PYAUTO_TESTS
+++ b/chrome/test/functional/PYAUTO_TESTS
@@ -28,14 +28,8 @@
'CONTINUOUS': {
'all': [
'autofill',
- '-autofill.AutofillTest.testComparePhoneNumbers',
- '-autofill.AutofillTest.testNoAutofillForReadOnlyFields',
# crbug.com/77113 - M13 feature.
'-autofill.AutofillTest.testProfileWithEmailInOtherFieldNotSaved',
- # crbug.com/80190
- '-autofill.AutofillTest.testDistinguishMiddleInitialWithinName',
- '-autofill.AutofillTest.testFormFillableOnReset',
- '-autofill.AutofillTest.testMultipleEmailFilledByOneUserGesture',
# crbug.com/81271
'-autofill.AutofillTest.testMergeAggregatedProfilesWithSameAddress',
'-autofill.AutofillTest.testProfilesNotMergedWhenNoMinAddressData',
diff --git a/chrome/test/functional/autofill.py b/chrome/test/functional/autofill.py
index 59f27d0..e9cc444 100644
--- a/chrome/test/functional/autofill.py
+++ b/chrome/test/functional/autofill.py
@@ -279,22 +279,6 @@ class AutofillTest(pyauto.PyUITest):
self.assertFalse(self.GetAutofillProfile()['profiles'],
msg='Profile with invalid email was aggregated.')
- def _SendKeyEventsToPopulateForm(self, tab_index=0, windex=0):
- """Send key events to populate a web form with Autofill profile data.
-
- Args:
- tab_index: The tab index, default is 0.
- windex: The window index, default is 0.
- """
- TAB_KEYPRESS = 0x09 # Tab keyboard key press.
- DOWN_KEYPRESS = 0x28 # Down arrow keyboard key press.
- RETURN_KEYPRESS = 0x0D # Return keyboard key press.
-
- self.SendWebkitKeypressEvent(TAB_KEYPRESS, tab_index, windex)
- self.SendWebkitKeypressEvent(DOWN_KEYPRESS, tab_index, windex)
- self.SendWebkitKeypressEvent(DOWN_KEYPRESS, tab_index, windex)
- self.SendWebkitKeypressEvent(RETURN_KEYPRESS, tab_index, windex)
-
def testComparePhoneNumbers(self):
"""Test phone fields parse correctly from a given profile.
@@ -314,7 +298,8 @@ class AutofillTest(pyauto.PyUITest):
os.path.join('autofill', 'functional', 'form_phones.html'))
for profile_expected in profiles_expected:
self.NavigateToURL(url)
- self._SendKeyEventsToPopulateForm()
+ self.assertTrue(self.AutofillPopulateForm('NAME_FIRST'),
+ msg='Autofill form could not be populated.')
form_values = {}
for key, value in profile_expected.iteritems():
js_returning_field_value = (
@@ -379,7 +364,8 @@ class AutofillTest(pyauto.PyUITest):
url = self.GetHttpURLForDataPath(
os.path.join('autofill', 'functional', 'read_only_field_test.html'))
self.NavigateToURL(url)
- self._SendKeyEventsToPopulateForm()
+ self.assertTrue(self.AutofillPopulateForm('firstname'),
+ msg='Autofill form could not be populated.')
js_return_readonly_field = (
'var field_value = document.getElementById("email").value;'
'window.domAutomationController.send(field_value);')
@@ -418,13 +404,15 @@ class AutofillTest(pyauto.PyUITest):
os.path.join('autofill', 'functional', 'autofill_test_form.html'))
self.NavigateToURL(url)
# Fill form using an address profile.
- self._SendKeyEventsToPopulateForm()
+ self.assertTrue(self.AutofillPopulateForm('NAME_FIRST'),
+ msg='Autofill form could not be populated.')
# Reset the form.
self.ExecuteJavascript('document.getElementById("testform").reset();'
'window.domAutomationController.send("done");',
0, 0)
# Fill in the form using an Autofill profile.
- self._SendKeyEventsToPopulateForm()
+ self.assertTrue(self.AutofillPopulateForm('NAME_FIRST'),
+ msg='Autofill form could not be populated.')
# Verify value in fields match value in the profile dictionary.
form_values = {}
for key, value in profile.iteritems():
@@ -456,7 +444,8 @@ class AutofillTest(pyauto.PyUITest):
os.path.join('autofill', 'functional', 'autofill_middleinit_form.html'))
self.NavigateToURL(url)
# Fill form using an address profile.
- self._SendKeyEventsToPopulateForm()
+ self.assertTrue(self.AutofillPopulateForm('NAME_FIRST'),
+ msg='Autofill form could not be populated.')
js_return_middleinit_field = (
'var field_value = document.getElementById("NAME_MIDDLE").value;'
'window.domAutomationController.send(field_value);')
@@ -482,7 +471,8 @@ class AutofillTest(pyauto.PyUITest):
'autofill_confirmemail_form.html'))
self.NavigateToURL(url)
# Fill form using an address profile.
- self._SendKeyEventsToPopulateForm()
+ self.assertTrue(self.AutofillPopulateForm('NAME_FIRST'),
+ msg='Autofill form could not be populated.')
js_return_confirmemail_field = (
'var field_value = document.getElementById("EMAIL_CONFIRM").value;'
'window.domAutomationController.send(field_value);')
@@ -550,7 +540,8 @@ class AutofillTest(pyauto.PyUITest):
list_of_dict = gen.GenerateDataset(num_of_dict_to_generate=1501)
self.FillAutofillProfile(profiles=list_of_dict)
self.NavigateToURL(url)
- self._SendKeyEventsToPopulateForm()
+ self.assertTrue(self.AutofillPopulateForm('NAME_FIRST'),
+ msg='Autofill form could not be populated.')
# TODO(dyu): add automated form hang or crash verification.
raw_input(
'Verify the test manually. Test hang time after submitting the form.')
diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py
index d14336d..be591ed 100644
--- a/chrome/test/pyautolib/pyauto.py
+++ b/chrome/test/pyautolib/pyauto.py
@@ -844,24 +844,6 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
}
self._GetResultFromJSONRequest(cmd_dict)
- def SendWebkitKeypressEvent(self, key_code, tab_index=0, windex=0):
- """Send webkit key press event to the browser.
-
- Used to simulate key press from the keyboard to interact with the browser.
- Simulates a key press which consists of a down key press and up key press.
-
- Args:
- key_code: the hex value associated with the keypress (virtual key code).
- tab_index: tab index to work on. Defaults to 0 (first tab).
- windex: window index to work on. Defaults to 0 (first window).
- """
- KEY_DOWN_TYPE = 0 # kRawKeyDownType
- KEY_UP_TYPE = 3 # kKeyUpType
-
- # Sending two requests, one each for "key down" and "key up".
- self.SendWebkitKeyEvent(KEY_DOWN_TYPE, key_code, tab_index, windex)
- self.SendWebkitKeyEvent(KEY_UP_TYPE, key_code, tab_index, windex)
-
def SendWebkitKeyEvent(self, key_type, key_code, tab_index=0, windex=0):
"""Send a webkit key event to the browser.
@@ -1537,6 +1519,123 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
}
return self._GetResultFromJSONRequest(cmd_dict, windex=window_index)
+ def AutofillTriggerSuggestions(self, field_id=None, tab_index=0, windex=0):
+ """Focuses a webpage form field and triggers the autofill popup in it.
+
+ This function focuses the specified input field in a webpage form, then
+ causes the autofill popup to appear in that field. The underlying
+ automation hook sends a "down arrow" keypress event to trigger the autofill
+ popup. This function waits until the popup is displayed before returning.
+
+ Args:
+ field_id: The string ID of the webpage form field to focus. Can be
+ 'None' (the default), in which case nothing is focused. This
+ can be useful if the field has already been focused by other
+ means.
+ tab_index: Integer index of the tab to work on; defaults to 0 (first tab).
+ windex: Integer index of the browser window to work on; defaults to 0
+ (first window).
+
+ Returns:
+ True, if no errors were encountered, or False otherwise.
+
+ Raises:
+ pyauto_errors.JSONInterfaceError if the automation call returns an error.
+ """
+ # Focus the field with the specified ID, if necessary.
+ if field_id:
+ if not self.JavascriptFocusElementById(field_id, tab_index, windex):
+ return False
+
+ # Cause the autofill popup to be shown in the focused form field.
+ cmd_dict = {
+ 'command': 'AutofillTriggerSuggestions',
+ 'tab_index': tab_index,
+ }
+ self._GetResultFromJSONRequest(cmd_dict, windex=windex)
+ return True
+
+ def AutofillHighlightSuggestion(self, direction, tab_index=0, windex=0):
+ """Highlights the previous or next suggestion in an existing autofill popup.
+
+ This function assumes that an existing autofill popup is currently displayed
+ in a webpage form. The underlying automation hook sends either a
+ "down arrow" or an "up arrow" keypress event to cause the next or previous
+ suggestion to be highlighted, respectively. This function waits until
+ autofill displays a preview of the form's filled state before returning.
+
+ Use AutofillTriggerSuggestions() to trigger the autofill popup before
+ calling this function. Use AutofillAcceptSelection() after calling this
+ function to accept a selection.
+
+ Args:
+ direction: The string direction in which to highlight an autofill
+ suggestion. Must be either "up" or "down".
+ tab_index: Integer index of the tab to work on; defaults to 0 (first tab).
+ windex: Integer index of the browser window to work on; defaults to 0
+ (first window).
+
+ Raises:
+ pyauto_errors.JSONInterfaceError if the automation call returns an error.
+ """
+ assert direction in ('up', 'down')
+ cmd_dict = {
+ 'command': 'AutofillHighlightSuggestion',
+ 'direction': direction,
+ 'tab_index': tab_index,
+ }
+ self._GetResultFromJSONRequest(cmd_dict, windex=windex)
+
+ def AutofillAcceptSelection(self, tab_index=0, windex=0):
+ """Accepts the current selection in an already-displayed autofill popup.
+
+ This function assumes that a profile is already highlighted in an existing
+ autofill popup in a webpage form. The underlying automation hook sends a
+ "return" keypress event to cause the highlighted profile to be accepted.
+ This function waits for the webpage form to be filled in with autofill data
+ before returning. This function does not submit the webpage form.
+
+ Raises:
+ pyauto_errors.JSONInterfaceError if the automation call returns an error.
+ """
+ cmd_dict = {
+ 'command': 'AutofillAcceptSelection',
+ 'tab_index': tab_index,
+ }
+ self._GetResultFromJSONRequest(cmd_dict, windex=windex)
+
+ def AutofillPopulateForm(self, field_id, profile_index=0, tab_index=0,
+ windex=0):
+ """Populates a webpage form using autofill data and keypress events.
+
+ This function focuses the specified input field in the form, and then
+ sends keypress events to the associated tab to cause the form to be
+ populated with information from the requested autofill profile.
+
+ Args:
+ field_id: The string ID of the webpage form field to focus for autofill
+ purposes.
+ profile_index: The index of the profile in the autofill popup to use to
+ populate the form; defaults to 0 (first profile).
+ tab_index: Integer index of the tab to work on; defaults to 0 (first tab).
+ windex: Integer index of the browser window to work on; defaults to 0
+ (first window).
+
+ Returns:
+ True, if the webpage form is populated successfully, or False if not.
+
+ Raises:
+ pyauto_errors.JSONInterfaceError if an automation call returns an error.
+ """
+ if not self.AutofillTriggerSuggestions(field_id, tab_index, windex):
+ return False
+
+ for _ in range(profile_index + 1):
+ self.AutofillHighlightSuggestion('down', tab_index, windex)
+
+ self.AutofillAcceptSelection(tab_index, windex)
+ return True
+
def AddHistoryItem(self, item):
"""Forge a history item for Chrome.
@@ -1966,6 +2065,29 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
logging.debug('Executing javascript: %s', js)
return self.ExecuteJavascript(js, windex, tab_index)
+ def JavascriptFocusElementById(self, field_id, tab_index=0, windex=0):
+ """Uses Javascript to focus an element with the given ID in a webpage.
+
+ Args:
+ field_id: The string ID of the webpage form field to focus.
+ tab_index: Integer index of the tab to work on; defaults to 0 (first tab).
+ windex: Integer index of the browser window to work on; defaults to 0
+ (first window).
+
+ Returns:
+ True, on success, or False on failure.
+ """
+ focus_field_js = """
+ var field = document.getElementById("%s");
+ if (!field) {
+ window.domAutomationController.send("error");
+ } else {
+ field.focus();
+ window.domAutomationController.send("done");
+ }
+ """ % field_id
+ return self.ExecuteJavascript(focus_field_js, windex, tab_index) == 'done'
+
def SignInToSync(self, username, password):
"""Signs in to sync using the given username and password.
diff --git a/chrome/test/pyautolib/pyautolib.h b/chrome/test/pyautolib/pyautolib.h
index fc90687..d3fbc4d 100644
--- a/chrome/test/pyautolib/pyautolib.h
+++ b/chrome/test/pyautolib/pyautolib.h
@@ -176,7 +176,7 @@ class PyUITestBase : public UITestBase {
// a low-level method intended for use mostly by GetDOMValue(). Note that
// any complicated manipulation of the page should be done by something
// like WebDriver, not PyAuto. Also note that in order for the script to
- // return a value to the calling code, it invoke
+ // return a value to the calling code, it invokes
// window.domAutomationController.send(), passing in the intended return
// value.
std::wstring ExecuteJavascript(const std::wstring& script,