~3v1n0/autopilot/badwindow-errors-protect

« back to all changes in this revision

Viewing changes to autopilot/tests/test_panel.py

  • Committer: Thomi Richards
  • Date: 2012-05-06 22:45:27 UTC
  • Revision ID: thomi.richards@canonical.com-20120506224527-xh6wixqiw0rarkmh
Imported code from unity.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
 
2
# Copyright 2012 Canonical
 
3
# Author: Marco Trevisan (Treviño)
 
4
#
 
5
# This program is free software: you can redistribute it and/or modify it
 
6
# under the terms of the GNU General Public License version 3, as published
 
7
# by the Free Software Foundation.
 
8
 
 
9
import logging
 
10
import os
 
11
from testtools.matchers import Equals,  GreaterThan, NotEquals
 
12
from time import sleep
 
13
 
 
14
from autopilot.emulators.X11 import ScreenGeometry
 
15
from autopilot.emulators.bamf import BamfWindow
 
16
from autopilot.emulators.unity.panel import IndicatorEntry
 
17
from autopilot.tests import AutopilotTestCase
 
18
 
 
19
 
 
20
logger = logging.getLogger(__name__)
 
21
 
 
22
 
 
23
def _make_monitor_scenarios():
 
24
    num_monitors = ScreenGeometry().get_num_monitors()
 
25
    scenarios = []
 
26
 
 
27
    if num_monitors == 1:
 
28
        scenarios = [('Single Monitor', {'panel_monitor': 0})]
 
29
    else:
 
30
        for i in range(num_monitors):
 
31
            scenarios += [('Monitor %d' % (i), {'panel_monitor': i})]
 
32
 
 
33
    return scenarios
 
34
 
 
35
 
 
36
class PanelTestsBase(AutopilotTestCase):
 
37
 
 
38
    panel_monitor = 0
 
39
 
 
40
    def setUp(self):
 
41
        super(PanelTestsBase, self).setUp()
 
42
        self.panel = self.panels.get_panel_for_monitor(self.panel_monitor)
 
43
        self.panel.move_mouse_below_the_panel()
 
44
        self.addCleanup(self.panel.move_mouse_below_the_panel)
 
45
 
 
46
    def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True):
 
47
        """Opens a new instance of the requested application, ensuring that only
 
48
        one window is opened.
 
49
 
 
50
        Returns the opened BamfWindow
 
51
 
 
52
        """
 
53
        self.close_all_app(app_name)
 
54
        app = self.start_app(app_name, locale="C")
 
55
 
 
56
        [app_win] = app.get_windows()
 
57
 
 
58
        app_win.set_focus()
 
59
        self.assertTrue(app.is_active)
 
60
        self.assertTrue(app_win.is_focused)
 
61
        self.assertThat(app.desktop_file, Equals(app_win.application.desktop_file))
 
62
 
 
63
        if move_to_monitor:
 
64
            self.move_window_to_panel_monitor(app_win)
 
65
 
 
66
        if maximized and not app_win.is_maximized:
 
67
            self.keybinding("window/maximize")
 
68
            self.addCleanup(self.keybinding, "window/restore")
 
69
        elif not maximized and app_win.is_maximized:
 
70
            self.keybinding("window/restore")
 
71
            self.addCleanup(self.keybinding, "window/maximize")
 
72
 
 
73
        app_win.set_focus()
 
74
        sleep(.25)
 
75
 
 
76
        self.assertThat(app_win.is_maximized, Equals(maximized))
 
77
 
 
78
        return app_win
 
79
 
 
80
    def move_window_to_panel_monitor(self, window, restore_position=True):
 
81
        """Drags a window to another monitor, eventually restoring it before"""
 
82
        if not isinstance(window, BamfWindow):
 
83
            raise TypeError("Window must be a BamfWindow")
 
84
 
 
85
        if window.monitor == self.panel_monitor:
 
86
            return
 
87
 
 
88
        if window.is_maximized:
 
89
            self.keybinding("window/restore")
 
90
            self.addCleanup(self.keybinding, "window/maximize")
 
91
            sleep(.1)
 
92
 
 
93
        if restore_position:
 
94
            self.addCleanup(self.screen_geo.drag_window_to_monitor, window, window.monitor)
 
95
 
 
96
        self.screen_geo.drag_window_to_monitor(window, self.panel_monitor)
 
97
        sleep(.25)
 
98
        self.assertThat(window.monitor, Equals(self.panel_monitor))
 
99
 
 
100
    def mouse_open_indicator(self, indicator):
 
101
        """This is an utility function that safely opens an indicator,
 
102
        ensuring that it is closed at the end of the test and that the pointer
 
103
        is moved outside the panel area (to make the panel hide the menus)
 
104
        """
 
105
        if not isinstance(indicator, IndicatorEntry):
 
106
            raise TypeError("Window must be a IndicatorEntry")
 
107
 
 
108
        indicator.mouse_click()
 
109
        self.addCleanup(self.panel.move_mouse_below_the_panel)
 
110
        self.addCleanup(self.keyboard.press_and_release, "Escape")
 
111
        sleep(.5)
 
112
        self.assertTrue(indicator.active)
 
113
 
 
114
 
 
115
class PanelTitleTests(PanelTestsBase):
 
116
 
 
117
    scenarios = _make_monitor_scenarios()
 
118
 
 
119
    def test_panel_title_on_empty_desktop(self):
 
120
        """With no windows shown, the panel must display the default title."""
 
121
        self.keybinding("window/show_desktop")
 
122
        # We need this sleep to give the time to showdesktop to properly resume
 
123
        # the initial status without getting a false-negative result
 
124
        self.addCleanup(sleep, 2)
 
125
        self.addCleanup(self.keybinding, "window/show_desktop")
 
126
        sleep(2)
 
127
 
 
128
        self.assertTrue(self.panel.desktop_is_active)
 
129
 
 
130
    def test_panel_title_with_restored_application(self):
 
131
        """Panel must display application name for a non-maximised application."""
 
132
        calc_win = self.open_new_application_window("Calculator")
 
133
 
 
134
        self.assertFalse(calc_win.is_maximized)
 
135
        self.assertThat(self.panel.title, Equals(calc_win.application.name))
 
136
 
 
137
    def test_panel_title_with_maximized_application(self):
 
138
        """Panel must display application name for a maximised application."""
 
139
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
140
 
 
141
        self.assertTrue(text_win.is_maximized)
 
142
        self.assertThat(self.panel.title, Equals(text_win.title))
 
143
 
 
144
    def test_panel_title_with_maximized_window_restored_child(self):
 
145
        """Tests the title shown in the panel when opening the restored child of
 
146
        a maximized application.
 
147
        """
 
148
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
149
 
 
150
        self.assertTrue(text_win.is_maximized)
 
151
        self.assertThat(self.panel.title, Equals(text_win.title))
 
152
 
 
153
        self.keyboard.press_and_release("Ctrl+h")
 
