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