| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """PyAuto: Python Interface to Chromium's Automation Proxy. | 6 """PyAuto: Python Interface to Chromium's Automation Proxy. |
| 7 | 7 |
| 8 PyAuto uses swig to expose Automation Proxy interfaces to Python. | 8 PyAuto uses swig to expose Automation Proxy interfaces to Python. |
| 9 For complete documentation on the functionality available, | 9 For complete documentation on the functionality available, |
| 10 run pydoc on this file. | 10 run pydoc on this file. |
| (...skipping 3196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3207 """ | 3207 """ |
| 3208 def _IsExtensionViewClosed(): | 3208 def _IsExtensionViewClosed(): |
| 3209 extension_views = self.GetBrowserInfo()['extension_views'] | 3209 extension_views = self.GetBrowserInfo()['extension_views'] |
| 3210 for extension_view in extension_views: | 3210 for extension_view in extension_views: |
| 3211 if view == extension_view['view']: | 3211 if view == extension_view['view']: |
| 3212 return False | 3212 return False |
| 3213 return True | 3213 return True |
| 3214 | 3214 |
| 3215 return self.WaitUntil(lambda: _IsExtensionViewClosed()) | 3215 return self.WaitUntil(lambda: _IsExtensionViewClosed()) |
| 3216 | 3216 |
| 3217 def FillAutofillProfile(self, profiles=None, credit_cards=None, | |
| 3218 tab_index=0, window_index=0): | |
| 3219 """Set the autofill profile to contain the given profiles and credit cards. | |
| 3220 | |
| 3221 If profiles or credit_cards are specified, they will overwrite existing | |
| 3222 profiles and credit cards. To update profiles and credit cards, get the | |
| 3223 existing ones with the GetAutofillProfile function and then append new | |
| 3224 profiles to the list and call this function. | |
| 3225 | |
| 3226 Autofill profiles (not credit cards) support multiple values for some of the | |
| 3227 fields. To account for this, all values in a profile must be specified as | |
| 3228 a list of strings. If a form field only has a single value associated with | |
| 3229 it, that value must still be specified as a list containing a single string. | |
| 3230 | |
| 3231 Args: | |
| 3232 profiles: (optional) a list of dictionaries representing each profile to | |
| 3233 add. Example: | |
| 3234 [{ | |
| 3235 'NAME_FIRST': ['Bob',], | |
| 3236 'NAME_LAST': ['Smith',], | |
| 3237 'ADDRESS_HOME_ZIP': ['94043',], | |
| 3238 }, | |
| 3239 { | |
| 3240 'EMAIL_ADDRESS': ['sue@example.com',], | |
| 3241 'COMPANY_NAME': ['Company X',], | |
| 3242 }] | |
| 3243 | |
| 3244 Other possible keys are: | |
| 3245 'NAME_FIRST', 'NAME_MIDDLE', 'NAME_LAST', 'EMAIL_ADDRESS', | |
| 3246 'COMPANY_NAME', 'ADDRESS_HOME_LINE1', 'ADDRESS_HOME_LINE2', | |
| 3247 'ADDRESS_HOME_CITY', 'ADDRESS_HOME_STATE', 'ADDRESS_HOME_ZIP', | |
| 3248 'ADDRESS_HOME_COUNTRY', 'PHONE_HOME_WHOLE_NUMBER' | |
| 3249 | |
| 3250 credit_cards: (optional) a list of dictionaries representing each credit | |
| 3251 card to add. Example: | |
| 3252 [{ | |
| 3253 'CREDIT_CARD_NAME': 'Bob C. Smith', | |
| 3254 'CREDIT_CARD_NUMBER': '5555555555554444', | |
| 3255 'CREDIT_CARD_EXP_MONTH': '12', | |
| 3256 'CREDIT_CARD_EXP_4_DIGIT_YEAR': '2011' | |
| 3257 }, | |
| 3258 { | |
| 3259 'CREDIT_CARD_NAME': 'Bob C. Smith', | |
| 3260 'CREDIT_CARD_NUMBER': '4111111111111111', | |
| 3261 'CREDIT_CARD_TYPE': 'Visa' | |
| 3262 } | |
| 3263 | |
| 3264 Other possible keys are: | |
| 3265 'CREDIT_CARD_NAME', 'CREDIT_CARD_NUMBER', 'CREDIT_CARD_EXP_MONTH', | |
| 3266 'CREDIT_CARD_EXP_4_DIGIT_YEAR' | |
| 3267 | |
| 3268 All values must be strings. | |
| 3269 | |
| 3270 tab_index: tab index, defaults to 0. | |
| 3271 | |
| 3272 window_index: window index, defaults to 0. | |
| 3273 | |
| 3274 Raises: | |
| 3275 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
| 3276 """ | |
| 3277 cmd_dict = { # Prepare command for the json interface | |
| 3278 'command': 'FillAutofillProfile', | |
| 3279 'tab_index': tab_index, | |
| 3280 'profiles': profiles, | |
| 3281 'credit_cards': credit_cards | |
| 3282 } | |
| 3283 self._GetResultFromJSONRequest(cmd_dict, windex=window_index) | |
| 3284 | |
| 3285 def GetAutofillProfile(self, tab_index=0, window_index=0): | |
| 3286 """Returns all autofill profile and credit card information. | |
| 3287 | |
| 3288 The format of the returned dictionary is described above in | |
| 3289 FillAutofillProfile. The general format is: | |
| 3290 {'profiles': [list of profile dictionaries as described above], | |
| 3291 'credit_cards': [list of credit card dictionaries as described above]} | |
| 3292 | |
| 3293 Args: | |
| 3294 tab_index: tab index, defaults to 0. | |
| 3295 window_index: window index, defaults to 0. | |
| 3296 | |
| 3297 Raises: | |
| 3298 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
| 3299 """ | |
| 3300 cmd_dict = { # Prepare command for the json interface | |
| 3301 'command': 'GetAutofillProfile', | |
| 3302 'tab_index': tab_index | |
| 3303 } | |
| 3304 return self._GetResultFromJSONRequest(cmd_dict, windex=window_index) | |
| 3305 | |
| 3306 def SubmitAutofillForm(self, js, frame_xpath='', tab_index=0, windex=0): | |
| 3307 """Submits a webpage autofill form and waits for autofill to be updated. | |
| 3308 | |
| 3309 This function should be called when submitting autofill profiles via | |
| 3310 webpage forms. It waits until the autofill data has been updated internally | |
| 3311 before returning. | |
| 3312 | |
| 3313 Args: | |
| 3314 js: The string Javascript code that can be injected into the given webpage | |
| 3315 to submit an autofill form. This Javascript MUST submit the form. | |
| 3316 frame_xpath: The string xpath for the frame in which to inject javascript. | |
| 3317 tab_index: Integer index of the tab to work on; defaults to 0 (first tab). | |
| 3318 windex: Integer index of the browser window to use; defaults to 0 | |
| 3319 (first window). | |
| 3320 """ | |
| 3321 cmd_dict = { # Prepare command for the json interface. | |
| 3322 'command': 'SubmitAutofillForm', | |
| 3323 'javascript': js, | |
| 3324 'frame_xpath': frame_xpath, | |
| 3325 'tab_index': tab_index, | |
| 3326 } | |
| 3327 self._GetResultFromJSONRequest(cmd_dict, windex=windex) | |
| 3328 | |
| 3329 def AutofillTriggerSuggestions(self, field_id=None, tab_index=0, windex=0): | |
| 3330 """Focuses a webpage form field and triggers the autofill popup in it. | |
| 3331 | |
| 3332 This function focuses the specified input field in a webpage form, then | |
| 3333 causes the autofill popup to appear in that field. The underlying | |
| 3334 automation hook sends a "down arrow" keypress event to trigger the autofill | |
| 3335 popup. This function waits until the popup is displayed before returning. | |
| 3336 | |
| 3337 Args: | |
| 3338 field_id: The string ID of the webpage form field to focus. Can be | |
| 3339 'None' (the default), in which case nothing is focused. This | |
| 3340 can be useful if the field has already been focused by other | |
| 3341 means. | |
| 3342 tab_index: Integer index of the tab to work on; defaults to 0 (first tab). | |
| 3343 windex: Integer index of the browser window to work on; defaults to 0 | |
| 3344 (first window). | |
| 3345 | |
| 3346 Returns: | |
| 3347 True, if no errors were encountered, or False otherwise. | |
| 3348 | |
| 3349 Raises: | |
| 3350 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
| 3351 """ | |
| 3352 # Focus the field with the specified ID, if necessary. | |
| 3353 if field_id: | |
| 3354 if not self.JavascriptFocusElementById(field_id, tab_index, windex): | |
| 3355 return False | |
| 3356 | |
| 3357 # Cause the autofill popup to be shown in the focused form field. | |
| 3358 cmd_dict = { | |
| 3359 'command': 'AutofillTriggerSuggestions', | |
| 3360 'tab_index': tab_index, | |
| 3361 } | |
| 3362 self._GetResultFromJSONRequest(cmd_dict, windex=windex) | |
| 3363 return True | |
| 3364 | |
| 3365 def AutofillHighlightSuggestion(self, direction, tab_index=0, windex=0): | |
| 3366 """Highlights the previous or next suggestion in an existing autofill popup. | |
| 3367 | |
| 3368 This function assumes that an existing autofill popup is currently displayed | |
| 3369 in a webpage form. The underlying automation hook sends either a | |
| 3370 "down arrow" or an "up arrow" keypress event to cause the next or previous | |
| 3371 suggestion to be highlighted, respectively. This function waits until | |
| 3372 autofill displays a preview of the form's filled state before returning. | |
| 3373 | |
| 3374 Use AutofillTriggerSuggestions() to trigger the autofill popup before | |
| 3375 calling this function. Use AutofillAcceptSelection() after calling this | |
| 3376 function to accept a selection. | |
| 3377 | |
| 3378 Args: | |
| 3379 direction: The string direction in which to highlight an autofill | |
| 3380 suggestion. Must be either "up" or "down". | |
| 3381 tab_index: Integer index of the tab to work on; defaults to 0 (first tab). | |
| 3382 windex: Integer index of the browser window to work on; defaults to 0 | |
| 3383 (first window). | |
| 3384 | |
| 3385 Raises: | |
| 3386 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
| 3387 """ | |
| 3388 assert direction in ('up', 'down') | |
| 3389 cmd_dict = { | |
| 3390 'command': 'AutofillHighlightSuggestion', | |
| 3391 'direction': direction, | |
| 3392 'tab_index': tab_index, | |
| 3393 } | |
| 3394 self._GetResultFromJSONRequest(cmd_dict, windex=windex) | |
| 3395 | |
| 3396 def AutofillAcceptSelection(self, tab_index=0, windex=0): | |
| 3397 """Accepts the current selection in an already-displayed autofill popup. | |
| 3398 | |
| 3399 This function assumes that a profile is already highlighted in an existing | |
| 3400 autofill popup in a webpage form. The underlying automation hook sends a | |
| 3401 "return" keypress event to cause the highlighted profile to be accepted. | |
| 3402 This function waits for the webpage form to be filled in with autofill data | |
| 3403 before returning. This function does not submit the webpage form. | |
| 3404 | |
| 3405 Raises: | |
| 3406 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
| 3407 """ | |
| 3408 cmd_dict = { | |
| 3409 'command': 'AutofillAcceptSelection', | |
| 3410 'tab_index': tab_index, | |
| 3411 } | |
| 3412 self._GetResultFromJSONRequest(cmd_dict, windex=windex) | |
| 3413 | |
| 3414 def AutofillPopulateForm(self, field_id, profile_index=0, tab_index=0, | |
| 3415 windex=0): | |
| 3416 """Populates a webpage form using autofill data and keypress events. | |
| 3417 | |
| 3418 This function focuses the specified input field in the form, and then | |
| 3419 sends keypress events to the associated tab to cause the form to be | |
| 3420 populated with information from the requested autofill profile. | |
| 3421 | |
| 3422 Args: | |
| 3423 field_id: The string ID of the webpage form field to focus for autofill | |
| 3424 purposes. | |
| 3425 profile_index: The index of the profile in the autofill popup to use to | |
| 3426 populate the form; defaults to 0 (first profile). | |
| 3427 tab_index: Integer index of the tab to work on; defaults to 0 (first tab). | |
| 3428 windex: Integer index of the browser window to work on; defaults to 0 | |
| 3429 (first window). | |
| 3430 | |
| 3431 Returns: | |
| 3432 True, if the webpage form is populated successfully, or False if not. | |
| 3433 | |
| 3434 Raises: | |
| 3435 pyauto_errors.JSONInterfaceError if an automation call returns an error. | |
| 3436 """ | |
| 3437 if not self.AutofillTriggerSuggestions(field_id, tab_index, windex): | |
| 3438 return False | |
| 3439 | |
| 3440 for _ in range(profile_index + 1): | |
| 3441 self.AutofillHighlightSuggestion('down', tab_index, windex) | |
| 3442 | |
| 3443 self.AutofillAcceptSelection(tab_index, windex) | |
| 3444 return True | |
| 3445 | |
| 3446 def AddHistoryItem(self, item): | 3217 def AddHistoryItem(self, item): |
| 3447 """Forge a history item for Chrome. | 3218 """Forge a history item for Chrome. |
| 3448 | 3219 |
| 3449 Args: | 3220 Args: |
| 3450 item: a python dictionary representing the history item. Example: | 3221 item: a python dictionary representing the history item. Example: |
| 3451 { | 3222 { |
| 3452 # URL is the only mandatory item. | 3223 # URL is the only mandatory item. |
| 3453 'url': 'http://news.google.com', | 3224 'url': 'http://news.google.com', |
| 3454 # Title is optional. | 3225 # Title is optional. |
| 3455 'title': 'Google News', | 3226 'title': 'Google News', |
| (...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4296 windex: index of the window. | 4067 windex: index of the window. |
| 4297 | 4068 |
| 4298 Returns: | 4069 Returns: |
| 4299 a string that was sent back via the domAutomationController.send method | 4070 a string that was sent back via the domAutomationController.send method |
| 4300 """ | 4071 """ |
| 4301 converted_args = map(lambda arg: json.dumps(arg), args) | 4072 converted_args = map(lambda arg: json.dumps(arg), args) |
| 4302 js = '%s(%s)' % (function, ', '.join(converted_args)) | 4073 js = '%s(%s)' % (function, ', '.join(converted_args)) |
| 4303 logging.debug('Executing javascript: %s', js) | 4074 logging.debug('Executing javascript: %s', js) |
| 4304 return self.ExecuteJavascript(js, tab_index, windex) | 4075 return self.ExecuteJavascript(js, tab_index, windex) |
| 4305 | 4076 |
| 4306 def JavascriptFocusElementById(self, field_id, tab_index=0, windex=0): | |
| 4307 """Uses Javascript to focus an element with the given ID in a webpage. | |
| 4308 | |
| 4309 Args: | |
| 4310 field_id: The string ID of the webpage form field to focus. | |
| 4311 tab_index: Integer index of the tab to work on; defaults to 0 (first tab). | |
| 4312 windex: Integer index of the browser window to work on; defaults to 0 | |
| 4313 (first window). | |
| 4314 | |
| 4315 Returns: | |
| 4316 True, on success, or False on failure. | |
| 4317 """ | |
| 4318 focus_field_js = """ | |
| 4319 var field = document.getElementById("%s"); | |
| 4320 if (!field) { | |
| 4321 window.domAutomationController.send("error"); | |
| 4322 } else { | |
| 4323 field.focus(); | |
| 4324 window.domAutomationController.send("done"); | |
| 4325 } | |
| 4326 """ % field_id | |
| 4327 return self.ExecuteJavascript(focus_field_js, tab_index, windex) == 'done' | |
| 4328 | |
| 4329 def SignInToSync(self, username, password): | 4077 def SignInToSync(self, username, password): |
| 4330 """Signs in to sync using the given username and password. | 4078 """Signs in to sync using the given username and password. |
| 4331 | 4079 |
| 4332 Args: | 4080 Args: |
| 4333 username: The account with which to sign in. Example: "user@gmail.com". | 4081 username: The account with which to sign in. Example: "user@gmail.com". |
| 4334 password: Password for the above account. Example: "pa$$w0rd". | 4082 password: Password for the above account. Example: "pa$$w0rd". |
| 4335 | 4083 |
| 4336 Returns: | 4084 Returns: |
| 4337 True, on success. | 4085 True, on success. |
| 4338 | 4086 |
| (...skipping 2659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6998 successful = result.wasSuccessful() | 6746 successful = result.wasSuccessful() |
| 6999 if not successful: | 6747 if not successful: |
| 7000 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) | 6748 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) |
| 7001 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ | 6749 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ |
| 7002 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) | 6750 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) |
| 7003 sys.exit(not successful) | 6751 sys.exit(not successful) |
| 7004 | 6752 |
| 7005 | 6753 |
| 7006 if __name__ == '__main__': | 6754 if __name__ == '__main__': |
| 7007 Main() | 6755 Main() |
| OLD | NEW |