154
        self.addCleanup(self.keyboard.press_and_release, "Escape")
 
155
        sleep(.25)
 
156
        self.assertThat(self.panel.title, Equals(text_win.application.name))
 
157
 
 
158
    def test_panel_title_switching_active_window(self):
 
159
        """Tests the title shown in the panel with a maximized application."""
 
160
        # Locked Launchers on all monitors
 
161
        self.set_unity_option('num_launchers', 0)
 
162
        self.set_unity_option('launcher_hide_mode', 0)
 
163
 
 
164
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
165
 
 
166
        self.assertTrue(text_win.is_maximized)
 
167
        self.assertThat(self.panel.title, Equals(text_win.title))
 
168
        sleep(.25)
 
169
 
 
170
        calc_win = self.open_new_application_window("Calculator")
 
171
        self.assertThat(self.panel.title, Equals(calc_win.application.name))
 
172
 
 
173
        icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file)
 
174
        launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor)
 
175
        launcher.click_launcher_icon(icon)
 
176
 
 
177
        self.assertTrue(text_win.is_focused)
 
178
        self.assertThat(self.panel.title, Equals(text_win.title))
 
179
 
 
180
    def test_panel_title_updates_on_maximized_window_title_changes(self):
 
181
        """Tests that the title of a maximized application updates with
 
182
        window title changes.
 
183
        """
 
184
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
185
 
 
186
        self.assertThat(self.panel.title, Equals(text_win.title))
 
187
        old_title = text_win.title
 
188
        sleep(.25)
 
189
 
 
190
        text_win.set_focus()
 
191
        self.keyboard.type("Unity rocks!")
 
192
        self.addCleanup(os.remove, "/tmp/autopilot-awesome-test.txt")
 
193
        self.keyboard.press_and_release("Ctrl+S")
 
194
        sleep(.25)
 
195
        self.keyboard.type("/tmp/autopilot-awesome-test.txt")
 
196
        self.keyboard.press_and_release("Return")
 
197
        sleep(1)
 
198
 
 
199
        self.assertThat(old_title, NotEquals(text_win.title))
 
200
        self.assertThat(self.panel.title, Equals(text_win.title))
 
201
 
 
202
 
 
203
class PanelWindowButtonsTests(PanelTestsBase):
 
204
 
 
205
    scenarios = _make_monitor_scenarios()
 
206
 
 
207
    def setUp(self):
 
208
        super(PanelWindowButtonsTests, self).setUp()
 
209
        # Locked Launchers on all monitors
 
210
        self.set_unity_option('num_launchers', 0)
 
211
        self.set_unity_option('launcher_hide_mode', 0)
 
212
 
 
213
    def test_window_buttons_dont_show_on_empty_desktop(self):
 
214
        """Tests that the window buttons are not shown on clean desktop."""
 
215
        # THis initially used Show Desktop mode, but it's very buggy from within
 
216
        # autopilot. We assume that workspace 2 is empty (which is safe for the
 
217
        # jenkins runs at least.)
 
218
        self.workspace.switch_to(2)
 
219
        sleep(.5)
 
220
        self.assertFalse(self.panel.window_buttons_shown)
 
221
        self.panel.move_mouse_over_window_buttons()
 
222
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
223
        self.assertFalse(self.panel.window_buttons_shown)
 
224
 
 
225
    def test_window_buttons_dont_show_for_restored_window(self):
 
226
        """Tests that the window buttons are not shown for a restored window."""
 
227
        self.open_new_application_window("Calculator")
 
228
 
 
229
        self.assertFalse(self.panel.window_buttons_shown)
 
230
 
 
231
        self.panel.move_mouse_over_window_buttons()
 
232
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
233
        self.assertFalse(self.panel.window_buttons_shown)
 
234
 
 
235
    def test_window_buttons_dont_show_for_maximized_window_on_mouse_out(self):
 
236
        """Tests that the windows button arenot shown for a maximized window
 
237
        when the mouse is outside the panel.
 
238
        """
 
239
        self.open_new_application_window("Text Editor", maximized=True)
 
240
 
 
241
        sleep(self.panel.menus.discovery_duration)
 
242
        sleep(self.panel.menus.discovery_fadein_duration / 1000.0)
 
243
        sleep(self.panel.menus.discovery_fadeout_duration / 1000.0)
 
244
        self.assertFalse(self.panel.window_buttons_shown)
 
245
 
 
246
    def test_window_buttons_show_for_maximized_window_on_mouse_in(self):
 
247
        """Tests that the window buttons are shown when a maximized window
 
248
        is focused and the mouse is over the menu-view panel areas.
 
249
        """
 
250
        self.open_new_application_window("Text Editor", maximized=True)
 
251
 
 
252
        sleep(self.panel.menus.discovery_duration)
 
253
 
 
254
        self.panel.move_mouse_over_window_buttons()
 
255
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
256
        self.assertTrue(self.panel.window_buttons_shown)
 
257
 
 
258
        buttons = self.panel.window_buttons.get_buttons()
 
259
        self.assertThat(len(buttons), Equals(3))
 
260
        for button in buttons:
 
261
            self.assertFalse(button.overlay_mode)
 
262
 
 
263
    def test_window_buttons_show_with_dash(self):
 
264
        """Tests that the window buttons are shown when opening the dash."""
 
265
        self.dash.ensure_visible()
 
266
        self.addCleanup(self.dash.ensure_hidden)
 
267
        sleep(.5)
 
268
        self.assertTrue(self.panel.window_buttons_shown)
 
269
 
 
270
        buttons = self.panel.window_buttons.get_buttons()
 
271
        self.assertThat(len(buttons), Equals(3))
 
272
        for button in buttons:
 
273
            self.assertTrue(button.overlay_mode)
 
274
 
 
275
    def test_window_buttons_show_with_hud(self):
 
276
        """Tests that the window buttons are shown when opening the HUD."""
 
277
        self.hud.ensure_visible()
 
278
        self.addCleanup(self.hud.ensure_hidden)
 
279
        sleep(1)
 
280
        self.assertTrue(self.panel.window_buttons_shown)
 
281
 
 
282
        buttons = self.panel.window_buttons.get_buttons()
 
283
        self.assertThat(len(buttons), Equals(3))
 
284
        for button in buttons:
 
285
            self.assertTrue(button.overlay_mode)
 
286
 
 
287
    def test_window_buttons_update_visual_state(self):
 
288
        """Tests that the window button updates its visual state."""
 
289
        self.hud.ensure_visible()
 
290
        self.addCleanup(self.hud.ensure_hidden)
 
291
        button = self.panel.window_buttons.close
 
292
 
 
293
        self.assertThat(button.visual_state, Equals("normal"))
 
294
 
 
295
        button.mouse_move_to()
 
296
        self.assertTrue(button.visible)
 
297
        self.assertTrue(button.enabled)
 
298
        sleep(.25)
 
