Use blessings when possible for WPT UI

Use blessings when it is possible for the WPT UI and fall back to using
raw control characters. This also fixes a bug where the UI didn't work
correctly in iTerm.app. Remove the one line version of the UI, since it
is no longer used as the iTerm fallback.
This commit is contained in:
Martin Robinson 2015-11-13 08:56:43 -08:00
parent f8c2c3c3e4
commit 7225e36d81

View file

@ -7,6 +7,9 @@ import collections
import os import os
import sys import sys
DEFAULT_MOVE_UP_CODE = u"\x1b[A"
DEFAULT_CLEAR_EOL_CODE = u"\x1b[K"
class GroupingFormatter(base.BaseFormatter): class GroupingFormatter(base.BaseFormatter):
"""Formatter designed to produce unexpected test results grouped """Formatter designed to produce unexpected test results grouped
@ -17,16 +20,15 @@ class GroupingFormatter(base.BaseFormatter):
self.need_to_erase_last_line = False self.need_to_erase_last_line = False
self.current_display = "" self.current_display = ""
self.running_tests = {} self.running_tests = {}
self.last_test_finished = "Running tests..."
self.test_output = collections.defaultdict(str) self.test_output = collections.defaultdict(str)
self.subtest_failures = collections.defaultdict(list) self.subtest_failures = collections.defaultdict(list)
self.test_failure_text = "" self.test_failure_text = ""
self.tests_with_failing_subtests = [] self.tests_with_failing_subtests = []
self.interactive = os.isatty(sys.stdout.fileno()) self.interactive = os.isatty(sys.stdout.fileno())
# iTerm2 doesn't support the terminal codes used to erase previous lines, # TODO(mrobinson, 8313): We need to add support for Windows terminals here.
# so only print one line and rely only on backspace characters. if self.interactive:
self.one_line = os.environ.get("TERM_PROGRAM", "") == "iTerm.app" self.move_up, self.clear_eol = self.get_move_up_and_clear_eol_codes()
self.expected = { self.expected = {
'OK': 0, 'OK': 0,
@ -47,16 +49,25 @@ class GroupingFormatter(base.BaseFormatter):
'CRASH': [], 'CRASH': [],
} }
def get_move_up_and_clear_eol_codes(self):
try:
import blessings
except ImportError:
return DEFAULT_MOVE_UP_CODE, DEFAULT_CLEAR_EOL_CODE
try:
self.terminal = blessings.Terminal()
return self.terminal.clear_eol, self.terminal.move_up
except Exception as exception:
sys.stderr.write("GroupingFormatter: Could not get terminal "
"control characters: %s\n" % exception)
return DEFAULT_MOVE_UP_CODE, DEFAULT_CLEAR_EOL_CODE
def text_to_erase_display(self): def text_to_erase_display(self):
if not self.interactive or not self.current_display: if not self.interactive or not self.current_display:
return "" return ""
return ((self.move_up + self.clear_eol) *
# TODO(mrobinson, 8313): We need to add support for Windows terminals here. len(self.current_display.splitlines()))
erase_length = len(self.current_display)
if self.one_line:
return "\b \b" * erase_length
else:
return ("\033[F" + "\033[K") * len(self.current_display.splitlines())
def generate_output(self, text=None, new_display=None): def generate_output(self, text=None, new_display=None):
if not self.interactive: if not self.interactive:
@ -75,9 +86,6 @@ class GroupingFormatter(base.BaseFormatter):
else: else:
new_display = " [%i/%i] " % (self.completed_tests, self.number_of_tests) new_display = " [%i/%i] " % (self.completed_tests, self.number_of_tests)
if self.one_line:
return new_display + self.last_test_finished
if self.running_tests: if self.running_tests:
indent = " " * len(new_display) indent = " " * len(new_display)
return new_display + ("\n%s" % indent).join( return new_display + ("\n%s" % indent).join(
@ -175,7 +183,6 @@ class GroupingFormatter(base.BaseFormatter):
subtest_failures = self.subtest_failures.pop(test_name, []) subtest_failures = self.subtest_failures.pop(test_name, [])
del self.running_tests[data['thread']] del self.running_tests[data['thread']]
self.last_test_finished = test_name
new_display = self.build_status_line() new_display = self.build_status_line()
if not had_unexpected_test_result and not subtest_failures: if not had_unexpected_test_result and not subtest_failures: