Back to index

unity  6.0.0
test_quicklist.py
Go to the documentation of this file.
00001 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
00002 # Copyright 2012 Canonical
00003 # Author: Thomi Richards,
00004 #         Marco Trevisan (TreviƱo)
00005 #
00006 # This program is free software: you can redistribute it and/or modify it
00007 # under the terms of the GNU General Public License version 3, as published
00008 # by the Free Software Foundation.
00009 
00010 from __future__ import absolute_import
00011 
00012 from autopilot.matchers import Eventually
00013 import os.path
00014 from testtools.matchers import Contains, Equals, NotEquals
00015 from xdg.DesktopEntry import DesktopEntry
00016 from time import sleep
00017 
00018 from unity.emulators.quicklist import QuicklistMenuItemLabel
00019 from unity.tests import UnityTestCase
00020 
00021 
00022 class QuicklistActionTests(UnityTestCase):
00023     """Tests for quicklist actions."""
00024 
00025     scenarios = [
00026         ('remmina', {'app_name': 'Remmina'}),
00027     ]
00028 
00029     def open_quicklist_for_icon(self, launcher_icon):
00030         """Open the quicklist for the given launcher icon.
00031 
00032         Returns the quicklist that was opened.
00033 
00034         """
00035         launcher = self.launcher.get_launcher_for_monitor(0)
00036         launcher.click_launcher_icon(launcher_icon, button=3)
00037         self.addCleanup(self.keyboard.press_and_release, "Escape")
00038         for i in range(10):
00039             ql = launcher_icon.get_quicklist()
00040             if ql:
00041                 return ql
00042             sleep(1)
00043 
00044     def test_quicklist_actions(self):
00045         """Test that all actions present in the destop file are shown in the quicklist."""
00046         self.start_app(self.app_name)
00047 
00048         # load the desktop file from disk:
00049         desktop_id = self.KNOWN_APPS[self.app_name]['desktop-file']
00050         desktop_file = os.path.join('/usr/share/applications', desktop_id)
00051         de = DesktopEntry(desktop_file)
00052         # get the launcher icon from the launcher:
00053         launcher_icon = self.launcher.model.get_icon_by_desktop_id(desktop_id)
00054         self.assertThat(launcher_icon, NotEquals(None))
00055 
00056         # open the icon quicklist, and get all the text labels:
00057         ql = self.open_quicklist_for_icon(launcher_icon)
00058         ql_item_texts = [i.text for i in ql.items if type(i) is QuicklistMenuItemLabel]
00059 
00060         # iterate over all the actions from the desktop file, make sure they're
00061         # present in the quicklist texts.
00062         # FIXME, this doesn't work using a locale other than English.
00063         actions = de.getActions()
00064         for action in actions:
00065             key = 'Desktop Action ' + action
00066             self.assertThat(de.content, Contains(key))
00067             name = de.content[key]['Name']
00068             self.assertThat(ql_item_texts, Contains(name))
00069 
00070     def test_quicklist_application_item_focus_last_active_window(self):
00071         """This tests shows that when you activate a quicklist application item
00072         only the last focused instance of that application is rasied.
00073 
00074         This is tested by opening 2 Mahjongg and a Calculator.
00075         Then we activate the Calculator quicklist item.
00076         Then we actiavte the Mahjongg launcher icon.
00077         """
00078         mah_win1 = self.start_app_window("Mahjongg")
00079         calc_win = self.start_app_window("Calculator")
00080         mah_win2 = self.start_app_window("Mahjongg")
00081 
00082         self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
00083 
00084         mahj_icon = self.launcher.model.get_icon_by_desktop_id(
00085             mah_win1.application.desktop_file)
00086         calc_icon = self.launcher.model.get_icon_by_desktop_id(
00087             calc_win.application.desktop_file)
00088 
00089         calc_ql = self.open_quicklist_for_icon(calc_icon)
00090         calc_ql.get_quicklist_application_item(calc_win.application.name).mouse_click()
00091 
00092         self.assertProperty(calc_win, is_focused=True)
00093         self.assertVisibleWindowStack([calc_win, mah_win2, mah_win1])
00094 
00095         mahj_ql = self.open_quicklist_for_icon(mahj_icon)
00096         mahj_ql.get_quicklist_application_item(mah_win1.application.name).mouse_click()
00097 
00098         self.assertProperty(mah_win2, is_focused=True)
00099         self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
00100 
00101     def test_quicklist_application_item_initiate_spread(self):
00102         """This tests shows that when you activate a quicklist application item
00103         when an application window is focused, the spread is initiated.
00104         """
00105         calc_win1 = self.start_app_window("Calculator")
00106         calc_win2 = self.start_app_window("Calculator")
00107         calc_app = calc_win1.application
00108 
00109         self.assertVisibleWindowStack([calc_win2, calc_win1])
00110         self.assertProperty(calc_win2, is_focused=True)
00111 
00112         calc_icon = self.launcher.model.get_icon_by_desktop_id(calc_app.desktop_file)
00113 
00114         calc_ql = self.open_quicklist_for_icon(calc_icon)
00115         app_item = calc_ql.get_quicklist_application_item(calc_app.name)
00116 
00117         self.addCleanup(self.keybinding, "spread/cancel")
00118         app_item.mouse_click()
00119         self.assertThat(self.window_manager.scale_active, Eventually(Equals(True)))
00120         self.assertThat(self.window_manager.scale_active_for_group, Eventually(Equals(True)))
00121 
00122     def test_quicklist_item_triggered_closes_dash(self):
00123         """When any quicklist item is triggered it must close the dash."""
00124 
00125         calc_win = self.start_app_window("Calculator")
00126         self.assertProperty(calc_win, is_focused=True)
00127 
00128         self.dash.ensure_visible()
00129 
00130         calc_icon = self.launcher.model.get_icon_by_desktop_id(
00131             calc_win.application.desktop_file)
00132         self.open_quicklist_for_icon(calc_icon)
00133 
00134         self.keyboard.press_and_release("Down")
00135         self.keyboard.press_and_release("Enter")
00136         self.assertThat(self.dash.visible, Eventually(Equals(False)))
00137 
00138 
00139 class QuicklistKeyNavigationTests(UnityTestCase):
00140     """Tests for the quicklist key navigation."""
00141 
00142     def setUp(self):
00143         super(QuicklistKeyNavigationTests, self).setUp()
00144 
00145         self.ql_app = self.start_app("Text Editor")
00146 
00147         self.ql_launcher_icon = self.launcher.model.get_icon_by_desktop_id(
00148             self.ql_app.desktop_file)
00149         self.assertThat(self.ql_launcher_icon, NotEquals(None))
00150 
00151         self.ql_launcher = self.launcher.get_launcher_for_monitor(0)
00152 
00153     def open_quicklist_with_mouse(self):
00154         """Opens a quicklist with the mouse."""
00155         self.ql_launcher.click_launcher_icon(self.ql_launcher_icon, button=3)
00156         self.addCleanup(self.keyboard.press_and_release, "Escape")
00157         self.quicklist = self.ql_launcher_icon.get_quicklist()
00158         self.assertThat(self.quicklist, NotEquals(None))
00159         self.quicklist.move_mouse_to_right()
00160         self.assertThat(self.quicklist.selected_item, Equals(None))
00161 
00162     def open_quicklist_with_keyboard(self):
00163         """Opens a quicklist using the keyboard."""
00164         self.screen_geo.move_mouse_to_monitor(0)
00165         self.ql_launcher.key_nav_start()
00166         self.addCleanup(self.ql_launcher.key_nav_cancel)
00167 
00168         self.ql_launcher.keyboard_select_icon(tooltip_text=self.ql_app.name)
00169         self.keybinding("launcher/keynav/open-quicklist")
00170         self.addCleanup(self.keybinding, "launcher/keynav/close-quicklist")
00171 
00172         self.assertThat(self.ql_launcher_icon.get_quicklist, Eventually(NotEquals(None)))
00173         self.quicklist = self.ql_launcher_icon.get_quicklist()
00174         self.assertThat(lambda: self.quicklist.selected_item, Eventually(NotEquals(None)))
00175 
00176     def test_keynav_selects_first_item_when_unselected(self):
00177         """Home key MUST select the first selectable item in a quicklist."""
00178         self.open_quicklist_with_mouse()
00179 
00180         self.keybinding("quicklist/keynav/first")
00181 
00182         expected_item = self.quicklist.selectable_items[0]
00183         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00184         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00185 
00186     def test_keynav_selects_first_item_when_selected(self):
00187         """Home key MUST select the first selectable item in a quicklist when
00188         another item is selected.
00189         """
00190         self.open_quicklist_with_mouse()
00191         mouse_item = self.quicklist.selectable_items[-1]
00192         mouse_item.mouse_move_to()
00193         self.assertThat(mouse_item.selected, Eventually(Equals(True)))
00194 
00195         self.keybinding("quicklist/keynav/first")
00196 
00197         expected_item = self.quicklist.selectable_items[0]
00198         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00199         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00200 
00201     def test_keynav_next_selects_first_item_when_unselected(self):
00202         """Down key MUST select the first valid item when nothing is selected."""
00203         self.open_quicklist_with_mouse()
00204 
00205         self.keybinding("quicklist/keynav/next")
00206 
00207         expected_item = self.quicklist.selectable_items[0]
00208         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00209         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00210 
00211     def test_keynav_selects_last_item_when_unselected(self):
00212         """End key MUST select the last selectable item in a quicklist."""
00213         self.open_quicklist_with_mouse()
00214 
00215         self.keybinding("quicklist/keynav/last")
00216 
00217         expected_item = self.quicklist.selectable_items[-1]
00218         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00219         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00220 
00221     def test_keynav_selects_last_item_when_selected(self):
00222         """End key MUST select the last selectable item in a quicklist when
00223         another item is selected.
00224         """
00225         self.open_quicklist_with_mouse()
00226         mouse_item = self.quicklist.selectable_items[0]
00227         mouse_item.mouse_move_to()
00228         self.assertThat(mouse_item.selected, Eventually(Equals(True)))
00229 
00230         self.keybinding("quicklist/keynav/last")
00231 
00232         expected_item = self.quicklist.selectable_items[-1]
00233         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00234         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00235 
00236     def test_keynav_prev_selects_last_item_when_unselected(self):
00237         """Up key MUST select the last valid item when nothing is selected."""
00238         self.open_quicklist_with_mouse()
00239 
00240         self.keybinding("quicklist/keynav/prev")
00241 
00242         expected_item = self.quicklist.selectable_items[-1]
00243         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00244         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00245 
00246     def test_launcher_keynav_selects_first_item(self):
00247         """The first selectable item of the quicklist must be selected when
00248         opening the quicklist using the launcher key navigation.
00249         """
00250         self.open_quicklist_with_keyboard()
00251 
00252         expected_item = self.quicklist.selectable_items[0]
00253         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00254         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00255 
00256     def test_keynav_next_selection_works(self):
00257         """Down key MUST select the next valid item."""
00258         self.open_quicklist_with_mouse()
00259 
00260         for item in self.quicklist.selectable_items:
00261             self.keybinding("quicklist/keynav/next")
00262             self.assertThat(item.selected, Eventually(Equals(True)))
00263             self.assertThat(self.quicklist.selected_item.id, Equals(item.id))
00264 
00265     def test_keynav_prev_selection_works(self):
00266         """Up key MUST select the previous valid item."""
00267         self.open_quicklist_with_mouse()
00268 
00269         for item in reversed(self.quicklist.selectable_items):
00270             self.keybinding("quicklist/keynav/prev")
00271             self.assertThat(item.selected, Eventually(Equals(True)))
00272             self.assertThat(self.quicklist.selected_item.id, Equals(item.id))
00273 
00274     def test_keynav_prev_is_cyclic(self):
00275         """Up key MUST select the last item, when the first one is selected."""
00276         self.open_quicklist_with_mouse()
00277 
00278         mouse_item = self.quicklist.selectable_items[0]
00279         mouse_item.mouse_move_to()
00280         self.assertThat(mouse_item.selected, Eventually(Equals(True)))
00281 
00282         self.keybinding("quicklist/keynav/prev")
00283         expected_item = self.quicklist.selectable_items[-1]
00284         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00285         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00286 
00287     def test_keynav_next_is_cyclic(self):
00288         """Down key MUST select the first item, when the last one is selected."""
00289         self.open_quicklist_with_mouse()
00290 
00291         mouse_item = self.quicklist.selectable_items[-1]
00292         mouse_item.mouse_move_to()
00293         self.assertThat(mouse_item.selected, Eventually(Equals(True)))
00294 
00295         self.keybinding("quicklist/keynav/next")
00296         expected_item = self.quicklist.selectable_items[0]
00297         self.assertThat(expected_item.selected, Eventually(Equals(True)))
00298         self.assertThat(self.quicklist.selected_item.id, Equals(expected_item.id))
00299 
00300     def test_keynav_mouse_interaction(self):
00301         """Tests that the interaction between key-navigation and mouse works as
00302         expected. See bug #911561.
00303         """
00304         self.open_quicklist_with_mouse()
00305         mouse_item = self.quicklist.selectable_items[-1]
00306         mouse_item.mouse_move_to()
00307         self.assertThat(mouse_item.selected, Eventually(Equals(True)))
00308 
00309         self.keybinding("quicklist/keynav/prev")
00310         sleep(.1)
00311         self.keybinding("quicklist/keynav/prev")
00312 
00313         key_item = self.quicklist.selectable_items[-3]
00314         self.assertThat(key_item.selected, Eventually(Equals(True)))
00315         self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
00316 
00317         # Moving the mouse horizontally doesn't change the selection
00318         self.mouse.move(mouse_item.x + mouse_item.width - 10, mouse_item.y + mouse_item.height / 2)
00319         self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
00320 
00321         # Moving the mouse outside doesn't change the selection
00322         self.mouse.move(mouse_item.x + mouse_item.width + 50, mouse_item.y + mouse_item.height / 2)
00323         self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id))
00324 
00325         # Moving the mouse to another entry, changes the selection
00326         mouse_item = self.quicklist.selectable_items[-2]
00327         mouse_item.mouse_move_to()
00328         self.assertThat(mouse_item.selected, Eventually(Equals(True)))
00329         self.assertThat(self.quicklist.selected_item.id, Equals(mouse_item.id))