299
        self.assertThat(button.visual_state, Equals("prelight"))
 
300
 
 
301
        self.mouse.press()
 
302
        self.addCleanup(self.mouse.release)
 
303
        sleep(.25)
 
304
        self.assertThat(button.visual_state, Equals("pressed"))
 
305
 
 
306
    def test_window_buttons_cancel(self):
 
307
        """Tests how the buttons ignore clicks when the mouse is pressed over
 
308
        them and released outside their area.
 
309
        """
 
310
        self.hud.ensure_visible()
 
311
        self.addCleanup(self.hud.ensure_hidden)
 
312
        button = self.panel.window_buttons.close
 
313
 
 
314
        button.mouse_move_to()
 
315
        self.mouse.press()
 
316
        self.addCleanup(self.mouse.release)
 
317
        sleep(.25)
 
318
        self.panel.move_mouse_below_the_panel()
 
319
        sleep(.25)
 
320
        self.assertTrue(self.hud.visible)
 
321
 
 
322
    def test_window_buttons_close_button_works_for_window(self):
 
323
        """Tests that the window button 'Close' actually closes a window."""
 
324
        text_win = self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=False)
 
325
        self.move_window_to_panel_monitor(text_win, restore_position=False)
 
326
        self.keybinding("window/maximize")
 
327
 
 
328
        self.panel.move_mouse_over_window_buttons()
 
329
        self.panel.window_buttons.close.mouse_click()
 
330
        sleep(1)
 
331
 
 
332
        self.assertTrue(text_win.closed)
 
333
 
 
334
    def test_window_buttons_close_follows_fitts_law(self):
 
335
        """Tests that the 'Close' button is activated when clicking at 0,0.
 
336
 
 
337
        See bug #839690
 
338
        """
 
339
        text_win = self.open_new_application_window("Text Editor", maximized=True, move_to_monitor=False)
 
340
        self.move_window_to_panel_monitor(text_win, restore_position=False)
 
341
        self.keybinding("window/maximize")
 
342
 
 
343
        self.panel.move_mouse_over_window_buttons()
 
344
        screen_x, screen_y, _, _ = self.screen_geo.get_monitor_geometry(self.panel_monitor)
 
345
        self.mouse.move(screen_x, screen_y, rate=20, time_between_events=0.005)
 
346
        sleep(.5)
 
347
        self.mouse.click(press_duration=.1)
 
348
        sleep(1)
 
349
 
 
350
        self.assertTrue(text_win.closed)
 
351
 
 
352
    def test_window_buttons_minimize_button_works_for_window(self):
 
353
        """Tests that the window button 'Minimize' actually minimizes a window."""
 
354
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
355
 
 
356
        self.panel.window_buttons.minimize.mouse_click()
 
357
        sleep(.5)
 
358
 
 
359
        self.assertTrue(text_win.is_hidden)
 
360
 
 
361
        icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file)
 
362
        launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor)
 
363
        launcher.click_launcher_icon(icon)
 
364
 
 
365
    def test_window_buttons_minimize_follows_fitts_law(self):
 
366
        """Tests that the 'Minimize' button is conform to Fitts's Law.
 
367
 
 
368
        See bug #839690
 
369
        """
 
370
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
371
 
 
372
        button = self.panel.window_buttons.minimize
 
373
        button.mouse_move_to()
 
374
        target_x = button.x + button.width / 2
 
375
        target_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[1]
 
376
        self.mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
 
377
        sleep(.5)
 
378
        self.mouse.click(press_duration=.1)
 
379
        sleep(1)
 
380
 
 
381
        self.assertTrue(text_win.is_hidden)
 
382
        icon = self.launcher.model.get_icon_by_desktop_id(text_win.application.desktop_file)
 
383
        launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor)
 
384
        launcher.click_launcher_icon(icon)
 
385
 
 
386
    def test_window_buttons_unmaximize_button_works_for_window(self):
 
387
        """Tests that the window button 'Unmaximize' actually unmaximizes a window."""
 
388
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
389
 
 
390
        self.panel.window_buttons.unmaximize.mouse_click()
 
391
        sleep(.5)
 
392
 
 
393
        self.assertFalse(text_win.is_maximized)
 
394
        self.assertTrue(text_win.is_focused)
 
395
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
396
        self.assertFalse(self.panel.window_buttons_shown)
 
397
 
 
398
    def test_window_buttons_unmaximize_follows_fitts_law(self):
 
399
        """Tests that the 'Unmaximize' button is conform to Fitts's Law.
 
400
 
 
401
        See bug #839690
 
402
        """
 
403
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
404
 
 
405
        button = self.panel.window_buttons.unmaximize
 
406
        button.mouse_move_to()
 
407
        target_x = button.x + button.width / 2
 
408
        target_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[1]
 
409
        self.mouse.move(target_x, target_y, rate=20, time_between_events=0.005)
 
410
        sleep(.5)
 
411
        self.mouse.click(press_duration=.1)
 
412
        sleep(1)
 
413
 
 
414
        self.assertFalse(text_win.is_maximized)
 
415
 
 
416
    def test_window_buttons_close_button_works_for_hud(self):
 
417
        """Tests that the window 'Close' actually closes the HUD."""
 
418
        self.hud.ensure_visible()
 
419
        self.addCleanup(self.hud.ensure_hidden)
 
420
        sleep(.5)
 
421
 
 
422
        self.panel.window_buttons.close.mouse_click()
 
423
        sleep(.75)
 
424
 
 
425
        self.assertFalse(self.hud.visible)
 
426
 
 
427
    def test_window_buttons_minimize_button_disabled_for_hud(self):
 
428
        """Tests that the window 'Minimize' does nothing to the HUD."""
 
429
        self.hud.ensure_visible()
 
430
        self.addCleanup(self.hud.ensure_hidden)
 
431
        sleep(.5)
 
432
 
 
433
        button = self.panel.window_buttons.minimize
 
434
        button.mouse_click()
 
435
        sleep(.5)
 
436
 
 
437
        self.assertFalse(button.enabled)
 
438
        self.assertTrue(self.hud.visible)
 
439
 
 
440
    def test_window_buttons_maximize_button_disabled_for_hud(self):
 
441
        """Tests that the window 'Maximize' does nothing to the HUD."""
 
442
        self.hud.ensure_visible()
 
443
        self.addCleanup(self.hud.ensure_hidden)
 
444
        sleep(.5)
 
445
 
 
446
        button = self.panel.window_buttons.maximize
 
447
        button.mouse_click()
 
448
        sleep(.5)
 
449
 
 
450
        self.assertFalse(button.enabled)
 
451
        self.assertTrue(self.hud.visible)
 
452
 
 
453
    def test_window_buttons_maximize_in_hud_does_not_change_dash_form_factor(self):
 
454
        """Clicking on the 'Maximize' button of the HUD must do nothing.
 
455
 
 
456
        See bug #939054
 
457
        """
 
