Merge lp:~alexlauni/unity/unity.ap-switcher-emu into lp:unity

Proposed by Alex Launi on 2012-04-24
Status: Merged
Approved by: Thomi Richards on 2012-04-26
Approved revision: 2322
Merged at revision: 2349
Proposed branch: lp:~alexlauni/unity/unity.ap-switcher-emu
Merge into: lp:unity
Diff against target: 846 lines (+292/-298)
2 files modified
tests/autopilot/autopilot/emulators/unity/switcher.py (+124/-121)
tests/autopilot/autopilot/tests/test_switcher.py (+168/-177)
To merge this branch: bzr merge lp:~alexlauni/unity/unity.ap-switcher-emu
Reviewer Review Type Date Requested Status
Thomi Richards (community) 2012-04-24 Approve on 2012-04-26
Review via email: mp+103338@code.launchpad.net

Commit Message

Port autopilot switcher emulator to new-style API.

Description of the Change

Refactors autopilot switcher emulator, and updates tests to match.

To post a comment you must log in.
Thomi Richards (thomir) wrote :

Hi,

A few things:

== switcher.py ==

1) Diff has several bits of trailing whitespace:

116 + @property
170 +
310 +
330 +

2) Your docstrings need to be PEP257 compliant. Specifically:

"""One line docstrings look like this."""

"""Multi-line docstrings start with a single sentence.

Then a newline, followed by one or more sentences. Multi-line
docstrings end with a blank line before the closing quotes as
well, like this.

"""

3) The docstring for 'Switcher.property' should be changes, as should the implementation. Currently it will sometimes return a typle of items, and sometimes return a single item. I suggest the following:

    @property
    def mode(self):
        """Returns a tuple of SwitcherMode items that describe the mode the switcher is in.

        For example, to check whether the switcher is in details mode:

        >>> SwitcherMode.DETAIL in self.switcher.mode
        ... True

        """
        if not self.visible:
            return tuple()
        if self.controller.model.detail_selection and not self.controller.model.only_detail_on_viewport:
            return (SwitcherMode.DETAIL, SwitcherMode.ALL)
        elif self.controller.model.detail_selection:
            return (SwitcherMode.DETAIL,)
        elif not self.controller.model.only_detail_on_viewport:
            return (SwitcherMode.ALL,)
        else:
            return (SwitcherMode.NORMAL,)

== test_switcher.py ==

1) Unused import: NotEquals

2) PEP8 compliance: need 2 blank lines between module-level blocks. So 2 blank lines between the end of one class and the start of the next, and between the end of the import block and the start of the first class.

3) Docstring issues here similar to the switcher.py file.

4) Lots of trailing whitespace in this file!

5) Should probably use Eventually in the first few tests of SwitcherTests class, for example:

    def test_witcher_starts_in_normal_mode(self):
        """Switcher must start in normal (i.e.- not details) mode.

        """
        self.start_app("Character Map")
        sleep(1)

        self.switcher.initiate()
        self.addCleanup(self.switcher.terminate)
        self.assertThat(self.switcher.mode, Eventually(Equals(SwitcherMode.NORMAL)))

6) Is the alt+Tab timeout value an introspectable property? If not, can we make it one? THen we can replace this:

370 + def set_timeout_setting(self, value):
371 + self.set_unity_option("alt_tab_timeout", value)
372 + sleep(1)

With this:

370 + def set_timeout_setting(self, value):
371 + self.set_unity_option("alt_tab_timeout", value)
372 + self.switcher.alt_tab_timeout.wait_for(value)

Otherwise, looks good - all switcher tests pass for me locally.

review: Needs Fixing
2321. By Alex Launi on 2012-04-26

update from merge comments

2322. By Alex Launi on 2012-04-26

merge thomi's whitespace fixes

