diff options
| author | Thomi Richards <thomi.richards@canonical.com> | 2012-02-29 19:44:10 -0500 |
|---|---|---|
| committer | Tarmac <> | 2012-02-29 19:44:10 -0500 |
| commit | 85adf93ea77d2ec274d3ae962c609fb1c228418c (patch) | |
| tree | 7f686855626d44e866dc449f0c3e5583064cca69 | |
| parent | f4d829e2379de9c499a1623839594b340143677d (diff) | |
| parent | 9b74200dde6e76d95edb52c81ef226cd2ebfa6ce (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.py | 18 | ||||
| -rw-r--r-- | tests/autopilot/autopilot/emulators/unity/dash.py | 27 | ||||
| -rw-r--r-- | tests/autopilot/autopilot/tests/__init__.py | 16 | ||||
| -rw-r--r-- | tests/autopilot/autopilot/tests/test_hud.py | 50 |
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: |