458
        inital_form_factor = self.dash.view.form_factor
 
459
        self.hud.ensure_visible()
 
460
        self.addCleanup(self.hud.ensure_hidden)
 
461
        sleep(.5)
 
462
 
 
463
        self.panel.window_buttons.maximize.mouse_click()
 
464
        sleep(.5)
 
465
 
 
466
        self.assertThat(self.dash.view.form_factor, Equals(inital_form_factor))
 
467
 
 
468
    def test_window_buttons_close_button_works_for_dash(self):
 
469
        """Tests that the window 'Close' actually closes the Dash."""
 
470
        self.dash.ensure_visible()
 
471
        self.addCleanup(self.dash.ensure_hidden)
 
472
        sleep(.5)
 
473
 
 
474
        self.panel.window_buttons.close.mouse_click()
 
475
        sleep(.75)
 
476
 
 
477
        self.assertFalse(self.dash.visible)
 
478
 
 
479
    def test_window_buttons_minimize_button_disabled_for_dash(self):
 
480
        """Tests that the 'Minimize' button is disabled for the dash."""
 
481
        self.dash.ensure_visible()
 
482
        self.addCleanup(self.dash.ensure_hidden)
 
483
        sleep(.5)
 
484
 
 
485
        button = self.panel.window_buttons.minimize
 
486
        button.mouse_click()
 
487
        sleep(.5)
 
488
 
 
489
        self.assertFalse(button.enabled)
 
490
        self.assertTrue(self.dash.visible)
 
491
 
 
492
    def test_window_buttons_maximization_buttons_works_for_dash(self):
 
493
        """'Maximize' and 'Restore' buttons (when both enabled) must work as expected."""
 
494
        self.dash.ensure_visible()
 
495
        self.addCleanup(self.panel.window_buttons.close.mouse_click)
 
496
        sleep(.5)
 
497
 
 
498
        unmaximize = self.panel.window_buttons.unmaximize
 
499
        maximize = self.panel.window_buttons.maximize
 
500
        netbook_dash = (self.dash.view.form_factor == "netbook")
 
501
 
 
502
        if netbook_dash and not unmaximize.enabled:
 
503
            unmaximize.mouse_click()
 
504
            sleep(.5)
 
505
            self.assertThat(self.dash.view.form_factor, Equals("netbook"))
 
506
        else:
 
507
            if maximize.visible:
 
508
                active_button = maximize
 
509
                unactive_button = unmaximize
 
510
            else:
 
511
                active_button = unmaximize
 
512
                unactive_button = maximize
 
513
 
 
514
            self.assertTrue(active_button.visible)
 
515
            self.assertTrue(active_button.sensitive)
 
516
            self.assertTrue(active_button.enabled)
 
517
            self.assertFalse(unactive_button.visible)
 
518
 
 
519
            self.addCleanup(unactive_button.mouse_click)
 
520
            active_button.mouse_click()
 
521
            sleep(.5)
 
522
 
 
523
            self.assertTrue(unactive_button.visible)
 
524
            self.assertTrue(unactive_button.sensitive)
 
525
            self.assertTrue(unactive_button.enabled)
 
526
            self.assertFalse(active_button.visible)
 
527
            sleep(.5)
 
528
 
 
529
            if netbook_dash:
 
530
                self.assertThat(self.dash.view.form_factor, Equals("desktop"))
 
531
            else:
 
532
                self.assertThat(self.dash.view.form_factor, Equals("netbook"))
 
533
 
 
534
            self.addCleanup(active_button.mouse_click)
 
535
            unactive_button.mouse_click()
 
536
            sleep(.5)
 
537
 
 
538
            self.assertTrue(active_button.visible)
 
539
            self.assertFalse(unactive_button.visible)
 
540
 
 
541
            if netbook_dash:
 
542
                self.assertThat(self.dash.view.form_factor, Equals("netbook"))
 
543
            else:
 
544
                self.assertThat(self.dash.view.form_factor, Equals("desktop"))
 
545
 
 
546
    def test_window_buttons_minimize_button_disabled_for_non_minimizable_windows(self):
 
547
        """Tests that if a maximized window doesn't support the minimization,
 
548
        then the 'Minimize' window button should be disabled.
 
549
        """
 
550
        text_win = self.open_new_application_window("Text Editor")
 
551
        sleep(.25)
 
552
        self.keyboard.press_and_release("Ctrl+S")
 
553
        self.addCleanup(self.keyboard.press_and_release, "Escape")
 
554
 
 
555
        wins = text_win.application.get_windows()
 
556
        self.assertThat(len(wins), Equals(2))
 
557
        for win in wins:
 
558
            if win.x_id != text_win.x_id:
 
559
                target_win = win
 
560
                break
 
561
 
 
562
        target_win.set_focus()
 
563
        self.assertTrue(target_win.is_focused)
 
564
        self.move_window_to_panel_monitor(target_win, restore_position=False)
 
565
 
 
566
        self.keybinding("window/maximize")
 
567
 
 
568
        self.assertThat(target_win.monitor, Equals(self.panel_monitor))
 
569
        self.assertTrue(target_win.is_maximized)
 
570
 
 
571
        self.assertTrue(self.panel.window_buttons.close.enabled)
 
572
        self.assertFalse(self.panel.window_buttons.minimize.enabled)
 
573
 
 
574
    def test_window_buttons_show_when_indicator_active_and_mouse_over_panel(self):
 
575
        """Tests that when an indicator is opened, and the mouse goes over the
 
576
        panel view, then the window buttons are revealed.
 
577
        """
 
578
        self.open_new_application_window("Text Editor", maximized=True)
 
579
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
580
        sleep(self.panel.menus.discovery_duration)
 
581
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
582
 
 
583
        indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session-devices")
 
584
        self.mouse_open_indicator(indicator)
 
585
 
 
586
        self.assertFalse(self.panel.window_buttons_shown)
 
587
        self.panel.move_mouse_below_the_panel()
 
588
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
589
 
 
590
        self.assertFalse(self.panel.window_buttons_shown)
 
591
        self.panel.move_mouse_over_grab_area()
 
592
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
593
        self.assertTrue(self.panel.window_buttons_shown)
 
594
 
 
595
    def test_window_buttons_show_when_holding_show_menu_key(self):
 
596
        self.open_new_application_window("Text Editor", maximized=True)
 
597
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
598
        sleep(self.panel.menus.discovery_duration)
 
599
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
600
 
 
601
        self.keybinding_hold("panel/show_menus")
 
602
        self.addCleanup(self.keybinding_release, "panel/show_menus")
 
603
        sleep(1)
 
604
        self.assertTrue(self.panel.window_buttons_shown)
 
605
 
 
606
        self.keybinding_release("panel/show_menus")
 
607
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
608
 
 
609
        self.assertFalse(self.panel.window_buttons_shown)
 
610
 
 
611
 
 
612
class PanelHoveringTests(PanelTestsBase):
 
