diff --git a/tests/uitests/details.py b/tests/uitests/details.py new file mode 100644 index 000000000..a90bf6a8d --- /dev/null +++ b/tests/uitests/details.py @@ -0,0 +1,84 @@ +import time +import unittest + +import tests +from tests.uitests import utils as uiutils + +import dogtail.rawinput +import pyatspi + + +class Details(unittest.TestCase): + """ + UI tests for virt-manager's VM details window + """ + def setUp(self): + self.app = uiutils.DogtailApp(tests.utils.uri_test) + def tearDown(self): + self.app.kill() + + + ################### + # Private helpers # + ################### + + def _open_details_window(self, vmname="test-many-devices"): + uiutils.find_fuzzy( + self.app.root, vmname, "table cell").doubleClick() + win = uiutils.find_pattern(self.app.root, "%s on" % vmname, "frame") + uiutils.find_pattern(win, "Details", "radio button").click() + return win + + + ############## + # Test cases # + ############## + + def testDetailsHardwareSmokeTest(self): + """ + Open the VM with all the crazy hardware and just verify that each + HW panel shows itself without raising any error. + """ + win = self._open_details_window() + + # Ensure the Overview page is the first selected + uiutils.find_pattern(win, "Hypervisor Details", "label") + uiutils.find_pattern(win, "Overview", "table cell").click() + + # After we hit this number of down presses, start checking for + # widget focus to determine if we hit the end of the list. We + # don't check for widget focus unconditionally because it's slow. + # The seemingly arbitrary number here is because it matches the + # number of devices in test-many-devices at the time of this writing. + check_after = 88 + + focused = None + old_focused = None + count = 0 + while True: + count += 1 + dogtail.rawinput.pressKey("Down") + + if not win.getState().contains(pyatspi.STATE_ACTIVE): + # Should mean an error dialog popped up + uiutils.find_pattern(self.app.root, "Error", "alert") + raise AssertionError( + "One of the hardware pages raised an error") + + if count < check_after: + time.sleep(.1) + continue + + old_focused = focused + focused = uiutils.focused_nodes(win) + if old_focused is None: + continue + + overlap = [w for w in old_focused if w in focused] + if len(overlap) == len(old_focused): + # Focus didn't change, meaning we hit the end of the HW list, + # so our testing is done + break + + self.app.quit() + return diff --git a/tests/uitests/utils.py b/tests/uitests/utils.py index 7e43db516..3656268aa 100644 --- a/tests/uitests/utils.py +++ b/tests/uitests/utils.py @@ -87,6 +87,10 @@ class DogtailApp(object): time.sleep(.5) +######################### +# Widget search helpers # +######################### + def find_pattern(root, name, roleName=None, labeller_text=None): """ Search root for any widget that contains the passed name/role regex @@ -120,6 +124,26 @@ def find_fuzzy(root, name, roleName=None, labeller_text=None): labeller_pattern) +def check_in_loop(func, timeout=-1): + """ + Run the passed func in a loop every .5 seconds until timeout is hit or + the func returns True. + If timeout=-1, check indefinitely. + """ + total_time = 0.0 + while True: + time.sleep(.5) + total_time += .5 + if func() is True: + return + if timeout > 0 and total_time >= timeout: + raise RuntimeError("Loop condition wasn't met") + + +##################### +# Debugging helpers # +##################### + def node_string(node): msg = "name='%s' roleName='%s'" % (node.name, node.roleName) if node.labeller: @@ -141,17 +165,15 @@ def print_nodes(root): root.findChildren(_walk, isLambda=True) -def check_in_loop(func, timeout=-1): +def focused_nodes(root): """ - Run the passed func in a loop every .5 seconds until timeout is hit or - the func returns True. - If timeout=-1, check indefinitely. + Return a list of all focused nodes. Useful for debugging """ - total_time = 0.0 - while True: - time.sleep(.5) - total_time += .5 - if func() is True: - return - if timeout > 0 and total_time >= timeout: - raise RuntimeError("Loop condition wasn't met") + def _walk(node): + try: + if node.focused: + return node + except Exception, e: + print "got exception: %s" % e + + return root.findChildren(_walk, isLambda=True) diff --git a/ui/details.ui b/ui/details.ui index 8b231046c..f76a8eb07 100644 --- a/ui/details.ui +++ b/ui/details.ui @@ -617,6 +617,16 @@ + + + hw-list + + + + + + + hw-list-scroll