Back to index

unity  6.0.0
test_panel.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: Marco Trevisan (TreviƱo)
00004 #
00005 # This program is free software: you can redistribute it and/or modify it
00006 # under the terms of the GNU General Public License version 3, as published
00007 # by the Free Software Foundation.
00008 
00009 from __future__ import absolute_import
00010 
00011 from autopilot.emulators.X11 import ScreenGeometry
00012 from autopilot.emulators.bamf import BamfWindow
00013 from autopilot.matchers import Eventually
00014 import logging
00015 import os
00016 from testtools.matchers import Equals,  GreaterThan, NotEquals
00017 from time import sleep
00018 
00019 from unity.emulators.panel import IndicatorEntry
00020 from unity.tests import UnityTestCase
00021 
00022 
00023 logger = logging.getLogger(__name__)
00024 
00025 
00026 def _make_monitor_scenarios():
00027     num_monitors = ScreenGeometry().get_num_monitors()
00028     scenarios = []
00029 
00030     if num_monitors == 1:
00031         scenarios = [('Single Monitor', {'panel_monitor': 0})]
00032     else:
00033         for i in range(num_monitors):
00034             scenarios += [('Monitor %d' % (i), {'panel_monitor': i})]
00035 
00036     return scenarios
00037 
00038 
00039 class PanelTestsBase(UnityTestCase):
00040 
00041     panel_monitor = 0
00042 
00043     def setUp(self):
00044         super(PanelTestsBase, self).setUp()
00045         self.panel = self.panels.get_panel_for_monitor(self.panel_monitor)
00046         self.panel.move_mouse_below_the_panel()
00047         self.addCleanup(self.panel.move_mouse_below_the_panel)
00048 
00049     def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True):
00050         """Opens a new instance of the requested application, ensuring that only
00051         one window is opened.
00052 
00053         Returns the opened BamfWindow
00054 
00055         """
00056         self.close_all_app(app_name)
00057         app = self.start_app(app_name, locale="C")
00058 
00059         [app_win] = app.get_windows()
00060 
00061         app_win.set_focus()
00062         self.assertTrue(app.is_active)
00063         self.assertTrue(app_win.is_focused)
00064         self.assertThat(app.desktop_file, Equals(app_win.application.desktop_file))
00065 
00066         if move_to_monitor:
00067             self.move_window_to_panel_monitor(app_win)
00068 
00069         if maximized and not app_win.is_maximized:
00070             self.keybinding("window/maximize")
00071             self.addCleanup(self.keybinding, "window/restore")
00072         elif not maximized and app_win.is_maximized:
00073             self.keybinding("window/restore")
00074             self.addCleanup(self.keybinding, "window/maximize")
00075 
00076         app_win.set_focus()
00077         sleep(.25)
00078 
00079         self.assertThat(app_win.is_maximized, Equals(maximized))
00080 
00081         return app_win
00082 
00083     def move_window_to_panel_monitor(self, window, restore_position=False):
00084         """Drags a window to another monitor, eventually restoring it before"""
00085         if not isinstance(window, BamfWindow):
00086             raise TypeError("Window must be a BamfWindow")
00087 
00088         if window.monitor == self.panel_monitor:
00089             return
00090 
00091         if window.is_maximized:
00092             self.keybinding("window/restore")
00093             self.addCleanup(self.keybinding, "window/maximize")
00094             sleep(.1)
00095 
00096         if restore_position:
00097             self.addCleanup(self.screen_geo.drag_window_to_monitor, window, window.monitor)
00098 
00099         self.screen_geo.drag_window_to_monitor(window, self.panel_monitor)
00100         sleep(.25)
00101         self.assertThat(window.monitor, Equals(self.panel_monitor))
00102 
00103     def mouse_open_indicator(self, indicator):
00104         """This is an utility function that safely opens an indicator,
00105         ensuring that it is closed at the end of the test and that the pointer
00106         is moved outside the panel area (to make the panel hide the menus)
00107         """
00108         if not isinstance(indicator, IndicatorEntry):
00109             raise TypeError("Window must be a IndicatorEntry")
00110 
00111         indicator.mouse_click()
00112         self.addCleanup(self.panel.move_mouse_below_the_panel)
00113         self.addCleanup(self.keyboard.press_and_release, "Escape")
00114         self.assertThat(indicator.active, Eventually(Equals(True)))
00115 
00116     def assert_win_buttons_in_overlay_mode(self, overlay_mode):
00117         """Assert that there are three panel window buttons and all of them are
00118         in the specified overlay mode.
00119 
00120         """
00121         if type(overlay_mode) is not bool:
00122             raise TypeError("overlay_mode must be True or False")
00123 
00124         buttons = self.panel.window_buttons.get_buttons()
00125         self.assertThat(len(buttons), Equals(3))
00126         for button in buttons:
00127             self.assertThat(button.overlay_mode, Eventually(Equals(overlay_mode)))
00128 
00129     def assert_no_window_open_with_xid(self, x_id):
00130         """Assert that Bamf doesn't know of any open windows with the given xid."""
00131         # We can't check text_win.closed since we've just destroyed the window.
00132         # Instead we make sure no window with it's x_id exists.
00133         refresh_fn = lambda: [w for w in self.bamf.get_open_windows() if w.x_id == x_id]
00134         self.assertThat(refresh_fn, Eventually(Equals([])))
00135 
00136     def sleep_menu_settle_period(self):
00137         """Sleep long enough for the menus to fade in and fade out again."""
00138         sleep(self.panel.menus.fadein_duration / 1000.0)
00139         sleep(self.panel.menus.discovery_duration)
00140         sleep(self.panel.menus.fadeout_duration / 1000.0)
00141 
00142 
00143 class PanelTitleTests(PanelTestsBase):
00144 
00145     scenarios = _make_monitor_scenarios()
00146 
00147     def test_panel_title_on_empty_desktop(self):
00148         """With no windows shown, the panel must display the default title."""
00149         self.window_manager.enter_show_desktop()
00150         self.addCleanup(self.window_manager.leave_show_desktop)
00151 
00152         self.assertThat(self.panel.desktop_is_active, Eventually(Equals(True)))
00153 
00154     def test_panel_title_with_restored_application(self):
00155         """Panel must display application name for a non-maximised application."""
00156         calc_win = self.open_new_application_window("Calculator", maximized=False)
00157 
00158         self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name)))
00159 
00160     def test_panel_title_with_maximized_application(self):
00161         """Panel must display application name for a maximised application."""
00162         text_win = self.open_new_application_window("Text Editor", maximized=True)
00163 
00164         self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))
00165 
00166     def test_panel_title_with_maximized_window_restored_child(self):
00167         """Tests the title shown in the panel when opening the restored child of
00168         a maximized application.
00169         """
00170         text_win = self.open_new_application_window("Text Editor", maximized=True)
00171 
00172         # Ctrl+h opens the replace dialog.
00173         self.keyboard.press_and_release("Ctrl+h")
00174         self.addCleanup(self.keyboard.press_and_release, "Escape")
00175 
00176         self.assertThat(lambda: len(text_win.application.get_windows()),
00177                         Eventually(Equals(2)))
00178         self.assertThat(self.panel.title, Equals(text_win.application.name))
00179 
00180     def test_panel_shows_app_title_with_maximised_app(self):
00181         """Tests app titles are shown in the panel with a non-focused maximized application."""
00182         self.open_new_application_window("Text Editor", maximized=True)
00183         calc_win = self.open_new_application_window("Calculator", maximized=False)
00184 
00185         self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name)))
00186 
00187     def test_panel_title_updates_when_switching_to_maximized_app(self):
00188         """Switching to a maximised app from a restored one must update the panel title."""
00189         text_win = self.open_new_application_window("Text Editor", maximized=True)
00190         self.open_new_application_window("Calculator", maximized=False)
00191 
00192         icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file)
00193         launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor)
00194         launcher.click_launcher_icon(icon)
00195 
00196         self.assertProperty(text_win, is_focused=True)
00197         self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))
00198 
00199     def test_panel_title_updates_on_maximized_window_title_changes(self):
00200         """Panel title must change when the title of a maximized application changes."""
00201         text_win = self.open_new_application_window("Text Editor", maximized=True)
00202         old_title = text_win.title
00203 
00204         text_win.set_focus()
00205         self.keyboard.type("Unity rocks!")
00206         self.keyboard.press_and_release("Ctrl+S")
00207         sleep(.25)
00208         self.keyboard.type("/tmp/autopilot-awesome-test.txt")
00209         self.keyboard.press_and_release("Return")
00210         self.addCleanup(os.remove, "/tmp/autopilot-awesome-test.txt")
00211 
00212         self.assertThat(lambda: text_win.title, Eventually(NotEquals(old_title)))
00213         self.assertThat(self.panel.title, Eventually(Equals(text_win.title)))
00214 
00215 
00216 class PanelWindowButtonsTests(PanelTestsBase):
00217 
00218     scenarios = _make_monitor_scenarios()
00219 
00220     def setUp(self):
00221         super(PanelWindowButtonsTests, self).setUp()
00222         # Locked Launchers on all monitors
00223         self.set_unity_option('num_launchers', 0)
00224         self.set_unity_option('launcher_hide_mode', 0)
00225 
00226     def test_window_buttons_dont_show_on_empty_desktop(self):
00227         """Tests that the window buttons are not shown on clean desktop."""
00228         # THis initially used Show Desktop mode, but it's very buggy from within
00229         # autopilot. We assume that workspace 2 is empty (which is safe for the
00230         # jenkins runs at least.)
00231         initial_workspace = self.workspace.current_workspace
00232         self.addCleanup(self.workspace.switch_to, initial_workspace)
00233 
00234         self.workspace.switch_to(2)
00235         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00236 
00237         self.panel.move_mouse_over_window_buttons()
00238         # Sleep twice as long as the timeout, just to be sure. timeout is in
00239         # mS, we need seconds, hence the divide by 500.0
00240         sleep(self.panel.menus.fadein_duration / 500.0)
00241         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00242 
00243     def test_window_buttons_dont_show_for_restored_window(self):
00244         """Window buttons must not show for a restored window."""
00245         self.open_new_application_window("Calculator")
00246         self.panel.move_mouse_below_the_panel()
00247 
00248         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00249 
00250     def test_window_buttons_dont_show_for_restored_window_with_mouse_in_panel(self):
00251         """Window buttons must not show for a restored window with the mouse in
00252         the panel."""
00253         self.open_new_application_window("Calculator")
00254         self.panel.move_mouse_over_window_buttons()
00255 
00256         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00257 
00258     def test_window_buttons_dont_show_for_maximized_window_on_mouse_out(self):
00259         """Window buttons must not show for a maximized window when the mouse is
00260         outside the panel.
00261         """
00262         self.open_new_application_window("Text Editor", maximized=True)
00263 
00264         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00265 
00266     def test_window_buttons_show_for_maximized_window_on_mouse_in(self):
00267         """Window buttons must show when a maximized window is focused and the
00268         mouse is over the menu-view panel areas.
00269 
00270         """
00271         self.open_new_application_window("Text Editor", maximized=True)
00272         self.panel.move_mouse_over_window_buttons()
00273 
00274         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00275         self.assert_win_buttons_in_overlay_mode(False)
00276 
00277     def test_window_buttons_show_with_dash(self):
00278         """Window buttons must be shown when the dash is open."""
00279         self.dash.ensure_visible()
00280         self.addCleanup(self.dash.ensure_hidden)
00281 
00282         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00283         self.assert_win_buttons_in_overlay_mode(True)
00284 
00285     def test_window_buttons_show_with_hud(self):
00286         """Window buttons must be shown when the HUD is open."""
00287         self.hud.ensure_visible()
00288         self.addCleanup(self.hud.ensure_hidden)
00289 
00290         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00291         self.assert_win_buttons_in_overlay_mode(True)
00292 
00293     def test_window_buttons_update_visual_state(self):
00294         """Window button must update its state in response to mouse events."""
00295         self.hud.ensure_visible()
00296         self.addCleanup(self.hud.ensure_hidden)
00297         button = self.panel.window_buttons.close
00298 
00299         self.assertThat(button.visual_state, Eventually(Equals("normal")))
00300 
00301         button.mouse_move_to()
00302         self.assertThat(button.visual_state, Eventually(Equals("prelight")))
00303 
00304         self.mouse.press()
00305         self.addCleanup(self.mouse.release)
00306         self.assertThat(button.visual_state, Eventually(Equals("pressed")))
00307 
00308     def test_window_buttons_cancel(self):
00309         """Window buttons must ignore clicks when the mouse released outside
00310         their area.
00311         """
00312         self.hud.ensure_visible()
00313         button = self.panel.window_buttons.close
00314 
00315         # FIXME: THere's a bug in unity that prevents us from doing:
00316         # self.addCleanup(self.hud.ensure_hidden)
00317         # SO we do this instead. The bug is:
00318         #
00319         # https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1021087
00320         #
00321         # Once that's fixed the next two lines can be removed, and the one above
00322         # added instead.
00323         self.addCleanup(self.assertThat, self.hud.visible, Eventually(Equals(False)))
00324         self.addCleanup(button.mouse_click)
00325 
00326         button.mouse_move_to()
00327         self.mouse.press()
00328         self.assertThat(button.visual_state, Eventually(Equals("pressed")))
00329         self.panel.move_mouse_below_the_panel()
00330         self.mouse.release()
00331 
00332         self.assertThat(button.visual_state, Eventually(Equals("normal")))
00333         self.assertThat(self.hud.visible, Eventually(Equals(True)))
00334 
00335     def test_window_buttons_close_button_works_for_window(self):
00336         """Close window button must actually closes a window."""
00337         text_win = self.open_new_application_window("Text Editor",
00338             maximized=True,
00339             move_to_monitor=True)
00340         win_xid = text_win.x_id
00341 
00342         self.panel.window_buttons.close.mouse_click()
00343         self.assert_no_window_open_with_xid(win_xid)
00344 
00345     def test_window_buttons_close_follows_fitts_law(self):
00346         """Tests that the 'Close' button is activated when clicking at 0,0.
00347 
00348         See bug #839690
00349         """
00350         text_win = self.open_new_application_window("Text Editor",
00351             maximized=True,
00352             move_to_monitor=True)
00353         win_xid = text_win.x_id
00354 
00355         self.panel.move_mouse_over_window_buttons()
00356         screen_x, screen_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[:2]
00357         self.mouse.move(screen_x, screen_y)
00358         self.mouse.click()
00359 
00360         self.assert_no_window_open_with_xid(win_xid)
00361 
00362     def test_window_buttons_minimize_button_works_for_window(self):
00363         """Tests that the window button 'Minimize' actually minimizes a window."""
00364         text_win = self.open_new_application_window("Text Editor",
00365             maximized=True,
00366             move_to_monitor=True)
00367 
00368         self.panel.window_buttons.minimize.mouse_click()
00369 
00370         self.assertThat(lambda: text_win.is_hidden, Eventually(Equals(True)))
00371 
00372     def test_window_buttons_minimize_follows_fitts_law(self):
00373         """Tests that the 'Minimize' button is conform to Fitts's Law.
00374 
00375         See bug #839690
00376         """
00377         text_win = self.open_new_application_window("Text Editor",
00378             maximized=True,
00379             move_to_monitor=True)
00380 
00381         self.panel.move_mouse_over_window_buttons()
00382         button = self.panel.window_buttons.minimize
00383         target_x = button.x + button.width / 2
00384         target_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[1]
00385         self.mouse.move(target_x, target_y)
00386         self.mouse.click()
00387 
00388         self.assertThat(lambda: text_win.is_hidden, Eventually(Equals(True)))
00389 
00390     def test_window_buttons_unmaximize_button_works_for_window(self):
00391         """Tests that the window button 'Unmaximize' actually unmaximizes a window."""
00392         text_win = self.open_new_application_window("Text Editor",
00393             maximized=True,
00394             move_to_monitor=True)
00395 
00396         self.panel.window_buttons.unmaximize.mouse_click()
00397 
00398         self.assertProperties(text_win, is_maximized=False, is_focused=True)
00399         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00400 
00401     def test_window_buttons_unmaximize_follows_fitts_law(self):
00402         """Tests that the 'Unmaximize' button is conform to Fitts's Law.
00403 
00404         See bug #839690
00405         """
00406         text_win = self.open_new_application_window("Text Editor",
00407             maximized=True,
00408             move_to_monitor=True)
00409 
00410         button = self.panel.window_buttons.unmaximize
00411         button.mouse_move_to()
00412         target_x = button.x + button.width / 2
00413         target_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[1]
00414         self.mouse.move(target_x, target_y)
00415         sleep(1)
00416         self.mouse.click()
00417 
00418         self.assertThat(lambda: text_win.is_maximized, Eventually(Equals(False)))
00419 
00420     def test_window_buttons_close_button_works_for_hud(self):
00421         """Tests that the window 'Close' actually closes the HUD."""
00422         self.hud.ensure_visible()
00423         self.addCleanup(self.hud.ensure_hidden)
00424 
00425         self.panel.window_buttons.close.mouse_click()
00426         self.assertThat(self.hud.visible, Eventually(Equals(False)))
00427 
00428     def test_minimize_button_disabled_for_hud(self):
00429         """Minimize button must be disabled for the HUD."""
00430         self.hud.ensure_visible()
00431         self.addCleanup(self.hud.ensure_hidden)
00432 
00433         self.assertThat(self.panel.window_buttons.minimize.enabled, Eventually(Equals(False)))
00434 
00435     def test_minimize_button_does_nothing_for_hud(self):
00436         """Minimize button must not affect the Hud."""
00437         self.hud.ensure_visible()
00438         # FIXME: When this bug is fixed:
00439         #
00440         # https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1021087
00441         #
00442         # We can replace the following line with:
00443         # self.addCleanup(self.hud.ensure_hidden)
00444         self.addCleanup(self.panel.window_buttons.close.mouse_click)
00445         self.panel.window_buttons.minimize.mouse_click()
00446 
00447         self.assertThat(self.hud.visible, Eventually(Equals(True)))
00448 
00449     def test_maximize_button_disabled_for_hud(self):
00450         """Maximize button must be disabled for the HUD."""
00451         self.hud.ensure_visible()
00452         self.addCleanup(self.hud.ensure_hidden)
00453 
00454         self.assertThat(self.panel.window_buttons.maximize.enabled, Eventually(Equals(False)))
00455 
00456     def test_maximize_button_does_nothing_for_hud(self):
00457         """Maximize button must not affect the Hud."""
00458         self.hud.ensure_visible()
00459         # FIXME: When this bug is fixed:
00460         #
00461         # https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1021087
00462         #
00463         # We can replace the following line with:
00464         # self.addCleanup(self.hud.ensure_hidden)
00465         self.addCleanup(self.panel.window_buttons.close.mouse_click)
00466         self.panel.window_buttons.maximize.mouse_click()
00467 
00468         self.assertThat(self.hud.visible, Eventually(Equals(True)))
00469 
00470     def test_hud_maximize_button_does_not_change_dash_form_factor(self):
00471         """Clicking on the 'Maximize' button of the HUD must not change the dash
00472         layout.
00473 
00474         See bug #939054
00475         """
00476         inital_form_factor = self.dash.view.form_factor
00477         self.hud.ensure_visible()
00478         # FIXME: When this bug is fixed:
00479         #
00480         # https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1021087
00481         #
00482         # We can replace the following line with:
00483         # self.addCleanup(self.hud.ensure_hidden)
00484         self.addCleanup(self.panel.window_buttons.close.mouse_click)
00485 
00486         self.panel.window_buttons.maximize.mouse_click()
00487         # long sleep here to make sure that any change that might happen will
00488         # have already happened.
00489         sleep(5)
00490         self.assertThat(self.dash.view.form_factor, Equals(inital_form_factor))
00491 
00492     def test_window_buttons_close_button_works_for_dash(self):
00493         """Tests that the window 'Close' actually closes the Dash."""
00494         self.dash.ensure_visible()
00495         self.addCleanup(self.dash.ensure_hidden)
00496         self.panel.window_buttons.close.mouse_click()
00497 
00498         self.assertThat(self.dash.visible, Eventually(Equals(False)))
00499 
00500     def test_minimize_button_disabled_for_dash(self):
00501         """Tests that the 'Minimize' button is disabled for the dash."""
00502         self.dash.ensure_visible()
00503         self.addCleanup(self.dash.ensure_hidden)
00504 
00505         self.assertThat(self.panel.window_buttons.minimize.enabled, Eventually(Equals(False)))
00506 
00507     def test_minimize_button_does_nothing_for_dash(self):
00508         """Tests that the 'Minimize' button is disabled for the dash."""
00509         self.dash.ensure_visible()
00510         self.addCleanup(self.dash.ensure_hidden)
00511 
00512         self.panel.window_buttons.minimize.mouse_click()
00513         sleep(5)
00514         self.assertThat(self.dash.visible, Eventually(Equals(True)))
00515 
00516     def test_window_buttons_maximization_buttons_works_for_dash(self):
00517         """'Maximize' and 'Restore' buttons (when both enabled) must work as expected."""
00518         # Mega-TODO:
00519         #
00520         # This test is terrible. The docstring is terrible. The test id is terrible.
00521         # Someone needs to split this into several smaller tests. However, I'm
00522         # not doing that in this branch. Consider this an invitation to split
00523         # this test out and make it suck less.
00524         #
00525         # For your sanity I have annotated it with comments.
00526         self.dash.ensure_visible()
00527         self.addCleanup(self.panel.window_buttons.close.mouse_click)
00528 
00529         unmaximize = self.panel.window_buttons.unmaximize
00530         maximize = self.panel.window_buttons.maximize
00531 
00532         # "netbook" means "dash is maximised"
00533         dash_maximised = (self.dash.view.form_factor == "netbook")
00534 
00535         # this if statement will trigger only when we're on very small screens,
00536         # where it doesn't make sense to have the dash anything other than
00537         # maximised.
00538         if dash_maximised and not unmaximize.enabled:
00539             unmaximize.mouse_click()
00540             # nice long sleep to make sure that any changes have time to process.
00541             sleep(5)
00542             self.assertThat(self.dash.view.form_factor, Equals("netbook"))
00543         else:
00544             # we are able to resize the dash.
00545             # maximise and unmaximise (restore) buttons are shown in the same place
00546             # but only one is shown at once:
00547             if maximize.visible:
00548                 active_button = maximize
00549                 inactive_button = unmaximize
00550             else:
00551                 active_button = unmaximize
00552                 inactive_button = maximize
00553 
00554             self.assertThat(active_button.visible, Eventually(Equals(True)))
00555             self.assertThat(active_button.sensitive, Eventually(Equals(True)))
00556             self.assertThat(active_button.enabled, Eventually(Equals(True)))
00557             self.assertThat(inactive_button.visible, Eventually(Equals(False)))
00558 
00559             self.addCleanup(inactive_button.mouse_click)
00560             active_button.mouse_click()
00561 
00562             self.assertThat(inactive_button.visible, Eventually(Equals(True)))
00563             self.assertThat(inactive_button.sensitive, Eventually(Equals(True)))
00564             self.assertThat(inactive_button.enabled, Eventually(Equals(True)))
00565             self.assertThat(active_button.visible, Eventually(Equals(False)))
00566 
00567             if dash_maximised:
00568                 self.assertThat(self.dash.view.form_factor, Eventually(Equals("desktop")))
00569             else:
00570                 self.assertThat(self.dash.view.form_factor, Eventually(Equals("netbook")))
00571 
00572             self.addCleanup(active_button.mouse_click)
00573             inactive_button.mouse_click()
00574 
00575             self.assertThat(active_button.visible, Eventually(Equals(True)))
00576             self.assertThat(inactive_button.visible, Eventually(Equals(False)))
00577 
00578             if dash_maximised:
00579                 self.assertThat(self.dash.view.form_factor, Eventually(Equals("netbook")))
00580             else:
00581                 self.assertThat(self.dash.view.form_factor, Eventually(Equals("desktop")))
00582 
00583     def test_minimize_button_disabled_for_non_minimizable_windows(self):
00584         """Minimize button must be disabled for windows that don't support minimization."""
00585         text_win = self.open_new_application_window("Text Editor",
00586             maximized=False,
00587             move_to_monitor=True)
00588 
00589         self.keyboard.press_and_release("Ctrl+S")
00590         self.addCleanup(self.keyboard.press_and_release, "Escape")
00591 
00592         wins = text_win.application.get_windows()
00593         self.assertThat(len(wins), Equals(2))
00594         [target_win] = [w for w in wins if w.x_id != text_win.x_id]
00595         self.move_window_to_panel_monitor(target_win, restore_position=False)
00596 
00597         self.keybinding("window/maximize")
00598         self.assertThat(lambda: target_win.is_maximized, Eventually(Equals(True)))
00599 
00600         self.assertThat(self.panel.window_buttons.close.enabled, Eventually(Equals(True)))
00601         self.assertThat(self.panel.window_buttons.minimize.enabled, Eventually(Equals(False)))
00602 
00603     def test_window_buttons_show_when_indicator_active_and_mouse_over_panel(self):
00604         """Window buttons must be shown when mouse is over panel area with an
00605         indicator open.
00606         """
00607         self.open_new_application_window("Text Editor",
00608             maximized=True,
00609             move_to_monitor=True)
00610 
00611         indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session-devices")
00612         self.mouse_open_indicator(indicator)
00613         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00614 
00615         self.panel.move_mouse_below_the_panel()
00616         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00617 
00618         self.panel.move_mouse_over_grab_area()
00619         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00620 
00621     def test_window_buttons_show_when_holding_show_menu_key(self):
00622         """Window buttons must show when we press the show-menu keybinding."""
00623         self.open_new_application_window("Text Editor",
00624             maximized=True,
00625             move_to_monitor=True)
00626 
00627         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00628 
00629         self.keybinding_hold("panel/show_menus")
00630         self.addCleanup(self.keybinding_release, "panel/show_menus")
00631 
00632         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00633 
00634         self.keybinding_release("panel/show_menus")
00635         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00636 
00637     def test_window_buttons_cant_accept_keynav_focus(self):
00638         """On a mouse down event over the window buttons
00639         you must still be able to type into the Hud.
00640 
00641         """
00642         self.hud.ensure_visible()
00643         self.addCleanup(self.hud.ensure_hidden)
00644 
00645         self.keyboard.type("Hello")
00646         self.panel.window_buttons.minimize.mouse_click()
00647         self.keyboard.type("World")
00648 
00649         self.assertThat(self.hud.search_string, Eventually(Equals("HelloWorld")))
00650 
00651 
00652 class PanelHoverTests(PanelTestsBase):
00653     """Tests with the mouse pointer hovering the panel area."""
00654 
00655     scenarios = _make_monitor_scenarios()
00656 
00657     def test_only_menus_show_for_restored_window_on_mouse_in_window_btn_area(self):
00658         """Restored windows should only show menus when the mouse is in the window
00659         button area.
00660         """
00661         self.open_new_application_window("Calculator",
00662             maximized=False,
00663             move_to_monitor=True)
00664         self.sleep_menu_settle_period()
00665 
00666         self.panel.move_mouse_over_window_buttons()
00667 
00668         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00669         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00670 
00671     def test_only_menus_show_for_restored_window_on_mouse_in_menu_area(self):
00672         """Restored windows should only show menus when the mouse is in the window
00673         menu area.
00674         """
00675         self.open_new_application_window("Calculator",
00676             maximized=False,
00677             move_to_monitor=True)
00678         self.sleep_menu_settle_period()
00679 
00680         self.panel.move_mouse_over_menus()
00681 
00682         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00683         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00684 
00685     def test_only_menus_show_for_restored_window_on_mouse_in_grab_area(self):
00686         """Restored windows should only show menus when the mouse is in the panel
00687         grab area.
00688         """
00689         self.open_new_application_window("Calculator",
00690             maximized=False,
00691             move_to_monitor=True)
00692         self.sleep_menu_settle_period()
00693 
00694         if self.panel.grab_area.width <= 0:
00695             self.skipTest("Grab area is too small to run test!")
00696 
00697         self.panel.move_mouse_over_grab_area()
00698 
00699         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00700         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00701 
00702     def test_hovering_over_indicators_does_not_show_app_menus(self):
00703         """Hovering the mouse over the indicators must not show app menus."""
00704         self.open_new_application_window("Calculator",
00705             maximized=False,
00706             move_to_monitor=True)
00707         self.sleep_menu_settle_period()
00708 
00709         self.panel.move_mouse_over_menus()
00710         # This assert is repeated from above, but we use it to make sure that
00711         # the menus are shown before we move over the indicators.
00712         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00713 
00714         self.panel.move_mouse_over_indicators()
00715 
00716         self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))
00717 
00718     def test_menus_show_for_maximized_window_on_mouse_in_btn_area(self):
00719         """Menus and window buttons must be shown when the mouse is in the window
00720         button area for a maximised application.
00721         """
00722         self.open_new_application_window("Text Editor",
00723             maximized=True,
00724             move_to_monitor=True)
00725         self.sleep_menu_settle_period()
00726 
00727         self.panel.move_mouse_over_window_buttons()
00728 
00729         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00730         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00731 
00732     def test_menus_show_for_maximized_window_on_mouse_in_menu_area(self):
00733         """Menus and window buttons must be shown when the mouse is in the menu
00734         area for a maximised application.
00735         """
00736         self.open_new_application_window("Text Editor",
00737             maximized=True,
00738             move_to_monitor=True)
00739         self.sleep_menu_settle_period()
00740 
00741         self.panel.move_mouse_over_menus()
00742 
00743         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00744         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00745 
00746     def test_menus_show_for_maximized_window_on_mouse_in_grab_area(self):
00747         """Menus and window buttons must be shown when the mouse is in the grab
00748         area for a maximised application.
00749         """
00750         if self.panel.grab_area.width <= 0:
00751             self.skipTest("Grab area is too small to run this test!")
00752 
00753         self.open_new_application_window("Text Editor",
00754             maximized=True,
00755             move_to_monitor=True)
00756         self.sleep_menu_settle_period()
00757 
00758         self.panel.move_mouse_over_grab_area()
00759 
00760         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00761         self.assertTrue(self.panel.menus_shown, Eventually(Equals(True)))
00762 
00763     def test_menus_and_btns_hidden_with_mouse_over_indicators(self):
00764         """Hovering the mouse over the indicators must hide the menus and window
00765         buttons.
00766         """
00767         self.open_new_application_window("Text Editor",
00768             maximized=True,
00769             move_to_monitor=True)
00770         self.sleep_menu_settle_period()
00771 
00772         self.panel.move_mouse_over_menus()
00773         # We use this assert to make sure that the menus are visible before we
00774         # move the mouse:
00775         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True)))
00776 
00777         self.panel.move_mouse_over_indicators()
00778 
00779         self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False)))
00780         self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))
00781 
00782     def test_hovering_indicators_open_menus(self):
00783         """Opening an indicator entry, and then hovering on other entries must
00784         open them.
00785         """
00786         self.open_new_application_window("Text Editor")
00787         entries = self.panel.get_indicator_entries(include_hidden_menus=True)
00788 
00789         self.assertThat(len(entries), GreaterThan(0))
00790         self.mouse_open_indicator(entries[0])
00791 
00792         for entry in entries:
00793             entry.mouse_move_to()
00794             self.assertThat(entry.active, Eventually(Equals(True)))
00795             self.assertThat(entry.menu_y, Eventually(NotEquals(0)))
00796 
00797 
00798 class PanelMenuTests(PanelTestsBase):
00799 
00800     scenarios = _make_monitor_scenarios()
00801 
00802     def test_menus_are_added_on_new_application(self):
00803         """Tests that menus are added when a new application is opened."""
00804         self.open_new_application_window("Calculator")
00805 
00806         refresh_fn = lambda: len(self.panel.menus.get_entries())
00807         self.assertThat(refresh_fn, Eventually(Equals(3)))
00808 
00809         menu_view = self.panel.menus
00810         self.assertThat(lambda: menu_view.get_menu_by_label("_Calculator"), Eventually(NotEquals(None)))
00811         self.assertThat(lambda: menu_view.get_menu_by_label("_Mode"), Eventually(NotEquals(None)))
00812         self.assertThat(lambda: menu_view.get_menu_by_label("_Help"), Eventually(NotEquals(None)))
00813 
00814     def test_menus_are_not_shown_if_the_application_has_no_menus(self):
00815         """Tests that if an application has no menus, then they are not
00816         shown or added.
00817         """
00818         # TODO: This doesn't test what it says on the tin. Setting MENUPROXY to ''
00819         # just makes the menu appear inside the app. That's fine, but it's not
00820         # what is described in the docstring or test id.
00821         self.patch_environment("UBUNTU_MENUPROXY", "")
00822         calc_win = self.open_new_application_window("Calculator")
00823 
00824         self.assertThat(lambda: len(self.panel.menus.get_entries()), Eventually(Equals(0)))
00825 
00826         self.panel.move_mouse_over_grab_area()
00827         self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name)))
00828 
00829     def test_menus_shows_when_new_application_is_opened(self):
00830         """This tests the menu discovery feature on new application."""
00831 
00832         self.open_new_application_window("Calculator")
00833         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00834         self.sleep_menu_settle_period()
00835         self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))
00836 
00837     def test_menus_dont_show_if_a_new_application_window_is_opened(self):
00838         """This tests the menu discovery feature on new window for a know application."""
00839         self.open_new_application_window("Calculator")
00840         self.sleep_menu_settle_period()
00841 
00842         self.start_app("Calculator")
00843         sleep(self.panel.menus.fadein_duration / 1000.0)
00844         # Not using Eventually here since this is time-critical. Need to work
00845         # out a better way to do this.
00846         self.assertThat(self.panel.menus_shown, Equals(False))
00847 
00848     def test_menus_dont_show_for_restored_window_on_mouse_out(self):
00849         """Restored window menus must not show when the mouse is outside the
00850         panel menu area.
00851         """
00852         self.open_new_application_window("Calculator")
00853         self.sleep_menu_settle_period()
00854 
00855         self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))
00856 
00857     def test_menus_show_for_restored_window_on_mouse_in(self):
00858         """Restored window menus must show only when the mouse is over the panel
00859         menu area.
00860         """
00861         self.open_new_application_window("Calculator")
00862         self.sleep_menu_settle_period()
00863 
00864         self.panel.move_mouse_over_menus()
00865 
00866         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00867 
00868     def test_menus_dont_show_for_maximized_window_on_mouse_out(self):
00869         """Maximized window menus must not show when the mouse is outside the
00870         panel menu area.
00871         """
00872         self.open_new_application_window("Text Editor", maximized=True)
00873 
00874         self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))
00875 
00876     def test_menus_show_for_maximized_window_on_mouse_in(self):
00877         """Maximized window menus must only show when the mouse is over the
00878         panel menu area.
00879         """
00880         self.open_new_application_window("Text Editor", maximized=True)
00881         self.sleep_menu_settle_period()
00882 
00883         self.panel.move_mouse_over_menus()
00884         self.assertThat(self.panel.menus_shown, Eventually(Equals(True)))
00885 
00886     def test_menus_dont_show_with_dash(self):
00887         """Tests that menus are not showing when opening the dash."""
00888         self.open_new_application_window("Text Editor", maximized=True)
00889         self.dash.ensure_visible()
00890         self.addCleanup(self.dash.ensure_hidden)
00891 
00892         self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))
00893 
00894 
00895     def test_menus_dont_show_with_hud(self):
00896         """Tests that menus are not showing when opening the HUD."""
00897         self.open_new_application_window("Text Editor", maximized=True)
00898         self.hud.ensure_visible()
00899         self.addCleanup(self.hud.ensure_hidden)
00900 
00901         self.assertThat(self.panel.menus_shown, Eventually(Equals(False)))
00902 
00903 
00904 class PanelIndicatorEntryTests(PanelTestsBase):
00905     """Tests for the indicator entries, including both menu and indicators."""
00906 
00907     scenarios = _make_monitor_scenarios()
00908 
00909     def test_menu_opens_on_click(self):
00910         """Tests that clicking on a menu entry, opens a menu."""
00911         self.open_new_application_window("Calculator")
00912         menu_entry = self.panel.menus.get_entries()[0]
00913         self.mouse_open_indicator(menu_entry)
00914 
00915         self.assertThat(menu_entry.active, Eventually(Equals(True)))
00916         self.assertThat(menu_entry.menu_x, Eventually(Equals(menu_entry.x)))
00917         self.assertThat(menu_entry.menu_y, Eventually(Equals(self.panel.height)))
00918 
00919     def test_menu_opens_closes_on_click(self):
00920         """Clicking on an open menu entru must close it again."""
00921         self.open_new_application_window("Calculator")
00922         menu_entry = self.panel.menus.get_entries()[0]
00923         self.mouse_open_indicator(menu_entry)
00924 
00925         # This assert is for timing purposes only:
00926         self.assertThat(menu_entry.active, Eventually(Equals(True)))
00927         self.mouse.click()
00928 
00929         self.assertThat(menu_entry.active, Eventually(Equals(False)))
00930         self.assertThat(menu_entry.menu_x, Eventually(Equals(0)))
00931         self.assertThat(menu_entry.menu_y, Eventually(Equals(0)))
00932 
00933     def test_menu_closes_on_click_outside(self):
00934         """Clicking outside an open menu must close it."""
00935         self.open_new_application_window("Calculator")
00936         menu_entry = self.panel.menus.get_entries()[0]
00937         self.mouse_open_indicator(menu_entry)
00938 
00939         # This assert is for timing purposes only:
00940         self.assertThat(menu_entry.active, Eventually(Equals(True)))
00941         target_x = menu_entry.menu_x + menu_entry.menu_width/2
00942         target_y = menu_entry.menu_y + menu_entry.menu_height + 10
00943         self.mouse.move(target_x, target_y)
00944         self.mouse.click()
00945 
00946         self.assertThat(menu_entry.active, Eventually(Equals(False)))
00947         self.assertThat(menu_entry.menu_x, Eventually(Equals(0)))
00948         self.assertThat(menu_entry.menu_y, Eventually(Equals(0)))
00949 
00950 
00951 class PanelKeyNavigationTests(PanelTestsBase):
00952 
00953     scenarios = _make_monitor_scenarios()
00954 
00955     def get_active_indicator(self):
00956         """Get the active indicator in a safe manner.
00957 
00958         This method will wait until the active indicator has been set.
00959 
00960         """
00961         self.assertThat(self.panel.get_active_indicator, Eventually(NotEquals(None)))
00962         return self.panel.get_active_indicator()
00963 
00964     def test_panel_first_menu_show_works(self):
00965         """Pressing the open-menus keybinding must open the first indicator."""
00966         self.open_new_application_window("Calculator")
00967         sleep(1)
00968         self.keybinding("panel/open_first_menu")
00969         self.addCleanup(self.keyboard.press_and_release, "Escape")
00970 
00971         open_indicator = self.get_active_indicator()
00972         expected_indicator = self.panel.get_indicator_entries(include_hidden_menus=True)[0]
00973         self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id)))
00974 
00975         self.keybinding("panel/open_first_menu")
00976         self.assertThat(self.panel.get_active_indicator(), Eventually(Equals(None)))
00977 
00978     def test_panel_menu_accelerators_work(self):
00979         """Pressing a valid menu accelerator must open the correct menu item."""
00980         self.open_new_application_window("Calculator")
00981         sleep(1)
00982         self.keyboard.press_and_release("Alt+c")
00983         self.addCleanup(self.keyboard.press_and_release, "Escape")
00984 
00985         open_indicator = self.get_active_indicator()
00986         self.assertThat(open_indicator.label, Eventually(Equals("_Calculator")))
00987 
00988     def test_panel_indicators_key_navigation_next_works(self):
00989         """Right arrow key must open the next menu."""
00990         self.open_new_application_window("Calculator")
00991         available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)
00992 
00993         self.keybinding("panel/open_first_menu")
00994         self.addCleanup(self.keyboard.press_and_release, "Escape")
00995 
00996         self.keybinding("panel/next_indicator")
00997         open_indicator = self.get_active_indicator()
00998         expected_indicator = available_indicators[1]
00999         self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id)))
01000 
01001     def test_panel_indicators_key_navigation_prev_works(self):
01002         """Left arrow key must open the previous menu."""
01003         self.open_new_application_window("Calculator")
01004         available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)
01005 
01006         self.keybinding("panel/open_first_menu")
01007         self.addCleanup(self.keyboard.press_and_release, "Escape")
01008 
01009         self.keybinding("panel/prev_indicator")
01010         open_indicator = self.get_active_indicator()
01011         expected_indicator = available_indicators[-1]
01012 
01013         self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id)))
01014 
01015     def test_mouse_does_not_break_key_navigation(self):
01016         """Must be able to use the mouse to open indicators after they've been
01017         opened with the keyboard.
01018         """
01019         self.open_new_application_window("Calculator")
01020         available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)
01021 
01022         self.keybinding("panel/open_first_menu")
01023         self.addCleanup(self.keyboard.press_and_release, "Escape")
01024 
01025         available_indicators[2].mouse_move_to()
01026         self.addCleanup(self.panel.move_mouse_below_the_panel)
01027 
01028         self.assertThat(available_indicators[2].active, Eventually(Equals(True)))
01029 
01030         self.keybinding("panel/prev_indicator")
01031         self.assertThat(available_indicators[1].active, Eventually(Equals(True)))
01032 
01033 
01034 class PanelGrabAreaTests(PanelTestsBase):
01035     """Panel grab area tests."""
01036 
01037     scenarios = _make_monitor_scenarios()
01038 
01039     def move_mouse_over_grab_area(self):
01040         self.panel.move_mouse_over_grab_area()
01041         self.addCleanup(self.panel.move_mouse_below_the_panel)
01042         sleep(.1)
01043 
01044     def test_unmaximize_from_grab_area_works(self):
01045         """Dragging a window down from the panel must unmaximize it."""
01046         text_win = self.open_new_application_window("Text Editor", maximized=True)
01047 
01048         self.move_mouse_over_grab_area()
01049         self.mouse.press()
01050         self.panel.move_mouse_below_the_panel()
01051         self.mouse.release()
01052 
01053         self.assertThat(lambda: text_win.is_maximized, Eventually(Equals(False)))
01054 
01055     def test_focus_the_maximized_window_works(self):
01056         """Clicking on the grab area must put a maximized window in focus."""
01057         text_win = self.open_new_application_window("Text Editor", maximized=True)
01058         calc_win = self.open_new_application_window("Calculator")
01059 
01060         self.assertThat(lambda: text_win.is_focused, Eventually(Equals(False)))
01061         self.assertThat(lambda: calc_win.is_focused, Eventually(Equals(True)))
01062 
01063         self.move_mouse_over_grab_area()
01064         self.mouse.click()
01065 
01066         self.assertThat(lambda: text_win.is_focused, Eventually(Equals(True)))
01067 
01068     def test_lower_the_maximized_window_works(self):
01069         """Middle-clicking on the panel grab area must lower a maximized window."""
01070         calc_win = self.open_new_application_window("Calculator")
01071         text_win = self.open_new_application_window("Text Editor", maximized=True)
01072 
01073         self.assertThat(lambda: text_win.is_focused, Eventually(Equals(True)))
01074         self.assertThat(lambda: calc_win.is_focused, Eventually(Equals(False)))
01075 
01076         self.move_mouse_over_grab_area()
01077         self.mouse.click(2)
01078 
01079         self.assertThat(lambda: calc_win.is_focused, Eventually(Equals(True)))
01080 
01081     def test_panels_dont_steal_keynav_foucs_from_hud(self):
01082         """On a mouse click event on the panel you must still be able to type into the Hud."""
01083         self.hud.ensure_visible()
01084         self.addCleanup(self.hud.ensure_hidden)
01085 
01086         self.keyboard.type("Hello")
01087         self.move_mouse_over_grab_area()
01088         self.mouse.click()
01089         self.keyboard.type("World")
01090 
01091         self.assertThat(self.hud.search_string, Eventually(Equals("HelloWorld")))
01092 
01093 
01094 class PanelCrossMonitorsTests(PanelTestsBase):
01095     """Multimonitor panel tests."""
01096 
01097     def setUp(self):
01098         super(PanelCrossMonitorsTests, self).setUp()
01099         if self.screen_geo.get_num_monitors() < 2:
01100             self.skipTest("This test requires a multimonitor setup")
01101 
01102     def test_panel_title_updates_moving_window(self):
01103         """Panel must show the title of a restored window when moved to it's monitor."""
01104         calc_win = self.open_new_application_window("Calculator")
01105 
01106         prev_monitor = None
01107         for monitor in range(0, self.screen_geo.get_num_monitors()):
01108             if calc_win.monitor != monitor:
01109                 self.screen_geo.drag_window_to_monitor(calc_win, monitor)
01110 
01111             if prev_monitor:
01112                 prev_panel = self.panels.get_panel_for_monitor(prev_monitor)
01113                 self.assertThat(prev_panel.active, Eventually(Equals(False)))
01114 
01115             panel = self.panels.get_panel_for_monitor(monitor)
01116             self.assertThat(panel.active, Eventually(Equals(True)))
01117             self.assertThat(panel.title, Eventually(Equals(calc_win.application.name)))
01118 
01119             prev_monitor = monitor
01120 
01121     def test_window_buttons_dont_show_for_maximized_window_on_mouse_in(self):
01122         """Window buttons must not show when the mouse is hovering the panel in
01123         other monitors.
01124         """
01125         self.open_new_application_window("Text Editor", maximized=True)
01126         self.sleep_menu_settle_period()
01127 
01128         for monitor in range(0, self.screen_geo.get_num_monitors()):
01129             panel = self.panels.get_panel_for_monitor(monitor)
01130             panel.move_mouse_over_window_buttons()
01131 
01132             self.sleep_menu_settle_period()
01133 
01134             if self.panel_monitor == monitor:
01135                 self.assertThat(panel.window_buttons_shown, Eventually(Equals(True)))
01136             else:
01137                 self.assertThat(panel.window_buttons_shown, Eventually(Equals(False)))
01138 
01139     def test_window_buttons_dont_show_in_other_monitors_when_dash_is_open(self):
01140         """Window buttons must not show on the panels other than the one where
01141         the dash is opened.
01142         """
01143         self.dash.ensure_visible()
01144         self.addCleanup(self.dash.ensure_hidden)
01145 
01146         for monitor in range(0, self.screen_geo.get_num_monitors()):
01147             panel = self.panels.get_panel_for_monitor(monitor)
01148 
01149             if self.dash.monitor == monitor:
01150                 self.assertThat(panel.window_buttons_shown, Eventually(Equals(True)))
01151             else:
01152                 self.assertThat(panel.window_buttons_shown, Eventually(Equals(False)))
01153 
01154     def test_window_buttons_dont_show_in_other_monitors_when_hud_is_open(self):
01155         """Window buttons must not show on the panels other than the one where
01156         the hud is opened.
01157         """
01158         self.hud.ensure_visible()
01159         self.addCleanup(self.hud.ensure_hidden)
01160 
01161         for monitor in range(0, self.screen_geo.get_num_monitors()):
01162             panel = self.panels.get_panel_for_monitor(monitor)
01163 
01164             if self.hud.monitor == monitor:
01165                 self.assertThat(panel.window_buttons_shown, Eventually(Equals(True)))
01166             else:
01167                 self.assertThat(panel.window_buttons_shown, Eventually(Equals(False)))
01168 
01169     def test_window_buttons_close_inactive_when_clicked_in_another_monitor(self):
01170         """Clicking the close button must not affect the active maximized window
01171         on another monitor.
01172 
01173         See bug #865701
01174         """
01175         text_win = self.open_new_application_window("Text Editor", maximized=True)
01176 
01177         for monitor in range(self.screen_geo.get_num_monitors()):
01178             panel = self.panels.get_panel_for_monitor(monitor)
01179 
01180             if monitor != text_win.monitor:
01181                 panel.window_buttons.close.mouse_move_to()
01182                 panel.window_buttons.close.mouse_click()
01183                 self.assertThat(text_win.closed, Equals(False))
01184 
01185     def test_window_buttons_minimize_inactive_when_clicked_in_another_monitor(self):
01186         """Clicking the minimise button must not affect the active maximized
01187         window on another monitor.
01188 
01189         See bug #865701
01190         """
01191         text_win = self.open_new_application_window("Text Editor", maximized=True)
01192 
01193         for monitor in range(self.screen_geo.get_num_monitors()):
01194             panel = self.panels.get_panel_for_monitor(monitor)
01195 
01196             if monitor != text_win.monitor:
01197                 panel.window_buttons.minimize.mouse_click()
01198                 self.assertThat(text_win.is_hidden, Equals(False))
01199 
01200     def test_window_buttons_unmaximize_inactive_when_clicked_in_another_monitor(self):
01201         """Clicking the restore button must not affect the active maximized
01202         window on another monitor.
01203 
01204         See bug #865701
01205         """
01206         text_win = self.open_new_application_window("Text Editor", maximized=True)
01207 
01208         for monitor in range(0, self.screen_geo.get_num_monitors()):
01209             panel = self.panels.get_panel_for_monitor(monitor)
01210 
01211             if monitor != text_win.monitor:
01212                 panel.window_buttons.unmaximize.mouse_click()
01213                 self.assertThat(text_win.is_maximized, Equals(True))
01214 
01215     def test_hovering_indicators_on_multiple_monitors(self):
01216         """Opening an indicator entry and then hovering others entries must open them."""
01217         text_win = self.open_new_application_window("Text Editor")
01218         panel = self.panels.get_panel_for_monitor(text_win.monitor)
01219         indicator = panel.indicators.get_indicator_by_name_hint("indicator-session-devices")
01220         self.mouse_open_indicator(indicator)
01221 
01222         for monitor in range(0, self.screen_geo.get_num_monitors()):
01223             panel = self.panels.get_panel_for_monitor(monitor)
01224 
01225             entries = panel.get_indicator_entries(include_hidden_menus=True)
01226             self.assertThat(len(entries), GreaterThan(0))
01227 
01228             for entry in entries:
01229                 entry.mouse_move_to()
01230 
01231                 if monitor != self.panel_monitor and entry.type == "menu":
01232                     # we're on the "other" monitor, so the menu should be hidden.
01233                     self.assertThat(entry.active, Eventually(Equals(False)))
01234                     self.assertThat(entry.visible, Eventually(Equals(False)))
01235                     self.assertThat(entry.menu_y, Eventually(Equals(0)))
01236                 else:
01237                     self.assertThat(entry.visible, Eventually(Equals(True)))
01238                     self.assertThat(entry.active, Eventually(Equals(True)))
01239                     self.assertThat(entry.menu_y, Eventually(NotEquals(0)))