613
    """Tests with the mouse pointer hovering the panel area."""
 
614
 
 
615
    scenarios = _make_monitor_scenarios()
 
616
 
 
617
    def test_only_menus_show_for_restored_window_on_mouse_in(self):
 
618
        """Tests that only menus of a restored window are shown only when
 
619
        the mouse pointer is over the panel menu area.
 
620
        """
 
621
        self.open_new_application_window("Calculator")
 
622
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
623
        sleep(self.panel.menus.discovery_duration)
 
624
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
625
 
 
626
        self.panel.move_mouse_over_window_buttons()
 
627
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
628
        self.assertFalse(self.panel.window_buttons_shown)
 
629
        self.assertTrue(self.panel.menus_shown)
 
630
 
 
631
        self.panel.move_mouse_over_menus()
 
632
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
633
        self.assertFalse(self.panel.window_buttons_shown)
 
634
        self.assertTrue(self.panel.menus_shown)
 
635
 
 
636
        if self.panel.grab_area.width > 0:
 
637
            self.panel.move_mouse_over_grab_area()
 
638
            sleep(self.panel.menus.fadeout_duration / 1000.0)
 
639
            self.assertFalse(self.panel.window_buttons_shown)
 
640
            self.assertTrue(self.panel.menus_shown)
 
641
 
 
642
        self.panel.move_mouse_over_indicators()
 
643
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
644
        self.assertFalse(self.panel.menus_shown)
 
645
 
 
646
    def test_menus_show_for_maximized_window_on_mouse_in(self):
 
647
        """Tests that menus and window buttons of a maximized window are shown
 
648
        only when the mouse pointer is over the panel menu area.
 
649
        """
 
650
        self.open_new_application_window("Text Editor", maximized=True)
 
651
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
652
        sleep(self.panel.menus.discovery_duration)
 
653
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
654
 
 
655
        self.panel.move_mouse_over_window_buttons()
 
656
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
657
        self.assertTrue(self.panel.window_buttons_shown)
 
658
        self.assertTrue(self.panel.menus_shown)
 
659
 
 
660
        self.panel.move_mouse_over_menus()
 
661
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
662
        self.assertTrue(self.panel.window_buttons_shown)
 
663
        self.assertTrue(self.panel.menus_shown)
 
664
 
 
665
        if self.panel.grab_area.width > 0:
 
666
            self.panel.move_mouse_over_grab_area()
 
667
            sleep(self.panel.menus.fadeout_duration / 1000.0)
 
668
            self.assertTrue(self.panel.window_buttons_shown)
 
669
            self.assertTrue(self.panel.menus_shown)
 
670
 
 
671
        self.panel.move_mouse_over_indicators()
 
672
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
673
        self.assertFalse(self.panel.window_buttons_shown)
 
674
        self.assertFalse(self.panel.menus_shown)
 
675
 
 
676
    def test_hovering_indicators_open_menus(self):
 
677
        """Opening an indicator entry, and then hovering on other entries must
 
678
        open them.
 
679
        """
 
680
        self.open_new_application_window("Text Editor")
 
681
        entries = self.panel.get_indicator_entries(include_hidden_menus=True)
 
682
 
 
683
        self.assertThat(len(entries), GreaterThan(0))
 
684
        self.mouse_open_indicator(entries[0])
 
685
 
 
686
        for entry in entries:
 
687
            entry.mouse_move_to()
 
688
            sleep(.25)
 
689
            self.assertTrue(entry.active)
 
690
            self.assertThat(entry.menu_y, NotEquals(0))
 
691
 
 
692
 
 
693
class PanelMenuTests(PanelTestsBase):
 
694
 
 
695
    scenarios = _make_monitor_scenarios()
 
696
 
 
697
    def test_menus_are_added_on_new_application(self):
 
698
        """Tests that menus are added when a new application is opened."""
 
699
        self.open_new_application_window("Calculator")
 
700
        sleep(.5)
 
701
        menu_entries = self.panel.menus.get_entries()
 
702
        self.assertThat(len(menu_entries), Equals(3))
 
703
 
 
704
        menu_view = self.panel.menus
 
705
        self.assertThat(menu_view.get_menu_by_label("_Calculator"), NotEquals(None))
 
706
        self.assertThat(menu_view.get_menu_by_label("_Mode"), NotEquals(None))
 
707
        self.assertThat(menu_view.get_menu_by_label("_Help"), NotEquals(None))
 
708
 
 
709
    def test_menus_are_not_shown_if_the_application_has_no_menus(self):
 
710
        """Tests that if an application has no menus, then they are not
 
711
        shown or added.
 
712
        """
 
713
        # TODO: This doesn't test what it says on the tin. Setting MENUPROXY to ''
 
714
        # just makes the menu appear inside the app. That's fine, but it's not
 
715
        # what is described in the docstring or test id.
 
716
        old_env = os.environ["UBUNTU_MENUPROXY"]
 
717
        os.putenv("UBUNTU_MENUPROXY", "")
 
718
        self.addCleanup(os.putenv, "UBUNTU_MENUPROXY", old_env)
 
719
        calc_win = self.open_new_application_window("Calculator")
 
720
        sleep(1)
 
721
 
 
722
        self.assertThat(len(self.panel.menus.get_entries()), Equals(0))
 
723
 
 
724
        self.panel.move_mouse_over_grab_area()
 
725
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
726
        self.assertThat(self.panel.title, Equals(calc_win.application.name))
 
727
 
 
728
    def test_menus_shows_when_new_application_is_opened(self):
 
729
        """This tests the menu discovery feature on new application."""
 
730
 
 
731
        self.open_new_application_window("Calculator")
 
732
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
733
 
 
734
        self.assertTrue(self.panel.menus_shown)
 
735
 
 
736
        sleep(self.panel.menus.discovery_duration)
 
737
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
738
 
 
739
        self.assertFalse(self.panel.menus_shown)
 
740
 
 
741
    def test_menus_dont_show_if_a_new_application_window_is_opened(self):
 
742
        """This tests the menu discovery feature on new window for a know application."""
 
743
        self.open_new_application_window("Calculator")
 
744
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
745
 
 
746
        self.assertTrue(self.panel.menus_shown)
 
747
 
 
748
        sleep(self.panel.menus.discovery_duration)
 
749
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
750
 
 
751
        self.start_app("Calculator")
 
752
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
753
        self.assertFalse(self.panel.menus_shown)
 
754
 
 
755
    def test_menus_dont_show_for_restored_window_on_mouse_out(self):
 
756
        """Restored window menus must not show when the mouse is outside the
 
757
        panel menu area.
 
758
        """
 
759
        self.open_new_application_window("Calculator")
 
760
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
761
        sleep(self.panel.menus.discovery_duration)
 
762
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
763
 
 
764
        self.assertFalse(self.panel.menus_shown)
 
765
 
 
766
    def test_menus_show_for_restored_window_on_mouse_in(self):
 
