| 849 | # synchronously, so we have a timeout, which can be hit if the VM |
| 850 | # we run on stalls temporarily). |
| 851 | def run_browser(self, html_file, expected=None, message=None, timeout=None, extra_tries=None): |
| 852 | if not has_browser(): |
| 853 | return |
| 854 | assert '?' not in html_file, 'URL params not supported' |
| 855 | if extra_tries is None: |
| 856 | extra_tries = common.EMTEST_RETRY_FLAKY if self.flaky else 0 |
| 857 | url = html_file |
| 858 | if self.capture_stdio: |
| 859 | url += '?capture_stdio' |
| 860 | if self.skip_exec: |
| 861 | self.skipTest('skipping test execution: ' + self.skip_exec) |
| 862 | if BrowserCore.unresponsive_tests >= BrowserCore.MAX_UNRESPONSIVE_TESTS: |
| 863 | self.skipTest('too many unresponsive tests, skipping remaining tests') |
| 864 | |
| 865 | if EMTEST_RESTART_BROWSER_EVERY_N_TESTS and BrowserCore.num_tests_ran >= EMTEST_RESTART_BROWSER_EVERY_N_TESTS: |
| 866 | logger.warning(f'[EMTEST_RESTART_BROWSER_EVERY_N_TESTS={EMTEST_RESTART_BROWSER_EVERY_N_TESTS} workaround: restarting browser]') |
| 867 | self.browser_restart() |
| 868 | BrowserCore.num_tests_ran += 1 |
| 869 | |
| 870 | self.assert_out_queue_empty('previous test') |
| 871 | if DEBUG: |
| 872 | print('[browser launch:', html_file, ']') |
| 873 | assert not (message and expected), 'run_browser expects `expected` or `message`, but not both' |
| 874 | |
| 875 | if expected is not None: |
| 876 | try: |
| 877 | self.harness_in_queue.put(( |
| 878 | 'http://localhost:%s/%s' % (self.PORT, url), |
| 879 | self.get_dir(), |
| 880 | )) |
| 881 | if timeout is None: |
| 882 | timeout = self.BROWSER_TIMEOUT |
| 883 | try: |
| 884 | output = self.harness_out_queue.get(block=True, timeout=timeout) |
| 885 | except queue.Empty: |
| 886 | BrowserCore.unresponsive_tests += 1 |
| 887 | print(f'[unresponsive test: {self.id()} total unresponsive={BrowserCore.unresponsive_tests}]') |
| 888 | self.browser_restart() |
| 889 | # Rather than fail the test here, let fail on the `assertContained` so |
| 890 | # that the test can be retried via `extra_tries` |
| 891 | output = '[no http server activity]' |
| 892 | if output is None: |
| 893 | # the browser harness reported an error already, and sent a None to tell |
| 894 | # us to also fail the test |
| 895 | self.fail('browser harness error') |
| 896 | output = unquote(output) |
| 897 | if output.startswith('/report_result?skipped:'): |
| 898 | self.skipTest(unquote(output[len('/report_result?skipped:'):]).strip()) |
| 899 | else: |
| 900 | # verify the result, and try again if we should do so |
| 901 | try: |
| 902 | self.assertContained(expected, output) |
| 903 | except self.failureException as e: |
| 904 | if extra_tries > 0: |
| 905 | record_flaky_test(self.id(), common.EMTEST_RETRY_FLAKY - extra_tries, common.EMTEST_RETRY_FLAKY, e) |
| 906 | if not self.capture_stdio: |
| 907 | print('[enabling stdio/stderr reporting]') |
| 908 | self.capture_stdio = True |