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 2957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2968 | 2968 |
2969 def AddDomMutationObserver(self, mutation_type, selector, | 2969 def AddDomMutationObserver(self, mutation_type, selector, |
2970 expected_value=None, automation_id=44444, | 2970 expected_value=None, automation_id=44444, |
2971 **kwargs): | 2971 **kwargs): |
2972 """Sets up an event observer watching for a specific DOM mutation. | 2972 """Sets up an event observer watching for a specific DOM mutation. |
2973 | 2973 |
2974 Creates an observer that raises an event when a mutation of the given type | 2974 Creates an observer that raises an event when a mutation of the given type |
2975 occurs on a DOM node specified by |selector|. | 2975 occurs on a DOM node specified by |selector|. |
2976 | 2976 |
2977 Args: | 2977 Args: |
2978 mutation_type: One of 'add', 'remove', or 'change'. | 2978 mutation_type: One of 'add', 'remove', 'change', or 'exists'. |
2979 selector: A DOMSelector object defining the DOM node to watch. The node | 2979 selector: A DOMSelector object defining the DOM node to watch. The node |
2980 must already exist if |mutation_type| is 'change'. | 2980 must already exist if |mutation_type| is 'change'. |
2981 expected_value: Optional regular expression to match against the node's | 2981 expected_value: Optional regular expression to match against the node's |
2982 textContent attribute after the mutation. Defaults to None. | 2982 textContent attribute after the mutation. Defaults to None. |
2983 automation_id: The automation_id used to route the observer javascript | 2983 automation_id: The automation_id used to route the observer javascript |
2984 messages. Defaults to 44444. | 2984 messages. Defaults to 44444. |
2985 | 2985 |
2986 Any additional keyword arguments are passed on to ExecuteJavascript and | 2986 Any additional keyword arguments are passed on to ExecuteJavascript and |
2987 can be used to select the tab where the DOM MutationObserver is created. | 2987 can be used to select the tab where the DOM MutationObserver is created. |
2988 | 2988 |
2989 Returns: | 2989 Returns: |
2990 The id of the created observer, which can be used with GetNextEvent(id) | 2990 The id of the created observer, which can be used with GetNextEvent(id) |
2991 and RemoveEventObserver(id). | 2991 and RemoveEventObserver(id). |
2992 | 2992 |
2993 Raises: | 2993 Raises: |
2994 pyauto_errors.JSONInterfaceError if the automation call returns an error. | 2994 pyauto_errors.JSONInterfaceError if the automation call returns an error. |
2995 RuntimeError if the injected javascript MutationObserver returns an error. | 2995 RuntimeError if the injected javascript MutationObserver returns an error. |
2996 """ | 2996 """ |
2997 assert mutation_type in ('add', 'remove', 'change'), \ | 2997 assert mutation_type in ('add', 'remove', 'change', 'exists'), \ |
2998 'Unexpected value "%s" for mutation_type.' % mutation_type | 2998 'Unexpected value "%s" for mutation_type.' % mutation_type |
2999 assert isinstance(selector, domselector.DOMSelector), \ | 2999 assert isinstance(selector, domselector.DOMSelector), \ |
3000 'Unexpected type: selector is not a instance of DOMSelector.' | 3000 'Unexpected type: selector is not a instance of DOMSelector.' |
3001 assert '"' not in selector.pattern, \ | 3001 assert '"' not in selector.pattern, \ |
3002 'Do not use character " in selector.' | 3002 'Do not use character " in selector.' |
3003 assert not expected_value or '"' not in expected_value, \ | 3003 assert not expected_value or '"' not in expected_value, \ |
3004 'Do not use character " in expected_value.' | 3004 'Do not use character " in expected_value.' |
3005 cmd_dict = { | 3005 cmd_dict = { |
3006 'command': 'AddDomEventObserver', | 3006 'command': 'AddDomEventObserver', |
3007 'event_name': '__dom_mutation_observer__:$(id)', | 3007 'event_name': '__dom_mutation_observer__:$(id)', |
3008 'automation_id': automation_id, | 3008 'automation_id': automation_id, |
3009 'recurring': False, | 3009 'recurring': False, |
3010 } | 3010 } |
3011 observer_id = ( | 3011 observer_id = ( |
3012 self._GetResultFromJSONRequest(cmd_dict, windex=None)['observer_id']) | 3012 self._GetResultFromJSONRequest(cmd_dict, windex=None)['observer_id']) |
3013 jsfile = os.path.join(os.path.abspath(os.path.dirname(__file__)), | 3013 jsfile = os.path.join(os.path.abspath(os.path.dirname(__file__)), |
3014 'dom_mutation_observer.js') | 3014 'dom_mutation_observer.js') |
3015 with open(jsfile, 'r') as f: | 3015 with open(jsfile, 'r') as f: |
3016 js = ('(' + f.read() + ')(%d, %d, "%s", "%s", "%s", %s);' % | 3016 js = ('(' + f.read() + ')(%d, %d, "%s", "%s", "%s", %s);' % |
3017 (automation_id, observer_id, mutation_type, | 3017 (automation_id, observer_id, mutation_type, |
3018 selector.pattern, selector.type_string, | 3018 selector.pattern, selector.type_string, |
3019 'null' if expected_value is None else '"%s"' % expected_value)) | 3019 'null' if expected_value is None else '"%s"' % expected_value)) |
3020 jsreturn = self.ExecuteJavascript(js, **kwargs) | 3020 jsreturn = self.ExecuteJavascript(js, **kwargs) |
3021 if jsreturn != 'success': | 3021 if jsreturn != 'success': |
3022 self.RemoveEventObserver(observer_id) | 3022 self.RemoveEventObserver(observer_id) |
3023 raise RuntimeError(jsreturn) | 3023 raise RuntimeError(jsreturn) |
3024 return observer_id | 3024 return observer_id |
3025 | 3025 |
3026 def WaitForDomNode(self, selector, expected_value=None, timeout=-1, **kwargs): | |
3027 """Waits until a node matching selector exists in the DOM. | |
3028 | |
3029 NOTE: This does NOT poll. It returns as soon as the node appears, or | |
3030 immediately if the node already exists. | |
3031 | |
3032 Args: | |
3033 selector: A DOMSelector object defining the DOM node to wait for. | |
3034 expected_value: Optional regular expression to match against the node's | |
3035 textContent attribute. Defaults to None. | |
3036 timeout: Time to wait for the node to exist before raising an exception, | |
3037 defaults to the default automation timeout. | |
3038 | |
3039 Any additional keyword arguments are passed on to ExecuteJavascript and | |
3040 can be used to select the tab where the DOM MutationObserver is created. | |
3041 | |
3042 Raises: | |
3043 pyauto_errors.JSONInterfaceError if the automation call returns an error. | |
3044 RuntimeError if the injected javascript MutationObserver returns an error. | |
frankf
2012/04/16 23:53:07
nit: RuntimeError is mostly a 'relic', think about
craigdh
2012/04/16 23:58:40
Done.
| |
3045 """ | |
3046 observer_id = self.AddDomMutationObserver('exists', selector, | |
3047 expected_value, **kwargs) | |
3048 self.GetNextEvent(observer_id, timeout=timeout) | |
3049 | |
3026 def GetNextEvent(self, observer_id=-1, blocking=True, timeout=-1): | 3050 def GetNextEvent(self, observer_id=-1, blocking=True, timeout=-1): |
3027 """Waits for an observed event to occur. | 3051 """Waits for an observed event to occur. |
3028 | 3052 |
3029 The returned event is removed from the Event Queue. If there is already a | 3053 The returned event is removed from the Event Queue. If there is already a |
3030 matching event in the queue it is returned immediately, otherwise the call | 3054 matching event in the queue it is returned immediately, otherwise the call |
3031 blocks until a matching event occurs. If blocking is disabled and no | 3055 blocks until a matching event occurs. If blocking is disabled and no |
3032 matching event is in the queue this function will immediately return None. | 3056 matching event is in the queue this function will immediately return None. |
3033 | 3057 |
3034 Args: | 3058 Args: |
3035 observer_id: The id of the observer to wait for, matches any event by | 3059 observer_id: The id of the observer to wait for, matches any event by |
(...skipping 2312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5348 successful = result.wasSuccessful() | 5372 successful = result.wasSuccessful() |
5349 if not successful: | 5373 if not successful: |
5350 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) | 5374 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) |
5351 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ | 5375 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ |
5352 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) | 5376 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) |
5353 sys.exit(not successful) | 5377 sys.exit(not successful) |
5354 | 5378 |
5355 | 5379 |
5356 if __name__ == '__main__': | 5380 if __name__ == '__main__': |
5357 Main() | 5381 Main() |
OLD | NEW |