767
        """Restored window menus must show only when the mouse is over the panel
 
768
        menu area.
 
769
        """
 
770
        self.open_new_application_window("Calculator")
 
771
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
772
        sleep(self.panel.menus.discovery_duration)
 
773
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
774
 
 
775
        self.panel.move_mouse_over_menus()
 
776
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
777
        self.assertTrue(self.panel.menus_shown)
 
778
 
 
779
    def test_menus_dont_show_for_maximized_window_on_mouse_out(self):
 
780
        """Maximized window menus must not show when the mouse is outside the
 
781
        panel menu area.
 
782
        """
 
783
        self.open_new_application_window("Text Editor", maximized=True)
 
784
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
785
        sleep(self.panel.menus.discovery_duration)
 
786
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
787
 
 
788
        self.assertFalse(self.panel.menus_shown)
 
789
 
 
790
    def test_menus_show_for_maximized_window_on_mouse_in(self):
 
791
        """Maximized window menus must only show when the mouse is over the
 
792
        panel menu area.
 
793
        """
 
794
        self.open_new_application_window("Text Editor", maximized=True)
 
795
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
796
        sleep(self.panel.menus.discovery_duration)
 
797
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
798
 
 
799
        self.panel.move_mouse_over_menus()
 
800
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
801
        self.assertTrue(self.panel.menus_shown)
 
802
 
 
803
    def test_menus_dont_show_with_dash(self):
 
804
        """Tests that menus are not showing when opening the dash."""
 
805
        self.dash.ensure_visible()
 
806
        self.addCleanup(self.dash.ensure_hidden)
 
807
        sleep(1)
 
808
 
 
809
        self.assertFalse(self.panel.menus_shown)
 
810
 
 
811
    def test_menus_dont_show_with_hud(self):
 
812
        """Tests that menus are not showing when opening the HUD."""
 
813
        self.hud.ensure_visible()
 
814
        self.addCleanup(self.hud.ensure_hidden)
 
815
        sleep(1)
 
816
 
 
817
        self.assertFalse(self.panel.menus_shown)
 
818
 
 
819
    def test_menus_show_after_closing_an_entry(self):
 
820
        """Opening a menu entry, and then hovering on other entries must open them.
 
821
 
 
822
        We also check that the menus are still drawn when closed.
 
823
        """
 
824
        # TODO - should be split into multiple tests.
 
825
        self.open_new_application_window("Calculator")
 
826
        entries = self.panel.menus.get_entries()
 
827
 
 
828
        self.assertThat(len(entries), GreaterThan(0))
 
829
        self.mouse_open_indicator(entries[0])
 
830
 
 
831
        for entry in entries:
 
832
            entry.mouse_move_to()
 
833
            sleep(.25)
 
834
            self.assertTrue(entry.active)
 
835
            self.assertThat(entry.menu_y, NotEquals(0))
 
836
            last_entry = entry
 
837
 
 
838
        last_entry.mouse_click()
 
839
        sleep(.25)
 
840
        self.assertFalse(last_entry.active)
 
841
        self.assertThat(last_entry.menu_y, Equals(0))
 
842
 
 
843
    def test_menus_show_when_indicator_active_and_mouse_over_panel(self):
 
844
        """When an indicator is opened, and the mouse goes over the panel view,
 
845
        the menus must be revealed.
 
846
        """
 
847
        self.open_new_application_window("Calculator")
 
848
        indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session-devices")
 
849
        self.mouse_open_indicator(indicator)
 
850
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
851
        sleep(self.panel.menus.discovery_duration)
 
852
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
853
 
 
854
        self.assertFalse(self.panel.menus_shown)
 
855
        self.panel.move_mouse_below_the_panel()
 
856
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
857
 
 
858
        self.assertFalse(self.panel.menus_shown)
 
859
        self.panel.move_mouse_over_grab_area()
 
860
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
861
        self.assertTrue(self.panel.menus_shown)
 
862
 
 
863
    def test_menus_show_when_holding_show_menu_key(self):
 
864
        self.open_new_application_window("Calculator")
 
865
        sleep(self.panel.menus.fadein_duration / 1000.0)
 
866
        sleep(self.panel.menus.discovery_duration)
 
867
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
868
 
 
869
        self.keybinding_hold("panel/show_menus")
 
870
        self.addCleanup(self.keybinding_release, "panel/show_menus")
 
871
        sleep(1)
 
872
        self.assertTrue(self.panel.menus_shown)
 
873
 
 
874
        self.keybinding_release("panel/show_menus")
 
875
        sleep(self.panel.menus.fadeout_duration / 1000.0)
 
876
 
 
877
        self.assertFalse(self.panel.menus_shown)
 
878
 
 
879
 
 
880
class PanelIndicatorEntriesTests(PanelTestsBase):
 
881
    """Tests for the indicator entries, including both menu and indicators."""
 
882
 
 
883
    scenarios = _make_monitor_scenarios()
 
884
 
 
885
    def test_menu_opens_on_click(self):
 
886
        """Tests that clicking on a menu entry, opens a menu."""
 
887
        self.open_new_application_window("Calculator")
 
888
        sleep(.5)
 
889
 
 
890
        menu_entry = self.panel.menus.get_entries()[0]
 
891
        self.mouse_open_indicator(menu_entry)
 
892
 
 
893
        self.assertTrue(menu_entry.active)
 
894
        self.assertThat(menu_entry.menu_x, Equals(menu_entry.x))
 
895
        self.assertThat(menu_entry.menu_y, Equals(self.panel.height))
 
896
 
 
897
    def test_menu_opens_closes_on_click(self):
 
898
        """Clicking on an open menu entru must close it again."""
 
899
        self.open_new_application_window("Calculator")
 
900
 
 
901
        menu_entry = self.panel.menus.get_entries()[0]
 
902
        self.mouse_open_indicator(menu_entry)
 
903
 
 
904
        self.mouse.click()
 
905
        sleep(.25)
 
906
        self.assertFalse(menu_entry.active)
 
907
        self.assertThat(menu_entry.menu_x, Equals(0))
 
908
        self.assertThat(menu_entry.menu_y, Equals(0))
 
909
 
 
910
    def test_menu_closes_on_click_outside(self):
 
911
        """Clicking outside an open menu must close it."""
 
912
        self.open_new_application_window("Calculator")
 
913
 
 
914
        menu_entry = self.panel.menus.get_entries()[0]
 
915
        self.mouse_open_indicator(menu_entry)
 
916
 
 
917
        self.assertTrue(menu_entry.active)
 
918
        target_x = menu_entry.menu_x + menu_entry.menu_width/2
 
919
        target_y = menu_entry.menu_y + menu_entry.menu_height + 10
 
920
        self.mouse.move(target_x, target_y)
 
921
        self.mouse.click()
 
922
        sleep(.5)
 
923
 
 
924
        self.assertFalse(menu_entry.active)
 
925
        self.assertThat(menu_entry.menu_x, Equals(0))
 
