mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-10-27 01:55:20 +03:00
uitests: Add a basic details.py test
Checks all hw of test-many-devices and make sure an error isn't raised
This commit is contained in:
parent
cfd980611a
commit
01da21b93a
84
tests/uitests/details.py
Normal file
84
tests/uitests/details.py
Normal file
@ -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
|
@ -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)
|
||||
|
@ -617,6 +617,16 @@
|
||||
<signal name="changed" handler="on_hw_list_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="hw-list-atkobject">
|
||||
<property name="AtkObject::accessible-name" translatable="yes">hw-list</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="scrolledwindow5-atkobject">
|
||||
<property name="AtkObject::accessible-name" translatable="yes">hw-list-scroll</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
Loading…
Reference in New Issue
Block a user