Thomi Richards (thomir) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/autopilot/autopilot/emulators/unity/switcher.py'
2--- tests/autopilot/autopilot/emulators/unity/switcher.py 2012-04-16 01:03:10 +0000
3+++ tests/autopilot/autopilot/emulators/unity/switcher.py 2012-04-26 20:14:23 +0000
4@@ -8,10 +8,9 @@
5 #
6
7 import logging
8-from time import sleep
9
10-from autopilot.emulators.unity import get_state_by_path, make_introspection_object
11-from autopilot.emulators.X11 import Keyboard, Mouse
12+from autopilot.emulators.unity import UnityIntrospectionObject
13+from autopilot.emulators.X11 import Mouse
14 from autopilot.keybindings import KeybindingsHelper
15
16 # even though we don't use these directly, we need to make sure they've been
17@@ -21,63 +20,80 @@
18
19 logger = logging.getLogger(__name__)
20
21-
22-# TODO: THis class needs to be ported to the new-style emulator classes.
23-# See launcher.py or dash.py for reference.
24+class SwitcherMode():
25+ """Define the possible modes the switcher can be in"""
26+ NORMAL = 0
27+ ALL = 1
28+ DETAIL = 2
29+
30+
31 class Switcher(KeybindingsHelper):
32- """Interact with the Unity switcher."""
33+ """A class for interacting with the switcher.
34+
35+ Abstracts out switcher implementation, and makes the necessary functionality available
36+ to consumer code.
37+
38+ """
39
40 def __init__(self):
41 super(Switcher, self).__init__()
42- self._keyboard = Keyboard()
43 self._mouse = Mouse()
44-
45- def initiate(self):
46- """Start the switcher with alt+tab."""
47- logger.debug("Initiating switcher with Alt+Tab")
48- self.keybinding_hold("switcher/reveal_normal")
49- self.keybinding_tap("switcher/reveal_normal")
50- sleep(1)
51-
52- def initiate_detail_mode(self):
53- """Start detail mode with alt+`"""
54- logger.debug("Initiating switcher detail mode with Alt+`")
55- self.keybinding_hold("switcher/reveal_details")
56- self.keybinding_tap("switcher/reveal_details")
57- sleep(1)
58-
59- def initiate_all_mode(self):
60- """Start switcher in 'all workspaces' mode.
61-
62- Shows apps from all workspaces, instead of just the current workspace.
63- """
64- logger.debug("Initiating switcher in 'all workspaces' mode.")
65- self.keybinding_hold("switcher/reveal_all")
66- self.keybinding_tap("switcher/reveal_all")
67- sleep(1)
68-
69- def initiate_right_arrow(self):
70- """Impropperly attempt to start switcher."""
71- logger.debug("Initiating switcher with Alt+Right (should not work)")
72- self.keybinding_hold("switcher/reveal_impropper")
73- self.keybinding_tap("switcher/right")
74- sleep(1)
75-
76- def terminate(self):
77- """Stop switcher without activating the selected icon."""
78- logger.debug("Terminating switcher.")
79- self.keybinding("switcher/cancel")
80- self.keybinding_release("switcher/reveal_normal")
81-
82- def cancel(self):
83- """Stop switcher without activating the selected icon and releasing the keys."""
84- logger.debug("Cancelling switcher.")
85- self.keybinding("switcher/cancel")
86-
87- def stop(self):
88- """Stop switcher and activate the selected icon."""
89- logger.debug("Stopping switcher")
90- self.keybinding_release("switcher/reveal_normal")
91+ controllers = SwitcherController.get_all_instances()
92+ assert(len(controllers) == 1)
93+ self.controller = controllers[0]
94+
95+ @property
96+ def visible(self):
97+ """Is the switcher currently visible
98+
99+ """
100+ return self.controller.visible
101+
102+ @property
103+ def icons(self):
104+ """The set of icons in the switcher model
105+
106+ """
107+ return self.controller.model.icons
108+
109+ @property
110+ def current_icon(self):
111+ """The currently selected switcher icon"""
112+ return self.icons[self.selection_index]
113+
114+ @property
115+ def selection_index(self):
116+ """The index of the currently selected icon"""
117+ return self.controller.model.selection_index
118+
119+ @property
120+ def mode(self):
121+ """Returns the SwitcherMode that the switcher is currently in."""
122+ if not self.visible:
123+ return None
124+ if self.controller.model.detail_selection and not self.controller.model.only_detail_on_viewport:
125+ return SwitcherMode.DETAIL, SwitcherMode.ALL
126+ elif self.controller.model.detail_selection:
127+ return SwitcherMode.DETAIL
128+ elif not self.controller.model.only_detail_on_viewport:
129+ return SwitcherMode.ALL
130+ else:
131+ return SwitcherMode.NORMAL
132+
133+ def initiate(self, mode=SwitcherMode.NORMAL):
134+ """Initiates the switcher in designated mode. Defaults to NORMAL"""
135+ if mode == SwitcherMode.NORMAL:
136+ logger.debug("Initiating switcher with Alt+Tab")
137+ self.keybinding_hold_part_then_tap("switcher/reveal_normal")
138+ self.visible.wait_for(True)
139+ elif mode == SwitcherMode.DETAIL:
140+ logger.debug("Initiating switcher detail mode with Alt+`")
141+ self.keybinding_hold_part_then_tap("switcher/reveal_details")
142+ self.controller.model.detail_selection.wait_for(True)
143+ elif mode == SwitcherMode.ALL:
144+ logger.debug("Initiating switcher in 'all workspaces' mode. Ctrl+Alt+Tab")
145+ self.keybinding_hold_part_then_tap("switcher/reveal_all")
146+ self.controller.model.only_detail_on_viewport.wait_for(False)
147
148 def next_icon(self):
149 """Move to the next icon."""
150@@ -89,14 +105,37 @@
151 logger.debug("Selecting previous item in switcher.")
152 self.keybinding("switcher/prev")
153
154- def next_icon_mouse(self):
155- """Move to the next icon using the mouse scroll wheel"""
156+ def cancel(self):
157+ """Stop switcher without activating the selected icon and releasing the keys.
158+
159+ NOTE: Does not release Alt.
160+
161+ """
162+ logger.debug("Cancelling switcher.")
163+ self.keybinding("switcher/cancel")
164+ self.controller.visible.wait_for(False)
165+
166+ def terminate(self):
167+ """Stop switcher without activating the selected icon."""
168+ logger.debug("Terminating switcher.")
169+ self.keybinding("switcher/cancel")
170+ self.keybinding_release("switcher/reveal_normal")
171+ self.controller.visible.wait_for(False)
172+
173+ def select(self):
174+ """Stop switcher and activate the selected icon."""
175+ logger.debug("Stopping switcher")
176+ self.keybinding_release("switcher/reveal_normal")
177+ self.controller.visible.wait_for(False)
178+
179+ def next_via_mouse(self):
180+ """Move to the next icon using the mouse scroll wheel."""
181 logger.debug("Selecting next item in switcher with mouse scroll wheel.")
182 self._mouse.press(6)
183 self._mouse.release(6)
184
185- def previous_icon_mouse(self):
186- """Move to the previous icon using the mouse scroll wheel"""
187+ def previous_via_mouse(self):
188+ """Move to the previous icon using the mouse scroll wheel."""
189 logger.debug("Selecting previous item in switcher with mouse scroll wheel.")
190 self._mouse.press(7)
191 self._mouse.release(7)
192@@ -105,11 +144,13 @@
193 """Show detail mode."""
194 logger.debug("Showing details view.")
195 self.keybinding("switcher/detail_start")
196+ self.controller.model.detail_selection.wait_for(True)
197
198 def hide_details(self):
199 """Hide detail mode."""
200 logger.debug("Hiding details view.")
201 self.keybinding("switcher/detail_stop")
202+ self.controller.model.detail_selection.wait_for(False)
203
204 def next_detail(self):
205 """Move to next detail in the switcher."""
206@@ -121,65 +162,27 @@
207 logger.debug("Selecting previous item in details mode.")
208 self.keybinding("switcher/detail_prev")
209
210- def __get_icon(self, index):
211- return self.__get_model()['Children'][index][1][0]
212-
213- @property
214- def current_icon(self):
215- """Get the currently-selected icon."""
216- if not self.get_is_visible:
217- return None
218- model = self.__get_model()
219- sel_idx = self.get_selection_index()
220- try:
221- return make_introspection_object(model['Children'][sel_idx])
222- except KeyError:
223- return None
224-
225- def get_icon_name(self, index):
226- return self.__get_icon(index)['tooltip_text']
227-
228- def get_icon_desktop_file(self, index):
229- try:
230- return self.__get_icon(index)['desktop_file']
231- except:
232- return None
233-
234- def get_model_size(self):
235- return len(self.__get_model()['Children'])
236-
237- def get_selection_index(self):
238- return int(self.__get_model()['selection-index'])
239-
240- def get_last_selection_index(self):
241- return bool(self.__get_model()['last-selection-index'])
242-
243- def get_is_visible(self):
244- return bool(self.__get_controller()['visible'])
245-
246- def get_monitor(self):
247- return int(self.__get_controller()['monitor'])
248-
249- def get_is_in_details_mode(self):
250- """Return True if the SwitcherView is in details mode."""
251- return bool(self.__get_model()['detail-selection'])
252-
253- def get_switcher_icons(self):
254- """Get all icons in the switcher model.
255-
256- The switcher needs to be initiated in order to get the model.
257-
258- """
259- icons = []
260- model = get_state_by_path('//SwitcherModel')[0]
261- for child in model['Children']:
262- icon = make_introspection_object(child)
263- if icon:
264- icons.append(icon)
265- return icons
266-
267- def __get_model(self):
268- return get_state_by_path('/Unity/SwitcherController/SwitcherModel')[0]
269-
270- def __get_controller(self):
271- return get_state_by_path('/Unity/SwitcherController')[0]
272+
273+class SwitcherController(UnityIntrospectionObject):
274+ """An emulator class for interacting with the switcher controller."""
275+
276+ @property
277+ def view(self):
278+ return self.get_children_by_type(SwitcherView)[0]
279+
280+ @property
281+ def model(self):
282+ return self.get_children_by_type(SwitcherModel)[0]
283+
284+
285+class SwitcherView(UnityIntrospectionObject):
286+ """An emulator class for interacting with with SwitcherView."""
287+
288+
289+class SwitcherModel(UnityIntrospectionObject):
290+ """An emulator class for interacting with the SwitcherModel."""
291+
292+ @property
293+ def icons(self):
294+ return self.get_children_by_type(SimpleLauncherIcon)
295+
296
297=== modified file 'tests/autopilot/autopilot/tests/test_switcher.py'
298--- tests/autopilot/autopilot/tests/test_switcher.py 2012-04-16 01:03:10 +0000
299+++ tests/autopilot/autopilot/tests/test_switcher.py 2012-04-26 20:14:23 +0000
300@@ -6,198 +6,172 @@
301 # under the terms of the GNU General Public License version 3, as published
302 # by the Free Software Foundation.
303
304-from testtools.matchers import Equals, NotEquals, Contains, Not
305+import logging
306+from testtools.matchers import Equals, Contains, Not
307 from time import sleep
308
309+from autopilot.matchers import Eventually
310+#from autopilot.emulators.window import Window
311+from autopilot.emulators.unity.switcher import SwitcherMode
312 from autopilot.tests import AutopilotTestCase
313
314-
315-class SwitcherTests(AutopilotTestCase):
316+logger = logging.getLogger(__name__)
317+
318+class SwitcherTestCase(AutopilotTestCase):
319+ def set_timeout_setting(self, value):
320+ self.set_unity_option("alt_tab_timeout", value)
321+ sleep(1)
322+
323+
324+class SwitcherTests(SwitcherTestCase):
325 """Test the switcher."""
326-
327 def set_timeout_setting(self, value):
328 self.set_unity_option("alt_tab_timeout", value)
329+ sleep(1)
330
331 def setUp(self):
332 super(SwitcherTests, self).setUp()
333-
334+ self.set_timeout_setting(False)
335 self.char_map = self.start_app('Character Map')
336 self.calc = self.start_app('Calculator')
337 self.mahjongg = self.start_app('Mahjongg')
338
339 def tearDown(self):
340 super(SwitcherTests, self).tearDown()
341+
342+ def test_nothing(self):
343+ pass
344+ #Window()
345+
346+ def test_witcher_starts_in_normal_mode(self):
347+ """Switcher must start in normal (i.e.- not details) mode."""
348+ self.start_app("Character Map")
349 sleep(1)
350
351+ self.switcher.initiate()
352+ self.addCleanup(self.switcher.terminate)
353+ self.assertThat(self.switcher.mode, Equals(SwitcherMode.NORMAL))
354+
355 def test_switcher_move_next(self):
356- self.set_timeout_setting(False)
357- sleep(1)
358-
359+ """Test that pressing the next icon binding moves to the next icon"""
360 self.switcher.initiate()
361- sleep(.2)
362+ self.addCleanup(self.switcher.terminate)
363
364- start = self.switcher.get_selection_index()
365+ start = self.switcher.selection_index
366 self.switcher.next_icon()
367- sleep(.2)
368-
369- end = self.switcher.get_selection_index()
370- self.switcher.terminate()
371-
372- self.assertThat(start, NotEquals(0))
373- self.assertThat(end, Equals(start + 1))
374+ self.assertThat(self.switcher.selection_index, Equals(start + 1))
375
376 def test_switcher_move_prev(self):
377- self.set_timeout_setting(False)
378- sleep(1)
379-
380+ """Test that pressing the previous icon binding moves to the previous icon"""
381 self.switcher.initiate()
382- sleep(.2)
383+ self.addCleanup(self.switcher.terminate)
384
385- start = self.switcher.get_selection_index()
386+ start = self.switcher.selection_index
387 self.switcher.previous_icon()
388- sleep(.2)
389-
390- end = self.switcher.get_selection_index()
391- self.switcher.terminate()
392-
393- self.assertThat(start, NotEquals(0))
394- self.assertThat(end, Equals(start - 1))
395+ self.assertThat(self.switcher.selection_index, Equals(start - 1))
396
397 def test_switcher_scroll_next(self):
398- self.set_timeout_setting(False)
399- sleep(1)
400-
401+ """Test that scrolling the mouse wheel down moves to the next icon"""
402 self.switcher.initiate()
403- sleep(.2)
404-
405- start = self.switcher.get_selection_index()
406- self.switcher.next_icon_mouse()
407- sleep(.2)
408-
409- end = self.switcher.get_selection_index()
410- self.assertThat(start, NotEquals(0))
411- self.assertThat(end, Equals(start + 1))
412-
413- self.switcher.terminate()
414+ self.addCleanup(self.switcher.terminate)
415+
416+ start = self.switcher.selection_index
417+ self.switcher.next_via_mouse()
418+
419+ self.assertThat(self.switcher.selection_index, Equals(start + 1))
420
421 def test_switcher_scroll_prev(self):
422- self.set_timeout_setting(False)
423- sleep(1)
424-
425+ """Test that scrolling the mouse wheel up moves to the previous icon"""
426 self.switcher.initiate()
427- sleep(.2)
428-
429- start = self.switcher.get_selection_index()
430- self.switcher.previous_icon_mouse()
431- sleep(.2)
432-
433- end = self.switcher.get_selection_index()
434- self.assertThat(start, NotEquals(0))
435+ self.addCleanup(self.switcher.terminate)
436+
437+ start = self.switcher.selection_index
438+ self.switcher.previous_via_mouse()
439+
440+ end = self.switcher.selection_index
441 self.assertThat(end, Equals(start - 1))
442
443 self.switcher.terminate()
444
445 def test_switcher_scroll_next_ignores_fast_events(self):
446- self.set_timeout_setting(False)
447- sleep(1)
448-
449+ """Ensures that smoothing is working correctly for next icon scrolling.
450+
451+ Only the first event in a rapid fire string of events should be acted upon.
452+ The rest ignored.
453+
454+ """
455 self.switcher.initiate()
456- sleep(.2)
457-
458- # Quickly repeatead events should be ignored (except the first)
459- start = self.switcher.get_selection_index()
460- self.switcher.next_icon_mouse()
461- self.switcher.next_icon_mouse()
462- self.switcher.next_icon_mouse()
463- sleep(.2)
464-
465- end = self.switcher.get_selection_index()
466- self.assertThat(start, NotEquals(0))
467- self.assertThat(end, Equals(start + 1))
468-
469- self.switcher.terminate()
470+ self.addCleanup(self.switcher.terminate)
471+
472+ # Quickly repeated events should be ignored (except the first)
473+ start = self.switcher.selection_index
474+ self.switcher.next_via_mouse()
475+ self.switcher.next_via_mouse()
476+ self.switcher.next_via_mouse()
477+
478+ self.assertThat(self.switcher.selection_index, Equals(start + 1))
479
480 def test_switcher_scroll_prev_ignores_fast_events(self):
481- self.set_timeout_setting(False)
482- sleep(1)
483-
484+ """Ensures that smoothing is working correctly for previous icon scrolling.
485+
486+ Only the first event in a rapid fire string of events should be acted upon.
487+ The rest ignored.
488+
489+ """
490 self.switcher.initiate()
491- sleep(.2)
492+ self.addCleanup(self.switcher.terminate)
493
494 # Quickly repeatead events should be ignored (except the first)
495- start = self.switcher.get_selection_index()
496- self.switcher.previous_icon_mouse()
497- self.switcher.previous_icon_mouse()
498- self.switcher.previous_icon_mouse()
499- sleep(.2)
500-
501- end = self.switcher.get_selection_index()
502- self.assertThat(end, Equals(start - 1))
503-
504- self.switcher.terminate()
505+ start = self.switcher.selection_index
506+ self.switcher.previous_via_mouse()
507+ self.switcher.previous_via_mouse()
508+ self.switcher.previous_via_mouse()
509+
510+ self.assertThat(self.switcher.selection_index, Equals(start - 1))
511
512 def test_switcher_arrow_key_does_not_init(self):
513- self.set_timeout_setting(False)
514- sleep(1)
515-
516- self.switcher.initiate_right_arrow()
517- sleep(.2)
518-
519- self.assertThat(self.switcher.get_is_visible(), Equals(False))
520- self.switcher.terminate()
521- self.set_timeout_setting(True)
522+ """Ensure that Alt+Right does not initiate switcher.
523+
524+ Regression test for LP:??????
525+
526+ """
527+ self.keyboard.press('Alt')
528+ self.addCleanup(self.keyboard.release, 'Alt')
529+ self.keyboard.press_and_release('Right')
530+ self.assertThat(self.switcher.visible, Equals(False))
531
532 def test_lazy_switcher_initiate(self):
533- self.set_timeout_setting(False)
534- sleep(1)
535-
536 self.keybinding_hold("switcher/reveal_normal")
537 self.addCleanup(self.keybinding_release, "switcher/reveal_normal")
538- sleep(1)
539- self.assertThat(self.switcher.get_is_visible(), Equals(False))
540+ self.assertThat(self.switcher.visible, Eventually(Equals(False)))
541
542- sleep(1)
543 self.keybinding_tap("switcher/reveal_normal")
544 self.addCleanup(self.keybinding, "switcher/cancel")
545- sleep(.5)
546- self.assertThat(self.switcher.get_is_visible(), Equals(True))
547+ self.assertThat(self.switcher.visible, Eventually(Equals(True)))
548
549 def test_switcher_cancel(self):
550- self.set_timeout_setting(False)
551- sleep(1)
552-
553 self.switcher.initiate()
554 self.addCleanup(self.switcher.terminate)
555- sleep(.2)
556-
557- self.assertThat(self.switcher.get_is_visible(), Equals(True))
558-
559+
560+ self.assertThat(self.switcher.visible, Eventually(Equals(True)))
561 self.switcher.cancel()
562- sleep(.2)
563-
564- self.assertThat(self.switcher.get_is_visible(), Equals(False))
565+ self.assertThat(self.switcher.visible, Eventually(Equals(False)))
566
567 def test_lazy_switcher_cancel(self):
568- self.set_timeout_setting(False)
569- sleep(1)
570-
571 self.keybinding_hold("switcher/reveal_normal")
572 self.addCleanup(self.keybinding_release, "switcher/reveal_normal")
573- sleep(1)
574- self.assertThat(self.switcher.get_is_visible(), Equals(False))
575-
576- sleep(1)
577+ self.assertThat(self.switcher.visible, Eventually(Equals(False)))
578 self.keybinding_tap("switcher/reveal_normal")
579- self.addCleanup(self.keybinding, "switcher/cancel")
580- sleep(.5)
581- self.assertThat(self.switcher.get_is_visible(), Equals(True))
582-
583+ self.assertThat(self.switcher.visible, Eventually(Equals(True)))
584 self.switcher.cancel()
585- sleep(.2)
586-
587- self.assertThat(self.switcher.get_is_visible(), Equals(False))
588+ self.assertThat(self.switcher.visible, Eventually(Equals(False)))
589
590 def test_switcher_appears_on_monitor_with_focused_window(self):
591+ """Tests that the switches appears on the correct monitor.
592+
593+ This is defined as the monitor with a focused window.
594+
595+ """
596 num_monitors = self.screen_geo.get_num_monitors()
597 if num_monitors == 1:
598 self.skip("No point testing this on one monitor")
599@@ -206,21 +180,24 @@
600 for monitor in range(num_monitors):
601 self.screen_geo.drag_window_to_monitor(calc_win, monitor)
602 self.switcher.initiate()
603- sleep(1)
604- self.assertThat(self.switcher.get_monitor(), Equals(monitor))
605- self.switcher.terminate()
606-
607-
608-class SwitcherWindowsManagementTests(AutopilotTestCase):
609+ self.addCleanup(self.switcher.terminate)
610+ self.assertThat(self.switcher.controller.monitor, Eventually(Equals(monitor)))
611+
612+
613+class SwitcherWindowsManagementTests(SwitcherTestCase):
614 """Test the switcher window management."""
615
616 def test_switcher_raises_only_last_focused_window(self):
617- """Tests that when we do an alt+tab only the previously focused window
618- is raised.
619+ """Tests that when we do an alt+tab only the previously focused window is raised.
620+
621 This is tests by opening 2 Calculators and a Mahjongg.
622 Then we do a quick alt+tab twice.
623 Then we close the currently focused window.
624+
625 """
626+ #FIXME: Setup
627+ # There are a lot of asserts in this test that are just making sure the env. is properly
628+ # initialized.
629 self.close_all_app("Mahjongg")
630 self.close_all_app("Calculator")
631
632@@ -243,37 +220,33 @@
633 self.assertTrue(mah_win2.is_focused)
634
635 self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
636+ #end setup?
637
638 self.keybinding("switcher/reveal_normal")
639 sleep(1)
640- self.assertTrue(calc_win.is_focused)
641+ self.assertThat(calc_win.is_focused, Equals(True))
642 self.assertVisibleWindowStack([calc_win, mah_win2, mah_win1])
643
644 self.keybinding("switcher/reveal_normal")
645 sleep(1)
646- self.assertTrue(mah_win2.is_focused)
647+ self.assertThat(mah_win2.is_focused, Equals(True))
648 self.assertVisibleWindowStack([mah_win2, calc_win, mah_win1])
649
650 self.keybinding("window/close")
651 sleep(1)
652-
653- self.assertTrue(calc_win.is_focused)
654+ self.assertThat(calc_win.is_focused, Equals(True))
655 self.assertVisibleWindowStack([calc_win, mah_win1])
656
657
658-class SwitcherDetailsTests(AutopilotTestCase):
659+class SwitcherDetailsTests(SwitcherTestCase):
660 """Test the details mode for the switcher."""
661-
662- def test_switcher_starts_in_normal_mode(self):
663- """Switcher must start in normal (i.e.- not details) mode."""
664- self.start_app("Character Map")
665- sleep(1)
666-
667- self.switcher.initiate()
668- self.addCleanup(self.switcher.terminate)
669- self.assertThat(self.switcher.get_is_in_details_mode(), Equals(False))
670+ def setUp(self):
671+ super(SwitcherDetailsTests, self).setUp()
672+ self.set_timeout_setting(True)
673
674 def test_details_mode_on_delay(self):
675+ """Test that details mode activates on a timeout."""
676+ #FIXME: Setup
677 self.close_all_app('Character Map')
678 self.workspace.switch_to(1)
679 self.start_app("Character Map")
680@@ -285,17 +258,23 @@
681 # the character map.
682 self.start_app('Mahjongg')
683 sleep(1)
684+ # end setup
685
686 self.switcher.initiate()
687 self.addCleanup(self.switcher.terminate)
688 # Wait longer than details mode.
689 sleep(3)
690- self.assertTrue(self.switcher.get_is_in_details_mode())
691+ self.assertThat(self.switcher.mode, Equals(SwitcherMode.DETAIL))
692
693 def test_no_details_for_apps_on_different_workspace(self):
694- # Re bug: 933406
695+ """Tests that details mode does not initiates when there are multiple windows
696+
697+ of an application spread across different workspaces.
698+ Regression test for LP:933406.
699+
700+ """
701+ #Fixme: setup
702 self.close_all_app('Character Map')
703-
704 self.workspace.switch_to(1)
705 self.start_app("Character Map")
706 sleep(1)
707@@ -306,15 +285,16 @@
708 # the character map.
709 self.start_app('Mahjongg')
710 sleep(1)
711+ # end setup
712
713 self.switcher.initiate()
714 self.addCleanup(self.switcher.terminate)
715 # Wait longer than details mode.
716 sleep(3)
717- self.assertFalse(self.switcher.get_is_in_details_mode())
718-
719-
720-class SwitcherDetailsModeTests(AutopilotTestCase):
721+ self.assertThat(self.switcher.mode, Equals(SwitcherMode.NORMAL))
722+
723+
724+class SwitcherDetailsModeTests(SwitcherTestCase):
725 """Tests for the details mode of the switcher.
726
727 Tests for initiation with both grave (`) and Down arrow.
728@@ -327,34 +307,38 @@
729 ]
730
731 def test_can_start_details_mode(self):
732- """Must be able to initiate details mode using selected scenario keycode."""
733+ """Must be able to initiate details mode using selected scenario keycode.
734+
735+ """
736 self.start_app("Character Map")
737 self.switcher.initiate()
738 self.addCleanup(self.switcher.terminate)
739 self.keyboard.press_and_release(self.initiate_keycode)
740- self.assertThat(self.switcher.get_is_in_details_mode(), Equals(True))
741-
742- def test_tab_from_last_detail_works(self):
743- """Pressing tab while showing last switcher item in details mode
744+ self.assertThat(self.switcher.mode, Equals(SwitcherMode.DETAIL))
745+
746+ def test_next_icon_from_last_detail_works(self):
747+ """Pressing next while showing last switcher item in details mode
748+
749 must select first item in the model in non-details mode.
750
751 """
752 self.start_app("Character Map")
753 self.switcher.initiate()
754 self.addCleanup(self.switcher.terminate)
755- while self.switcher.get_selection_index() < self.switcher.get_model_size() -1:
756+ while self.switcher.selection_index < len(self.switcher.icons) -1:
757 self.switcher.next_icon()
758 self.keyboard.press_and_release(self.initiate_keycode)
759 sleep(0.5)
760 self.switcher.next_icon()
761- self.assertThat(self.switcher.get_selection_index(), Equals(0))
762-
763-
764-class SwitcherWorkspaceTests(AutopilotTestCase):
765+ self.assertThat(self.switcher.selection_index, Equals(0))
766+
767+
768+class SwitcherWorkspaceTests(SwitcherTestCase):
769 """Test Switcher behavior with respect to multiple workspaces."""
770
771 def test_switcher_shows_current_workspace_only(self):
772 """Switcher must show apps from the current workspace only."""
773+ #FIXME: SETUP
774 self.close_all_app('Calculator')
775 self.close_all_app('Character Map')
776
777@@ -364,11 +348,12 @@
778 self.workspace.switch_to(2)
779 char_map = self.start_app("Character Map")
780 sleep(1)
781+ # END SETUP
782
783 self.switcher.initiate()
784- sleep(1)
785- icon_names = [i.tooltip_text for i in self.switcher.get_switcher_icons()]
786- self.switcher.terminate()
787+ self.addCleanup(self.switcher.terminate)
788+
789+ icon_names = [i.tooltip_text for i in self.switcher.icons]
790 self.assertThat(icon_names, Contains(char_map.name))
791 self.assertThat(icon_names, Not(Contains(calc.name)))
792
793@@ -377,23 +362,29 @@
794 self.close_all_app('Calculator')
795 self.close_all_app('Character Map')
796
797+ #FIXME: this is setup
798 self.workspace.switch_to(1)
799 calc = self.start_app("Calculator")
800 sleep(1)
801 self.workspace.switch_to(2)
802 char_map = self.start_app("Character Map")
803 sleep(1)
804-
805- self.switcher.initiate_all_mode()
806- sleep(1)
807- icon_names = [i.tooltip_text for i in self.switcher.get_switcher_icons()]
808- self.switcher.terminate()
809+ # END SETUP
810+
811+ self.switcher.initiate(SwitcherMode.ALL)
812+ self.addCleanup(self.switcher.terminate)
813+
814+ icon_names = [i.tooltip_text for i in self.switcher.icons]
815 self.assertThat(icon_names, Contains(calc.name))
816 self.assertThat(icon_names, Contains(char_map.name))
817
818 def test_switcher_can_switch_to_minimised_window(self):
819 """Switcher must be able to switch to a minimised window when there's
820- another instance of the same application on a different workspace."""
821+
822+ another instance of the same application on a different workspace.
823+
824+ """
825+ #FIXME this is setup.
826 # disable automatic gridding of the switcher after a timeout, since it makes
827 # it harder to write the tests.
828 self.set_unity_option("alt_tab_timeout", False)
829@@ -411,14 +402,14 @@
830
831 self.start_app("Calculator")
832 sleep(1)
833+ # END SETUP
834
835 self.switcher.initiate()
836- sleep(1)
837 while self.switcher.current_icon.tooltip_text != mahjongg.name:
838+ logger.debug("%s -> %s" % (self.switcher.current_icon.tooltip_text, mahjongg.name))
839 self.switcher.next_icon()
840 sleep(1)
841- self.switcher.stop()
842- sleep(1)
843+ self.switcher.select()
844
845 #get mahjongg windows - there should be two:
846 wins = mahjongg.get_windows()