926
        self.assertThat(menu_entry.menu_y, Equals(0))
 
927
 
 
928
 
 
929
class PanelKeyNavigationTests(PanelTestsBase):
 
930
 
 
931
    scenarios = _make_monitor_scenarios()
 
932
 
 
933
    def test_panel_first_menu_show_works(self):
 
934
        """Pressing the open-menus keybinding must open the first indicator."""
 
935
        self.open_new_application_window("Calculator")
 
936
        sleep(1)
 
937
        self.keybinding("panel/open_first_menu")
 
938
        self.addCleanup(self.keyboard.press_and_release, "Escape")
 
939
        sleep(1)
 
940
 
 
941
        open_indicator = self.panel.get_active_indicator()
 
942
        expected_indicator = self.panel.get_indicator_entries(include_hidden_menus=True)[0]
 
943
        self.assertThat(open_indicator, NotEquals(None))
 
944
        self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id))
 
945
 
 
946
        self.keybinding("panel/open_first_menu")
 
947
        sleep(.5)
 
948
        self.assertThat(self.panel.get_active_indicator(), Equals(None))
 
949
 
 
950
    def test_panel_menu_accelerators_work(self):
 
951
        self.open_new_application_window("Calculator")
 
952
        sleep(1)
 
953
        self.keyboard.press_and_release("Alt+c")
 
954
        self.addCleanup(self.keyboard.press_and_release, "Escape")
 
955
        sleep(.5)
 
956
 
 
957
        open_indicator = self.panel.get_active_indicator()
 
958
        self.assertThat(open_indicator, NotEquals(None))
 
959
        self.assertThat(open_indicator.label, Equals("_Calculator"))
 
960
 
 
961
    def test_panel_indicators_key_navigation_next_works(self):
 
962
        self.open_new_application_window("Calculator")
 
963
        available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)
 
964
        sleep(1)
 
965
 
 
966
        self.keybinding("panel/open_first_menu")
 
967
        self.addCleanup(self.keyboard.press_and_release, "Escape")
 
968
        sleep(1)
 
969
 
 
970
        open_indicator = self.panel.get_active_indicator()
 
971
        expected_indicator = available_indicators[0]
 
972
        self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id))
 
973
        sleep(.5)
 
974
 
 
975
        self.keybinding("panel/next_indicator")
 
976
        open_indicator = self.panel.get_active_indicator()
 
977
        expected_indicator = available_indicators[1]
 
978
        sleep(.5)
 
979
        self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id))
 
980
 
 
981
    def test_panel_indicators_key_navigation_prev_works(self):
 
982
        self.open_new_application_window("Calculator")
 
983
        available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)
 
984
        sleep(1)
 
985
 
 
986
        self.keybinding("panel/open_first_menu")
 
987
        self.addCleanup(self.keyboard.press_and_release, "Escape")
 
988
        sleep(1)
 
989
 
 
990
        open_indicator = self.panel.get_active_indicator()
 
991
        expected_indicator = available_indicators[0]
 
992
        self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id))
 
993
        sleep(.5)
 
994
 
 
995
        self.keybinding("panel/prev_indicator")
 
996
        open_indicator = self.panel.get_active_indicator()
 
997
        expected_indicator = available_indicators[-1]
 
998
        sleep(.5)
 
999
        self.assertThat(open_indicator.entry_id, Equals(expected_indicator.entry_id))
 
1000
 
 
1001
    def test_mouse_does_not_break_key_navigation(self):
 
1002
        self.open_new_application_window("Calculator")
 
1003
        available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True)
 
1004
        sleep(1)
 
1005
 
 
1006
        self.keybinding("panel/open_first_menu")
 
1007
        self.addCleanup(self.keyboard.press_and_release, "Escape")
 
1008
        sleep(1)
 
1009
 
 
1010
        available_indicators[2].mouse_move_to()
 
1011
        self.addCleanup(self.panel.move_mouse_below_the_panel)
 
1012
        sleep(.25)
 
1013
        self.assertTrue(available_indicators[2].active)
 
1014
        sleep(1)
 
1015
 
 
1016
        self.keybinding("panel/prev_indicator")
 
1017
        self.assertTrue(available_indicators[1].active)
 
1018
 
 
1019
 
 
1020
class PanelGrabAreaTests(PanelTestsBase):
 
1021
    """Panel grab area tests."""
 
1022
 
 
1023
    scenarios = _make_monitor_scenarios()
 
1024
 
 
1025
    def move_mouse_over_grab_area(self):
 
1026
        self.panel.move_mouse_over_grab_area()
 
1027
        self.addCleanup(self.panel.move_mouse_below_the_panel)
 
1028
        sleep(.1)
 
1029
 
 
1030
    def test_unmaximize_from_grab_area_works(self):
 
1031
        """Dragging a window down from the panel must unmaximize it."""
 
1032
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
1033
 
 
1034
        self.move_mouse_over_grab_area()
 
1035
        self.mouse.press()
 
1036
        self.panel.move_mouse_below_the_panel()
 
1037
        self.mouse.release()
 
1038
        sleep(.5)
 
1039
 
 
1040
        self.assertFalse(text_win.is_maximized)
 
1041
 
 
1042
    def test_focus_the_maximized_window_works(self):
 
1043
        """Clicking on the grab area must put a maximized window in focus."""
 
1044
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
1045
        sleep(.5)
 
1046
        self.open_new_application_window("Calculator")
 
1047
        self.assertFalse(text_win.is_focused)
 
1048
 
 
1049
        self.move_mouse_over_grab_area()
 
1050
        self.mouse.click()
 
1051
        sleep(.5)
 
1052
 
 
1053
        self.assertTrue(text_win.is_focused)
 
1054
 
 
1055
    def test_lower_the_maximized_window_works(self):
 
1056
        """Middle-clicking on the panel grab area must lower a maximized window."""
 
1057
        calc_win = self.open_new_application_window("Calculator")
 
1058
        sleep(.5)
 
1059
        self.open_new_application_window("Text Editor", maximized=True)
 
1060
        self.assertFalse(calc_win.is_focused)
 
1061
 
 
1062
        self.move_mouse_over_grab_area()
 
1063
        self.mouse.click(2)
 
1064
        sleep(.5)
 
1065
 
 
1066
        self.assertTrue(calc_win.is_focused)
 
1067
 
 
1068
 
 
1069
class PanelCrossMonitorsTests(PanelTestsBase):
 
1070
    """Multimonitor panel tests."""
 
1071
 
 
1072
    def setUp(self):
 
1073
        super(PanelCrossMonitorsTests, self).setUp()
 
1074
        if self.screen_geo.get_num_monitors() < 2:
 
1075
            self.skipTest("This test requires a multimonitor setup")
 
1076
 
 
1077
    def test_panel_title_updates_moving_window(self):
 
1078
        """Tests the title shown in the panel, moving a restored window around them."""
 
1079
        calc_win = self.open_new_application_window("Calculator")
 
1080
 
 
1081
        prev_monitor = -1
 
1082
        for monitor in range(0, self.screen_geo.get_num_monitors()):
 
1083
            if calc_win.monitor != monitor:
 
1084
                self.addCleanup(self.screen_geo.drag_window_to_monitor, calc_win, calc_win.monitor)
 
1085
                self.screen_geo.drag_window_to_monitor(calc_win, monitor)
 
1086
                sleep(.25)
 
1087
 
 
1088
            if prev_monitor >= 0:
 
1089
                self.assertFalse(self.panels.get_panel_for_monitor(prev_monitor).active)
 
1090
 
 
1091
            panel = self.panels.get_panel_for_monitor(monitor)
 
1092
            self.assertTrue(panel.active)
 
1093
            self.assertThat(panel.title, Equals(calc_win.application.name))
 
1094
 
 
1095
            prev_monitor = monitor
 
1096
 
 
1097
    def test_window_buttons_dont_show_for_maximized_window_on_mouse_in(self):
 
1098
        """Window buttons must not show when the mouse is hovering the panel in
 
1099
        other monitors.
 
1100
        """
 
1101
        self.open_new_application_window("Text Editor", maximized=True)
 
1102
 
 
1103
        sleep(self.panel.menus.discovery_duration)
 
1104
 
 
1105
        for monitor in range(0, self.screen_geo.get_num_monitors()):
 
1106
            panel = self.panels.get_panel_for_monitor(monitor)
 
1107
            panel.move_mouse_over_window_buttons()
 
1108
            sleep(self.panel.menus.fadein_duration / 1000.0)
 
1109
 
 
1110
            if self.panel_monitor == monitor:
 
1111
                self.assertTrue(panel.window_buttons_shown)
 
1112
            else:
 
1113
                self.assertFalse(panel.window_buttons_shown)
 
1114
 
 
1115
    def test_window_buttons_dont_show_in_other_monitors_when_dash_is_open(self):
 
1116
        """Window buttons must not show on the panels other than the one where
 
1117
        the dash is opened.
 
1118
        """
 
1119
        self.dash.ensure_visible()
 
1120
        self.addCleanup(self.dash.ensure_hidden)
 
1121
 
 
1122
        for monitor in range(0, self.screen_geo.get_num_monitors()):
 
1123
            panel = self.panels.get_panel_for_monitor(monitor)
 
1124
 
 
1125
            if self.dash.monitor == monitor:
 
1126
                self.assertTrue(panel.window_buttons_shown)
 
1127
            else:
 
1128
                self.assertFalse(panel.window_buttons_shown)
 
1129
 
 
1130
    def test_window_buttons_dont_show_in_other_monitors_when_hud_is_open(self):
 
1131
        """Window buttons must not show on the panels other than the one where
 
1132
        the hud is opened.
 
1133
        """
 
1134
        self.hud.ensure_visible()
 
1135
        self.addCleanup(self.hud.ensure_hidden)
 
1136
 
 
1137
        for monitor in range(0, self.screen_geo.get_num_monitors()):
 
1138
            panel = self.panels.get_panel_for_monitor(monitor)
 
1139
 
 
1140
            if self.hud.monitor == monitor:
 
1141
                self.assertTrue(panel.window_buttons_shown)
 
1142
            else:
 
1143
                self.assertFalse(panel.window_buttons_shown)
 
1144
 
 
1145
    def test_window_buttons_close_inactive_when_clicked_in_another_monitor(self):
 
1146
        """Clicking the close button must not affect the active maximized window on another monitor.
 
1147
 
 
1148
        See bug #865701
 
1149
        """
 
1150
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
1151
 
 
1152
        for monitor in range(self.screen_geo.get_num_monitors()):
 
1153
            panel = self.panels.get_panel_for_monitor(monitor)
 
1154
 
 
1155
            if monitor != text_win.monitor:
 
1156
                panel.window_buttons.close.mouse_click()
 
1157
                sleep(.25)
 
1158
                self.assertFalse(text_win.closed)
 
1159
 
 
1160
    def test_window_buttons_minimize_inactive_when_clicked_in_another_monitor(self):
 
1161
        """Clicking the minimise button must not affect the active maximized window on another monitor.
 
1162
 
 
1163
        See bug #865701
 
1164
        """
 
1165
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
1166
 
 
1167
        for monitor in range(self.screen_geo.get_num_monitors()):
 
1168
            panel = self.panels.get_panel_for_monitor(monitor)
 
1169
 
 
1170
            if monitor != text_win.monitor:
 
1171
                panel.window_buttons.minimize.mouse_click()
 
1172
                sleep(.25)
 
1173
                self.assertFalse(text_win.is_hidden)
 
1174
 
 
1175
    def test_window_buttons_unmaximize_inactive_when_clicked_in_another_monitor(self):
 
1176
        """Clicking the restore button must not affect the active maximized window on another monitor.
 
1177
 
 
1178
        See bug #865701
 
1179
        """
 
1180
        text_win = self.open_new_application_window("Text Editor", maximized=True)
 
1181
 
 
1182
        for monitor in range(0, self.screen_geo.get_num_monitors()):
 
1183
            panel = self.panels.get_panel_for_monitor(monitor)
 
1184
 
 
1185
            if monitor != text_win.monitor:
 
1186
                panel.window_buttons.unmaximize.mouse_click()
 
1187
                sleep(.25)
 
1188
                self.assertTrue(text_win.is_maximized)
 
1189
 
 
1190
    def test_hovering_indicators_on_multiple_monitors(self):
 
1191
        """Opening an indicator entry and then hovering others entries must open them."""
 
1192
        text_win = self.open_new_application_window("Text Editor")
 
1193
        panel = self.panels.get_panel_for_monitor(text_win.monitor)
 
1194
        indicator = panel.indicators.get_indicator_by_name_hint("indicator-session-devices")
 
1195
        self.mouse_open_indicator(indicator)
 
1196
 
 
1197
        for monitor in range(0, self.screen_geo.get_num_monitors()):
 
1198
            panel = self.panels.get_panel_for_monitor(monitor)
 
1199
 
 
1200
            entries = panel.get_indicator_entries(include_hidden_menus=True)
 
1201
            self.assertThat(len(entries), GreaterThan(0))
 
1202
 
 
1203
            for entry in entries:
 
1204
                entry.mouse_move_to()
 
1205
                sleep(.5)
 
1206
 
 
1207
                if monitor != self.panel_monitor and entry.type == "menu":
 
1208
                    self.assertFalse(entry.active)
 
1209
                    self.assertFalse(entry.visible)
 
1210
                    self.assertThat(entry.menu_y, Equals(0))
 
1211
                else:
 
1212
                    self.assertTrue(entry.visible)
 
1213
                    self.assertTrue(entry.active)
 
1214
                    self.assertThat(entry.menu_y, NotEquals(0))