| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import argparse | 5 import argparse |
| 6 import json | 6 import json |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import re | 9 import re |
| 10 import socket | 10 import socket |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 This class is the tool that is used by every integration test to interact with | 120 This class is the tool that is used by every integration test to interact with |
| 121 the Chromium browser and validate proper functionality. This class sits on top | 121 the Chromium browser and validate proper functionality. This class sits on top |
| 122 of the Selenium Chrome Webdriver with added utility and helper functions for | 122 of the Selenium Chrome Webdriver with added utility and helper functions for |
| 123 Chrome-Proxy. This class should be used with Python's 'with' operator. | 123 Chrome-Proxy. This class should be used with Python's 'with' operator. |
| 124 | 124 |
| 125 Attributes: | 125 Attributes: |
| 126 _flags: A Namespace object from the call to ParseFlags() | 126 _flags: A Namespace object from the call to ParseFlags() |
| 127 _driver: A reference to the driver object from the Chrome Driver library. | 127 _driver: A reference to the driver object from the Chrome Driver library. |
| 128 _chrome_args: A set of string arguments to start Chrome with. | 128 _chrome_args: A set of string arguments to start Chrome with. |
| 129 _url: The string URL that Chrome will navigate to for this test. | 129 _url: The string URL that Chrome will navigate to for this test. |
| 130 _has_logs: Boolean flag set when a page is loaded and cleared when logs are |
| 131 fetched. |
| 130 """ | 132 """ |
| 131 | 133 |
| 132 def __init__(self): | 134 def __init__(self): |
| 133 self._flags = ParseFlags() | 135 self._flags = ParseFlags() |
| 134 self._driver = None | 136 self._driver = None |
| 135 self._chrome_args = set() | 137 self._chrome_args = set() |
| 136 self._url = '' | 138 self._url = '' |
| 137 self._logger = GetLogger(name='TestDriver') | 139 self._logger = GetLogger(name='TestDriver') |
| 140 self._has_logs = False |
| 138 | 141 |
| 139 def __enter__(self): | 142 def __enter__(self): |
| 140 return self | 143 return self |
| 141 | 144 |
| 142 def __exit__(self, exc_type, exc_value, tb): | 145 def __exit__(self, exc_type, exc_value, tb): |
| 143 if self._driver: | 146 if self._driver: |
| 144 self._StopDriver() | 147 self._StopDriver() |
| 145 | 148 |
| 146 def _OverrideChromeArgs(self): | 149 def _OverrideChromeArgs(self): |
| 147 """Overrides any given arguments in the code with those given on the command | 150 """Overrides any given arguments in the code with those given on the command |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 if (len(urlparse.urlparse(url).netloc) == 0 and | 279 if (len(urlparse.urlparse(url).netloc) == 0 and |
| 277 len(urlparse.urlparse(url).scheme) == 0): | 280 len(urlparse.urlparse(url).scheme) == 0): |
| 278 self._logger.warn('Invalid URL: "%s". Did you forget to prepend ' | 281 self._logger.warn('Invalid URL: "%s". Did you forget to prepend ' |
| 279 '"http://"? See RFC 1808 for more information', url) | 282 '"http://"? See RFC 1808 for more information', url) |
| 280 if not self._driver: | 283 if not self._driver: |
| 281 self._StartDriver() | 284 self._StartDriver() |
| 282 self._driver.set_page_load_timeout(timeout) | 285 self._driver.set_page_load_timeout(timeout) |
| 283 self._logger.debug('Set page load timeout to %f seconds', timeout) | 286 self._logger.debug('Set page load timeout to %f seconds', timeout) |
| 284 self._driver.get(self._url) | 287 self._driver.get(self._url) |
| 285 self._logger.debug('Loaded page %s', url) | 288 self._logger.debug('Loaded page %s', url) |
| 289 self._has_logs = True |
| 286 | 290 |
| 287 def ExecuteJavascript(self, script, timeout=30): | 291 def ExecuteJavascript(self, script, timeout=30): |
| 288 """Executes the given javascript in the browser's current page in an | 292 """Executes the given javascript in the browser's current page in an |
| 289 anonymous function. | 293 anonymous function. |
| 290 | 294 |
| 291 If you expect a result and don't get one, try adding a return statement or | 295 If you expect a result and don't get one, try adding a return statement or |
| 292 using ExecuteJavascriptStatement() below. | 296 using ExecuteJavascriptStatement() below. |
| 293 | 297 |
| 294 Args: | 298 Args: |
| 295 script: A string of Javascript code. | 299 script: A string of Javascript code. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 while not result and total_waited_time < timeout: | 352 while not result and total_waited_time < timeout: |
| 349 time.sleep(poll_interval) | 353 time.sleep(poll_interval) |
| 350 total_waited_time += poll_interval | 354 total_waited_time += poll_interval |
| 351 result = self.ExecuteJavascriptStatement(expression) | 355 result = self.ExecuteJavascriptStatement(expression) |
| 352 if not result: | 356 if not result: |
| 353 self._logger.error('%s not true after %f seconds' % (expression, timeout)) | 357 self._logger.error('%s not true after %f seconds' % (expression, timeout)) |
| 354 raise Exception('%s not true after %f seconds' % (expression, timeout)) | 358 raise Exception('%s not true after %f seconds' % (expression, timeout)) |
| 355 return result | 359 return result |
| 356 | 360 |
| 357 def GetPerformanceLogs(self, method_filter=r'Network\.responseReceived'): | 361 def GetPerformanceLogs(self, method_filter=r'Network\.responseReceived'): |
| 358 """Returns all logged Performance events from Chrome. | 362 """Returns all logged Performance events from Chrome. Raises an Exception if |
| 363 no pages have been loaded since the last time this function was called. |
| 359 | 364 |
| 360 Args: | 365 Args: |
| 361 method_filter: A regex expression to match the method of logged events | 366 method_filter: A regex expression to match the method of logged events |
| 362 against. Only logs who's method matches the regex will be returned. | 367 against. Only logs who's method matches the regex will be returned. |
| 363 Returns: | 368 Returns: |
| 364 Performance logs as a list of dicts, since the last time this function was | 369 Performance logs as a list of dicts, since the last time this function was |
| 365 called. | 370 called. |
| 366 """ | 371 """ |
| 372 if not self._has_logs: |
| 373 raise Exception('No pages loaded since last Network log query!') |
| 367 all_messages = [] | 374 all_messages = [] |
| 368 for log in self._driver.execute('getLog', {'type': 'performance'})['value']: | 375 for log in self._driver.execute('getLog', {'type': 'performance'})['value']: |
| 369 message = json.loads(log['message'])['message'] | 376 message = json.loads(log['message'])['message'] |
| 370 self._logger.debug('Got Performance log: %s', log['message']) | 377 self._logger.debug('Got Performance log: %s', log['message']) |
| 371 if re.match(method_filter, message['method']): | 378 if re.match(method_filter, message['method']): |
| 372 all_messages.append(message) | 379 all_messages.append(message) |
| 373 self._logger.info('Got %d performance logs with filter method=%s', | 380 self._logger.info('Got %d performance logs with filter method=%s', |
| 374 len(all_messages), method_filter) | 381 len(all_messages), method_filter) |
| 382 self._has_logs = False |
| 375 return all_messages | 383 return all_messages |
| 376 | 384 |
| 377 def GetHTTPResponses(self, include_favicon=False, skip_domainless_pages=True): | 385 def GetHTTPResponses(self, include_favicon=False, skip_domainless_pages=True): |
| 378 """Parses the Performance Logs and returns a list of HTTPResponse objects. | 386 """Parses the Performance Logs and returns a list of HTTPResponse objects. |
| 379 | 387 |
| 380 Use caution when calling this function multiple times. Only responses | 388 Use caution when calling this function multiple times. Only responses |
| 381 since the last time this function was called are returned (or since Chrome | 389 since the last time this function was called are returned (or since Chrome |
| 382 started, whichever is later). | 390 started, whichever is later). An Exception will be raised if no page was |
| 391 loaded since the last time this function was called. |
| 383 | 392 |
| 384 Args: | 393 Args: |
| 385 include_favicon: A bool that if True will include responses for favicons. | 394 include_favicon: A bool that if True will include responses for favicons. |
| 386 skip_domainless_pages: If True, only responses with a net_loc as in RFC | 395 skip_domainless_pages: If True, only responses with a net_loc as in RFC |
| 387 1808 will be included. Pages such as about:blank will be skipped. | 396 1808 will be included. Pages such as about:blank will be skipped. |
| 388 Returns: | 397 Returns: |
| 389 A list of HTTPResponse objects, each representing a single completed HTTP | 398 A list of HTTPResponse objects, each representing a single completed HTTP |
| 390 transaction by Chrome. | 399 transaction by Chrome. |
| 391 """ | 400 """ |
| 392 def MakeHTTPResponse(log_dict): | 401 def MakeHTTPResponse(log_dict): |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 for test_suite in test_suite_iter: | 574 for test_suite in test_suite_iter: |
| 566 for test_case in test_suite: | 575 for test_case in test_suite: |
| 567 for test in test_case: | 576 for test in test_case: |
| 568 # Drop the file name in the form <filename>.<classname>.<methodname> | 577 # Drop the file name in the form <filename>.<classname>.<methodname> |
| 569 test_id = test.id()[test.id().find('.') + 1:] | 578 test_id = test.id()[test.id().find('.') + 1:] |
| 570 if re.match(test_filter_re, test_id): | 579 if re.match(test_filter_re, test_id): |
| 571 tests.addTest(test) | 580 tests.addTest(test) |
| 572 testRunner = unittest.runner.TextTestRunner(verbosity=2, | 581 testRunner = unittest.runner.TextTestRunner(verbosity=2, |
| 573 failfast=flags.failfast, buffer=(not flags.disable_buffer)) | 582 failfast=flags.failfast, buffer=(not flags.disable_buffer)) |
| 574 testRunner.run(tests) | 583 testRunner.run(tests) |
| OLD | NEW |