| # Copyright (C) 2017 Igalia S.L. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # |
| # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY |
| # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| import logging |
| import os |
| |
| from webkitpy.common.webkit_finder import WebKitFinder |
| from webkitpy.webdriver_tests.webdriver_w3c_executor import WebDriverW3CExecutor |
| from webkitpy.webdriver_tests.webdriver_test_result import WebDriverTestResult |
| from webkitpy.webdriver_tests.webdriver_w3c_web_server import WebDriverW3CWebServer |
| |
| _log = logging.getLogger(__name__) |
| |
| |
| class WebDriverTestRunnerW3C(object): |
| |
| def __init__(self, port, driver, env, expectations): |
| self._port = port |
| self._driver = driver |
| self._env = env |
| self._expectations = expectations |
| self._results = [] |
| self._tests_dir = WebKitFinder(self._port.host.filesystem).path_from_webkit_base('WebDriverTests') |
| |
| self._server = WebDriverW3CWebServer(self._port) |
| |
| def collect_tests(self, tests): |
| skipped = [os.path.join(self._tests_dir, test) for test in self._expectations.skipped_tests()] |
| relative_tests_dir = os.path.join('imported', 'w3c', 'webdriver', 'tests') |
| w3c_tests = [] |
| if not tests: |
| tests = [relative_tests_dir] |
| for test in tests: |
| subtest = None |
| if '::' in test: |
| test, subtest = test.split('::') |
| |
| if not test.startswith(relative_tests_dir): |
| continue |
| |
| test_path = os.path.join(self._tests_dir, test) |
| if os.path.isdir(test_path): |
| w3c_tests.extend(self._scan_directory(test_path, skipped)) |
| elif self._is_test(test_path) and test_path not in skipped: |
| if subtest is not None: |
| w3c_tests.append(test_path + '::' + subtest) |
| else: |
| w3c_tests.append(test_path) |
| return w3c_tests |
| |
| def _is_test(self, test): |
| if not os.path.isfile(test): |
| return False |
| if os.path.splitext(test)[1] != '.py': |
| return False |
| if os.path.basename(test) in ['conftest.py', '__init__.py']: |
| return False |
| if os.path.basename(os.path.dirname(test)) == 'support': |
| return False |
| return True |
| |
| def _scan_directory(self, directory, skipped): |
| tests = [] |
| for path in self._port.host.filesystem.files_under(directory): |
| if self._is_test(path) and path not in skipped: |
| tests.append(path) |
| return tests |
| |
| def _subtest_name(self, subtest): |
| path, test = subtest.split('::', 1) |
| return os.path.basename(path) + '::' + test |
| |
| def run(self, tests=[]): |
| self._server.start() |
| |
| executor = WebDriverW3CExecutor(self._driver, self._server, self._env, self._port.get_option('timeout'), self._expectations) |
| executor.setup() |
| need_restart = False |
| try: |
| for test in tests: |
| test_name = os.path.relpath(test.split('::')[0], self._tests_dir) |
| harness_result, test_results = executor.run(test) |
| result = WebDriverTestResult(test_name, *harness_result) |
| if harness_result[0] == 'OK': |
| for subtest, status, message, backtrace in test_results: |
| result.add_subtest_results(self._subtest_name(subtest), status, message, backtrace) |
| need_restart = need_restart or status in ('FAIL', 'ERROR', 'XFAIL', 'TIMEOUT') |
| else: |
| _log.error("Test %s failed:" % test_name) |
| _log.error(harness_result[1]) |
| need_restart = True |
| self._results.append(result) |
| |
| if need_restart: |
| executor.teardown() |
| executor.setup() |
| finally: |
| executor.teardown() |
| self._server.stop() |
| |
| def results(self): |
| return self._results |