summaryrefslogtreecommitdiff
diff options
authorThomi Richards <thomi.richards@canonical.com>2012-02-29 19:44:10 -0500
committerTarmac <>2012-02-29 19:44:10 -0500
commit85adf93ea77d2ec274d3ae962c609fb1c228418c (patch)
tree7f686855626d44e866dc449f0c3e5583064cca69
parentf4d829e2379de9c499a1623839594b340143677d (diff)
parent9b74200dde6e76d95edb52c81ef226cd2ebfa6ce (diff)
Fixed several stability issues with autopilot tests.
Specifically:  * hud tests now make sure the hud is hidden after each test.  * Keyboard and mouse cleanup happens after test tearDown methods are called, so tests can do things like hide the dash and the keyboard cleanup will still work as expected.  * Keyboard cleanup now removes pressed keys from the global list after releasing them (oops!)  * Mouse cleanup now releases pressed mouse buttons as well as moving mouse to a safe position.  * Keyboard and mouse release methods will log a warning when asked to release a key that wasn't pressed, rather than crashing. This shouldn't normally happen, but crashing is never the right thing to do.  * Revealing the dash, or any lens will now clear the old search text by default. UNBLOCK. Fixes: . Approved by Marco Trevisan (Treviño). (bzr r2042)
-rw-r--r--tests/autopilot/autopilot/emulators/X11.py18
-rw-r--r--tests/autopilot/autopilot/emulators/unity/dash.py27
-rw-r--r--tests/autopilot/autopilot/tests/__init__.py16
-rw-r--r--tests/autopilot/autopilot/tests/test_hud.py50
4 files changed, 67 insertions, 44 deletions
diff --git a/tests/autopilot/autopilot/emulators/X11.py b/tests/autopilot/autopilot/emulators/X11.py
index 3ce773d1f..757af0460 100644
--- a/tests/autopilot/autopilot/emulators/X11.py
+++ b/tests/autopilot/autopilot/emulators/X11.py
@@ -26,6 +26,7 @@ from Xlib.ext.xtest import fake_input
import gtk.gdk
_PRESSED_KEYS = []
+_PRESSED_MOUSE_BUTTONS = []
_DISPLAY = Display()
logger = logging.getLogger(__name__)
@@ -159,9 +160,11 @@ class Keyboard(object):
any keys that were pressed and not released.
"""
+ global _PRESSED_KEYS
for keycode in _PRESSED_KEYS:
logger.warning("Releasing key %r as part of cleanup call.", keycode)
fake_input(_DISPLAY, X.KeyRelease, keycode)
+ _PRESSED_KEYS = []
def __perform_on_keys(self, keys, event):
keycode = 0
@@ -176,7 +179,10 @@ class Keyboard(object):
if event == X.KeyPress:
_PRESSED_KEYS.append(keycode)
elif event == X.KeyRelease:
- _PRESSED_KEYS.remove(keycode)
+ if keycode in _PRESSED_KEYS:
+ _PRESSED_KEYS.remove(keycode)
+ else:
+ logger.warning("Generating release event for keycode %d that was not pressed.", keycode)
fake_input(_DISPLAY, event, keycode)
_DISPLAY.sync()
@@ -225,12 +231,17 @@ class Mouse(object):
def press(self, button=1):
"""Press mouse button at current mouse location."""
logger.debug("Pressing mouse button %d", button)
+ _PRESSED_MOUSE_BUTTONS.append(button)
fake_input(_DISPLAY, X.ButtonPress, button)
_DISPLAY.sync()
def release(self, button=1):
"""Releases mouse button at current mouse location."""
logger.debug("Releasing mouse button %d", button)
+ if button in _PRESSED_MOUSE_BUTTONS:
+ _PRESSED_MOUSE_BUTTONS.remove(button)
+ else:
+ logger.warning("Generating button release event or button %d that was not pressed.", button)
fake_input(_DISPLAY, X.ButtonRelease, button)
_DISPLAY.sync()
@@ -284,6 +295,11 @@ class Mouse(object):
@staticmethod
def cleanup():
"""Put mouse in a known safe state."""
+ global _PRESSED_MOUSE_BUTTONS
+ for btn in _PRESSED_MOUSE_BUTTONS:
+ logger.debug("Releasing mouse button %d as part of cleanup", btn)
+ fake_input(_DISPLAY, X.ButtonRelease, btn)
+ _PRESSED_MOUSE_BUTTONS = []
sg = ScreenGeometry()
sg.move_mouse_to_monitor(0)
diff --git a/tests/autopilot/autopilot/emulators/unity/dash.py b/tests/autopilot/autopilot/emulators/unity/dash.py
index 8c1115c38..201bdb84d 100644
--- a/tests/autopilot/autopilot/emulators/unity/dash.py
+++ b/tests/autopilot/autopilot/emulators/unity/dash.py
@@ -38,12 +38,14 @@ class Dash(KeybindingsHelper):
self.keybinding("dash/reveal")
sleep(1)
- def ensure_visible(self):
+ def ensure_visible(self, clear_search=True):
"""
Ensures the dash is visible.
"""
if not self.get_is_visible():
self.toggle_reveal()
+ if clear_search:
+ self.clear_search()
def ensure_hidden(self):
"""
@@ -68,25 +70,40 @@ class Dash(KeybindingsHelper):
self.view.refresh_state()
return self.view.num_rows
- def reveal_application_lens(self):
+ def clear_search(self):
+ """Clear the contents of the search bar.
+
+ Assumes dash is already visible, and search bar has keyboard focus.
+
+ """
+ self._keyboard.press_and_release("Ctrl+a")
+ self._keyboard.press_and_release("Delete")
+
+ def reveal_application_lens(self, clear_search=True):
"""Reveal the application lense."""
logger.debug("Revealing application lens with Super+a.")
self._reveal_lens("lens_reveal/apps")
+ if clear_search:
+ self.clear_search()
- def reveal_music_lens(self):
+ def reveal_music_lens(self, clear_search=True):
"""Reveal the music lense."""
logger.debug("Revealing music lens with Super+m.")
self._reveal_lens("lens_reveal/music")
- def reveal_file_lens(self):
+ def reveal_file_lens(self, clear_search=True):
"""Reveal the file lense."""
logger.debug("Revealing file lens with Super+f.")
self._reveal_lens("lens_reveal/files")
+ if clear_search:
+ self.clear_search()
- def reveal_command_lens(self):
+ def reveal_command_lens(self, clear_search=True):
"""Reveal the 'run command' lens."""
logger.debug("Revealing command lens with Alt+F2.")
self._reveal_lens("lens_reveal/command")
+ if clear_search:
+ self.clear_search()
def _reveal_lens(self, binding_name):
self.keybinding_hold(binding_name)
diff --git a/tests/autopilot/autopilot/tests/__init__.py b/tests/autopilot/autopilot/tests/__init__.py
index 95afae8fc..ced286d83 100644
--- a/tests/autopilot/autopilot/tests/__init__.py
+++ b/tests/autopilot/autopilot/tests/__init__.py
@@ -18,6 +18,7 @@ from autopilot.emulators.unity.switcher import Switcher
from autopilot.emulators.unity.workspace import WorkspaceManager
from autopilot.keybindings import KeybindingsHelper
+logger = logging.getLogger(__name__)
class LoggedTestCase(TestWithScenarios, TestCase):
"""Initialize the logging for the test case."""
@@ -47,9 +48,6 @@ class LoggedTestCase(TestWithScenarios, TestCase):
super(LoggedTestCase, self).setUp()
def tearDown(self):
- Keyboard.cleanup()
- Mouse.cleanup()
-
logger = logging.getLogger()
for handler in logger.handlers:
handler.flush()
@@ -78,10 +76,6 @@ class AutopilotTestCase(LoggedTestCase, KeybindingsHelper):
'desktop-file': 'mahjongg.desktop',
'process-name': 'mahjongg',
},
- 'Text Editor' : {
- 'desktop-file': 'gedit.desktop',
- 'process-name': 'gedit'
- }
}
def setUp(self):
@@ -92,14 +86,12 @@ class AutopilotTestCase(LoggedTestCase, KeybindingsHelper):
self.switcher = Switcher()
self.workspace = WorkspaceManager()
self.addCleanup(self.workspace.switch_to, self.workspace.current_workspace)
-
- def tearDown(self):
- Keyboard.cleanup()
- Mouse.cleanup()
- super(AutopilotTestCase, self).tearDown()
+ self.addCleanup(Keyboard.cleanup)
+ self.addCleanup(Mouse.cleanup)
def start_app(self, app_name):
"""Start one of the known apps, and kill it on tear down."""
+ logger.info("Starting application '%s'", app_name)
app = self.KNOWN_APPS[app_name]
self.bamf.launch_application(app['desktop-file'])
self.addCleanup(call, ["killall", app['process-name']])
diff --git a/tests/autopilot/autopilot/tests/test_hud.py b/tests/autopilot/autopilot/tests/test_hud.py
index e52848ba5..12220b35a 100644
--- a/tests/autopilot/autopilot/tests/test_hud.py
+++ b/tests/autopilot/autopilot/tests/test_hud.py
@@ -6,13 +6,11 @@
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
-from subprocess import call
+from testtools.matchers import LessThan
from time import sleep
-from autopilot.emulators.bamf import Bamf
from autopilot.emulators.unity.hud import HudController
from autopilot.emulators.unity.launcher import Launcher
-from autopilot.emulators.X11 import Keyboard
from autopilot.tests import AutopilotTestCase
from autopilot.glibrunner import GlibRunner
@@ -21,6 +19,14 @@ class HudTests(AutopilotTestCase):
run_test_with = GlibRunner
+ def setUp(self):
+ super(HudTests, self).setUp()
+ self.hud_controller = self.get_hud_controller()
+
+ def tearDown(self):
+ super(HudTests, self).tearDown()
+ self.hud_controller.ensure_hidden()
+
def get_hud_controller(self):
controllers = HudController.get_all_instances()
self.assertEqual(1, len(controllers))
@@ -29,55 +35,47 @@ class HudTests(AutopilotTestCase):
def get_num_active_launcher_icons(self, launcher):
num_active = 0
for icon in launcher.get_launcher_icons():
- if icon.quirk_active:
+ if icon.quirk_active and icon.quirk_visible:
num_active += 1
return num_active
def test_initially_hidden(self):
- hud = self.get_hud_controller()
- self.assertFalse(hud.is_visible())
+ self.assertFalse(self.hud_controller.is_visible())
def test_reveal_hud(self):
- hud = self.get_hud_controller()
- hud.toggle_reveal()
- self.addCleanup(hud.toggle_reveal)
- self.assertTrue(hud.is_visible())
+ self.hud_controller.toggle_reveal()
+ self.assertTrue(self.hud_controller.is_visible())
def test_slow_tap_not_reveal_hud(self):
- hud = self.get_hud_controller()
- hud.toggle_reveal(tap_delay=0.3)
- self.assertFalse(hud.is_visible())
+ self.hud_controller.toggle_reveal(tap_delay=0.3)
+ self.assertFalse(self.hud_controller.is_visible())
def test_alt_f4_doesnt_show_hud(self):
- hud = self.get_hud_controller()
self.start_app('Calculator')
sleep(1)
# Do a very fast Alt+F4
self.keyboard.press_and_release("Alt+F4", 0.05)
- self.assertFalse(hud.is_visible())
+ self.assertFalse(self.hud_controller.is_visible())
def test_reveal_hud_with_no_apps(self):
"""Hud must show even with no visible applications."""
- hud = self.get_hud_controller()
-
self.keyboard.press_and_release("Ctrl+Alt+d")
self.addCleanup(self.keyboard.press_and_release, "Ctrl+Alt+d")
sleep(1)
- hud.toggle_reveal()
+ self.hud_controller.toggle_reveal()
sleep(1)
- self.assertTrue(hud.is_visible())
+ self.assertTrue(self.hud_controller.is_visible())
- hud.toggle_reveal()
+ self.hud_controller.toggle_reveal()
sleep(1)
- self.assertFalse(hud.is_visible())
+ self.assertFalse(self.hud_controller.is_visible())
def test_multiple_hud_reveal_does_not_break_launcher(self):
"""Multiple Hud reveals must not cause the launcher to set multiple
apps as active.
"""
- hud_controller = self.get_hud_controller()
launcher = Launcher()
# We need an app to switch to:
@@ -86,15 +84,15 @@ class HudTests(AutopilotTestCase):
self.start_app('Calculator')
sleep(1)
- # before we start, make sure there's only one active icon:
+ # before we start, make sure there's zero or one active icon:
num_active = self.get_num_active_launcher_icons(launcher)
- self.assertEqual(num_active, 1, "Invalid number of launcher icons active before test has run!")
+ self.assertThat(num_active, LessThan(2), "Invalid number of launcher icons active before test has run!")
# reveal and hide hud several times over:
for i in range(3):
- hud_controller.ensure_visible()
+ self.hud_controller.ensure_visible()
sleep(0.5)
- hud_controller.ensure_hidden()
+ self.hud_controller.ensure_hidden()
sleep(0.5)
# click application icons for running apps in the launcher: