diff -Nru unity-6.4.0/.pc.armhf/.quilt_patches unity-6.4.0/.pc.armhf/.quilt_patches --- unity-6.4.0/.pc.armhf/.quilt_patches 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/.pc.armhf/.quilt_patches 2012-09-01 20:08:50.000000000 +0000 @@ -0,0 +1 @@ +debian/patches/ diff -Nru unity-6.4.0/.pc.armhf/.quilt_series unity-6.4.0/.pc.armhf/.quilt_series --- unity-6.4.0/.pc.armhf/.quilt_series 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/.pc.armhf/.quilt_series 2012-09-01 20:08:50.000000000 +0000 @@ -0,0 +1 @@ +series diff -Nru unity-6.4.0/.pc.armhf/.version unity-6.4.0/.pc.armhf/.version --- unity-6.4.0/.pc.armhf/.version 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/.pc.armhf/.version 2012-09-01 20:08:50.000000000 +0000 @@ -0,0 +1 @@ +2 diff -Nru unity-6.4.0/.pc.armhf/series unity-6.4.0/.pc.armhf/series --- unity-6.4.0/.pc.armhf/series 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/.pc.armhf/series 2012-09-01 20:08:49.000000000 +0000 @@ -0,0 +1 @@ +disable_standalone-clients.patch diff -Nru unity-6.4.0/debian/changelog unity-6.4.0/debian/changelog --- unity-6.4.0/debian/changelog 2012-09-01 20:45:10.000000000 +0000 +++ unity-6.4.0/debian/changelog 2012-09-02 11:55:00.000000000 +0000 @@ -1,3 +1,9 @@ +unity (6.4.0-0ubuntu3) quantal-proposed; urgency=low + + * no-change rebuild to pick up nux-dev gles bits on armel/armhf + + -- Oliver Grawert Sun, 02 Sep 2012 11:54:17 +0000 + unity (6.4.0-0ubuntu2) quantal-proposed; urgency=low * debian/rules: "foo" really isnt a valid architecture, set diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/__init__.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/__init__.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/__init__.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,19 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +"""A collection of Unity-specific emulators.""" + + +from autopilot.introspection.dbus import DBusIntrospectionObject + + +class UnityIntrospectionObject(DBusIntrospectionObject): + + DBUS_SERVICE = "com.canonical.Unity" + DBUS_OBJECT = "/com/canonical/Unity/Debug" diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/dash.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/dash.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/dash.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/dash.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,550 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +from autopilot.emulators.X11 import Keyboard, Mouse +from autopilot.keybindings import KeybindingsHelper +from testtools.matchers import GreaterThan + +from unity.emulators import UnityIntrospectionObject +import logging +from time import sleep + + +logger = logging.getLogger(__name__) + + +class Dash(KeybindingsHelper): + """ + An emulator class that makes it easier to interact with the unity dash. + """ + + def __init__(self): + super(Dash, self).__init__() + controllers = DashController.get_all_instances() + assert(len(controllers) == 1) + self.controller = controllers[0] + self._keyboard = Keyboard() + + @property + def view(self): + return self.controller.get_dash_view() + + def toggle_reveal(self): + """ + Reveals the dash if it's currently hidden, hides it otherwise. + """ + old_state = self.visible + logger.debug("Toggling dash visibility with Super key.") + self.keybinding("dash/reveal", 0.1) + self.visible.wait_for(not old_state) + + def ensure_visible(self, clear_search=True): + """ + Ensures the dash is visible. + """ + if not self.visible: + self.toggle_reveal() + self.visible.wait_for(True) + if clear_search: + self.clear_search() + + def ensure_hidden(self): + """ + Ensures the dash is hidden. + """ + if self.visible: + self.toggle_reveal() + self.visible.wait_for(False) + + @property + def visible(self): + """Returns if the dash is currently visible""" + return self.controller.visible + + @property + def monitor(self): + """The monitor where the dash is""" + return self.controller.monitor + + @property + def search_string(self): + return self.searchbar.search_string + + @property + def searchbar(self): + """Returns the searchbar attached to the dash.""" + return self.view.get_searchbar() + + @property + def preview_displaying(self): + """Returns true if the dash is currently displaying a preview""" + return self.view.preview_displaying; + + def get_num_rows(self): + """Returns the number of displayed rows in the dash.""" + return self.view.num_rows + + def clear_search(self): + """Clear the contents of the search bar. + + Assumes dash is already visible, and search bar has keyboard focus. + + """ + self._keyboard.press_and_release("Ctrl+a") + self._keyboard.press_and_release("Delete") + self.search_string.wait_for("") + + def reveal_application_lens(self, clear_search=True): + """Reveal the application lense.""" + logger.debug("Revealing application lens with Super+a.") + self._reveal_lens("lens_reveal/apps", clear_search) + return self.view.get_lensview_by_name("applications.lens") + + def reveal_music_lens(self, clear_search=True): + """Reveal the music lense.""" + logger.debug("Revealing music lens with Super+m.") + self._reveal_lens("lens_reveal/music", clear_search) + return self.view.get_lensview_by_name("music.lens") + + def reveal_file_lens(self, clear_search=True): + """Reveal the file lense.""" + logger.debug("Revealing file lens with Super+f.") + self._reveal_lens("lens_reveal/files", clear_search) + return self.view.get_lensview_by_name("files.lens") + + def reveal_video_lens(self, clear_search=True): + """Reveal the video lens""" + logger.debug("Revealing video lens with Super+v.") + self._reveal_lens("lens_reveal/video", clear_search) + return self.view.get_lensview_by_name("video.lens") + + def reveal_command_lens(self, clear_search=True): + """Reveal the 'run command' lens.""" + logger.debug("Revealing command lens with Alt+F2.") + self._reveal_lens("lens_reveal/command", clear_search) + return self.view.get_lensview_by_name("commands.lens") + + def _reveal_lens(self, binding_name, clear_search): + self.keybinding_hold(binding_name) + self.keybinding_tap(binding_name) + self.keybinding_release(binding_name) + self.visible.wait_for(True) + if clear_search: + self.clear_search() + + @property + def active_lens(self): + return self.view.get_lensbar().active_lens + + def get_current_lens(self): + """Get the currently-active LensView object.""" + active_lens_name = self.view.get_lensbar().active_lens + return self.view.get_lensview_by_name(active_lens_name) + + +class DashController(UnityIntrospectionObject): + """The main dash controller object.""" + + def get_dash_view(self): + """Get the dash view that's attached to this controller.""" + return self.get_children_by_type(DashView)[0] + + +class DashView(UnityIntrospectionObject): + """The dash view.""" + + def get_searchbar(self): + """Get the search bar attached to this dash view.""" + return self.get_children_by_type(SearchBar)[0] + + def get_lensbar(self): + """Get the lensbar attached to this dash view.""" + return self.get_children_by_type(LensBar)[0] + + def get_lensview_by_name(self, lens_name): + """Get a LensView child object by it's name. For example, "home.lens".""" + lenses = self.get_children_by_type(LensView) + for lens in lenses: + if lens.name == lens_name: + return lens + + def get_preview_container(self): + """Get the preview container attached to this dash view.""" + preview_containers = self.get_children_by_type(PreviewContainer) + for preview_container in preview_containers: + return preview_container + return None + + +class SearchBar(UnityIntrospectionObject): + """The search bar for the dash view.""" + + +class LensBar(UnityIntrospectionObject): + """The bar of lens icons at the bottom of the dash.""" + def get_icon_by_name(self, name): + """Get a LensBarIcon child object by it's name. For example, 'home.lens'.""" + icons = self.get_children_by_type(LensBarIcon) + for icon in icons: + if icon.name == name: + return icon + +class LensBarIcon(UnityIntrospectionObject): + """A lens icon at the bottom of the dash.""" + + +class LensView(UnityIntrospectionObject): + """A Lens View.""" + + def get_groups(self): + """Get a list of all groups within this lensview. May return an empty list.""" + groups = self.get_children_by_type(PlacesGroup) + return groups + + def get_focused_category(self): + """Return a PlacesGroup instance for the category whose header has keyboard focus. + + Returns None if no category headers have keyboard focus. + + """ + categories = self.get_children_by_type(PlacesGroup) + matches = [m for m in categories if m.header_has_keyfocus] + if matches: + return matches[0] + return None + + def get_category_by_name(self, category_name): + """Return a PlacesGroup instance with the given name, or None.""" + categories = self.get_children_by_type(PlacesGroup) + matches = [m for m in categories if m.name == category_name] + if matches: + return matches[0] + return None + + def get_num_visible_categories(self): + """Get the number of visible categories in this lens.""" + return len([c for c in self.get_children_by_type(PlacesGroup) if c.is_visible]) + + def get_filterbar(self): + """Get the filter bar for the current lense, or None if it doesn't have one.""" + bars = self.get_children_by_type(FilterBar) + if bars: + return bars[0] + return None + + +class PlacesGroup(UnityIntrospectionObject): + """A category in the lense view.""" + + def get_results(self): + """Get a list of all results within this category. May return an empty list.""" + result_view = self.get_children_by_type(ResultView)[0] + return result_view.get_children_by_type(Result) + + +class ResultView(UnityIntrospectionObject): + """Contains a list of Result objects.""" + + +class Result(UnityIntrospectionObject): + """A single result in the dash.""" + + def activate(self): + tx = self.x + (self.width / 2) + ty = self.y + (self.height / 2) + m = Mouse() + m.move(tx, ty) + m.click(1) + + def preview(self): + tx = self.x + (self.width / 2) + ty = self.y + (self.height / 2) + m = Mouse() + m.move(tx, ty) + m.click(3) + + +class FilterBar(UnityIntrospectionObject): + """A filterbar, as shown inside a lens.""" + + def get_num_filters(self): + """Get the number of filters in this filter bar.""" + filters = self.get_children_by_type(FilterExpanderLabel) + return len(filters) + + def get_focused_filter(self): + """Returns the id of the focused filter widget.""" + filters = self.get_children_by_type(FilterExpanderLabel) + for filter_label in filters: + if filter_label.expander_has_focus: + return filter_label + return None + + @property + def expanded(self): + """Return True if the filterbar on this lens is expanded, False otherwise. + """ + searchbar = self._get_searchbar() + return searchbar.showing_filters + + def ensure_expanded(self): + """Expand the filter bar, if it's not already.""" + if not self.expanded: + searchbar = self._get_searchbar() + tx = searchbar.filter_label_x + (searchbar.filter_label_width / 2) + ty = searchbar.filter_label_y + (searchbar.filter_label_height / 2) + m = Mouse() + m.move(tx, ty) + m.click() + self.expanded.wait_for(True) + + def ensure_collapsed(self): + """Collapse the filter bar, if it's not already.""" + if self.expanded: + searchbar = self._get_searchbar() + tx = searchbar.filter_label_x + (searchbar.filter_label_width / 2) + ty = searchbar.filter_label_y + (searchbar.filter_label_height / 2) + m = Mouse() + m.move(tx, ty) + m.click() + self.expanded.wait_for(False) + + def _get_searchbar(self): + """Get the searchbar. + + This hack exists because there's now more than one SearchBar in Unity, + and for some reason the FilterBar stuff is bundled in the SearchBar. + + """ + searchbar_state = self.get_state_by_path("//DashView/SearchBar") + assert(len(searchbar_state) == 1) + return self.make_introspection_object(searchbar_state[0]) + + +class FilterExpanderLabel(UnityIntrospectionObject): + """A label that expands into a filter within a filter bar.""" + + def ensure_expanded(self): + """Expand the filter expander label, if it's not already""" + if not self.expanded: + tx = x + width / 2 + ty = y + height / 2 + m = Mouse() + m.move(tx, ty) + m.click() + self.expanded.wait_for(True) + + def ensure_collapsed(self): + """Collapse the filter expander label, if it's not already""" + if self.expanded: + tx = x + width / 2 + ty = y + height / 2 + m = Mouse() + m.move(tx, ty) + m.click() + self.expanded.wait_for(False) + + +class CoverArt(UnityIntrospectionObject): + """A view which can be used to show a texture, or generate one using a thumbnailer.""" + + +class RatingsButton(UnityIntrospectionObject): + """A button which shows user rating as a function of stars.""" + + +class Preview(UnityIntrospectionObject): + """A preview of a dash lens result.""" + + def get_num_actions(self): + """Get the number of actions for the preview.""" + actions = self.get_children_by_type(ActionButton) + return len(actions) + + def get_action_by_id(self, action_id): + """Returns the action given it's action hint.""" + actions = self.get_children_by_type(ActionButton) + for action in actions: + if action.action == action_id: + return action + return None + + def execute_action_by_id(action_id, action): + """Executes an action given by the id.""" + action = self.get_action_by_id(action_id) + if action: + tx = action.x + (searchbar.width / 2) + ty = action.y + (searchbar.height / 2) + m = Mouse() + m.move(tx, ty) + m.click() + + @property + def cover_art(self): + return self.get_children_by_type(CoverArt)[0] + +class ApplicationPreview(Preview): + """A application preview of a dash lens result.""" + +class GenericPreview(Preview): + """A generic preview of a dash lens result.""" + +class MusicPreview(Preview): + """A music preview of a dash lens result.""" + +class MoviePreview(Preview): + """A movie preview of a dash lens result.""" + +class PreviewContent(UnityIntrospectionObject): + """A preview content layout for the dash previews.""" + + def get_current_preview(self): + previews = self.get_children_by_type(Preview) + if len(previews) > 0: + return previews[0] + return None + + +class PreviewContainer(UnityIntrospectionObject): + """A container view for the main dash preview widget.""" + + @property + def content(self): + return self.get_content() + + def get_num_previews(self): + """Get the number of previews queued and current in the container.""" + previews = self.content.get_children_by_type(Preview) + return len(previews) + + def get_content(self): + """Get the preview content layout for the container.""" + return self.get_children_by_type(PreviewContent)[0] + + def get_left_navigator(self): + """Return the left navigator object""" + navigators = self.get_children_by_type(PreviewNavigator) + for nav in navigators: + if nav.direction == 2: + return nav + return None + + def get_right_navigator(self): + """Return the right navigator object""" + navigators = self.get_children_by_type(PreviewNavigator) + for nav in navigators: + if nav.direction == 3: + return nav + return None + + def navigate_left(self, count=1): + """Navigate preview left""" + navigator = self.get_left_navigator() + + tx = navigator.button_x + (navigator.button_width / 2) + ty = navigator.button_y + (navigator.button_height / 2) + m = Mouse() + m.move(tx, ty) + + old_preview_initiate_count = self.preview_initiate_count + + for i in range(count): + self.navigate_left_enabled.wait_for(True) + m.click() + self.preview_initiate_count.wait_for(GreaterThan(old_preview_initiate_count)) + old_preview_initiate_count = self.preview_initiate_count + + def navigate_right(self, count=1): + """Navigate preview right""" + navigator = self.get_right_navigator() + + tx = navigator.button_x + (navigator.button_width / 2) + ty = navigator.button_y + (navigator.button_height / 2) + m = Mouse() + m.move(tx, ty) + + old_preview_initiate_count = self.preview_initiate_count + + for i in range(count): + self.navigate_right_enabled.wait_for(True) + m.click() + self.preview_initiate_count.wait_for(GreaterThan(old_preview_initiate_count)) + old_preview_initiate_count = self.preview_initiate_count + + @property + def animating(self): + """Return True if the preview is animating, False otherwise.""" + return self.content.animating + + @property + def waiting_preview(self): + """Return True if waiting for a preview, False otherwise.""" + return self.content.waiting_preview + + @property + def animation_progress(self): + """Return the progress of the current preview animation.""" + return self.content.animation_progress + + @property + def current_preview(self): + """Return the current preview object.""" + return self.content.get_current_preview() + preview_initiate_count_ + + @property + def preview_initiate_count(self): + """Return the number of initiated previews since opened.""" + return self.content.preview_initiate_count + + @property + def navigation_complete_count(self): + """Return the number of completed previews since opened.""" + return self.content.navigation_complete_count + + @property + def relative_nav_index(self): + """Return the navigation position relative to the direction of movement.""" + return self.content.relative_nav_index + + @property + def navigate_right_enabled(self): + """Return True if right preview navigation is enabled, False otherwise.""" + return self.content.navigate_right_enabled + + @property + def navigate_left_enabled(self): + """Return True if left preview navigation is enabled, False otherwise.""" + return self.content.navigate_left_enabled + + +class PreviewNavigator(UnityIntrospectionObject): + """A view containing a button to nagivate between previews.""" + + def icon(self): + return self.get_children_by_type(IconTexture); + + +class PreviewRatingsWidget(UnityIntrospectionObject): + """A view containing a rating button and user rating count.""" + + +class Tracks(UnityIntrospectionObject): + """A view containing music tracks.""" + + +class Track(UnityIntrospectionObject): + """A singular music track for dash prevews.""" + + +class ActionButton(UnityIntrospectionObject): + """A preview action button.""" + diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/hud.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/hud.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/hud.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/hud.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,170 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +from autopilot.emulators.X11 import Keyboard +from autopilot.keybindings import KeybindingsHelper +from HTMLParser import HTMLParser +import re + +from unity.emulators import UnityIntrospectionObject +from unity.emulators.dash import SearchBar +from unity.emulators.icons import HudEmbeddedIcon, HudLauncherIcon + + +class Hud(KeybindingsHelper): + """An emulator class that makes it easier to iteract with unity hud.""" + + def __init__(self): + super (Hud, self).__init__() + controllers = HudController.get_all_instances() + assert(len(controllers) == 1) + self.controller = controllers[0] + self.keyboard = Keyboard() + + def ensure_hidden(self): + """Hides the hud if it's not already hidden.""" + if self.visible: + if self.search_string: + # need this to clear the search string, and then another to + # close the hud. + self.keyboard.press_and_release("Escape") + self.search_string.wait_for("") + self.keyboard.press_and_release("Escape") + self.visible.wait_for(False) + + def ensure_visible(self): + """Shows the hud if it's not already showing.""" + if not self.visible: + self.toggle_reveal() + self.visible.wait_for(True) + + def toggle_reveal(self, tap_delay=0.1): + """Tap the 'Alt' key to toggle the hud visibility.""" + old_state = self.visible + self.keybinding("hud/reveal", tap_delay) + self.visible.wait_for(not old_state) + + def get_embedded_icon(self): + """Returns the HUD view embedded icon or None if is not shown.""" + view = self.view + if (not view): + return None + + icons = view.get_children_by_type(HudEmbeddedIcon) + return icons[0] if icons else None + + def get_launcher_icon(self): + """Returns the HUD launcher icon""" + icons = HudLauncherIcon.get_all_instances() + assert(len(icons) == 1) + return icons[0] + + @property + def icon(self): + if self.is_locked_launcher: + return self.get_launcher_icon() + else: + return self.get_embedded_icon() + + @property + def view(self): + """Returns the HudView.""" + return self.controller.get_hud_view() + + @property + def visible(self): + """Is the Hud visible?""" + return self.controller.visible + + @property + def searchbar(self): + """Returns the searchbar attached to the hud.""" + return self.controller.get_hud_view().searchbar + + @property + def search_string(self): + """Returns the searchbars' search string.""" + return self.searchbar.search_string + + @property + def is_locked_launcher(self): + return self.controller.locked_to_launcher + + @property + def monitor(self): + return self.controller.hud_monitor + + @property + def geometry(self): + return (self.controller.x, self.controller.y, self.controller.width, self.controller.height) + + @property + def selected_button(self): + view = self.controller.get_hud_view() + if view: + return view.selected_button + else: + return 0 + + @property + def hud_buttons(self): + """Returns a list of current HUD buttons.""" + return self.view.hud_buttons + + @property + def selected_hud_button(self): + try: + [button] = filter(lambda x: x.focused, self.hud_buttons) + return button + except IndexError: + raise RuntimeError("No HUD buttons found, is hud active?") + + @property + def num_buttons(self): + view = self.controller.get_hud_view() + if view: + return view.num_buttons + else: + return 0 + + +class HudView(UnityIntrospectionObject): + """Proxy object for the hud view child of the controller.""" + + @property + def searchbar(self): + """Get the search bar attached to this hud view.""" + return self.get_children_by_type(SearchBar)[0] + + @property + def hud_buttons(self): + return self.get_children_by_type(HudButton) + + @property + def geometry(self): + return (self.x, self.y, self.width, self.height) + + +class HudController(UnityIntrospectionObject): + """Proxy object for the Unity Hud Controller.""" + + def get_hud_view(self): + views = self.get_children_by_type(HudView) + return views[0] if views else None + +class HudButton(UnityIntrospectionObject): + """Proxy object for the hud buttons.""" + + @property + def label_no_formatting(self): + """Returns the label text with the formatting removed.""" + htmlparser = HTMLParser() + return htmlparser.unescape(re.sub("<[^>]*>", "", self.label)) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/icons.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/icons.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/icons.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/icons.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,99 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +from unity.emulators import UnityIntrospectionObject +from unity.emulators.quicklist import Quicklist +from unity.emulators.tooltip import ToolTip + +class SimpleLauncherIcon(UnityIntrospectionObject): + """Holds information about a simple launcher icon. + + Do not instantiate an instance of this class yourself. Instead, use the + appropriate methods in the Launcher class instead. + + """ + + @property + def center_position(self): + """Get the center point of an icon, returns a tuple with (x, y, z).""" + return (self.center_x, self.center_y, self.center_z) + + def get_quicklist(self): + """Get the quicklist for this launcher icon. + + This may return None, if there is no quicklist associated with this + launcher icon. + + """ + matches = self.get_children_by_type(Quicklist) + return matches[0] if matches else None + + def get_tooltip(self): + """Get the tooltip for this launcher icon. + + This may return None, if there is no tooltip associated with this + launcher icon. + + """ + matches = self.get_children_by_type(ToolTip) + return matches[0] if matches else None + + def is_on_monitor(self, monitor): + """Returns True if the icon is available in the defined monitor.""" + if monitor >= 0 and monitor < len(self.monitors_visibility): + return self.monitors_visibility[monitor] + + return False + + def controls_window(self, xid): + """Returns true if the icon controls the specified xid.""" + + return self.xids.contains(xid) + + +class BFBLauncherIcon(SimpleLauncherIcon): + """Represents the BFB button in the launcher.""" + + +class HudLauncherIcon(SimpleLauncherIcon): + """Represents the HUD button in the launcher.""" + + +class BamfLauncherIcon(SimpleLauncherIcon): + """Represents a launcher icon with BAMF integration.""" + + +class TrashLauncherIcon(SimpleLauncherIcon): + """Represents the trash launcher icon.""" + + +class DeviceLauncherIcon(SimpleLauncherIcon): + """Represents a device icon in the launcher.""" + + +class DesktopLauncherIcon(SimpleLauncherIcon): + """Represents an icon that may appear in the switcher.""" + + +class SoftwareCenterLauncherIcon(BamfLauncherIcon): + """Represents a launcher icon of a Software Center app.""" + + +class HudEmbeddedIcon(UnityIntrospectionObject): + """Proxy object for the hud embedded icon child of the view.""" + + @property + def geometry(self): + return (self.x, self.y, self.width, self.height) + + +class LauncherEntry(UnityIntrospectionObject): + """Proxy for the LauncherEntryRemote instances in Unity.""" diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/launcher.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/launcher.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/launcher.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/launcher.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,503 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +from autopilot.emulators.dbus_handler import session_bus +from autopilot.emulators.X11 import Mouse, ScreenGeometry +from autopilot.keybindings import KeybindingsHelper +from autopilot.utilities import get_compiz_option +import dbus +import logging +from math import floor +from testtools.matchers import NotEquals +from time import sleep + +from unity.emulators import UnityIntrospectionObject +from unity.emulators.icons import BFBLauncherIcon, BamfLauncherIcon, SimpleLauncherIcon + +logger = logging.getLogger(__name__) + + +class IconDragType: + """Define possible positions to drag an icon onto another""" + INSIDE = 0 + OUTSIDE = 1 + + +class LauncherController(UnityIntrospectionObject): + """The LauncherController class.""" + + def get_launcher_for_monitor(self, monitor_num): + """Return an instance of Launcher for the specified monitor, or None.""" + launchers = self.get_children_by_type(Launcher, monitor=monitor_num) + return launchers[0] if launchers else None + + def get_launchers(self): + """Return the available launchers, or None.""" + return self.get_children_by_type(Launcher) + + @property + def model(self): + """Return the launcher model.""" + models = LauncherModel.get_all_instances() + assert(len(models) == 1) + return models[0] + + def add_launcher_item_from_position(self,name,icon,icon_x,icon_y,icon_size,desktop_file,aptdaemon_task): + """ Emulate a DBus call from Software Center to pin an icon to the launcher """ + launcher_object = session_bus.get_object('com.canonical.Unity.Launcher', + '/com/canonical/Unity/Launcher') + launcher_iface = dbus.Interface(launcher_object, 'com.canonical.Unity.Launcher') + launcher_iface.AddLauncherItemFromPosition(name, + icon, + icon_x, + icon_y, + icon_size, + desktop_file, + aptdaemon_task) + + +class Launcher(UnityIntrospectionObject, KeybindingsHelper): + """An individual launcher for a monitor.""" + + def __init__(self, *args, **kwargs): + super(Launcher, self).__init__(*args, **kwargs) + + self.show_timeout = 1 + self.hide_timeout = 1 + self.in_keynav_mode = False + self.in_switcher_mode = False + + self._mouse = Mouse() + self._screen = ScreenGeometry() + + def _perform_key_nav_binding(self, keybinding): + if not self.in_keynav_mode: + raise RuntimeError("Cannot perform key navigation when not in kaynav mode.") + self.keybinding(keybinding) + + def _perform_key_nav_exit_binding(self, keybinding): + self._perform_key_nav_binding(keybinding) + self.in_keynav_mode = False + + def _perform_switcher_binding(self, keybinding): + if not self.in_switcher_mode: + raise RuntimeError("Cannot interact with launcher switcher when not in switcher mode.") + self.keybinding(keybinding) + + def _perform_switcher_exit_binding(self, keybinding): + # If we're doing a normal activation, all we need to do is release the + # keybinding. Otherwise, perform the keybinding specified *then* release + # the switcher keybinding. + if keybinding != "launcher/switcher": + self._perform_switcher_binding(keybinding) + self.keybinding_release("launcher/switcher") + self.in_switcher_mode = False + + def _get_controller(self): + """Get the launcher controller.""" + [controller] = LauncherController.get_all_instances() + return controller + + def move_mouse_to_right_of_launcher(self): + """Places the mouse to the right of this launcher.""" + self._screen.move_mouse_to_monitor(self.monitor) + (x, y, w, h) = self.geometry + target_x = x + w + 10 + target_y = y + h / 2 + + logger.debug("Moving mouse away from launcher.") + self._mouse.move(target_x, target_y, False) + sleep(self.show_timeout) + + def move_mouse_over_launcher(self): + """Move the mouse over this launcher.""" + self._screen.move_mouse_to_monitor(self.monitor) + (x, y, w, h) = self.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + logger.debug("Moving mouse to center of launcher.") + self._mouse.move(target_x, target_y) + + def move_mouse_to_icon(self, icon): + # The icon may be off the bottom of screen, so we do this in a loop: + while 1: + target_x = icon.center_x + self.x + target_y = icon.center_y + if self._mouse.x == target_x and self._mouse.y == target_y: + break + self._mouse.move(target_x, target_y) + sleep(0.5) + + def mouse_reveal_launcher(self): + """Reveal this launcher with the mouse. + + If the launcher is already visible calling this method does nothing. + """ + if self.is_showing: + return + self._screen.move_mouse_to_monitor(self.monitor) + (x, y, w, h) = self.geometry + + target_x = x - 920 # this is the pressure we need to reveal the launcher. + target_y = y + h / 2 + logger.debug("Revealing launcher on monitor %d with mouse.", self.monitor) + self._mouse.move(target_x, target_y, True, 5, .002) + sleep(self.show_timeout) + + def keyboard_reveal_launcher(self): + """Reveal this launcher using the keyboard.""" + self._screen.move_mouse_to_monitor(self.monitor) + logger.debug("Revealing launcher with keyboard.") + self.keybinding_hold("launcher/reveal") + self.is_showing.wait_for(True) + + def keyboard_unreveal_launcher(self): + """Un-reveal this launcher using the keyboard.""" + self._screen.move_mouse_to_monitor(self.monitor) + logger.debug("Un-revealing launcher with keyboard.") + self.keybinding_release("launcher/reveal") + # only wait if the launcher is set to autohide + if self.hidemode == 1: + self.is_showing.wait_for(False) + + def keyboard_select_icon(self, **kwargs): + """Using either keynav mode or the switcher, select an icon in the launcher. + + The desired mode (keynav or switcher) must be started already before + calling this methods or a RuntimeError will be raised. + + This method won't activate the icon, it will only select it. + + Icons are selected by passing keyword argument filters to this method. + For example: + + >>> launcher.keyboard_select_icon(tooltip_text="Calculator") + + ...will select the *first* icon that has a 'tooltip_text' attribute equal + to 'Calculator'. If an icon is missing the attribute, it is treated as + not matching. + + If no icon is found, this method will raise a ValueError. + + """ + + if not self.in_keynav_mode and not self.in_switcher_mode: + raise RuntimeError("Launcher must be in keynav or switcher mode") + + [launcher_model] = LauncherModel.get_all_instances() + all_icons = launcher_model.get_launcher_icons() + logger.debug("all_icons = %r", [i.tooltip_text for i in all_icons]) + for icon in all_icons: + # can't iterate over the model icons directly since some are hidden + # from the user. + if not icon.visible: + continue + logger.debug("Selected icon = %s", icon.tooltip_text) + matches = True + for arg,val in kwargs.iteritems(): + if not hasattr(icon, arg) or getattr(icon, arg, None) != val: + matches = False + break + if matches: + return + if self.in_keynav_mode: + self.key_nav_next() + elif self.in_switcher_mode: + self.switcher_next() + raise ValueError("No icon found that matches: %r", kwargs) + + def key_nav_start(self): + """Start keyboard navigation mode by pressing Alt+F1.""" + self._screen.move_mouse_to_monitor(self.monitor) + logger.debug("Initiating launcher keyboard navigation with Alt+F1.") + self.keybinding("launcher/keynav") + self._get_controller().key_nav_is_active.wait_for(True) + self.in_keynav_mode = True + + def key_nav_cancel(self): + """End the key navigation.""" + logger.debug("Cancelling keyboard navigation mode.") + self._perform_key_nav_exit_binding("launcher/keynav/exit") + self._get_controller().key_nav_is_active.wait_for(False) + + def key_nav_activate(self): + """Activates the selected launcher icon. In the current implementation + this also exits key navigation""" + logger.debug("Ending keyboard navigation mode, activating icon.") + self._perform_key_nav_exit_binding("launcher/keynav/activate") + self._get_controller().key_nav_is_active.wait_for(False) + + def key_nav_next(self): + """Moves the launcher keynav focus to the next launcher icon""" + logger.debug("Selecting next item in keyboard navigation mode.") + old_selection = self._get_controller().key_nav_selection + self._perform_key_nav_binding("launcher/keynav/next") + self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection)) + + def key_nav_prev(self): + """Moves the launcher keynav focus to the previous launcher icon""" + logger.debug("Selecting previous item in keyboard navigation mode.") + old_selection = self._get_controller().key_nav_selection + self._perform_key_nav_binding("launcher/keynav/prev") + self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection)) + + def key_nav_enter_quicklist(self): + logger.debug("Opening quicklist for currently selected icon.") + self._perform_key_nav_binding("launcher/keynav/open-quicklist") + self.quicklist_open.wait_for(True) + + def key_nav_exit_quicklist(self): + logger.debug("Closing quicklist for currently selected icon.") + self._perform_key_nav_binding("launcher/keynav/close-quicklist") + self.quicklist_open.wait_for(False) + + def switcher_start(self): + """Start the super+Tab switcher on this launcher.""" + self._screen.move_mouse_to_monitor(self.monitor) + logger.debug("Starting Super+Tab switcher.") + self.keybinding_hold_part_then_tap("launcher/switcher") + self._get_controller().key_nav_is_active.wait_for(True) + self.in_switcher_mode = True + + def switcher_cancel(self): + """End the super+tab swithcer.""" + logger.debug("Cancelling keyboard navigation mode.") + self._perform_switcher_exit_binding("launcher/switcher/exit") + self._get_controller().key_nav_is_active.wait_for(False) + + def switcher_activate(self): + """Activates the selected launcher icon. In the current implementation + this also exits the switcher""" + logger.debug("Ending keyboard navigation mode.") + self._perform_switcher_exit_binding("launcher/switcher") + self._get_controller().key_nav_is_active.wait_for(False) + + def switcher_next(self): + logger.debug("Selecting next item in keyboard navigation mode.") + old_selection = self._get_controller().key_nav_selection + self._perform_switcher_binding("launcher/switcher/next") + self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection)) + + def switcher_prev(self): + logger.debug("Selecting previous item in keyboard navigation mode.") + old_selection = self._get_controller().key_nav_selection + self._perform_switcher_binding("launcher/switcher/prev") + self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection)) + + def switcher_up(self): + logger.debug("Selecting next item in keyboard navigation mode.") + old_selection = self._get_controller().key_nav_selection + self._perform_switcher_binding("launcher/switcher/up") + self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection)) + + def switcher_down(self): + logger.debug("Selecting previous item in keyboard navigation mode.") + old_selection = self._get_controller().key_nav_selection + self._perform_switcher_binding("launcher/switcher/down") + self._get_controller().key_nav_selection.wait_for(NotEquals(old_selection)) + + def click_launcher_icon(self, icon, button=1, move_mouse_after=True): + """Move the mouse over the launcher icon, and click it. + `icon` must be an instance of SimpleLauncherIcon or it's descendants. + `move_mouse_after` moves the mouse outside the launcher if true. + """ + if not isinstance(icon, SimpleLauncherIcon): + raise TypeError("icon must be a LauncherIcon, not %s" % type(icon)) + + logger.debug("Clicking launcher icon %r on monitor %d with mouse button %d", + icon, self.monitor, button) + self.mouse_reveal_launcher() + + # The icon may be off the screen, so we do this in a loop: + while 1: + target_x = icon.center_x + self.x + target_y = icon.center_y + if self._mouse.x == target_x and self._mouse.y == target_y: + break + self._mouse.move(target_x, target_y ) + sleep(1) + self._mouse.click(button) + if (move_mouse_after): + self.move_mouse_to_right_of_launcher() + + def drag_icon_to_position(self, icon, pos, drag_type=IconDragType.INSIDE): + """Place the supplied icon above the icon in the position pos. + + The icon is dragged inside or outside the launcher. + + >>> drag_icon_to_position(calc_icon, 0, IconDragType.INSIDE) + + This will drag the calculator icon above the bfb (but as you can't go + above the bfb it will move below it (to position 1)) + + """ + if not isinstance(icon, BamfLauncherIcon): + raise TypeError("icon must be a LauncherIcon") + + [launcher_model] = LauncherModel.get_all_instances() + all_icons = launcher_model.get_launcher_icons() + all_icon_len = len(all_icons) + if pos >= all_icon_len: + raise ValueError("pos is outside valid range (0-%d)" % all_icon_len) + + logger.debug("Dragging launcher icon %r on monitor %d to position %s" + % (icon, self.monitor, pos)) + self.mouse_reveal_launcher() + + icon_height = get_compiz_option("unityshell", "icon_size") + + target_icon = all_icons[pos] + if target_icon.id == icon.id: + logger.warning("%s is already the icon in position %d. Nothing to do." % (icon, pos)) + return + + self.move_mouse_to_icon(icon) + self._mouse.press() + sleep(2) + + if drag_type == IconDragType.OUTSIDE: + shift_over = self._mouse.x + (icon_height * 2) + self._mouse.move(shift_over, self._mouse.y) + sleep(0.5) + + # find the target drop position, between the center & top of the target icon + target_y = target_icon.center_y - floor(icon_height / 4) + + # Need to move the icons top (if moving up) or bottom (if moving + # downward) to the target position + moving_up = True if icon.center_y > target_icon.center_y else False + icon_half_height = floor(icon_height / 2) + fudge_factor = 5 + if moving_up or drag_type == IconDragType.OUTSIDE: + target_y += icon_half_height + fudge_factor + else: + target_y -= icon_half_height - fudge_factor + + self._mouse.move(self._mouse.x, target_y, rate=20, + time_between_events=0.05) + sleep(1) + + self._mouse.release() + self.move_mouse_to_right_of_launcher() + + def lock_to_launcher(self, icon): + """lock 'icon' to the launcher, if it's not already. + `icon` must be an instance of BamfLauncherIcon. + """ + if not isinstance(icon, BamfLauncherIcon): + raise TypeError("Can only lock instances of BamfLauncherIcon") + if icon.sticky: + # Nothing to do. + return + + logger.debug("Locking icon %r to launcher.", icon) + self.click_launcher_icon(icon, button=3) + quicklist = icon.get_quicklist() + pin_item = quicklist.get_quicklist_item_by_text('Lock to Launcher') + quicklist.click_item(pin_item) + + def unlock_from_launcher(self, icon): + """lock 'icon' to the launcher, if it's not already. + + `icon` must be an instance of BamfLauncherIcon. + + """ + if not isinstance(icon, BamfLauncherIcon): + raise TypeError("Can only unlock instances of BamfLauncherIcon") + if not icon.sticky: + # nothing to do. + return + + logger.debug("Unlocking icon %r from launcher.") + self.click_launcher_icon(icon, button=3) + quicklist = icon.get_quicklist() + pin_item = quicklist.get_quicklist_item_by_text('Unlock from Launcher') + quicklist.click_item(pin_item) + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the current launcher.""" + return (self.x, self.y, self.width, self.height) + + +class LauncherModel(UnityIntrospectionObject): + """The launcher model. Contains all launcher icons as children.""" + + def get_bfb_icon(self): + icons = BFBLauncherIcon.get_all_instances() + assert(len(icons) == 1) + return icons[0] + + def get_launcher_icons(self, visible_only=True): + """Get a list of launcher icons in this launcher.""" + if visible_only: + return self.get_children_by_type(SimpleLauncherIcon, visible=True) + else: + return self.get_children_by_type(SimpleLauncherIcon) + + def get_bamf_launcher_icons(self, visible_only=True): + """Get a list of bamf launcher icons in this launcher.""" + if visible_only: + return self.get_children_by_type(BamfLauncherIcon, visible=True) + else: + return self.get_children_by_type(BamfLauncherIcon) + + def get_launcher_icons_for_monitor(self, monitor, visible_only=True): + """Get a list of launcher icons for provided monitor.""" + icons = [] + for icon in self.get_launcher_icons(visible_only): + if icon.is_on_monitor(monitor): + icons.append(icon) + + return icons + + def get_icon(self, **kwargs): + """Get a launcher icon from the model according to some filters. + + This method accepts keyword argument that are the filters to use when + looking for an icon. For example, to find an icon with a particular + desktop_id, one might do this from within a test: + + >>> self.launcher.model.get_icon(desktop_id="gcalctool.desktop") + + This method returns only one icon. It is the callers responsibility to + ensure that the filter matches only one icon. + + This method will attempt to get the launcher icon, and will retry several + times, so the caller can be assured that if this method doesn't find + the icon it really does not exist. + + If no keyword arguments are specified, ValueError will be raised. + + If no icons are matched, None is returned. + + """ + + if not kwargs: + raise ValueError("You must specify at least one keyword argument to ths method.") + + for i in range(10): + icons = self.get_children_by_type(SimpleLauncherIcon, **kwargs) + if len(icons) > 1: + logger.warning("Got more than one icon returned using filters=%r. Returning first one", kwargs) + if icons: + return icons[0] + sleep(1) + return None + + def num_launcher_icons(self): + """Get the number of icons in the launcher model.""" + return len(self.get_launcher_icons()) + + def num_bamf_launcher_icons(self, visible_only=True): + """Get the number of bamf icons in the launcher model.""" + return len(self.get_bamf_launcher_icons(visible_only)) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/panel.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/panel.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/panel.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/panel.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,346 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +import logging +from time import sleep + +from autopilot.emulators.X11 import Mouse +from autopilot.keybindings import KeybindingsHelper + +from unity.emulators import UnityIntrospectionObject +logger = logging.getLogger(__name__) + + +class PanelController(UnityIntrospectionObject): + """The PanelController class.""" + + def get_panel_for_monitor(self, monitor_num): + """Return an instance of panel for the specified monitor, or None.""" + panels = self.get_children_by_type(UnityPanel, monitor=monitor_num) + assert(len(panels) == 1) + return panels[0] + + def get_active_panel(self): + """Return the active panel, or None.""" + panels = self.get_children_by_type(UnityPanel, active=True) + assert(len(panels) == 1) + return panels[0] + + def get_active_indicator(self): + for panel in self.get_panels: + active = panel.get_active_indicator() + if active: + return active + + return None + + @property + def get_panels(self): + """Return the available panels, or None.""" + return self.get_children_by_type(UnityPanel) + + +class UnityPanel(UnityIntrospectionObject, KeybindingsHelper): + """An individual panel for a monitor.""" + + def __init__(self, *args, **kwargs): + super(UnityPanel, self).__init__(*args, **kwargs) + self._mouse = Mouse() + + def __get_menu_view(self): + """Return the menu view.""" + menus = self.get_children_by_type(MenuView) + assert(len(menus) == 1) + return menus[0] + + def __get_window_buttons(self): + """Return the window buttons view.""" + buttons = self.menus.get_children_by_type(WindowButtons) + assert(len(buttons) == 1) + return buttons[0] + + def __get_grab_area(self): + """Return the panel grab area.""" + grab_areas = self.menus.get_children_by_type(GrabArea) + assert(len(grab_areas) == 1) + return grab_areas[0] + + def __get_indicators_view(self): + """Return the menu view.""" + indicators = self.get_children_by_type(Indicators) + assert(len(indicators) == 1) + return indicators[0] + + def move_mouse_below_the_panel(self): + """Places the mouse to bottom of this panel.""" + (x, y, w, h) = self.geometry + target_x = x + w / 2 + target_y = y + h + 10 + + logger.debug("Moving mouse away from panel.") + self._mouse.move(target_x, target_y) + + def move_mouse_over_menus(self): + """Move the mouse over the menu area for this panel.""" + (x, y, w, h) = self.menus.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + # The menu view has bigger geometry than the real layout + menu_entries = self.menus.get_entries() + if len(menu_entries) > 0: + first_x = menu_entries[0].x + last_x = menu_entries[-1].x + menu_entries[-1].width / 2 + + target_x = first_x + (last_x - first_x) / 2 + + logger.debug("Moving mouse to center of menu area.") + self._mouse.move(target_x, target_y) + + def move_mouse_over_grab_area(self): + """Move the mouse over the grab area for this panel.""" + (x, y, w, h) = self.grab_area.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + logger.debug("Moving mouse to center of grab area.") + self._mouse.move(target_x, target_y) + + def move_mouse_over_window_buttons(self): + """Move the mouse over the center of the window buttons area for this panel.""" + (x, y, w, h) = self.window_buttons.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + logger.debug("Moving mouse to center of the window buttons.") + self._mouse.move(target_x, target_y) + + def move_mouse_over_indicators(self): + """Move the mouse over the center of the indicators area for this panel.""" + (x, y, w, h) = self.indicators.geometry + target_x = x + w / 2 + target_y = y + h / 2 + + logger.debug("Moving mouse to center of the indicators area.") + self._mouse.move(target_x, target_y) + + def get_indicator_entries(self, visible_only=True, include_hidden_menus=False): + """Returns a list of entries for this panel including both menus and indicators""" + entries = [] + if include_hidden_menus or self.menus_shown: + entries = self.menus.get_entries() + entries += self.indicators.get_ordered_entries(visible_only) + return entries + + def get_active_indicator(self): + """Returns the indicator entry that is currently active""" + entries = self.get_indicator_entries(False, True) + entries = filter(lambda e: e.active == True, entries) + assert(len(entries) <= 1) + return entries[0] if entries else None + + def get_indicator_entry(self, entry_id): + """Returns the indicator entry for the given ID or None""" + entries = self.get_indicator_entries(False, True) + entries = filter(lambda e: e.entry_id == entry_id, entries) + assert(len(entries) <= 1) + return entries[0] if entries else None + + @property + def title(self): + return self.menus.panel_title + + @property + def desktop_is_active(self): + return self.menus.desktop_active + + @property + def menus_shown(self): + return self.active and self.menus.draw_menus + + @property + def window_buttons_shown(self): + return self.menus.draw_window_buttons + + @property + def window_buttons(self): + return self.__get_window_buttons() + + @property + def menus(self): + return self.__get_menu_view() + + @property + def grab_area(self): + return self.__get_grab_area() + + @property + def indicators(self): + return self.__get_indicators_view() + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the current panel.""" + return (self.x, self.y, self.width, self.height) + + +class MenuView(UnityIntrospectionObject): + """The Menu View class.""" + + def get_entries(self): + """Return a list of menu entries""" + return self.get_children_by_type(IndicatorEntry) + + def get_menu_by_label(self, entry_label): + """Return the first indicator entry found with the given label""" + indicators = self.get_children_by_type(IndicatorEntry, label=entry_label) + return indicators[0] if indicators else None + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the current menu view.""" + return (self.x, self.y, self.width, self.height) + + +class WindowButtons(UnityIntrospectionObject): + """The window buttons class""" + + def get_buttons(self, visible_only=True): + """Return a list of window buttons""" + if visible_only: + return self.get_children_by_type(WindowButton, visible=True) + else: + return self.get_children_by_type(WindowButton) + + def get_button(self, type): + buttons = self.get_children_by_type(WindowButton, type=type) + assert(len(buttons) == 1) + return buttons[0] + + @property + def visible(self): + return len(self.get_buttons()) != 0 + + @property + def close(self): + return self.get_button("Close") + + @property + def minimize(self): + return self.get_button("Minimize") + + @property + def unmaximize(self): + return self.get_button("Unmaximize") + + @property + def maximize(self): + return self.get_button("Maximize") + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the current panel.""" + return (self.x, self.y, self.width, self.height) + + +class WindowButton(UnityIntrospectionObject): + """The Window WindowButton class.""" + + def __init__(self, *args, **kwargs): + super(WindowButton, self).__init__(*args, **kwargs) + self._mouse = Mouse() + + def mouse_move_to(self): + target_x = self.x + self.width / 2 + target_y = self.y + self.height / 2 + self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005) + + def mouse_click(self): + self.mouse_move_to() + sleep(.2) + self._mouse.click(press_duration=.1) + sleep(.01) + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the window button.""" + return (self.x, self.y, self.width, self.height) + + +class GrabArea(UnityIntrospectionObject): + """The grab area class""" + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the grab area.""" + return (self.x, self.y, self.width, self.height) + + +class Indicators(UnityIntrospectionObject): + """The Indicators View class.""" + + def get_ordered_entries(self, visible_only=True): + """Return a list of indicators, ordered by their priority""" + + if visible_only: + entries = self.get_children_by_type(IndicatorEntry, visible=True) + else: + entries = self.get_children_by_type(IndicatorEntry) + + return sorted(entries, key=lambda entry: entry.priority) + + def get_indicator_by_name_hint(self, name_hint): + """Return the IndicatorEntry with the name_hint""" + indicators = self.get_children_by_type(IndicatorEntry, name_hint=name_hint) + assert(len(indicators) == 1) + return indicators[0] + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the indicators area.""" + return (self.x, self.y, self.width, self.height) + + +class IndicatorEntry(UnityIntrospectionObject): + """The IndicatorEntry View class.""" + + def __init__(self, *args, **kwargs): + super(IndicatorEntry, self).__init__(*args, **kwargs) + self._mouse = Mouse() + + def mouse_move_to(self): + target_x = self.x + self.width / 2 + target_y = self.y + self.height / 2 + self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005) + + def mouse_click(self, button=1): + self.mouse_move_to() + sleep(.2) + assert(self.visible) + self._mouse.click(press_duration=.1) + sleep(.01) + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the indicator entry.""" + return (self.x, self.y, self.width, self.height) + + @property + def menu_geometry(self): + """Returns a tuple of (x,y,w,h) for the opened menu geometry.""" + return (self.menu_x, self.menu_y, self.menu_width, self.menu_height) + + def __repr__(self): + return "" % (id(self), self.label) + + +class Tray(UnityIntrospectionObject): + """A panel tray object.""" diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/quicklist.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/quicklist.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/quicklist.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/quicklist.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,103 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +import logging + +from autopilot.emulators.X11 import Mouse + +from unity.emulators import UnityIntrospectionObject + +logger = logging.getLogger(__name__) + + +class Quicklist(UnityIntrospectionObject): + """Represents a quicklist.""" + + @property + def items(self): + """Individual items in the quicklist.""" + return self.get_children_by_type(QuicklistMenuItem, visible=True) + + @property + def selectable_items(self): + """Items that can be selected in the quicklist.""" + return self.get_children_by_type(QuicklistMenuItem, visible=True, selectable=True) + + def get_quicklist_item_by_text(self, text): + """Returns a QuicklistMenuItemLabel object with the given text, or None.""" + if not self.active: + raise RuntimeError("Cannot get quicklist items. Quicklist is inactive!") + + matches = self.get_children_by_type(QuicklistMenuItemLabel, text=text) + + return matches[0] if matches else None + + def get_quicklist_application_item(self, application_name): + """Returns the QuicklistMenuItemLabel for the given application_name""" + return self.get_quicklist_item_by_text(""+application_name+"") + + def click_item(self, item): + """Click one of the quicklist items.""" + if not isinstance(item, QuicklistMenuItem): + raise TypeError("Item must be a subclass of QuicklistMenuItem") + + item.mouse_click() + + def move_mouse_to_right(self): + """Moves the mouse outside the quicklist""" + logger.debug("Moving mouse outside the quicklist %r", self) + target_x = self.x + self.width + 10 + target_y = self.y + self.height / 2 + Mouse().move(target_x, target_y, animate=False) + + @property + def selected_item(self): + items = self.get_children_by_type(QuicklistMenuItem, selected=True) + assert(len(items) <= 1) + return items[0] if items else None + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the quicklist.""" + return (self.x, self.y, self.width, self.height) + + +class QuicklistMenuItem(UnityIntrospectionObject): + """Represents a single item in a quicklist.""" + + def __init__(self, *args, **kwargs): + super(QuicklistMenuItem, self).__init__(*args, **kwargs) + self._mouse = Mouse() + + @property + def geometry(self): + """Returns a tuple of (x,y,w,h) for the quicklist item.""" + return (self.x, self.y, self.width, self.height) + + def mouse_move_to(self): + assert(self.visible) + logger.debug("Moving mouse over quicklist item %r", self) + target_x = self.x + self.width / 2 + target_y = self.y + self.height / 2 + self._mouse.move(target_x, target_y, rate=20, time_between_events=0.005) + + def mouse_click(self, button=1): + logger.debug("Clicking on quicklist item %r", self) + self.mouse_move_to() + self._mouse.click() + + +class QuicklistMenuItemLabel(QuicklistMenuItem): + """Represents a text label inside a quicklist.""" + + +class QuicklistMenuItemSeparator(QuicklistMenuItem): + """Represents a separator in a quicklist.""" diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/shortcut_hint.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/shortcut_hint.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/shortcut_hint.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/shortcut_hint.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,59 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +import logging + +from autopilot.keybindings import KeybindingsHelper + +from unity.emulators import UnityIntrospectionObject + +logger = logging.getLogger(__name__) + +class ShortcutView(UnityIntrospectionObject): + """Proxy object for the shortcut view child of the controller.""" + +class ShortcutController(UnityIntrospectionObject, KeybindingsHelper): + """ShortcutController proxy class.""" + + def get_shortcut_view(self): + views = self.get_children_by_type(ShortcutView) + return views[0] if views else None + + def show(self): + """Push the keys necessary to reveal the shortcut hint, but don't block.""" + logger.debug("Revealing shortcut hint with keyboard.") + self.keybinding_hold("shortcuthint/reveal") + + def ensure_visible(self): + """Block until the shortcut hint is visible.""" + if not self.visible: + logger.debug("Revealing shortcut hint with keyboard.") + self.keybinding_hold("shortcuthint/reveal") + self.visible.wait_for(True) + + def hide(self): + """Release the keys keeping the shortcut hint open, but don't block.""" + logger.debug("Un-revealing shortcut hint with keyboard.") + self.keybinding_release("shortcuthint/reveal") + + def ensure_hidden(self): + """Block until the shortcut hint is hidden.""" + if self.visible: + logger.debug("Un-revealing shortcut hint with keyboard.") + self.keybinding_release("shortcuthint/reveal") + self.visible.wait_for(False) + + def cancel(self): + logger.debug("Hide the shortcut hint with keyboard, without releasing the reveal key.") + self.keybinding("shortcuthint/cancel") + + def get_show_timeout(self): + return self.timeout_duration / 1000.0 diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/switcher.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/switcher.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/switcher.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/switcher.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,239 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +import logging + +from autopilot.emulators.X11 import Mouse +from autopilot.keybindings import KeybindingsHelper + +from unity.emulators import UnityIntrospectionObject +# even though we don't use these directly, we need to make sure they've been +# imported so the classes contained are registered with the introspection API. +from unity.emulators.icons import * + + +logger = logging.getLogger(__name__) + +class SwitcherMode(): + """Define the possible modes the switcher can be in""" + NORMAL = 0 + ALL = 1 + DETAIL = 2 + + +class Switcher(KeybindingsHelper): + """A class for interacting with the switcher. + + Abstracts out switcher implementation, and makes the necessary functionality available + to consumer code. + + """ + + DIRECTION_FORWARDS = 0 + DIRECTION_BACKWARDS = 1 + + def __init__(self): + super(Switcher, self).__init__() + self._mouse = Mouse() + controllers = SwitcherController.get_all_instances() + assert(len(controllers) == 1) + self.controller = controllers[0] + + @property + def visible(self): + """Is the switcher currently visible + + """ + return self.controller.visible + + @property + def icons(self): + """The set of icons in the switcher model + + """ + return self.controller.model.icons + + @property + def current_icon(self): + """The currently selected switcher icon""" + return self.icons[self.selection_index] + + @property + def selection_index(self): + """The index of the currently selected icon""" + return self.controller.model.selection_index + + @property + def mode(self): + """Returns the SwitcherMode that the switcher is currently in.""" + if not self.visible: + return None + 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 + + def initiate(self, mode=SwitcherMode.NORMAL): + """Initiates the switcher in designated mode. Defaults to NORMAL""" + if mode == SwitcherMode.NORMAL: + logger.debug("Initiating switcher with Alt+Tab") + self.keybinding_hold_part_then_tap("switcher/reveal_normal") + self.visible.wait_for(True) + elif mode == SwitcherMode.DETAIL: + logger.debug("Initiating switcher detail mode with Alt+`") + self.keybinding_hold_part_then_tap("switcher/reveal_details") + self.visible.wait_for(True) + elif mode == SwitcherMode.ALL: + logger.debug("Initiating switcher in 'all workspaces' mode. Ctrl+Alt+Tab") + self.keybinding_hold_part_then_tap("switcher/reveal_all") + self.controller.model.only_detail_on_viewport.wait_for(False) + + def next_icon(self): + """Move to the next icon.""" + logger.debug("Selecting next item in switcher.") + self.keybinding("switcher/next") + + def previous_icon(self): + """Move to the previous icon.""" + logger.debug("Selecting previous item in switcher.") + self.keybinding("switcher/prev") + + def select_icon(self, direction, **kwargs): + """Select an icon in the switcher. + + direction must be one of Switcher.DIRECTION_FORWARDS or Switcher.DIRECTION_BACKWARDS. + + The keyword arguments are used to select an icon. For example, you might + do this to select the 'Show Desktop' icon: + + >>> self.switcher.select_icon(Switcher.DIRECTION_BACKWARDS, tooltip_text="Show Desktop") + + The switcher must be initiated already, and must be in normal mode when + this method is called, or a RuntimeError will be raised. + + If no icon matches, a ValueError will be raised. + + """ + if self.mode != SwitcherMode.NORMAL: + raise RuntimeError("Switcher must be initiated in normal mode before calling this method.") + + if direction not in (self.DIRECTION_BACKWARDS, self.DIRECTION_FORWARDS): + raise ValueError("direction must be one of Switcher.DIRECTION_BACKWARDS, Switcher.DIRECTION_FORWARDS") + + for i in self.controller.model.icons: + current_icon = self.current_icon + passed=True + for key,val in kwargs.iteritems(): + if not hasattr(current_icon, key) or getattr(current_icon, key) != val: + passed=False + if passed: + return + if direction == self.DIRECTION_FORWARDS: + self.next_icon() + elif direction == self.DIRECTION_BACKWARDS: + self.previous_icon() + raise ValueError("No icon found in switcher model that matches: %r" % kwargs) + + def cancel(self): + """Stop switcher without activating the selected icon and releasing the keys. + + NOTE: Does not release Alt. + + """ + logger.debug("Cancelling switcher.") + self.keybinding("switcher/cancel") + self.controller.visible.wait_for(False) + + def terminate(self): + """Stop switcher without activating the selected icon.""" + logger.debug("Terminating switcher.") + self.keybinding("switcher/cancel") + self.keybinding_release("switcher/reveal_normal") + self.controller.visible.wait_for(False) + + def select(self): + """Stop switcher and activate the selected icon.""" + logger.debug("Stopping switcher") + self.keybinding_release("switcher/reveal_normal") + self.controller.visible.wait_for(False) + + def next_via_mouse(self): + """Move to the next icon using the mouse scroll wheel.""" + logger.debug("Selecting next item in switcher with mouse scroll wheel.") + self._mouse.press(6) + self._mouse.release(6) + + def previous_via_mouse(self): + """Move to the previous icon using the mouse scroll wheel.""" + logger.debug("Selecting previous item in switcher with mouse scroll wheel.") + self._mouse.press(7) + self._mouse.release(7) + + @property + def detail_selection_index(self): + """The index of the currently selected detail""" + return self.controller.model.detail_selection_index + + @property + def detail_current_count(self): + """The number of shown details""" + return self.controller.model.detail_current_count + + def show_details(self): + """Show detail mode.""" + logger.debug("Showing details view.") + self.keybinding("switcher/detail_start") + self.controller.model.detail_selection.wait_for(True) + + def hide_details(self): + """Hide detail mode.""" + logger.debug("Hiding details view.") + self.keybinding("switcher/detail_stop") + self.controller.model.detail_selection.wait_for(False) + + def next_detail(self): + """Move to next detail in the switcher.""" + logger.debug("Selecting next item in details mode.") + self.keybinding("switcher/detail_next") + + def previous_detail(self): + """Move to the previous detail in the switcher.""" + logger.debug("Selecting previous item in details mode.") + self.keybinding("switcher/detail_prev") + + +class SwitcherController(UnityIntrospectionObject): + """An emulator class for interacting with the switcher controller.""" + + @property + def view(self): + return self.get_children_by_type(SwitcherView)[0] + + @property + def model(self): + return self.get_children_by_type(SwitcherModel)[0] + + +class SwitcherView(UnityIntrospectionObject): + """An emulator class for interacting with with SwitcherView.""" + + +class SwitcherModel(UnityIntrospectionObject): + """An emulator class for interacting with the SwitcherModel.""" + + @property + def icons(self): + return self.get_children_by_type(SimpleLauncherIcon) + diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/tooltip.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/tooltip.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/tooltip.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/tooltip.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,16 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Andrea Azzarone +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +from unity.emulators import UnityIntrospectionObject + + +class ToolTip(UnityIntrospectionObject): + """Represents a tooltip.""" diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/unity.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/unity.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/unity.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/unity.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,62 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +from autopilot.emulators.dbus_handler import session_bus +from dbus import Interface + +# acquire the debugging dbus object +UNITY_BUS_NAME = 'com.canonical.Unity' +DEBUG_PATH = '/com/canonical/Unity/Debug' +LOGGING_IFACE = 'com.canonical.Unity.Debug.Logging' + + +def get_dbus_proxy_object(): + return session_bus.get_object(UNITY_BUS_NAME, DEBUG_PATH) + + +def get_dbus_logging_interface(): + return Interface(get_dbus_proxy_object(), LOGGING_IFACE) + + +def start_log_to_file(file_path): + """Instruct Unity to start logging to the given file.""" + get_dbus_logging_interface().StartLogToFile(file_path) + + +def reset_logging(): + """Instruct Unity to stop logging to a file.""" + get_dbus_logging_interface().ResetLogging() + + +def set_log_severity(component, severity): + """Instruct Unity to set a log component's severity. + + 'component' is the unity logging component name. + + 'severity' is the severity name (like 'DEBUG', 'INFO' etc.) + + """ + get_dbus_logging_interface().SetLogSeverity(component, severity) + + +def log_unity_message(severity, message): + """Instruct unity to log a message for us. + + severity: one of ('TRACE', 'DEBUG', 'INFO', 'WARNING', 'ERROR'). + + message: The message to log. + + For debugging purposes only! If you want to log a message during an autopilot + test, use the python logging framework instead. + + """ + get_dbus_logging_interface().LogMessage(severity, message) + diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/window_manager.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/window_manager.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/window_manager.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/window_manager.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,44 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + +import logging +from autopilot.keybindings import KeybindingsHelper + +from unity.emulators import UnityIntrospectionObject + +logger = logging.getLogger(__name__) + + +class WindowManager(UnityIntrospectionObject, KeybindingsHelper): + """The WindowManager class.""" + + @property + def screen_geometry(self): + """Returns a tuple of (x,y,w,h) for the screen.""" + return (self.x, self.y, self.width, self.height) + + def enter_show_desktop(self): + if not self.showdesktop_active: + logger.info("Entering show desktop mode.") + self.keybinding("window/show_desktop") + self.showdesktop_active.wait_for(True) + else: + logger.warning("Test tried to enter show desktop mode while already \ + in show desktop mode.") + + def leave_show_desktop(self): + if self.showdesktop_active: + logger.info("Leaving show desktop mode.") + self.keybinding("window/show_desktop") + self.showdesktop_active.wait_for(False) + else: + logger.warning("Test tried to leave show desktop mode while not in \ + show desktop mode.") diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/workspace.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/workspace.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/workspace.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/emulators/workspace.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,93 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# + +from __future__ import absolute_import + + +from autopilot.globals import global_context +from autopilot.keybindings import KeybindingsHelper +from autopilot.utilities import ( + get_compiz_option, + get_desktop_geometry, + get_desktop_viewport, + ) + + +class WorkspaceManager(KeybindingsHelper): + """Class to manage switching to different workspaces.""" + + def __init__(self): + super(WorkspaceManager, self).__init__() + self.refresh_workspace_information() + + @property + def num_workspaces(self): + """The number of workspaces configured.""" + return self._workspaces_wide * self._workspaces_high + + @property + def current_workspace(self): + """The current workspace number. 0 <= x < num_workspaces.""" + vx,vy = get_desktop_viewport() + return self._coordinates_to_vp_number(vx, vy) + + def refresh_workspace_information(self): + """Re-read information about available workspaces from compiz and X11.""" + self._workspaces_wide = get_compiz_option("core", "hsize") + self._workspaces_high = get_compiz_option("core", "vsize") + self._desktop_width, self.desktop_height = get_desktop_geometry() + self._viewport_width = self._desktop_width / self._workspaces_wide + self._viewport_height = self.desktop_height / self._workspaces_high + + def switch_to(self, workspace_num): + """Switch to the workspace specified. + + ValueError is raised if workspace_num is outside 0<= workspace_num < num_workspaces. + + """ + if workspace_num < 0 or workspace_num >= self.num_workspaces: + raise ValueError("Workspace number must be between 0 and %d" % self.num_workspaces) + + current_row, current_col = self._vp_number_to_row_col(self.current_workspace) + target_row, target_col = self._vp_number_to_row_col(workspace_num) + lefts = rights = ups = downs = 0 + if current_col > target_col: + lefts = current_col - target_col + else: + rights = target_col - current_col + if current_row > target_row: + ups = current_row - target_row + else: + downs = target_row - current_row + + for i in range(lefts): + self.keybinding("workspace/move_left") + for i in range(rights): + self.keybinding("workspace/move_right") + for i in range(ups): + self.keybinding("workspace/move_up") + for i in range(downs): + self.keybinding("workspace/move_down") + + def _coordinates_to_vp_number(self, vx, vy): + """Translate viewport coordinates to a viewport number.""" + row,col = self._coordinates_to_row_col(vx, vy) + return (row * self._workspaces_wide) + col + + def _coordinates_to_row_col(self, vx, vy): + """Translate viewport coordinates to viewport row,col.""" + row = vy / self._viewport_height + col = vx / self._viewport_width + return (row,col) + + def _vp_number_to_row_col(self, vp_number): + """Translate a viewport number to a viewport row/col.""" + row = vp_number / self._workspaces_wide + col = vp_number % self._workspaces_wide + return (row,col) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/__init__.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/__init__.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/__init__.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,206 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +"""Autopilot test case class for Unity-specific tests.""" + +from __future__ import absolute_import + +from autopilot.emulators.bamf import BamfWindow +from autopilot.matchers import Eventually +from autopilot.testcase import AutopilotTestCase +from dbus import DBusException +from logging import getLogger +import os +from tempfile import mktemp +from testtools.content import text_content +from testtools.matchers import Equals + +from unity.emulators.dash import Dash +from unity.emulators.hud import Hud +from unity.emulators.launcher import LauncherController +from unity.emulators.panel import PanelController +from unity.emulators.switcher import Switcher +from unity.emulators.window_manager import WindowManager +from unity.emulators.workspace import WorkspaceManager +from unity.emulators.unity import ( + set_log_severity, + start_log_to_file, + reset_logging, + ) + + +log = getLogger(__name__) + + +class UnityTestCase(AutopilotTestCase): + """Unity test case base class, with improvments specific to Unity tests.""" + + def __init__(self, *args): + super(UnityTestCase, self).__init__(*args) + + def setUp(self): + super(UnityTestCase, self).setUp() + self._setUpUnityLogging() + self._initial_workspace_num = self.workspace.current_workspace + self.addCleanup(self.check_test_behavior) + # + # Setting this here since the show desktop feature seems to be a bit + # ropey. Once it's been proven to work reliably we can remove this line: + self.set_unity_log_level("unity.plugin", "DEBUG") + + def check_test_behavior(self): + """Fail the test if it did something naughty. + + This includes leaving the dash or the hud open, changing the current + workspace, or leaving the system in show_desktop mode. + + """ + well_behaved = True + reasons = [] + log.info("Checking system state for badly behaving test...") + + # Have we switched workspace? + if not self.well_behaved(self.workspace, current_workspace=self._initial_workspace_num): + well_behaved = False + reasons.append("The test changed the active workspace from %d to %d." \ + % (self._initial_workspace_num, self.workspace.current_workspace)) + log.warning("Test changed the active workspace, changing it back...") + self.workspace.switch_to(self._initial_workspace_num) + # Have we left the dash open? + if not self.well_behaved(self.dash, visible=False): + well_behaved = False + reasons.append("The test left the dash open.") + log.warning("Test left the dash open, closing it...") + self.dash.ensure_hidden() + # ... or the hud? + if not self.well_behaved(self.hud, visible=False): + well_behaved = False + reasons.append("The test left the hud open.") + log.warning("Test left the hud open, closing it...") + self.hud.ensure_hidden() + # Are we in show desktop mode? + if not self.well_behaved(self.window_manager, showdesktop_active=False): + well_behaved = False + reasons.append("The test left the system in show_desktop mode.") + log.warning("Test left the system in show desktop mode, exiting it...") + self.window_manager.leave_show_desktop() + for launcher in self.launcher.get_launchers(): + if not self.well_behaved(launcher, in_keynav_mode=False): + well_behaved = False + reasons.append("The test left the launcher keynav mode enabled.") + log.warning("Test left the launcher in keynav mode, exiting it...") + launcher.key_nav_cancel() + if not self.well_behaved(launcher, in_switcher_mode=False): + well_behaved = False + reasons.append("The test left the launcher in switcher mode.") + log.warning("Test left the launcher in switcher mode, exiting it...") + launcher.switcher_cancel() + + if not well_behaved: + self.fail("/n".join(reasons)) + else: + log.info("Test was well behaved.") + + def well_behaved(self, object, **kwargs): + try: + self.assertProperty(object, **kwargs) + except AssertionError: + return False + return True + + @property + def dash(self): + if not getattr(self, '__dash', None): + self.__dash = Dash() + return self.__dash + + @property + def hud(self): + if not getattr(self, '__hud', None): + self.__hud = Hud(); + return self.__hud + + @property + def launcher(self): + if not getattr(self, '__launcher', None): + self.__launcher = self._get_launcher_controller() + return self.__launcher + + @property + def panels(self): + if not getattr(self, '__panels', None): + self.__panels = self._get_panel_controller() + return self.__panels + + @property + def switcher(self): + if not getattr(self, '__switcher', None): + self.__switcher = Switcher() + return self.__switcher + + @property + def window_manager(self): + if not getattr(self, '__window_manager', None): + self.__window_manager = self._get_window_manager() + return self.__window_manager + + @property + def workspace(self): + if not getattr(self, '__workspace', None): + self.__workspace = WorkspaceManager() + return self.__workspace + + def _get_launcher_controller(self): + controllers = LauncherController.get_all_instances() + self.assertThat(len(controllers), Equals(1)) + return controllers[0] + + def _get_panel_controller(self): + controllers = PanelController.get_all_instances() + self.assertThat(len(controllers), Equals(1)) + return controllers[0] + + def _get_window_manager(self): + managers = WindowManager.get_all_instances() + self.assertThat(len(managers), Equals(1)) + return managers[0] + + def _setUpUnityLogging(self): + self._unity_log_file_name = mktemp(prefix=self.shortDescription()) + start_log_to_file(self._unity_log_file_name) + self.addCleanup(self._tearDownUnityLogging) + + def _tearDownUnityLogging(self): + # If unity dies, our dbus interface has gone, and reset_logging will fail + # but we still want our log, so we ignore any errors. + try: + reset_logging() + except DBusException: + pass + with open(self._unity_log_file_name) as unity_log: + self.addDetail('unity-log', text_content(unity_log.read())) + os.remove(self._unity_log_file_name) + self._unity_log_file_name = "" + + def set_unity_log_level(self, component, level): + """Set the unity log level for 'component' to 'level'. + + Valid levels are: TRACE, DEBUG, INFO, WARNING and ERROR. + + Components are dotted unity component names. The empty string specifies + the root logging component. + """ + valid_levels = ('TRACE', 'DEBUG', 'INFO', 'WARN', 'WARNING', 'ERROR') + if level not in valid_levels: + raise ValueError("Log level '%s' must be one of: %r" % (level, valid_levels)) + set_log_severity(component, level) + + def assertNumberWinsIsEventually(self, app, num): + """Asserts that 'app' eventually has 'num' wins. Waits up to 10 seconds.""" + + self.assertThat(lambda: len(app.get_windows()), Eventually(Equals(num))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/__init__.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/__init__.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/__init__.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,59 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +"""Autopilot test case class for all Launcher tests""" + +from autopilot.emulators.X11 import ScreenGeometry +from autopilot.testcase import multiply_scenarios + +from unity.tests import UnityTestCase + + +def _make_scenarios(): + """Make scenarios for launcher test cases based on the number of configured + monitors. + """ + screen_geometry = ScreenGeometry() + num_monitors = screen_geometry.get_num_monitors() + + # it doesn't make sense to set only_primary when we're running in a single-monitor setup. + if num_monitors == 1: + return [('Single Monitor', {'launcher_monitor': 0, 'only_primary': False})] + + monitor_scenarios = [('Monitor %d' % (i), {'launcher_monitor': i}) for i in range(num_monitors)] + launcher_mode_scenarios = [('launcher_on_primary', {'only_primary': True}), + ('launcher on all', {'only_primary': False})] + return multiply_scenarios(monitor_scenarios, launcher_mode_scenarios) + + +class LauncherTestCase(UnityTestCase): + """A base class for all launcher tests that uses scenarios to run on + each launcher (for multi-monitor setups). + """ + scenarios = _make_scenarios() + + def setUp(self): + super(LauncherTestCase, self).setUp() + self.screen_geo = ScreenGeometry() + self.set_unity_log_level("unity.launcher", "DEBUG") + self.addCleanup(self.set_unity_log_level, "unity.launcher", "INFO") + + self.set_unity_option('num_launchers', int(self.only_primary)) + self.launcher_instance = self.get_launcher() + + if self.only_primary: + try: + old_primary_screen = self.screen_geo.get_primary_monitor() + self.screen_geo.set_primary_monitor(self.launcher_monitor) + self.addCleanup(self.screen_geo.set_primary_monitor, old_primary_screen) + except ScreenGeometry.BlacklistedDriverError: + self.skipTest("Impossible to set the monitor %d as primary" % self.launcher_monitor) + + def get_launcher(self): + """Get the launcher for the current scenario.""" + return self.launcher.get_launcher_for_monitor(self.launcher_monitor) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_capture.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_capture.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_capture.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_capture.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,129 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: Thomi Richards, +# Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.emulators.X11 import ScreenGeometry +from autopilot.matchers import Eventually +import logging +from testtools.matchers import Equals, LessThan, GreaterThan +from time import sleep + +from unity.tests import UnityTestCase + +logger = logging.getLogger(__name__) + + +class LauncherCaptureTests(UnityTestCase): + """Test the launchers ability to capture/not capture the mouse.""" + + screen_geo = ScreenGeometry() + + def setUp(self): + super(LauncherCaptureTests, self).setUp() + + if self.screen_geo.get_num_monitors() <= 1: + self.skipTest("This test requires two or more monitors.") + + self.set_unity_option('launcher_capture_mouse', True) + self.set_unity_option('num_launchers', 0) + self.setHideMode(0) + + def setHideMode(self, mode): + self.set_unity_option('launcher_hide_mode', mode) + launcher = self.launcher.get_launcher_for_monitor(0) + self.assertThat(launcher.hidemode, Eventually(Equals(mode))) + + def leftMostMonitor(self): + x1, y1, width, height = self.screen_geo.get_monitor_geometry(0) + x2, y2, width, height = self.screen_geo.get_monitor_geometry(1) + + if x1 < x2: + return 0 + return 1 + + def rightMostMonitor(self): + # TODO: This will break setups with 3 or more monitors. + return 1 - self.leftMostMonitor() + + + def test_launcher_captures_while_sticky_and_revealed(self): + """Tests that the launcher captures the mouse when moving between monitors + while revealed. + """ + x, y, width, height = self.screen_geo.get_monitor_geometry(self.rightMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + self.mouse.move(x - width / 2, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, GreaterThan(x - width / 2)) + + def test_launcher_not_capture_while_not_sticky_and_revealed(self): + """Tests that the launcher doesn't captures the mouse when moving between monitors + while revealed and stick is off. + """ + + self.set_unity_option('launcher_capture_mouse', False) + + x, y, width, height = self.screen_geo.get_monitor_geometry(self.rightMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + self.mouse.move(x - width / 2, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, Equals(x - width / 2)) + + def test_launcher_capture_while_not_sticky_and_hidden(self): + """Tests that the launcher captures the mouse when moving between monitors + while hidden and sticky is off. (moving left) + """ + + self.set_unity_option('launcher_capture_mouse', False) + self.setHideMode(1) + + x, y, width, height = self.screen_geo.get_monitor_geometry(self.rightMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + self.mouse.move(x - width / 2, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, GreaterThan(x - width / 2)) + + def test_launcher_not_capture_while_not_sticky_and_hidden_moving_right(self): + """Tests that the launcher doesn't capture the mouse when moving between monitors + while hidden and sticky is off (moving right). + """ + + self.set_unity_option('launcher_capture_mouse', False) + self.setHideMode(1) + + x, y, width, height = self.screen_geo.get_monitor_geometry(self.leftMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + sleep(1.5) + self.mouse.move(x + width * 1.5, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, Equals(x + width * 1.5)) + + def test_launcher_capture_while_sticky_and_hidden_moving_right(self): + """Tests that the launcher captures the mouse when moving between monitors + while hidden. + """ + self.setHideMode(1) + + x, y, width, height = self.screen_geo.get_monitor_geometry(self.leftMostMonitor()) + self.mouse.move(x + width / 2, y + height / 2, False) + sleep(1.5) + self.mouse.move(x + width * 1.5, y + height / 2, True, 5, .002) + + x_fin, y_fin = self.mouse.position() + # The launcher should have held the mouse a little bit + self.assertThat(x_fin, LessThan(x + width * 1.5)) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_icon_behavior.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_icon_behavior.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_icon_behavior.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_icon_behavior.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,208 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: Thomi Richards, +# Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +from autopilot.testcase import multiply_scenarios +import logging +from testtools.matchers import Equals, NotEquals +from time import sleep + +from unity.emulators.icons import BamfLauncherIcon +from unity.emulators.launcher import IconDragType +from unity.tests.launcher import LauncherTestCase, _make_scenarios + +logger = logging.getLogger(__name__) + + +class LauncherIconsTests(LauncherTestCase): + """Test the launcher icons interactions""" + + def setUp(self): + super(LauncherIconsTests, self).setUp() + self.set_unity_option('launcher_hide_mode', 0) + + def test_bfb_tooltip_disappear_when_dash_is_opened(self): + """Tests that the bfb tooltip disappear when the dash is opened.""" + bfb = self.launcher.model.get_bfb_icon() + self.mouse.move(bfb.center_x, bfb.center_y) + + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False))) + + def test_bfb_tooltip_is_disabled_when_dash_is_open(self): + """Tests the that bfb tooltip is disabled when the dash is open.""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + bfb = self.launcher.model.get_bfb_icon() + self.mouse.move(bfb.center_x, bfb.center_y) + + self.assertThat(bfb.get_tooltip().active, Eventually(Equals(False))) + + def test_shift_click_opens_new_application_instance(self): + """Shift+Clicking MUST open a new instance of an already-running application.""" + app = self.start_app("Calculator") + icon = self.launcher.model.get_icon(desktop_id=app.desktop_file) + launcher_instance = self.launcher.get_launcher_for_monitor(0) + + self.keyboard.press("Shift") + self.addCleanup(self.keyboard.release, "Shift") + launcher_instance.click_launcher_icon(icon) + + self.assertNumberWinsIsEventually(app, 2) + + def test_launcher_activate_last_focused_window(self): + """Activating a launcher icon must raise only the last focused instance + of that application. + + """ + char_win1 = self.start_app_window("Character Map") + calc_win = self.start_app_window("Calculator") + char_win2 = self.start_app_window("Character Map") + + self.assertVisibleWindowStack([char_win2, calc_win, char_win1]) + + char_icon = self.launcher.model.get_icon( + desktop_id=char_win2.application.desktop_file) + calc_icon = self.launcher.model.get_icon( + desktop_id=calc_win.application.desktop_file) + + self.launcher_instance.click_launcher_icon(calc_icon) + self.assertProperty(calc_win, is_focused=True) + self.assertVisibleWindowStack([calc_win, char_win2, char_win1]) + + self.launcher_instance.click_launcher_icon(char_icon) + self.assertProperty(char_win2, is_focused=True) + self.assertVisibleWindowStack([char_win2, calc_win, char_win1]) + + self.keybinding("window/minimize") + + self.assertThat(lambda: char_win2.is_hidden, Eventually(Equals(True))) + self.assertProperty(calc_win, is_focused=True) + self.assertVisibleWindowStack([calc_win, char_win1]) + + self.launcher_instance.click_launcher_icon(char_icon) + self.assertProperty(char_win1, is_focused=True) + self.assertThat(lambda: char_win2.is_hidden, Eventually(Equals(True))) + self.assertVisibleWindowStack([char_win1, calc_win]) + + def test_clicking_icon_twice_initiates_spread(self): + """This tests shows that when you click on a launcher icon twice, + when an application window is focused, the spread is initiated. + """ + char_win1 = self.start_app_window("Character Map") + char_win2 = self.start_app_window("Character Map") + char_app = char_win1.application + + self.assertVisibleWindowStack([char_win2, char_win1]) + self.assertProperty(char_win2, is_focused=True) + + char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file) + self.addCleanup(self.keybinding, "spread/cancel") + self.launcher_instance.click_launcher_icon(char_icon) + + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + self.assertThat(self.window_manager.scale_active_for_group, Eventually(Equals(True))) + + def test_while_in_scale_mode_the_dash_will_still_open(self): + """If scale is initiated through the laucher pressing super must close + scale and open the dash. + """ + char_win1 = self.start_app_window("Character Map") + char_win2 = self.start_app_window("Character Map") + char_app = char_win1.application + + self.assertVisibleWindowStack([char_win2, char_win1]) + self.assertProperty(char_win2, is_focused=True) + + char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file) + self.launcher_instance.click_launcher_icon(char_icon) + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + self.assertThat(self.dash.visible, Eventually(Equals(True))) + self.assertThat(self.window_manager.scale_active, Eventually(Equals(False))) + + def test_icon_shows_on_quick_application_reopen(self): + """Icons must stay on launcher when an application is quickly closed/reopened.""" + calc = self.start_app("Calculator") + desktop_file = calc.desktop_file + calc_icon = self.launcher.model.get_icon(desktop_id=desktop_file) + self.assertThat(calc_icon.visible, Eventually(Equals(True))) + + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + sleep(2) + + calc_icon = self.launcher.model.get_icon(desktop_id=desktop_file) + self.assertThat(calc_icon, NotEquals(None)) + self.assertThat(calc_icon.visible, Eventually(Equals(True))) + + +class LauncherDragIconsBehavior(LauncherTestCase): + """Tests dragging icons around the Launcher.""" + + scenarios = multiply_scenarios(_make_scenarios(), + [ + ('inside', {'drag_type': IconDragType.INSIDE}), + ('outside', {'drag_type': IconDragType.OUTSIDE}), + ]) + + def ensure_calc_icon_not_in_launcher(self): + """Wait until the launcher model updates and removes the calc icon.""" + # Normally we'd use get_icon(desktop_id="...") but we're expecting it to + # not exist, and we don't want to wait for 10 seconds, so we do this + # the old fashioned way. + refresh_fn = lambda: self.launcher.model.get_children_by_type( + BamfLauncherIcon, desktop_id="gcalctool.desktop") + self.assertThat(refresh_fn, Eventually(Equals([]))) + + def test_can_drag_icon_below_bfb(self): + """Application icons must be draggable to below the BFB.""" + + self.ensure_calc_icon_not_in_launcher() + calc = self.start_app("Calculator") + calc_icon = self.launcher.model.get_icon(desktop_id=calc.desktop_file) + + bfb_icon_position = 0 + self.launcher_instance.drag_icon_to_position(calc_icon, + bfb_icon_position, + self.drag_type) + moved_icon = self.launcher.model.\ + get_launcher_icons_for_monitor(self.launcher_monitor)[1] + self.assertThat(moved_icon.id, Equals(calc_icon.id)) + + def test_can_drag_icon_above_window_switcher(self): + """Application icons must be dragable to above the workspace switcher icon.""" + + self.ensure_calc_icon_not_in_launcher() + calc = self.start_app("Calculator") + calc_icon = self.launcher.model.get_icon(desktop_id=calc.desktop_file) + + # Move a known icon to the top as it needs to be more than 2 icon + # spaces away for this test to actually do anything + bfb_icon_position = 0 + self.launcher_instance.drag_icon_to_position(calc_icon, + bfb_icon_position, + self.drag_type) + sleep(1) + switcher_pos = -2 + self.launcher_instance.drag_icon_to_position(calc_icon, + switcher_pos, + self.drag_type) + + moved_icon = self.launcher.model.\ + get_launcher_icons_for_monitor(self.launcher_monitor)[-3] + self.assertThat(moved_icon.id, Equals(calc_icon.id)) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_keynav.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_keynav.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_keynav.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_keynav.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,200 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: Thomi Richards, +# Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +import logging +from testtools.matchers import Equals, GreaterThan + +from unity.tests.launcher import LauncherTestCase + +logger = logging.getLogger(__name__) + + +class LauncherKeyNavTests(LauncherTestCase): + """Test the launcher key navigation""" + + def start_keynav_with_cleanup_cancel(self): + """Start keynav mode safely. + + This adds a cleanup action that cancels keynav mode at the end of the + test if it's still running (but does nothing otherwise). + + """ + self.launcher_instance.key_nav_start() + self.addCleanup(self.safe_quit_keynav) + + def safe_quit_keynav(self): + """Quit the keynav mode if it's engaged.""" + if self.launcher.key_nav_is_active: + self.launcher_instance.key_nav_cancel() + + def test_launcher_keynav_initiate(self): + """Tests we can initiate keyboard navigation on the launcher.""" + self.start_keynav_with_cleanup_cancel() + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True))) + self.assertThat(self.launcher.key_nav_is_grabbed, Eventually(Equals(True))) + + def test_launcher_keynav_cancel(self): + """Test that we can exit keynav mode.""" + self.launcher_instance.key_nav_start() + self.launcher_instance.key_nav_cancel() + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False))) + self.assertThat(self.launcher.key_nav_is_grabbed, Eventually(Equals(False))) + + def test_launcher_keynav_cancel_resume_focus(self): + """Test that ending the launcher keynav resume the focus.""" + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + + self.start_keynav_with_cleanup_cancel() + self.assertFalse(calc.is_active) + + self.launcher_instance.key_nav_cancel() + self.assertTrue(calc.is_active) + + def test_launcher_keynav_starts_at_index_zero(self): + """Test keynav mode starts at index 0.""" + self.start_keynav_with_cleanup_cancel() + self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0))) + + def test_launcher_keynav_forward(self): + """Must be able to move forwards while in keynav mode.""" + self.start_keynav_with_cleanup_cancel() + self.launcher_instance.key_nav_next() + # The launcher model has hidden items, so the keynav indexes do not + # increase by 1 each time. This test was failing because the 2nd icon + # had an index of 2, not 1 as expected. The best we can do here is to + # make sure that the index has increased. This opens us to the + # possibility that the launcher really is skipping forward more than one + # icon at a time, but we can't do much about that. + self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(0))) + + def test_launcher_keynav_prev_works(self): + """Must be able to move backwards while in keynav mode.""" + self.start_keynav_with_cleanup_cancel() + self.launcher_instance.key_nav_next() + self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(0))) + self.launcher_instance.key_nav_prev() + self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0))) + + def test_launcher_keynav_cycling_forward(self): + """Launcher keynav must loop through icons when cycling forwards""" + self.start_keynav_with_cleanup_cancel() + prev_icon = 0 + for icon in range(1, self.launcher.model.num_launcher_icons()): + self.launcher_instance.key_nav_next() + # FIXME We can't directly check for selection/icon number equalty + # since the launcher model also contains "hidden" icons that aren't + # shown, so the selection index can increment by more than 1. + self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(prev_icon))) + prev_icon = self.launcher.key_nav_selection + + self.launcher_instance.key_nav_next() + self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0))) + + def test_launcher_keynav_cycling_backward(self): + """Launcher keynav must loop through icons when cycling backwards""" + self.start_keynav_with_cleanup_cancel() + self.launcher_instance.key_nav_prev() + # FIXME We can't directly check for self.launcher.num_launcher_icons - 1 + self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(1))) + + def test_launcher_keynav_can_open_and_close_quicklist(self): + """Tests that we can open and close a quicklist from keynav mode.""" + self.start_keynav_with_cleanup_cancel() + self.launcher_instance.key_nav_next() + self.launcher_instance.key_nav_enter_quicklist() + self.assertThat(self.launcher_instance.quicklist_open, Eventually(Equals(True))) + self.launcher_instance.key_nav_exit_quicklist() + self.assertThat(self.launcher_instance.quicklist_open, Eventually(Equals(False))) + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True))) + self.assertThat(self.launcher.key_nav_is_grabbed, Eventually(Equals(True))) + + def test_launcher_keynav_mode_toggles(self): + """Tests that keynav mode toggles with Alt+F1.""" + # was initiated in setup. + self.start_keynav_with_cleanup_cancel() + self.keybinding("launcher/keynav") + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False))) + + def test_launcher_keynav_activate_keep_focus(self): + """Activating a running launcher icon must focus it.""" + calc = self.start_app("Calculator") + mahjongg = self.start_app("Mahjongg") + self.assertTrue(mahjongg.is_active) + self.assertFalse(calc.is_active) + + self.start_keynav_with_cleanup_cancel() + + self.launcher_instance.keyboard_select_icon(tooltip_text=calc.name) + self.launcher_instance.key_nav_activate() + + self.assertTrue(calc.is_active) + self.assertFalse(mahjongg.is_active) + + def test_launcher_keynav_expo_focus(self): + """When entering expo mode from KeyNav the Desktop must get focus.""" + self.start_keynav_with_cleanup_cancel() + + self.launcher_instance.keyboard_select_icon(tooltip_text="Workspace Switcher") + self.launcher_instance.key_nav_activate() + self.addCleanup(self.keybinding, "expo/cancel") + + self.assertThat(self.panels.get_active_panel().title, Eventually(Equals("Ubuntu Desktop"))) + + def test_launcher_keynav_expo_exit_on_esc(self): + """Esc should quit expo when entering it from KeyNav.""" + self.start_keynav_with_cleanup_cancel() + + self.launcher_instance.keyboard_select_icon(tooltip_text="Workspace Switcher") + self.launcher_instance.key_nav_activate() + + self.keyboard.press_and_release("Escape") + self.assertThat(self.window_manager.expo_active, Eventually(Equals(False))) + + def test_launcher_keynav_alt_tab_quits(self): + """Tests that alt+tab exits keynav mode.""" + self.start_keynav_with_cleanup_cancel() + + self.keybinding("switcher/reveal_normal") + self.addCleanup(self.switcher.terminate) + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False))) + + def test_launcher_keynav_alt_grave_quits(self): + """Tests that alt+` exits keynav mode.""" + self.start_keynav_with_cleanup_cancel() + # Can't use switcher emulat here since the switcher won't appear. + self.keybinding("switcher/reveal_details") + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False))) + + def test_launcher_keynav_cancel_doesnt_activate_icon(self): + """This tests when canceling keynav the current icon doesnt activate.""" + self.start_keynav_with_cleanup_cancel() + self.keyboard.press_and_release("Escape") + self.assertThat(self.dash.visible, Eventually(Equals(False))) + + def test_alt_f1_closes_dash(self): + """Pressing Alt+F1 when the Dash is open must close the Dash and start keynav.""" + self.dash.ensure_visible() + + self.start_keynav_with_cleanup_cancel() + + self.assertThat(self.dash.visible, Equals(False)) + self.assertThat(self.launcher.key_nav_is_active, Equals(True)) + + def test_alt_f1_closes_hud(self): + """Pressing Alt+F1 when the HUD is open must close the HUD and start keynav.""" + self.hud.ensure_visible() + + self.start_keynav_with_cleanup_cancel() + + self.assertThat(self.hud.visible, Equals(False)) + self.assertThat(self.launcher.key_nav_is_active, Equals(True)) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_reveal.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_reveal.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_reveal.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_reveal.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,115 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: Thomi Richards, +# Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +import logging +from testtools.matchers import Equals, GreaterThan +from time import sleep + +from unity.tests.launcher import LauncherTestCase + +logger = logging.getLogger(__name__) + + +class LauncherRevealTests(LauncherTestCase): + """Test the launcher reveal behavior when in autohide mode.""" + + def setUp(self): + super(LauncherRevealTests, self).setUp() + # these automatically reset to the original value, as implemented in AutopilotTestCase + self.set_unity_option('launcher_capture_mouse', True) + self.set_unity_option('launcher_hide_mode', 1) + launcher = self.get_launcher() + self.assertThat(launcher.hidemode, Eventually(Equals(1))) + + def test_launcher_keyboard_reveal_works(self): + """Revealing launcher with keyboard must work.""" + self.launcher_instance.keyboard_reveal_launcher() + self.addCleanup(self.launcher_instance.keyboard_unreveal_launcher) + self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True))) + + def test_reveal_on_mouse_to_edge(self): + """Tests reveal of launchers by mouse pressure.""" + self.launcher_instance.move_mouse_to_right_of_launcher() + self.launcher_instance.mouse_reveal_launcher() + self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True))) + + def test_reveal_with_mouse_under_launcher(self): + """The Launcher must hide properly if the mouse is under the launcher.""" + + self.launcher_instance.move_mouse_over_launcher() + # we can't use "launcher_instance.keyboard_reveal_launcher()" + # since it moves the mouse out of the way, invalidating the test. + self.keybinding_hold("launcher/reveal") + sleep(1) + self.keybinding_release("launcher/reveal") + self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(False))) + + def test_reveal_does_not_hide_again(self): + """Tests reveal of launchers by mouse pressure to ensure it doesn't + automatically hide again. + """ + self.launcher_instance.move_mouse_to_right_of_launcher() + self.launcher_instance.mouse_reveal_launcher() + self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True))) + + def test_launcher_does_not_reveal_with_mouse_down(self): + """Launcher must not reveal if have mouse button 1 down.""" + self.screen_geo.move_mouse_to_monitor(self.launcher_instance.monitor) + self.mouse.press(1) + self.addCleanup(self.mouse.release, 1) + #FIXME: This is really bad API. it says reveal but it's expected to fail. bad bad bad!! + self.launcher_instance.mouse_reveal_launcher() + # Need a sleep here otherwise this test would pass even if the code failed. + # THis test needs to be rewritten... + sleep(5) + self.assertThat(self.launcher_instance.is_showing, Equals(False)) + + def test_launcher_stays_open_after_spread(self): + """Clicking on the launcher to close an active spread must not hide the launcher.""" + char_win1 = self.start_app_window("Character Map") + char_win2 = self.start_app_window("Character Map") + char_app = char_win1.application + + char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file) + + self.launcher_instance.click_launcher_icon(char_icon, move_mouse_after=False) + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + self.launcher_instance.click_launcher_icon(char_icon, move_mouse_after=False) + + self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True))) + self.assertThat(self.window_manager.scale_active, Eventually(Equals(False))) + + def test_launcher_stays_open_after_icon_click(self): + """Clicking on a launcher icon must not hide the launcher.""" + char_win = self.start_app_window("Character Map") + char_app = char_win.application + + char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file) + self.launcher_instance.click_launcher_icon(char_icon, move_mouse_after=False) + + # Have to sleep to give the launcher time to hide (what the old behavior was) + sleep(5) + + self.assertThat(self.launcher_instance.is_showing, Eventually(Equals(True))) + + def test_new_icon_has_the_shortcut(self): + """New icons should have an associated shortcut""" + if self.launcher.model.num_bamf_launcher_icons() >= 10: + self.skip("There are already more than 9 icons in the launcher") + + desktop_file = self.KNOWN_APPS['Calculator']['desktop-file'] + if self.launcher.model.get_icon(desktop_id=desktop_file) != None: + self.skip("Calculator icon is already on the launcher.") + + self.start_app('Calculator') + icon = self.launcher.model.get_icon(desktop_id=desktop_file) + self.assertThat(icon.shortcut, GreaterThan(0)) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_shortcut.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_shortcut.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_shortcut.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_shortcut.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,55 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: Thomi Richards, +# Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +import logging +from testtools.matchers import Equals +from time import sleep + +from unity.tests.launcher import LauncherTestCase + +logger = logging.getLogger(__name__) + + +class LauncherShortcutTests(LauncherTestCase): + """Tests for the shortcut hint window.""" + + def setUp(self): + super(LauncherShortcutTests, self).setUp() + self.launcher_instance.keyboard_reveal_launcher() + self.addCleanup(self.launcher_instance.keyboard_unreveal_launcher) + sleep(2) + + def test_launcher_keyboard_reveal_shows_shortcut_hints(self): + """Launcher icons must show shortcut hints after revealing with keyboard.""" + self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(True))) + + def test_launcher_switcher_keeps_shorcuts(self): + """Initiating launcher switcher after showing shortcuts must not hide shortcuts""" + self.launcher_instance.switcher_start() + self.addCleanup(self.launcher_instance.switcher_cancel) + + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True))) + self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(True))) + + def test_launcher_switcher_next_keeps_shortcuts(self): + """Launcher switcher next action must keep shortcuts after they've been shown.""" + self.launcher_instance.switcher_start() + self.addCleanup(self.launcher_instance.switcher_cancel) + self.launcher_instance.switcher_next() + self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(True))) + + def test_launcher_switcher_prev_keeps_shortcuts(self): + """Launcher switcher prev action must keep shortcuts after they've been shown.""" + self.launcher_instance.switcher_start() + self.addCleanup(self.launcher_instance.switcher_cancel) + self.launcher_instance.switcher_prev() + self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(True))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_switcher.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_switcher.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_switcher.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_switcher.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,168 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: Thomi Richards, +# Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually + +import logging +from testtools.matchers import Equals, NotEquals, GreaterThan +from time import sleep + +from unity.tests.launcher import LauncherTestCase + + +logger = logging.getLogger(__name__) + + +class LauncherSwitcherTests(LauncherTestCase): + """ Tests the functionality of the launcher's switcher capability""" + + def start_switcher_with_cleanup_cancel(self): + """Start switcher mode safely. + + This adds a cleanup action that cancels keynav mode at the end of the + test if it's still running (but does nothing otherwise). + + """ + self.launcher_instance.switcher_start() + self.addCleanup(self.safe_quit_switcher) + + def safe_quit_switcher(self): + """Quit the keynav mode if it's engaged.""" + if self.launcher.key_nav_is_active: + self.launcher_instance.switcher_cancel() + + def test_launcher_switcher_cancel(self): + """Test that ending the launcher switcher actually works.""" + self.launcher_instance.switcher_start() + self.launcher_instance.switcher_cancel() + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False))) + + def test_launcher_switcher_cancel_resume_focus(self): + """Test that ending the launcher switcher resume the focus.""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + + self.start_switcher_with_cleanup_cancel() + sleep(.5) + self.assertFalse(calc.is_active) + + self.launcher_instance.switcher_cancel() + sleep(.5) + self.assertTrue(calc.is_active) + + def test_launcher_switcher_starts_at_index_zero(self): + """Test that starting the Launcher switcher puts the keyboard focus on item 0.""" + self.start_switcher_with_cleanup_cancel() + + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(True))) + self.assertThat(self.launcher.key_nav_is_grabbed, Eventually(Equals(False))) + self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0))) + + def test_launcher_switcher_next(self): + """Moving to the next launcher item while switcher is activated must work.""" + self.start_switcher_with_cleanup_cancel() + self.launcher_instance.switcher_next() + # The launcher model has hidden items, so the keynav indexes do not + # increase by 1 each time. This test was failing because the 2nd icon + # had an index of 2, not 1 as expected. The best we can do here is to + # make sure that the index has increased. This opens us to the + # possibility that the launcher really is skipping forward more than one + # icon at a time, but we can't do much about that. + self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(0))) + + def test_launcher_switcher_prev(self): + """Moving to the previous launcher item while switcher is activated must work.""" + self.start_switcher_with_cleanup_cancel() + self.launcher_instance.switcher_prev() + self.assertThat(self.launcher.key_nav_selection, Eventually(NotEquals(0))) + + def test_launcher_switcher_down(self): + """Pressing the down arrow key while switcher is activated must work.""" + self.start_switcher_with_cleanup_cancel() + self.launcher_instance.switcher_down() + # The launcher model has hidden items, so the keynav indexes do not + # increase by 1 each time. This test was failing because the 2nd icon + # had an index of 2, not 1 as expected. The best we can do here is to + # make sure that the index has increased. This opens us to the + # possibility that the launcher really is skipping forward more than one + # icon at a time, but we can't do much about that. + self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(0))) + + def test_launcher_switcher_up(self): + """Pressing the up arrow key while switcher is activated must work.""" + self.start_switcher_with_cleanup_cancel() + self.launcher_instance.switcher_up() + self.assertThat(self.launcher.key_nav_selection, Eventually(NotEquals(0))) + + def test_launcher_switcher_next_doesnt_show_shortcuts(self): + """Moving forward in launcher switcher must not show launcher shortcuts.""" + self.start_switcher_with_cleanup_cancel() + self.launcher_instance.switcher_next() + # sleep so that the shortcut timeout could be triggered + sleep(2) + self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(False))) + + def test_launcher_switcher_prev_doesnt_show_shortcuts(self): + """Moving backward in launcher switcher must not show launcher shortcuts.""" + self.start_switcher_with_cleanup_cancel() + self.launcher_instance.switcher_prev() + # sleep so that the shortcut timeout could be triggered + sleep(2) + self.assertThat(self.launcher_instance.shortcuts_shown, Eventually(Equals(False))) + + def test_launcher_switcher_cycling_forward(self): + """Launcher Switcher must loop through icons when cycling forwards""" + self.start_switcher_with_cleanup_cancel() + prev_icon = 0 + num_icons = self.launcher.model.num_launcher_icons() + logger.info("This launcher has %d icons", num_icons) + for icon in range(1, num_icons): + self.launcher_instance.switcher_next() + # FIXME We can't directly check for selection/icon number equalty + # since the launcher model also contains "hidden" icons that aren't + # shown, so the selection index can increment by more than 1. + self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(prev_icon))) + prev_icon = self.launcher.key_nav_selection + + self.launcher_instance.switcher_next() + self.assertThat(self.launcher.key_nav_selection, Eventually(Equals(0))) + + def test_launcher_switcher_cycling_backward(self): + """Launcher Switcher must loop through icons when cycling backwards""" + self.start_switcher_with_cleanup_cancel() + self.launcher_instance.switcher_prev() + # FIXME We can't directly check for self.launcher.num_launcher_icons - 1 + self.assertThat(self.launcher.key_nav_selection, Eventually(GreaterThan(1))) + + def test_launcher_switcher_activate_keep_focus(self): + """Activating a running launcher icon should focus the application.""" + calc = self.start_app("Calculator") + mahjongg = self.start_app("Mahjongg") + self.assertTrue(mahjongg.is_active) + self.assertFalse(calc.is_active) + + self.start_switcher_with_cleanup_cancel() + + self.launcher_instance.keyboard_select_icon(tooltip_text=calc.name) + self.launcher_instance.switcher_activate() + + self.assertThat(lambda: calc.is_active, Eventually(Equals(True))) + self.assertThat(lambda: mahjongg.is_active, Eventually(Equals(False))) + + def test_launcher_switcher_using_shorcuts(self): + """Using some other shortcut while switcher is active must cancel switcher.""" + self.start_switcher_with_cleanup_cancel() + self.keyboard.press_and_release("s") + sleep(.25) + self.keyboard.press_and_release("Escape") + sleep(.25) + self.assertThat(self.launcher.key_nav_is_active, Eventually(Equals(False))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_visual.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_visual.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_visual.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/launcher/test_visual.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,76 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: Thomi Richards, +# Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +import logging +from testtools.matchers import Equals +from time import sleep + +from unity.emulators.icons import BFBLauncherIcon +from unity.tests.launcher import LauncherTestCase + +logger = logging.getLogger(__name__) + + +class LauncherVisualTests(LauncherTestCase): + """Tests for visual aspects of the launcher (icon saturation etc.).""" + + def test_keynav_from_dash_saturates_icons(self): + """Starting super+tab switcher from the dash must resaturate launcher icons. + + Tests fix for bug #913569. + """ + bfb = self.launcher.model.get_bfb_icon() + self.mouse.move(bfb.center_x, bfb.center_y) + self.dash.ensure_visible() + sleep(1) + # We can't use 'launcher_instance.switcher_start()' since it moves the mouse. + self.keybinding_hold_part_then_tap("launcher/switcher") + self.addCleanup(self.keybinding_release, "launcher/switcher") + self.addCleanup(self.keybinding, "launcher/switcher/exit") + + self.keybinding_tap("launcher/switcher/next") + for icon in self.launcher.model.get_launcher_icons(): + self.assertThat(icon.desaturated, Eventually(Equals(False))) + + def test_opening_dash_desaturates_icons(self): + """Opening the dash must desaturate all the launcher icons.""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + for icon in self.launcher.model.get_launcher_icons(): + if isinstance(icon, BFBLauncherIcon): + self.assertThat(icon.desaturated, Eventually(Equals(False))) + else: + self.assertThat(icon.desaturated, Eventually(Equals(True))) + + def test_opening_dash_with_mouse_over_launcher_keeps_icon_saturation(self): + """Opening dash with mouse over launcher must not desaturate icons.""" + launcher_instance = self.get_launcher() + x,y,w,h = launcher_instance.geometry + self.mouse.move(x + w/2, y + h/2) + sleep(.5) + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + for icon in self.launcher.model.get_launcher_icons(): + self.assertThat(icon.desaturated, Eventually(Equals(False))) + + def test_mouse_over_with_dash_open_desaturates_icons(self): + """Moving mouse over launcher with dash open must saturate icons.""" + launcher_instance = self.get_launcher() + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + sleep(.5) + x,y,w,h = launcher_instance.geometry + self.mouse.move(x + w/2, y + h/2) + sleep(.5) + for icon in self.launcher.model.get_launcher_icons(): + self.assertThat(icon.desaturated, Eventually(Equals(False))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_command_lens.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_command_lens.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_command_lens.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_command_lens.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,86 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +from testtools.matchers import Equals +from time import sleep + +from unity.tests import UnityTestCase + + +class CommandLensSearchTests(UnityTestCase): + """Test the command lense search bahavior.""" + + def setUp(self): + super(CommandLensSearchTests, self).setUp() + + def tearDown(self): + self.dash.ensure_hidden() + super(CommandLensSearchTests, self).tearDown() + + def test_no_results(self): + """An empty string should get no results.""" + self.dash.reveal_command_lens() + command_lens = self.dash.get_current_lens() + + if self.dash.search_string != "": + self.keyboard.press_and_release("Delete") + + self.assertThat(self.dash.search_string, Eventually(Equals(""))) + results_category = command_lens.get_category_by_name("Results") + self.assertThat(results_category.is_visible, Eventually(Equals(False))) + + def test_results_category_appears(self): + """Results category must appear when there are some results.""" + self.dash.reveal_command_lens() + command_lens = self.dash.get_current_lens() + # lots of apps start with 'a'... + self.keyboard.type("a") + self.assertThat(self.dash.search_string, Eventually(Equals("a"))) + results_category = command_lens.get_category_by_name("Results") + self.assertThat(results_category.is_visible, Eventually(Equals(True))) + + def test_result_category_actually_contains_results(self): + """With a search string of 'a', the results category must contain some results.""" + self.dash.reveal_command_lens() + command_lens = self.dash.get_current_lens() + # lots of apps start with 'a'... + self.keyboard.type("a") + self.assertThat(self.dash.search_string, Eventually(Equals("a"))) + results_category = command_lens.get_category_by_name("Results") + results = results_category.get_results() + self.assertTrue(results) + + def test_run_before_refresh(self): + """Hitting enter before view has updated results must run the correct command.""" + if self.app_is_running("Text Editor"): + self.close_all_app("Text Editor") + sleep(1) + + self.dash.reveal_command_lens() + self.keyboard.type("g") + sleep(1) + self.keyboard.type("edit", 0.1) + self.keyboard.press_and_release("Enter", 0.1) + self.addCleanup(self.close_all_app, "Text Editor") + app_found = self.bamf.wait_until_application_is_running("gedit.desktop", 5) + self.assertTrue(app_found) + + def test_ctrl_tab_switching(self): + """Pressing Ctrl+Tab after launching command lens must switch to Home lens.""" + self.dash.reveal_command_lens() + self.keybinding("dash/lens/next") + self.assertThat(self.dash.active_lens, Eventually(Equals("home.lens"))) + + def test_ctrl_shift_tab_switching(self): + """Pressing Ctrl+Shift+Tab after launching command lens must switch to Video lens.""" + self.dash.reveal_command_lens() + self.keybinding("dash/lens/prev") + self.assertThat(self.dash.active_lens, Eventually(Equals("video.lens"))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_dash.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_dash.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_dash.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_dash.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,833 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2010 Canonical +# Author: Alex Launi +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.emulators.clipboard import get_clipboard_contents +from autopilot.matchers import Eventually +from testtools.matchers import Equals, NotEquals, GreaterThan +from time import sleep + +from unity.tests import UnityTestCase + + +class DashTestCase(UnityTestCase): + def setUp(self): + super(DashTestCase, self).setUp() + self.set_unity_log_level("unity.shell", "DEBUG") + self.set_unity_log_level("unity.launcher", "DEBUG") + self.dash.ensure_hidden() + # On shutdown, ensure hidden too. Also add a delay. Cleanup is LIFO. + self.addCleanup(self.dash.ensure_hidden) + self.addCleanup(sleep, 1) + + +class DashRevealTests(DashTestCase): + """Test the Unity dash Reveal.""" + + def test_dash_reveal(self): + """Ensure we can show and hide the dash.""" + self.dash.ensure_visible() + self.dash.ensure_hidden() + + def test_application_lens_shortcut(self): + """Application lense must reveal when Super+a is pressed.""" + self.dash.reveal_application_lens() + self.assertThat(self.dash.active_lens, Eventually(Equals('applications.lens'))) + + def test_music_lens_shortcut(self): + """Music lense must reveal when Super+w is pressed.""" + self.dash.reveal_music_lens() + self.assertThat(self.dash.active_lens, Eventually(Equals('music.lens'))) + + def test_file_lens_shortcut(self): + """File lense must reveal when Super+f is pressed.""" + self.dash.reveal_file_lens() + self.assertThat(self.dash.active_lens, Eventually(Equals('files.lens'))) + + def test_video_lens_shortcut(self): + """Video lens must reveal when super+v is pressed.""" + self.dash.reveal_video_lens() + self.assertThat(self.dash.active_lens, Eventually(Equals('video.lens'))) + + def test_command_lens_shortcut(self): + """Run Command lens must reveat on alt+F2.""" + self.dash.reveal_command_lens() + self.assertThat(self.dash.active_lens, Eventually(Equals('commands.lens'))) + + def test_alt_f4_close_dash(self): + """Dash must close on alt+F4.""" + self.dash.ensure_visible() + self.keyboard.press_and_release("Alt+F4") + self.assertThat(self.dash.visible, Eventually(Equals(False))) + + def test_alt_f4_close_dash_with_capslock_on(self): + """Dash must close on Alt+F4 even when the capslock is turned on.""" + self.keyboard.press_and_release("Caps_Lock") + self.addCleanup(self.keyboard.press_and_release, "Caps_Lock") + + self.dash.ensure_visible() + self.keyboard.press_and_release("Alt+F4") + self.assertThat(self.dash.visible, Eventually(Equals(False))) + + def test_dash_closes_on_spread(self): + """This test shows that when the spread is initiated, the dash closes.""" + self.dash.ensure_visible() + self.addCleanup(self.keybinding, "spread/cancel") + self.keybinding("spread/start") + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + self.assertThat(self.dash.visible, Eventually(Equals(False))) + + def test_dash_opens_when_in_spread(self): + """This test shows the dash opens when in spread mode.""" + self.keybinding("spread/start") + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + + self.dash.ensure_visible() + self.assertThat(self.dash.visible, Eventually(Equals(True))) + + def test_command_lens_opens_when_in_spread(self): + """This test shows the command lens opens when in spread mode.""" + self.keybinding("spread/start") + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + + self.dash.reveal_command_lens() + self.assertThat(self.dash.active_lens, Eventually(Equals('commands.lens'))) + + def test_lens_opens_when_in_spread(self): + """This test shows that any lens opens when in spread mode.""" + self.keybinding("spread/start") + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + + self.dash.reveal_application_lens() + self.assertThat(self.dash.active_lens, Eventually(Equals('applications.lens'))) + + +class DashSearchInputTests(DashTestCase): + """Test features involving input to the dash search""" + + def assertSearchText(self, text): + self.assertThat(self.dash.search_string, Eventually(Equals(text))) + + def test_search_keyboard_focus(self): + """Dash must put keyboard focus on the search bar at all times.""" + self.dash.ensure_visible() + self.keyboard.type("Hello") + self.assertSearchText("Hello") + + +class DashMultiKeyTests(DashSearchInputTests): + def setUp(self): + # set the multi key first so that we're not getting a new _DISPLAY while keys are held down. + old_value = self.call_gsettings_cmd('get', 'org.gnome.libgnomekbd.keyboard', 'options') + self.addCleanup(self.call_gsettings_cmd, 'set', 'org.gnome.libgnomekbd.keyboard', 'options', old_value) + self.call_gsettings_cmd('set', 'org.gnome.libgnomekbd.keyboard', 'options', "['Compose key\tcompose:caps']") + + super(DashMultiKeyTests, self).setUp() + + def test_multi_key(self): + """Pressing 'Multi_key' must not add any characters to the search.""" + self.dash.reveal_application_lens() + self.keyboard.press_and_release('Multi_key') + self.keyboard.type("o") + self.assertSearchText("") + + def test_multi_key_o(self): + """Pressing the sequences 'Multi_key' + '^' + 'o' must produce 'ô'.""" + self.dash.reveal_application_lens() + self.keyboard.press_and_release('Multi_key') + self.keyboard.type("^o") + self.assertSearchText("ô") + + def test_multi_key_copyright(self): + """Pressing the sequences 'Multi_key' + 'c' + 'o' must produce '©'.""" + self.dash.reveal_application_lens() + self.keyboard.press_and_release('Multi_key') + self.keyboard.type("oc") + self.assertSearchText("©") + + def test_multi_key_delete(self): + """Pressing 'Multi_key' must not get stuck looking for a sequence.""" + self.dash.reveal_application_lens() + self.keyboard.type("dd") + self.keyboard.press_and_release('Multi_key') + self.keyboard.press_and_release('BackSpace') + self.keyboard.press_and_release('BackSpace') + self.assertSearchText("d") + + +class DashKeyNavTests(DashTestCase): + """Test the unity Dash keyboard navigation.""" + + def test_lensbar_gets_keyfocus(self): + """Test that the lensbar gets key focus after using Down keypresses.""" + self.dash.ensure_visible() + + # Make sure that the lens bar can get the focus + for i in range(self.dash.get_num_rows()): + self.keyboard.press_and_release("Down") + lensbar = self.dash.view.get_lensbar() + self.assertThat(lensbar.focused_lens_icon, Eventually(NotEquals(''))) + + def test_lensbar_focus_changes(self): + """Lensbar focused icon should change with Left and Right keypresses.""" + self.dash.ensure_visible() + + for i in range(self.dash.get_num_rows()): + self.keyboard.press_and_release("Down") + lensbar = self.dash.view.get_lensbar() + + current_focused_icon = lensbar.focused_lens_icon + + self.keyboard.press_and_release("Right") + self.assertThat(lensbar.focused_lens_icon, Eventually(NotEquals(current_focused_icon))) + + self.keyboard.press_and_release("Left") + self.assertThat(lensbar.focused_lens_icon, Eventually(Equals(current_focused_icon))) + + def test_lensbar_enter_activation(self): + """Must be able to activate LensBar icons that have focus with an Enter keypress.""" + self.dash.ensure_visible() + + for i in range(self.dash.get_num_rows()): + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Right") + lensbar = self.dash.view.get_lensbar() + focused_icon = lensbar.focused_lens_icon + self.keyboard.press_and_release("Enter") + + self.assertThat(lensbar.active_lens, Eventually(Equals(focused_icon))) + + # lensbar should lose focus after activation. + self.assertThat(lensbar.focused_lens_icon, Eventually(Equals(""))) + + def test_focus_returns_to_searchbar(self): + """This test makes sure that the focus is returned to the searchbar of the newly + activated lens.""" + self.dash.ensure_visible() + + for i in range(self.dash.get_num_rows()): + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Right") + lensbar = self.dash.view.get_lensbar() + focused_icon = lensbar.focused_lens_icon + self.keyboard.press_and_release("Enter") + + self.assertThat(lensbar.active_lens, Eventually(Equals(focused_icon))) + self.assertThat(lensbar.focused_lens_icon, Eventually(Equals(""))) + + # Now we make sure if the newly activated lens searchbar have the focus. + self.keyboard.type("HasFocus") + + self.assertThat(self.dash.search_string, Eventually(Equals("HasFocus"))) + + def test_category_header_keynav(self): + """ Tests that a category header gets focus when 'down' is pressed after the + dash is opened + + OK important to note that this test only tests that A category is + focused, not the first and from doing this it seems that it's common + for a header other than the first to get focus. + """ + self.dash.ensure_visible() + # Make sure that a category have the focus. + self.keyboard.press_and_release("Down") + lens = self.dash.get_current_lens() + category = lens.get_focused_category() + self.assertIsNot(category, None) + # Make sure that the category is highlighted. + self.assertTrue(category.header_is_highlighted) + + def test_control_tab_lens_cycle(self): + """This test makes sure that Ctrl+Tab cycles lenses.""" + self.dash.ensure_visible() + + self.keyboard.press('Control') + self.keyboard.press_and_release('Tab') + self.keyboard.release('Control') + + lensbar = self.dash.view.get_lensbar() + self.assertEqual(lensbar.active_lens, u'applications.lens') + + self.keyboard.press('Control') + self.keyboard.press('Shift') + self.keyboard.press_and_release('Tab') + self.keyboard.release('Control') + self.keyboard.release('Shift') + + self.assertThat(lensbar.active_lens, Eventually(Equals('home.lens'))) + + def test_tab_cycle_category_headers(self): + """ Makes sure that pressing tab cycles through the category headers""" + self.dash.ensure_visible() + lens = self.dash.get_current_lens() + + # Test that tab cycles through the categories. + # + 1 is to cycle back to first header + for i in range(lens.get_num_visible_categories() + 1): + self.keyboard.press_and_release('Tab') + category = lens.get_focused_category() + self.assertIsNot(category, None) + + def test_tab_with_filter_bar(self): + """ This test makes sure that Tab works well with the filter bara.""" + self.dash.reveal_application_lens() + lens = self.dash.get_current_lens() + + # Tabs to last category + for i in range(lens.get_num_visible_categories()): + self.keyboard.press_and_release('Tab') + + self.keyboard.press_and_release('Tab') + self.assertThat(self.dash.searchbar.expander_has_focus, Eventually(Equals(True))) + + filter_bar = lens.get_filterbar() + if not self.dash.searchbar.showing_filters: + self.keyboard.press_and_release('Enter') + self.assertThat(self.dash.searchbar.showing_filters, Eventually(Equals(True))) + self.addCleanup(filter_bar.ensure_collapsed) + + for i in range(filter_bar.get_num_filters()): + self.keyboard.press_and_release('Tab') + new_focused_filter = filter_bar.get_focused_filter() + self.assertIsNotNone(new_focused_filter) + + # Ensure that tab cycles back to a category header + self.keyboard.press_and_release('Tab') + category = lens.get_focused_category() + self.assertIsNot(category, None) + + def test_bottom_up_keynav_with_filter_bar(self): + """This test makes sure that bottom-up key navigation works well + in the dash filter bar. + """ + self.dash.reveal_application_lens() + lens = self.dash.get_current_lens() + + filter_bar = lens.get_filterbar() + filter_bar.ensure_expanded() + + # Tab to fist filter expander + self.keyboard.press_and_release('Tab') + self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(NotEquals(None))) + old_focused_filter = filter_bar.get_focused_filter() + old_focused_filter.ensure_expanded() + + # Tab to the next filter expander + self.keyboard.press_and_release('Tab') + self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(NotEquals(None))) + new_focused_filter = filter_bar.get_focused_filter() + self.assertNotEqual(old_focused_filter, new_focused_filter) + new_focused_filter.ensure_expanded() + + # Move the focus up. + self.keyboard.press_and_release("Up") + self.assertThat(lambda: filter_bar.get_focused_filter(), Eventually(Equals(None))) + self.assertThat(old_focused_filter.content_has_focus, Eventually(Equals(True))) + + +class DashClipboardTests(DashTestCase): + """Test the Unity clipboard""" + + def test_ctrl_a(self): + """ This test if ctrl+a selects all text """ + self.dash.ensure_visible() + + self.keyboard.type("SelectAll") + self.assertThat(self.dash.search_string, Eventually(Equals("SelectAll"))) + + self.keyboard.press_and_release("Ctrl+a") + self.keyboard.press_and_release("Delete") + self.assertThat(self.dash.search_string, Eventually(Equals(''))) + + def test_ctrl_c(self): + """ This test if ctrl+c copies text into the clipboard """ + self.dash.ensure_visible() + + self.keyboard.type("Copy") + self.assertThat(self.dash.search_string, Eventually(Equals("Copy"))) + + self.keyboard.press_and_release("Ctrl+a") + self.keyboard.press_and_release("Ctrl+c") + + self.assertThat(get_clipboard_contents, Eventually(Equals("Copy"))) + + def test_ctrl_x(self): + """ This test if ctrl+x deletes all text and copys it """ + self.dash.ensure_visible() + + self.keyboard.type("Cut") + self.assertThat(self.dash.search_string, Eventually(Equals("Cut"))) + + self.keyboard.press_and_release("Ctrl+a") + self.keyboard.press_and_release("Ctrl+x") + self.assertThat(self.dash.search_string, Eventually(Equals(""))) + + self.assertThat(get_clipboard_contents, Eventually(Equals('Cut'))) + + def test_ctrl_c_v(self): + """ This test if ctrl+c and ctrl+v copies and pastes text""" + self.dash.ensure_visible() + + self.keyboard.type("CopyPaste") + self.assertThat(self.dash.search_string, Eventually(Equals("CopyPaste"))) + + self.keyboard.press_and_release("Ctrl+a") + self.keyboard.press_and_release("Ctrl+c") + self.keyboard.press_and_release("Ctrl+v") + self.keyboard.press_and_release("Ctrl+v") + + self.assertThat(self.dash.search_string, Eventually(Equals('CopyPasteCopyPaste'))) + + def test_ctrl_x_v(self): + """ This test if ctrl+x and ctrl+v cuts and pastes text""" + self.dash.ensure_visible() + + self.keyboard.type("CutPaste") + self.assertThat(self.dash.search_string, Eventually(Equals("CutPaste"))) + + self.keyboard.press_and_release("Ctrl+a") + self.keyboard.press_and_release("Ctrl+x") + self.keyboard.press_and_release("Ctrl+v") + self.keyboard.press_and_release("Ctrl+v") + + self.assertThat(self.dash.search_string, Eventually(Equals('CutPasteCutPaste'))) + + def test_middle_click_paste(self): + """Tests if Middle mouse button pastes into searchbar""" + + self.start_app_window("Calculator", locale='C') + + self.keyboard.type("ThirdButtonPaste") + self.keyboard.press_and_release("Ctrl+a") + + self.dash.ensure_visible() + + self.mouse.move(self.dash.searchbar.x + self.dash.searchbar.width / 2, + self.dash.searchbar.y + self.dash.searchbar.height / 2) + + self.mouse.click(button=2) + + self.assertThat(self.dash.search_string, Eventually(Equals('ThirdButtonPaste'))) + + +class DashKeyboardFocusTests(DashTestCase): + """Tests that keyboard focus works.""" + + def test_filterbar_expansion_leaves_kb_focus(self): + """Expanding or collapsing the filterbar must keave keyboard focus in the + search bar. + """ + self.dash.reveal_application_lens() + filter_bar = self.dash.get_current_lens().get_filterbar() + filter_bar.ensure_collapsed() + + self.keyboard.type("hello") + filter_bar.ensure_expanded() + self.addCleanup(filter_bar.ensure_collapsed) + self.keyboard.type(" world") + self.assertThat(self.dash.search_string, Eventually(Equals("hello world"))) + + +class DashLensResultsTests(DashTestCase): + """Tests results from the lens view.""" + + def test_results_message_empty_search(self): + """This tests a message is not shown when there is no text.""" + self.dash.reveal_application_lens() + lens = self.dash.get_current_lens() + self.assertThat(lens.no_results_active, Eventually(Equals(False))) + + def test_results_message(self): + """This test no mesage will be shown when results are there.""" + self.dash.reveal_application_lens() + self.keyboard.type("Terminal") + self.assertThat(self.dash.search_string, Eventually(Equals("Terminal"))) + lens = self.dash.get_current_lens() + self.assertThat(lens.no_results_active, Eventually(Equals(False))) + + def test_no_results_message(self): + """This test shows a message will appear in the lens.""" + self.dash.reveal_application_lens() + self.keyboard.type("qwerlkjzvxc") + self.assertThat(self.dash.search_string, Eventually(Equals("qwerlkjzvxc"))) + lens = self.dash.get_current_lens() + self.assertThat(lens.no_results_active, Eventually(Equals(True))) + + def test_results_update_on_filter_changed(self): + """This test makes sure the results change when filters change.""" + self.dash.reveal_application_lens() + lens = self.dash.get_current_lens() + self.keyboard.type(" ") + self.assertThat(self.dash.search_string, Eventually(Equals(" "))) + results_category = lens.get_category_by_name("Installed") + old_results = results_category.get_results() + + # FIXME: This should be a method on the dash emulator perhaps, or + # maybe a proper method of this class. It should NOT be an inline + # function that is only called once! + def activate_filter(add_cleanup = False): + # Tabs to last category + for i in range(lens.get_num_visible_categories()): + self.keyboard.press_and_release('Tab') + + self.keyboard.press_and_release('Tab') + self.assertThat(self.dash.searchbar.expander_has_focus, Eventually(Equals(True))) + + filter_bar = lens.get_filterbar() + if not self.dash.searchbar.showing_filters: + self.keyboard.press_and_release('Enter') + self.assertThat(self.dash.searchbar.showing_filters, Eventually(Equals(True))) + if add_cleanup: + self.addCleanup(filter_bar.ensure_collapsed) + + # Tab to the "Type" filter in apps lens + self.keyboard.press_and_release('Tab') + new_focused_filter = filter_bar.get_focused_filter() + self.assertIsNotNone(new_focused_filter) + + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Down") + # We should be on the Education category + self.keyboard.press_and_release('Enter') + + activate_filter(True) + self.addCleanup(activate_filter) + + results_category = lens.get_category_by_name("Installed") + results = results_category.get_results() + self.assertIsNot(results, old_results) + + # so we can clean up properly + self.keyboard.press_and_release('BackSpace') + + +class DashVisualTests(DashTestCase): + """Tests that the dash visual is correct.""" + + def test_see_more_result_alignment(self): + """The see more results label should be baseline aligned + with the category name label. + """ + self.dash.reveal_application_lens() + + lens = self.dash.get_current_lens() + groups = lens.get_groups() + + for group in groups: + if (group.is_visible and group.expand_label_is_visible): + expand_label_y = group.expand_label_y + group.expand_label_baseline + name_label_y = group.name_label_y + group.name_label_baseline + self.assertThat(expand_label_y, Equals(name_label_y)) + + +class DashLensBarTests(DashTestCase): + """Tests that the lensbar works well.""" + + def setUp(self): + super(DashLensBarTests, self).setUp() + self.dash.ensure_visible() + self.lensbar = self.dash.view.get_lensbar() + + def test_click_inside_highlight(self): + """Lens selection should work when clicking in + the rectangle outside of the icon. + """ + app_icon = self.lensbar.get_icon_by_name(u'applications.lens') + + self.mouse.move(app_icon.x + (app_icon.width / 2), + app_icon.y + (app_icon.height / 2)) + self.mouse.click() + + self.assertThat(self.lensbar.active_lens, Eventually(Equals('applications.lens'))) + + +class DashBorderTests(DashTestCase): + """Tests that the dash border works well. + """ + def setUp(self): + super(DashBorderTests, self).setUp() + self.dash.ensure_visible() + + def test_click_right_border(self): + """Clicking on the right dash border should do nothing, + *NOT* close the dash. + """ + if (self.dash.view.form_factor != "desktop"): + self.skip("Not in desktop form-factor.") + + x = self.dash.view.x + self.dash.view.width + self.dash.view.right_border_width / 2 + y = self.dash.view.y + self.dash.view.height / 2 + + self.mouse.move(x, y) + self.mouse.click() + + self.assertThat(self.dash.visible, Eventually(Equals(True))) + + def test_click_bottom_border(self): + """Clicking on the bottom dash border should do nothing, + *NOT* close the dash. + """ + if (self.dash.view.form_factor != "desktop"): + self.skip("Not in desktop form-factor.") + + x = self.dash.view.x + self.dash.view.width / 2 + y = self.dash.view.y + self.dash.view.height + self.dash.view.bottom_border_height / 2 + + self.mouse.move(x, y) + self.mouse.click() + + self.assertThat(self.dash.visible, Eventually(Equals(True))) + + +class CategoryHeaderTests(DashTestCase): + """Tests that category headers work. + """ + def test_click_inside_highlight(self): + """Clicking into a category highlight must expand/collapse + the view. + """ + lens = self.dash.reveal_file_lens() + self.addCleanup(self.dash.ensure_hidden) + + category = lens.get_category_by_name("Folders") + is_expanded = category.is_expanded + + self.mouse.move(self.dash.view.x + self.dash.view.width / 2, + category.header_y + category.header_height / 2) + + self.mouse.click() + self.assertThat(category.is_expanded, Eventually(Equals(not is_expanded))) + + self.mouse.click() + self.assertThat(category.is_expanded, Eventually(Equals(is_expanded))) + + +class PreviewInvocationTests(DashTestCase): + """Tests that dash previews can be opened and closed in different + lenses. + + """ + + def test_app_lens_preview_open_close(self): + """Right-clicking on an application lens result must show + its preview. + + """ + lens = self.dash.reveal_application_lens() + self.addCleanup(self.dash.ensure_hidden) + + category = lens.get_category_by_name("Installed") + results = category.get_results() + result = results[0] + # result.preview handles finding xy co-ords and right mouse-click + result.preview() + self.assertThat(self.dash.preview_displaying, Eventually(Equals(True))) + + self.keyboard.press_and_release("Escape") + + self.assertThat(self.dash.preview_displaying, Eventually(Equals(False))) + + def test_files_lens_preview_open_close(self): + """Right-clicking on a files lens result must show its + preview. + + """ + lens = self.dash.reveal_file_lens() + self.addCleanup(self.dash.ensure_hidden) + + category = lens.get_category_by_name("Folders") + results = category.get_results() + result = results[0] + # result.preview handles finding xy co-ords and right mouse-click + result.preview() + self.assertThat(self.dash.preview_displaying, Eventually(Equals(True))) + + self.keyboard.press_and_release("Escape") + + self.assertThat(self.dash.preview_displaying, Eventually(Equals(False))) + + def test_music_lens_preview_open_close(self): + """Right-clicking on a music lens result must show its + preview. + + """ + lens = self.dash.reveal_music_lens() + self.addCleanup(self.dash.ensure_hidden) + + category = lens.get_category_by_name("Songs") + # Incase there was no music ever played we skip the test instead + # of failing. + if category is None: + self.skipTest("This lens is probably empty") + + results = category.get_results() + + result = results[0] + # result.preview handles finding xy co-ords and right mouse-click + result.preview() + self.assertThat(self.dash.preview_displaying, Eventually(Equals(True))) + + self.keyboard.press_and_release("Escape") + + self.assertThat(self.dash.preview_displaying, Eventually(Equals(False))) + + def test_video_lens_preview_open_close(self): + """Right-clicking on a video lens result must show its + preview. + + """ + lens = self.dash.reveal_video_lens() + self.addCleanup(self.dash.ensure_hidden) + + category = lens.get_category_by_name("Recently Viewed") + # If there was no video played on this system this category is expected + # to be empty, if its empty we check if the 'Online' category have any + # contents, if not then we skip the test. + if category is None: + category = lens.get_category_by_name("Online") + if category is None: + self.skipTest("This lens is probably empty") + + results = category.get_results() + + result = results[0] + # result.preview handles finding xy co-ords and right mouse-click + result.preview() + self.assertThat(self.dash.preview_displaying, Eventually(Equals(True))) + + self.keyboard.press_and_release("Escape") + + self.assertThat(self.dash.preview_displaying, Eventually(Equals(False))) + + +class PreviewNavigateTests(DashTestCase): + """Tests that mouse navigation works with previews.""" + + def setUp(self): + super(PreviewNavigateTests, self).setUp() + + self.dash.reveal_application_lens() + self.addCleanup(self.dash.ensure_hidden) + + lens = self.dash.get_current_lens() + + results_category = lens.get_category_by_name("Installed") + results = results_category.get_results() + # wait for results (we need 4 results to perorm the multi-navigation tests) + refresh_fn = lambda: len(results) + self.assertThat(refresh_fn, Eventually(GreaterThan(4))) + + result = results[2] # 2 so we can navigate left + result.preview() + self.assertThat(self.dash.view.preview_displaying, Eventually(Equals(True))) + + self.preview_container = self.dash.view.get_preview_container() + + def test_navigate_left(self): + """Tests that left navigation works with previews.""" + + # wait until preview has finished animating + self.assertThat(self.preview_container.animating, Eventually(Equals(False))) + self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True))) + + old_navigation_complete_count = self.preview_container.navigation_complete_count + old_relative_nav_index = self.preview_container.relative_nav_index + + self.preview_container.navigate_left(1) + + self.assertThat(self.preview_container.navigation_complete_count, Eventually(Equals(old_navigation_complete_count+1))) + self.assertThat(self.preview_container.relative_nav_index, Eventually(Equals(old_relative_nav_index-1))) + + # should be one more on the left + self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True))) + # if we've navigated left, there should be at least one preview available on right. + self.assertThat(self.preview_container.navigate_right_enabled, Eventually(Equals(True))) + + # Test close preview after navigate + self.keyboard.press_and_release("Escape") + self.assertThat(self.dash.preview_displaying, Eventually(Equals(False))) + + def test_navigate_left_multi(self): + """Tests that multiple left navigation works with previews.""" + + # wait until preview has finished animating + self.assertThat(self.preview_container.animating, Eventually(Equals(False))) + self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True))) + + old_navigation_complete_count = self.preview_container.navigation_complete_count + old_relative_nav_index = self.preview_container.relative_nav_index + + self.preview_container.navigate_left(2) + + self.assertThat(self.preview_container.navigation_complete_count, Eventually(Equals(old_navigation_complete_count+2))) + self.assertThat(self.preview_container.relative_nav_index, Eventually(Equals(old_relative_nav_index-2))) + + # shouldnt be any previews on left. + self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(False))) + # if we've navigated left, there should be at least one preview available on right. + self.assertThat(self.preview_container.navigate_right_enabled, Eventually(Equals(True))) + + + def test_navigate_right(self): + """Tests that right navigation works with previews.""" + + # wait until preview has finished animating + self.assertThat(self.preview_container.animating, Eventually(Equals(False))) + self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True))) + + old_navigation_complete_count = self.preview_container.navigation_complete_count + old_relative_nav_index = self.preview_container.relative_nav_index + + self.preview_container.navigate_right(1) + + self.assertThat(self.preview_container.navigation_complete_count, Eventually(Equals(old_navigation_complete_count+1))) + self.assertThat(self.preview_container.relative_nav_index, Eventually(Equals(old_relative_nav_index+1))) + + # should be at least one more on the left + self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True))) + # if we've navigated right, there should be at least one preview available on left. + self.assertThat(self.preview_container.navigate_right_enabled, Eventually(Equals(True))) + + # Test close preview after navigate + self.keyboard.press_and_release("Escape") + self.assertThat(self.dash.preview_displaying, Eventually(Equals(False))) + + def test_navigate_right_multi(self): + """Tests that multiple right navigation works with previews.""" + + # wait until preview has finished animating + self.assertThat(self.preview_container.animating, Eventually(Equals(False))) + self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True))) + + old_navigation_complete_count = self.preview_container.navigation_complete_count + old_relative_nav_index = self.preview_container.relative_nav_index + + self.preview_container.navigate_right(2) + + self.assertThat(self.preview_container.navigation_complete_count, Eventually(Equals(old_navigation_complete_count+2))) + self.assertThat(self.preview_container.relative_nav_index, Eventually(Equals(old_relative_nav_index+2))) + + # if we've navigated right, there should be at least one preview available on left. + self.assertThat(self.preview_container.navigate_left_enabled, Eventually(Equals(True))) + + def test_preview_refocus_close(self): + """Clicking on a preview element must not lose keyboard focus.""" + cover_art = self.preview_container.current_preview.cover_art + + # click the cover-art (this will set focus) + tx = cover_art.x + (cover_art.width / 2) + ty = cover_art.y + (cover_art.height / 2) + self.mouse.move(tx, ty) + self.mouse.click() + + self.keyboard.press_and_release("Escape") + + self.assertThat(self.dash.preview_displaying, Eventually(Equals(False))) + diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_home_lens.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_home_lens.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_home_lens.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_home_lens.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,42 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Michal Hruby +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +from testtools.matchers import Equals +from time import sleep + +from unity.tests import UnityTestCase + + +class HomeLensSearchTests(UnityTestCase): + """Test the command lense search bahavior.""" + + def setUp(self): + super(HomeLensSearchTests, self).setUp() + + def tearDown(self): + self.dash.ensure_hidden() + super(HomeLensSearchTests, self).tearDown() + + def test_quick_run_app(self): + """Hitting enter runs an application even though a search might not have fully finished yet.""" + if self.app_is_running("Text Editor"): + self.close_all_app("Text Editor") + sleep(1) + + kb = self.keyboard + self.dash.ensure_visible() + kb.type("g") + self.assertThat(self.dash.search_string, Eventually(Equals("g"))) + kb.type("edit", 0.1) + kb.press_and_release("Enter", 0.1) + self.addCleanup(self.close_all_app, "Text Editor") + app_found = self.bamf.wait_until_application_is_running("gedit.desktop", 5) + self.assertTrue(app_found) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_hud.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_hud.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_hud.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_hud.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,612 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Alex Launi, +# Marco Trevisan +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +from autopilot.emulators.X11 import ScreenGeometry +from autopilot.testcase import multiply_scenarios +from os import remove +from testtools.matchers import ( + Equals, + EndsWith, + GreaterThan, + LessThan, + NotEquals, + ) +from time import sleep + +from unity.emulators.icons import HudLauncherIcon +from unity.tests import UnityTestCase + + +def _make_monitor_scenarios(): + num_monitors = ScreenGeometry().get_num_monitors() + scenarios = [] + + if num_monitors == 1: + scenarios = [('Single Monitor', {'hud_monitor': 0})] + else: + for i in range(num_monitors): + scenarios += [('Monitor %d' % (i), {'hud_monitor': i})] + + return scenarios + + +class HudTestsBase(UnityTestCase): + + def setUp(self): + super(HudTestsBase, self).setUp() + + def tearDown(self): + self.hud.ensure_hidden() + super(HudTestsBase, self).tearDown() + + def get_num_active_launcher_icons(self): + num_active = 0 + for icon in self.launcher.model.get_launcher_icons(): + if icon.active and icon.visible: + num_active += 1 + return num_active + + +class HudBehaviorTests(HudTestsBase): + + def setUp(self): + super(HudBehaviorTests, self).setUp() + + self.hud_monitor = self.screen_geo.get_primary_monitor() + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) + + def test_no_initial_values(self): + self.hud.ensure_visible() + self.assertThat(self.hud.num_buttons, Equals(0)) + self.assertThat(self.hud.selected_button, Equals(0)) + + def test_check_a_values(self): + self.hud.ensure_visible() + self.keyboard.type('a') + self.assertThat(self.hud.search_string, Eventually(Equals('a'))) + self.assertThat(self.hud.num_buttons, Eventually(Equals(5))) + self.assertThat(self.hud.selected_button, Eventually(Equals(1))) + + def test_up_down_arrows(self): + self.hud.ensure_visible() + self.keyboard.type('a') + self.assertThat(self.hud.search_string, Eventually(Equals('a'))) + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Eventually(Equals(2))) + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Eventually(Equals(3))) + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Eventually(Equals(4))) + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Eventually(Equals(5))) + # Down again stays on 5. + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Eventually(Equals(5))) + self.keyboard.press_and_release('Up') + self.assertThat(self.hud.selected_button, Eventually(Equals(4))) + self.keyboard.press_and_release('Up') + self.assertThat(self.hud.selected_button, Eventually(Equals(3))) + self.keyboard.press_and_release('Up') + self.assertThat(self.hud.selected_button, Eventually(Equals(2))) + self.keyboard.press_and_release('Up') + self.assertThat(self.hud.selected_button, Eventually(Equals(1))) + # Up again stays on 1. + self.keyboard.press_and_release('Up') + self.assertThat(self.hud.selected_button, Eventually(Equals(1))) + + def test_no_reset_selected_button(self): + """Hud must not change selected button when results update over time.""" + # TODO - this test doesn't test anything. Onmy system the results never update. + # ideally we'd send artificial results to the hud from the test. + self.hud.ensure_visible() + self.keyboard.type('is') + self.assertThat(self.hud.search_string, Eventually(Equals('is'))) + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Eventually(Equals(2))) + # long sleep to let the service send updated results + sleep(10) + self.assertThat(self.hud.selected_button, Equals(2)) + + def test_slow_tap_not_reveal_hud(self): + """A slow tap must not reveal the HUD.""" + self.keybinding("hud/reveal", 0.3) + # need a long sleep to ensure that we test after the hud controller has + # seen the keypress. + sleep(5) + self.assertThat(self.hud.visible, Equals(False)) + + def test_alt_f4_doesnt_show_hud(self): + self.start_app('Calculator') + sleep(1) + # Do a very fast Alt+F4 + self.keyboard.press_and_release("Alt+F4", 0.05) + sleep(1) + self.assertFalse(self.hud.visible) + + def test_reveal_hud_with_no_apps(self): + """Hud must show even with no visible applications. + + This used to cause unity to crash (hence the lack of assertion in this test). + + """ + self.window_manager.enter_show_desktop() + self.addCleanup(self.window_manager.leave_show_desktop) + + self.hud.ensure_visible() + self.hud.ensure_hidden() + + def test_restore_focus(self): + """Ensures that once the hud is dismissed, the same application + that was focused before hud invocation is refocused. + """ + calc = self.start_app("Calculator") + + # first ensure that the application has started and is focused + self.assertEqual(calc.is_active, True) + + self.hud.ensure_visible() + self.hud.ensure_hidden() + + # again ensure that the application we started is focused + self.assertEqual(calc.is_active, True) + + self.hud.ensure_visible() + self.hud.ensure_hidden() + # why do we do this: ??? + self.keyboard.press_and_release('Return') + sleep(1) + + self.assertEqual(calc.is_active, True) + + def test_gedit_undo(self): + """Test that the 'undo' action in the Hud works with GEdit.""" + + self.addCleanup(remove, '/tmp/autopilot_gedit_undo_test_temp_file.txt') + self.start_app('Text Editor', files=['/tmp/autopilot_gedit_undo_test_temp_file.txt'], locale='C') + + self.keyboard.type("0") + self.keyboard.type(" ") + self.keyboard.type("1") + + self.hud.ensure_visible() + + self.keyboard.type("undo") + hud_query_check = lambda: self.hud.selected_hud_button.label_no_formatting + self.assertThat(hud_query_check, + Eventually(Equals("Edit > Undo"))) + self.keyboard.press_and_release('Return') + self.assertThat(self.hud.visible, Eventually(Equals(False))) + self.keyboard.press_and_release("Ctrl+s") + sleep(1) + + contents = open("/tmp/autopilot_gedit_undo_test_temp_file.txt").read().strip('\n') + self.assertEqual("0 ", contents) + + def test_hud_to_dash_has_key_focus(self): + """When switching from the hud to the dash you don't lose key focus.""" + self.hud.ensure_visible() + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + self.keyboard.type('focus1') + self.assertThat(self.dash.search_string, Eventually(Equals('focus1'))) + + def test_dash_to_hud_has_key_focus(self): + """When switching from the dash to the hud you don't lose key focus.""" + self.dash.ensure_visible() + self.hud.ensure_visible() + self.keyboard.type('focus2') + self.assertThat(self.hud.search_string, Eventually(Equals('focus2'))) + + def test_hud_closes_on_workspace_switch(self): + """This test shows that when you switch to another workspace the hud closes.""" + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + self.hud.ensure_visible() + self.workspace.switch_to(1) + self.workspace.switch_to(2) + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_hud_closes_on_spread(self): + """This test shows that when the spread is initiated, the hud closes.""" + self.hud.ensure_visible() + self.addCleanup(self.keybinding, "spread/cancel") + self.keybinding("spread/start") + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_hud_closes_click_outside_geo_shrunk(self): + """ + Clicking outside the hud when it is shurnk will make it close. + Shurnk is when the hud has no results and is much smaller then normal. + """ + + self.hud.ensure_visible() + (x,y,w,h) = self.hud.view.geometry + self.mouse.move(w/2, h-50) + self.mouse.click() + + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_hud_closes_click_outside_geo(self): + """Clicking outside of the hud will make it close.""" + + self.hud.ensure_visible() + self.keyboard.type("Test") + + (x,y,w,h) = self.hud.view.geometry + self.mouse.move(w/2, h+50) + self.mouse.click() + + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_hud_closes_click_after_text_removed(self): + """Clicking outside of the hud after a search text has been entered and + then removed from the searchbox will make it close.""" + + self.hud.ensure_visible() + self.keyboard.type("Test") + self.keyboard.press_and_release("Escape") + + (x,y,w,h) = self.hud.view.geometry + self.mouse.move(w/2, h+50) + self.mouse.click() + + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_alt_f4_close_hud(self): + """Hud must close on alt+F4.""" + self.hud.ensure_visible() + self.keyboard.press_and_release("Alt+F4") + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_alt_f4_close_hud_with_capslock_on(self): + """Hud must close on Alt+F4 even when the capslock is turned on.""" + self.keyboard.press_and_release("Caps_Lock") + self.addCleanup(self.keyboard.press_and_release, "Caps_Lock") + + self.hud.ensure_visible() + self.keyboard.press_and_release("Alt+F4") + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_app_activate_on_enter(self): + """Hud must close after activating a search item with Enter.""" + self.hud.ensure_visible() + + self.keyboard.type("Device > System Settings") + self.assertThat(self.hud.search_string, Eventually(Equals("Device > System Settings"))) + + self.keyboard.press_and_release("Enter") + + app_found = self.bamf.wait_until_application_is_running("gnome-control-center.desktop", 5) + self.assertTrue(app_found) + self.addCleanup(self.close_all_app, "System Settings") + + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_hud_closes_on_escape(self): + """Hud must close on escape after searchbox is cleared""" + self.hud.ensure_visible() + + self.keyboard.type("ThisText") + self.keyboard.press_and_release("Escape") + self.keyboard.press_and_release("Escape") + + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_hud_closes_on_escape_shrunk(self): + """Hud must close when escape key is pressed""" + self.hud.ensure_visible() + self.keyboard.press_and_release("Escape") + + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_alt_arrow_keys_not_eaten(self): + """Tests that Alt+ArrowKey events are correctly passed to the + active window when Unity is not responding to them.""" + + self.start_app_window("Terminal") + + #There's no easy way to read text from terminal, writing input + #to a text file and then reading from there works. + self.keyboard.type('echo "') + + #Terminal is receiving input with Alt+Arrowkeys + self.keyboard.press("Alt") + self.keyboard.press_and_release("Up") + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Right") + self.keyboard.press_and_release("Left") + self.keyboard.release("Alt") + + self.keyboard.type('" > /tmp/ap_test_alt_keys') + self.addCleanup(remove, '/tmp/ap_test_alt_keys') + self.keyboard.press_and_release("Enter") + + file_contents = open('/tmp/ap_test_alt_keys', 'r').read().strip() + + self.assertThat(file_contents, Equals('ABCD')) + + def test_hud_closes_on_item_activated(self): + """Activating a HUD item with the 'Enter' key MUST close the HUD.""" + # starting on a clean desktop because this way we are sure that our search + # string won't match any menu item from a focused application + self.window_manager.enter_show_desktop() + self.addCleanup(self.window_manager.leave_show_desktop) + + self.hud.ensure_visible() + + self.keyboard.type("settings") + self.assertThat(self.hud.search_string, Eventually(Equals("settings"))) + + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Eventually(Equals(2))) + self.keyboard.press_and_release('Down') + self.assertThat(self.hud.selected_button, Eventually(Equals(3))) + self.keyboard.press_and_release('Enter') + + self.addCleanup(self.close_all_app, "System Settings") + + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + +class HudLauncherInteractionsTests(HudTestsBase): + + launcher_modes = [('Launcher autohide', {'launcher_autohide': False}), + ('Launcher never hide', {'launcher_autohide': True})] + + scenarios = multiply_scenarios(_make_monitor_scenarios(), launcher_modes) + + def setUp(self): + super(HudLauncherInteractionsTests, self).setUp() + # Launchers on all monitors + self.set_unity_option('num_launchers', 0) + self.set_unity_option('launcher_hide_mode', int(self.launcher_autohide)) + + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) + sleep(0.5) + + def test_multiple_hud_reveal_does_not_break_launcher(self): + """Multiple Hud reveals must not cause the launcher to set multiple + apps as active. + + """ + launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor) + + # We need an app to switch to: + self.start_app('Character Map') + # We need an application to play with - I'll use the calculator. + self.start_app('Calculator') + sleep(1) + + # before we start, make sure there's zero or one active icon: + num_active = self.get_num_active_launcher_icons() + self.assertThat(num_active, LessThan(2), "Invalid number of launcher icons active before test has run!") + + # reveal and hide hud several times over: + for i in range(3): + self.hud.ensure_visible() + self.hud.ensure_hidden() + + # click application icons for running apps in the launcher: + icon = self.launcher.model.get_icon(desktop_id="gucharmap.desktop") + launcher.click_launcher_icon(icon) + + # see how many apps are marked as being active: + num_active = self.get_num_active_launcher_icons() + self.assertLessEqual(num_active, 1, "More than one launcher icon active after test has run!") + + def test_hud_does_not_change_launcher_status(self): + """Opening the HUD must not change the launcher visibility.""" + + launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor) + + launcher_shows_pre = launcher.is_showing + self.hud.ensure_visible() + launcher_shows_post = launcher.is_showing + self.assertThat(launcher_shows_pre, Equals(launcher_shows_post)) + + +class HudLockedLauncherInteractionsTests(HudTestsBase): + + scenarios = _make_monitor_scenarios() + + def setUp(self): + super(HudLockedLauncherInteractionsTests, self).setUp() + # Locked Launchers on all monitors + self.set_unity_option('num_launchers', 0) + self.set_unity_option('launcher_hide_mode', 0) + + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) + sleep(0.5) + + def test_hud_launcher_icon_hides_bfb(self): + """BFB icon must be hidden when the HUD launcher icon is shown.""" + + hud_icon = self.hud.get_launcher_icon() + bfb_icon = self.launcher.model.get_bfb_icon() + + self.assertThat(bfb_icon.visible, Eventually(Equals(True))) + self.assertTrue(bfb_icon.is_on_monitor(self.hud_monitor)) + self.assertThat(hud_icon.visible, Eventually(Equals(False))) + + self.hud.ensure_visible() + + self.assertThat(hud_icon.visible, Eventually(Equals(True))) + self.assertTrue(hud_icon.is_on_monitor(self.hud_monitor)) + # For some reason the BFB icon is always visible :-/ + #bfb_icon.visible, Eventually(Equals(False) + + def test_hud_desaturates_launcher_icons(self): + """Launcher icons must desaturate when the HUD is opened.""" + + self.hud.ensure_visible() + + for icon in self.launcher.model.get_launcher_icons_for_monitor(self.hud_monitor): + if isinstance(icon, HudLauncherIcon): + self.assertThat(icon.desaturated, Eventually(Equals(False))) + else: + self.assertThat(icon.desaturated, Eventually(Equals(True))) + + def test_hud_launcher_icon_click_hides_hud(self): + """Clicking the Hud Icon should hide the HUD""" + + hud_icon = self.hud.get_launcher_icon() + self.hud.ensure_visible() + + launcher = self.launcher.get_launcher_for_monitor(self.hud_monitor) + launcher.click_launcher_icon(hud_icon) + + self.assertThat(self.hud.visible, Eventually(Equals(False))) + self.assertThat(hud_icon.visible, Eventually(Equals(False))) + + +class HudVisualTests(HudTestsBase): + + launcher_modes = [('Launcher autohide', {'launcher_autohide': False}), + ('Launcher never hide', {'launcher_autohide': True})] + + launcher_screen = [('Launcher on primary monitor', {'launcher_primary_only': False}), + ('Launcher on all monitors', {'launcher_primary_only': True})] + + scenarios = multiply_scenarios(_make_monitor_scenarios(), launcher_modes, launcher_screen) + + def setUp(self): + super(HudVisualTests, self).setUp() + self.screen_geo.move_mouse_to_monitor(self.hud_monitor) + self.set_unity_option('launcher_hide_mode', int(self.launcher_autohide)) + self.set_unity_option('num_launchers', int(self.launcher_primary_only)) + self.hud_monitor_is_primary = (self.screen_geo.get_primary_monitor() == self.hud_monitor) + self.hud_locked = (not self.launcher_autohide and (not self.launcher_primary_only or self.hud_monitor_is_primary)) + sleep(0.5) + + def test_initially_hidden(self): + self.assertFalse(self.hud.visible) + + def test_hud_is_on_right_monitor(self): + """HUD must be drawn on the monitor where the mouse is.""" + self.hud.ensure_visible() + self.assertThat(self.hud.monitor, Eventually(Equals(self.hud_monitor))) + self.assertTrue(self.screen_geo.is_rect_on_monitor(self.hud.monitor, self.hud.geometry)) + + def test_hud_geometries(self): + """Tests the HUD geometries for the given monitor and status.""" + self.hud.ensure_visible() + monitor_geo = self.screen_geo.get_monitor_geometry(self.hud_monitor) + monitor_x = monitor_geo[0] + monitor_w = monitor_geo[2] + hud_x = self.hud.geometry[0] + hud_w = self.hud.geometry[2] + + if self.hud_locked: + self.assertThat(hud_x, GreaterThan(monitor_x)) + self.assertThat(hud_x, LessThan(monitor_x + monitor_w)) + self.assertThat(hud_w, Equals(monitor_x + monitor_w - hud_x)) + else: + self.assertThat(hud_x, Equals(monitor_x)) + self.assertThat(hud_w, Equals(monitor_w)) + + def test_hud_is_locked_to_launcher(self): + """Tests if the HUD is locked to launcher as we expect or not.""" + self.hud.ensure_visible() + self.assertThat(self.hud.is_locked_launcher, Eventually(Equals(self.hud_locked))) + + def test_hud_icon_is_shown(self): + """Tests that the correct HUD icon is shown.""" + self.hud.ensure_visible() + hud_launcher_icon = self.hud.get_launcher_icon() + hud_embedded_icon = self.hud.get_embedded_icon() + + if self.hud.is_locked_launcher: + self.assertThat(hud_launcher_icon.visible, Eventually(Equals(True))) + self.assertTrue(hud_launcher_icon.is_on_monitor(self.hud_monitor)) + self.assertTrue(hud_launcher_icon.active) + self.assertThat(hud_launcher_icon.monitor, Equals(self.hud_monitor)) + self.assertFalse(hud_launcher_icon.desaturated) + self.assertThat(hud_embedded_icon, Equals(None)) + else: + self.assertThat(hud_launcher_icon.visible, Eventually(Equals(False))) + self.assertFalse(hud_launcher_icon.active) + # the embedded icon has no visible property. + self.assertThat(hud_embedded_icon, NotEquals(None)) + + def test_hud_icon_shows_the_focused_application_emblem(self): + """Tests that the correct HUD icon is shown.""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + self.hud.ensure_visible() + + self.assertThat(self.hud.icon.icon_name, Eventually(Equals(calc.icon))) + + def test_hud_icon_shows_the_ubuntu_emblem_on_empty_desktop(self): + """When in 'show desktop' mode the hud icon must be the BFB icon.""" + self.window_manager.enter_show_desktop() + self.addCleanup(self.window_manager.leave_show_desktop) + self.hud.ensure_visible() + + self.assertThat(self.hud.icon.icon_name, Eventually(EndsWith("launcher_bfb.png"))) + + def test_switch_dash_hud_does_not_break_the_focused_application_emblem(self): + """Switching from Dash to HUD must still show the correct HUD icon.""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + + self.dash.ensure_visible() + self.hud.ensure_visible() + + self.assertThat(self.hud.icon.icon_name, Eventually(Equals(calc.icon))) + + def test_switch_hud_dash_does_not_break_the_focused_application_emblem(self): + """Switching from HUD to Dash and back must still show the correct HUD icon.""" + self.close_all_app("Calculator") + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + + self.hud.ensure_visible() + self.dash.ensure_visible() + self.hud.ensure_visible() + self.assertThat(self.hud.icon.icon_name, Eventually(Equals(calc.icon))) + + def test_dash_hud_only_uses_icon_from_current_desktop(self): + """ + Switching from the dash to Hud must pick an icon from applications + from the current desktop. As the Hud must go through the entire window + stack to find the top most window. + """ + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + self.workspace.switch_to(0) + calc = self.start_app("Calculator") + self.assertTrue(calc.is_active) + self.workspace.switch_to(2) + self.dash.ensure_visible() + self.hud.ensure_visible() + + self.assertThat(self.hud.icon.icon_name, Eventually(EndsWith("launcher_bfb.png"))) + + +class HudAlternativeKeybindingTests(HudTestsBase): + + def test_super_h(self): + """Test hud reveal on h.""" + self.set_unity_option("show_hud", "h") + # Don't use reveal_hud, but be explicit in the keybindings. + self.keyboard.press_and_release("Super+h") + self.assertThat(self.hud.visible, Eventually(Equals(True))) + + def test_ctrl_alt_h(self): + """Test hud reveal on h.""" + self.set_unity_option("show_hud", "h") + # Don't use reveal_hud, but be explicit in the keybindings. + self.keyboard.press_and_release("Ctrl+Alt+h") + self.assertThat(self.hud.visible, Eventually(Equals(True))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_ibus.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_ibus.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_ibus.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_ibus.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,340 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards, Martin Mrazik +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +"""Tests to ensure unity is compatible with ibus input method.""" + +from __future__ import absolute_import + +from autopilot.emulators.ibus import ( + get_active_input_engines, + set_active_engines, + get_available_input_engines, + ) +from autopilot.matchers import Eventually +from autopilot.testcase import multiply_scenarios +from testtools.matchers import Equals, NotEquals +from unity.emulators.dash import Dash +from unity.emulators.hud import Hud + +from unity.tests import UnityTestCase + + +class IBusTests(UnityTestCase): + """Base class for IBus tests.""" + + def setUp(self): + super(IBusTests, self).setUp() + self.set_correct_ibus_trigger_keys() + + def set_correct_ibus_trigger_keys(self): + """Set the correct keys to trigger IBus. + + This method configures the ibus trigger keys inside gconf, and also sets + self.activate_binding and self.activate_release_binding. + + This method adds a cleanUp to reset the old keys once the test is done. + + """ + # get the existing keys: + trigger_hotkey_path = '/desktop/ibus/general/hotkey/trigger' + old_keys = self.get_gconf_option(trigger_hotkey_path) + + self.activate_binding = 'Control+space' + activate_release_binding_option = 'Alt+Release+Control_L' + new_keys = [self.activate_binding, activate_release_binding_option] + + if new_keys != old_keys: + self.set_gconf_option(trigger_hotkey_path, new_keys) + self.addCleanup(self.set_gconf_option, trigger_hotkey_path, old_keys) + self.activate_release_binding = 'Alt+Control_L' + + @classmethod + def setUpClass(cls): + cls._old_engines = None + + @classmethod + def tearDownClass(cls): + if cls._old_engines is not None: + set_active_engines(cls._old_engines) + + def activate_input_engine_or_skip(self, engine_name): + """Activate the input engine 'engine_name', or skip the test if the + engine name is not avaialble (probably because it's not been installed). + + """ + available_engines = get_available_input_engines() + if engine_name in available_engines: + if get_active_input_engines() != [engine_name]: + IBusTests._old_engines = set_active_engines([engine_name]) + else: + self.skip("This test requires the '%s' engine to be installed." % (engine_name)) + + def activate_ibus(self, widget): + """Activate IBus, and wait till it's actived on 'widget'.""" + self.assertThat(widget.im_active, Equals(False)) + self.keyboard.press_and_release(self.activate_binding) + self.assertThat(widget.im_active, Eventually(Equals(True))) + + def deactivate_ibus(self, widget): + """Deactivate ibus, and wait till it's inactive on 'widget'.""" + self.assertThat(widget.im_active, Equals(True)) + self.keyboard.press_and_release(self.activate_binding) + self.assertThat(widget.im_active, Eventually(Equals(False))) + + +class IBusWidgetScenariodTests(IBusTests): + """A class that includes scenarios for the hud and dash widgets.""" + + scenarios = [ + ('dash', {'widget': Dash()}), + ('hud', {'widget': Hud()}) + ] + + def do_ibus_test(self): + """Do the basic IBus test on self.widget using self.input and self.result.""" + self.widget.ensure_visible() + self.addCleanup(self.widget.ensure_hidden) + self.activate_ibus(self.widget.searchbar) + self.keyboard.type(self.input) + commit_key = getattr(self, 'commit_key', None) + if commit_key: + self.keyboard.press_and_release(commit_key) + self.deactivate_ibus(self.widget.searchbar) + self.assertThat(self.widget.search_string, Eventually(Equals(self.result))) + + + +class IBusTestsPinyin(IBusWidgetScenariodTests): + """Tests for the Pinyin(Chinese) input engine.""" + + engine_name = "pinyin" + + scenarios = multiply_scenarios( + IBusWidgetScenariodTests.scenarios, + [ + ('basic', {'input': 'abc1', 'result': u'\u963f\u5e03\u4ece'}), + ('photo', {'input': 'zhaopian ', 'result': u'\u7167\u7247'}), + ('internet', {'input': 'hulianwang ', 'result': u'\u4e92\u8054\u7f51'}), + ('disk', {'input': 'cipan ', 'result': u'\u78c1\u76d8'}), + ('disk_management', {'input': 'cipan guanli ', 'result': u'\u78c1\u76d8\u7ba1\u7406'}), + ] + ) + + def setUp(self): + super(IBusTestsPinyin, self).setUp() + self.activate_input_engine_or_skip(self.engine_name) + + def test_pinyin(self): + self.do_ibus_test() + + +class IBusTestsHangul(IBusWidgetScenariodTests): + """Tests for the Hangul(Korean) input engine.""" + + engine_name = "hangul" + + scenarios = multiply_scenarios( + IBusWidgetScenariodTests.scenarios, + [ + ('transmission', {'input': 'xmfostmaltus ', 'result': u'\ud2b8\ub79c\uc2a4\ubbf8\uc158 '}), + ('social', {'input': 'httuf ', 'result': u'\uc18c\uc15c '}), + ('document', {'input': 'anstj ', 'result': u'\ubb38\uc11c '}), + ] + ) + + def setUp(self): + super(IBusTestsHangul, self).setUp() + self.activate_input_engine_or_skip(self.engine_name) + + def test_hangul(self): + self.do_ibus_test() + + +class IBusTestsAnthy(IBusWidgetScenariodTests): + """Tests for the Anthy(Japanese) input engine.""" + + engine_name = "anthy" + + scenarios = multiply_scenarios( + IBusWidgetScenariodTests.scenarios, + [ + ('system', {'input': 'shisutemu ', 'result': u'\u30b7\u30b9\u30c6\u30e0'}), + ('game', {'input': 'ge-mu ', 'result': u'\u30b2\u30fc\u30e0'}), + ('user', {'input': 'yu-za- ', 'result': u'\u30e6\u30fc\u30b6\u30fc'}), + ], + [ + ('commit_j', {'commit_key': 'Ctrl+j'}), + ('commit_enter', {'commit_key': 'Enter'}), + ] + ) + + def setUp(self): + super(IBusTestsAnthy, self).setUp() + self.activate_input_engine_or_skip(self.engine_name) + + def test_anthy(self): + self.do_ibus_test() + + +class IBusTestsPinyinIgnore(IBusTests): + """Tests for ignoring key events while the Pinyin input engine is active.""" + + engine_name = "pinyin" + + def setUp(self): + super(IBusTestsPinyinIgnore, self).setUp() + self.activate_input_engine_or_skip(self.engine_name) + + def test_ignore_key_events_on_dash(self): + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + self.activate_ibus(self.dash.searchbar) + self.keyboard.type("cipan") + self.keyboard.press_and_release("Tab") + self.keyboard.type(" ") + self.deactivate_ibus(self.dash.searchbar) + self.assertThat(self.dash.search_string, Eventually(NotEquals(" "))) + + def test_ignore_key_events_on_hud(self): + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.keyboard.type("a") + self.activate_ibus(self.hud.searchbar) + self.keyboard.type("riqi") + old_selected = self.hud.selected_button + self.keyboard.press_and_release("Down") + new_selected = self.hud.selected_button + self.deactivate_ibus(self.hud.searchbar) + + self.assertEqual(old_selected, new_selected) + + +class IBusTestsAnthyIgnore(IBusTests): + """Tests for ignoring key events while the Anthy input engine is active.""" + + scenarios = None + engine_name = "anthy" + + def setUp(self): + super(IBusTestsAnthyIgnore, self).setUp() + self.activate_input_engine_or_skip(self.engine_name) + + def test_ignore_key_events_on_dash(self): + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + self.activate_ibus(self.dash.searchbar) + self.keyboard.type("shisutemu ") + self.keyboard.press_and_release("Tab") + self.keyboard.press_and_release("Ctrl+j") + self.deactivate_ibus(self.dash.searchbar) + dash_search_string = self.dash.search_string + + self.assertNotEqual("", dash_search_string) + + def test_ignore_key_events_on_hud(self): + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + self.keyboard.type("a") + self.activate_ibus(self.hud.searchbar) + self.keyboard.type("hiduke") + old_selected = self.hud.selected_button + self.keyboard.press_and_release("Down") + new_selected = self.hud.selected_button + self.deactivate_ibus(self.hud.searchbar) + + self.assertEqual(old_selected, new_selected) + + +class IBusActivationTests(IBusTests): + + """This class contains tests that make sure each IBus engine can activate + and deactivate correctly with various keystrokes. + + """ + + scenarios = multiply_scenarios( + IBusWidgetScenariodTests.scenarios, + [ (e, {'engine_name': e}) for e in ('pinyin','anthy','hangul') ] + ) + + def setUp(self): + super(IBusActivationTests, self).setUp() + self.activate_input_engine_or_skip(self.engine_name) + + def activate_ibus_on_release(self, widget): + """Activate IBus when keys have been released, and wait till it's actived + on 'widget'. + + """ + self.assertThat(widget.im_active, Equals(False)) + self.keyboard.press_and_release(self.activate_release_binding) + self.assertThat(widget.im_active, Eventually(Equals(True))) + + def deactivate_ibus_on_release(self, widget): + """Activate IBus when keys have been released, and wait till it's actived + on 'widget'. + + """ + self.assertThat(widget.im_active, Equals(True)) + self.keyboard.press_and_release(self.activate_release_binding) + self.assertThat(widget.im_active, Eventually(Equals(False))) + + def test_activate(self): + """Tests the ibus activation using the "key-down" keybinding.""" + self.widget.ensure_visible() + self.addCleanup(self.widget.ensure_hidden) + self.assertThat(self.widget.searchbar.im_active, Equals(False)) + + self.keyboard.press(self.activate_binding) + self.addCleanup(self.keyboard.release, self.activate_binding) + + self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(True))) + self.keyboard.release(self.activate_binding) + + self.deactivate_ibus(self.widget.searchbar) + + def test_deactivate(self): + """Tests the ibus deactivation using the "key-down" keybinding""" + self.widget.ensure_visible() + self.addCleanup(self.widget.ensure_hidden) + self.activate_ibus(self.widget.searchbar) + + self.assertThat(self.widget.searchbar.im_active, Equals(True)) + self.keyboard.press(self.activate_binding) + self.addCleanup(self.keyboard.release, self.activate_binding) + self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(False))) + self.keyboard.release(self.activate_binding) + self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(False))) + + def test_activate_on_release(self): + """Tests the ibus activation using "key-up" keybinding""" + self.widget.ensure_visible() + self.addCleanup(self.widget.ensure_hidden) + + self.assertThat(self.widget.searchbar.im_active, Equals(False)) + self.keyboard.press(self.activate_release_binding) + self.addCleanup(self.keyboard.release, self.activate_release_binding) + self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(False))) + self.keyboard.release(self.activate_release_binding) + self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(True))) + + self.deactivate_ibus_on_release(self.widget.searchbar) + + def test_deactivate_on_release(self): + """Tests the ibus deactivation using "key-up" keybinding""" + self.widget.ensure_visible() + self.addCleanup(self.widget.ensure_hidden) + self.activate_ibus_on_release(self.widget.searchbar) + + self.assertThat(self.widget.searchbar.im_active, Equals(True)) + self.keyboard.press(self.activate_release_binding) + self.addCleanup(self.keyboard.release, self.activate_release_binding) + self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(True))) + self.keyboard.release(self.activate_release_binding) + self.assertThat(self.widget.searchbar.im_active, Eventually(Equals(False))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_panel.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_panel.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_panel.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_panel.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,1238 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.emulators.X11 import ScreenGeometry +from autopilot.emulators.bamf import BamfWindow +from autopilot.matchers import Eventually +import logging +import os +from testtools.matchers import Equals, GreaterThan, NotEquals +from time import sleep + +from unity.emulators.panel import IndicatorEntry +from unity.tests import UnityTestCase + + +logger = logging.getLogger(__name__) + + +def _make_monitor_scenarios(): + num_monitors = ScreenGeometry().get_num_monitors() + scenarios = [] + + if num_monitors == 1: + scenarios = [('Single Monitor', {'panel_monitor': 0})] + else: + for i in range(num_monitors): + scenarios += [('Monitor %d' % (i), {'panel_monitor': i})] + + return scenarios + + +class PanelTestsBase(UnityTestCase): + + panel_monitor = 0 + + def setUp(self): + super(PanelTestsBase, self).setUp() + self.panel = self.panels.get_panel_for_monitor(self.panel_monitor) + self.panel.move_mouse_below_the_panel() + self.addCleanup(self.panel.move_mouse_below_the_panel) + + def open_new_application_window(self, app_name, maximized=False, move_to_monitor=True): + """Opens a new instance of the requested application, ensuring that only + one window is opened. + + Returns the opened BamfWindow + + """ + self.close_all_app(app_name) + app_win = self.start_app_window(app_name, locale="C") + app = app_win.application + + app_win.set_focus() + self.assertTrue(app.is_active) + self.assertTrue(app_win.is_focused) + self.assertThat(app.desktop_file, Equals(app_win.application.desktop_file)) + + if move_to_monitor: + self.move_window_to_panel_monitor(app_win) + + if maximized and not app_win.is_maximized: + self.keybinding("window/maximize") + self.addCleanup(self.keybinding, "window/restore") + elif not maximized and app_win.is_maximized: + self.keybinding("window/restore") + self.addCleanup(self.keybinding, "window/maximize") + + app_win.set_focus() + sleep(.25) + + self.assertThat(app_win.is_maximized, Equals(maximized)) + + return app_win + + def move_window_to_panel_monitor(self, window, restore_position=False): + """Drags a window to another monitor, eventually restoring it before""" + if not isinstance(window, BamfWindow): + raise TypeError("Window must be a BamfWindow") + + if window.monitor == self.panel_monitor: + return + + if window.is_maximized: + self.keybinding("window/restore") + self.addCleanup(self.keybinding, "window/maximize") + sleep(.1) + + if restore_position: + self.addCleanup(self.screen_geo.drag_window_to_monitor, window, window.monitor) + + self.screen_geo.drag_window_to_monitor(window, self.panel_monitor) + sleep(.25) + self.assertThat(window.monitor, Equals(self.panel_monitor)) + + def mouse_open_indicator(self, indicator): + """This is an utility function that safely opens an indicator, + ensuring that it is closed at the end of the test and that the pointer + is moved outside the panel area (to make the panel hide the menus) + """ + if not isinstance(indicator, IndicatorEntry): + raise TypeError("Window must be a IndicatorEntry") + + indicator.mouse_click() + self.addCleanup(self.panel.move_mouse_below_the_panel) + self.addCleanup(self.keyboard.press_and_release, "Escape") + self.assertThat(indicator.active, Eventually(Equals(True))) + + def assertWinButtonsInOverlayMode(self, overlay_mode): + """Assert that there are three panel window buttons and all of them are + in the specified overlay mode. + + """ + if type(overlay_mode) is not bool: + raise TypeError("overlay_mode must be True or False") + + buttons = self.panel.window_buttons.get_buttons() + self.assertThat(len(buttons), Equals(3)) + for button in buttons: + self.assertThat(button.overlay_mode, Eventually(Equals(overlay_mode))) + + def assertNoWindowOpenWithXid(self, x_id): + """Assert that Bamf doesn't know of any open windows with the given xid.""" + # We can't check text_win.closed since we've just destroyed the window. + # Instead we make sure no window with it's x_id exists. + refresh_fn = lambda: [w for w in self.bamf.get_open_windows() if w.x_id == x_id] + self.assertThat(refresh_fn, Eventually(Equals([]))) + + def sleep_menu_settle_period(self): + """Sleep long enough for the menus to fade in and fade out again.""" + sleep(self.panel.menus.fadein_duration / 1000.0) + sleep(self.panel.menus.discovery_duration) + sleep(self.panel.menus.fadeout_duration / 1000.0) + + +class PanelTitleTests(PanelTestsBase): + + scenarios = _make_monitor_scenarios() + + def test_panel_title_on_empty_desktop(self): + """With no windows shown, the panel must display the default title.""" + self.window_manager.enter_show_desktop() + self.addCleanup(self.window_manager.leave_show_desktop) + + self.assertThat(self.panel.desktop_is_active, Eventually(Equals(True))) + + def test_panel_title_with_restored_application(self): + """Panel must display application name for a non-maximised application.""" + calc_win = self.open_new_application_window("Calculator", maximized=False) + + self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name))) + + def test_panel_title_with_maximized_application(self): + """Panel must display application name for a maximised application.""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.assertThat(self.panel.title, Eventually(Equals(text_win.title))) + + def test_panel_title_with_maximized_window_restored_child(self): + """Tests the title shown in the panel when opening the restored child of + a maximized application. + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + # Ctrl+h opens the replace dialog. + self.keyboard.press_and_release("Ctrl+h") + self.addCleanup(self.keyboard.press_and_release, "Escape") + + self.assertThat(lambda: len(text_win.application.get_windows()), + Eventually(Equals(2))) + self.assertThat(self.panel.title, Equals(text_win.application.name)) + + def test_panel_shows_app_title_with_maximised_app(self): + """Tests app titles are shown in the panel with a non-focused maximized application.""" + self.open_new_application_window("Text Editor", maximized=True) + calc_win = self.open_new_application_window("Calculator", maximized=False) + + self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name))) + + def test_panel_title_updates_when_switching_to_maximized_app(self): + """Switching to a maximised app from a restored one must update the panel title.""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + self.open_new_application_window("Calculator", maximized=False) + + icon = self.launcher.model.get_icon(desktop_id=text_win.application.desktop_file) + launcher = self.launcher.get_launcher_for_monitor(self.panel_monitor) + launcher.click_launcher_icon(icon) + + self.assertProperty(text_win, is_focused=True) + self.assertThat(self.panel.title, Eventually(Equals(text_win.title))) + + def test_panel_title_updates_on_maximized_window_title_changes(self): + """Panel title must change when the title of a maximized application changes.""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + old_title = text_win.title + + text_win.set_focus() + self.keyboard.press_and_release("Ctrl+n") + + self.assertThat(lambda: text_win.title, Eventually(NotEquals(old_title))) + self.assertThat(self.panel.title, Eventually(Equals(text_win.title))) + + def test_panel_title_doesnt_change_with_switcher(self): + """Switching between apps must not change the Panels title.""" + calc_win = self.open_new_application_window("Calculator") + text_win = self.open_new_application_window("Text Editor") + current_title = self.panel.title + + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + self.switcher.next_icon() + + self.assertThat(self.panel.title, + Eventually(Equals(current_title))) + + +class PanelWindowButtonsTests(PanelTestsBase): + + scenarios = _make_monitor_scenarios() + + def setUp(self): + super(PanelWindowButtonsTests, self).setUp() + # Locked Launchers on all monitors + self.set_unity_option('num_launchers', 0) + self.set_unity_option('launcher_hide_mode', 0) + + def test_window_buttons_dont_show_on_empty_desktop(self): + """Tests that the window buttons are not shown on clean desktop.""" + # This initially used Show Desktop mode, but it's very buggy from within + # autopilot. We assume that workspace 2 is empty (which is safe for the + # jenkins runs at least.) + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + + self.workspace.switch_to(2) + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + self.panel.move_mouse_over_window_buttons() + # Sleep twice as long as the timeout, just to be sure. timeout is in + # mS, we need seconds, hence the divide by 500.0 + sleep(self.panel.menus.fadein_duration / 500.0) + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_dont_show_for_restored_window(self): + """Window buttons must not show for a restored window.""" + self.open_new_application_window("Calculator") + self.panel.move_mouse_below_the_panel() + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_dont_show_for_restored_window_with_mouse_in_panel(self): + """Window buttons must not show for a restored window with the mouse in + the panel.""" + self.open_new_application_window("Calculator") + self.panel.move_mouse_over_window_buttons() + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_dont_show_for_maximized_window_on_mouse_out(self): + """Window buttons must not show for a maximized window when the mouse is + outside the panel. + """ + self.open_new_application_window("Text Editor", maximized=True) + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_show_for_maximized_window_on_mouse_in(self): + """Window buttons must show when a maximized window is focused and the + mouse is over the menu-view panel areas. + + """ + self.open_new_application_window("Text Editor", maximized=True) + self.panel.move_mouse_over_window_buttons() + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + self.assertWinButtonsInOverlayMode(False) + + def test_window_buttons_show_with_dash(self): + """Window buttons must be shown when the dash is open.""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + self.assertWinButtonsInOverlayMode(True) + + def test_window_buttons_show_with_hud(self): + """Window buttons must be shown when the HUD is open.""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + self.assertWinButtonsInOverlayMode(True) + + def test_window_buttons_update_visual_state(self): + """Window button must update its state in response to mouse events.""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + button = self.panel.window_buttons.close + + self.assertThat(button.visual_state, Eventually(Equals("normal"))) + + button.mouse_move_to() + self.assertThat(button.visual_state, Eventually(Equals("prelight"))) + + self.mouse.press() + self.addCleanup(self.mouse.release) + self.assertThat(button.visual_state, Eventually(Equals("pressed"))) + + def test_window_buttons_cancel(self): + """Window buttons must ignore clicks when the mouse released outside + their area. + """ + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + button = self.panel.window_buttons.close + button.mouse_move_to() + self.mouse.press() + self.assertThat(button.visual_state, Eventually(Equals("pressed"))) + self.panel.move_mouse_below_the_panel() + self.mouse.release() + + self.assertThat(button.visual_state, Eventually(Equals("normal"))) + self.assertThat(self.hud.visible, Eventually(Equals(True))) + + def test_window_buttons_close_button_works_for_window(self): + """Close window button must actually closes a window.""" + text_win = self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + win_xid = text_win.x_id + + self.panel.window_buttons.close.mouse_click() + self.assertNoWindowOpenWithXid(win_xid) + + def test_window_buttons_close_follows_fitts_law(self): + """Tests that the 'Close' button is activated when clicking at 0,0. + + See bug #839690 + """ + text_win = self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + win_xid = text_win.x_id + + self.panel.move_mouse_over_window_buttons() + screen_x, screen_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[:2] + self.mouse.move(screen_x, screen_y) + self.mouse.click() + + self.assertNoWindowOpenWithXid(win_xid) + + def test_window_buttons_minimize_button_works_for_window(self): + """Tests that the window button 'Minimize' actually minimizes a window.""" + text_win = self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + + self.panel.window_buttons.minimize.mouse_click() + + self.assertProperty(text_win, is_hidden=True) + + def test_window_buttons_minimize_follows_fitts_law(self): + """Tests that the 'Minimize' button is conform to Fitts's Law. + + See bug #839690 + """ + text_win = self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + + self.panel.move_mouse_over_window_buttons() + button = self.panel.window_buttons.minimize + target_x = button.x + button.width / 2 + target_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[1] + self.mouse.move(target_x, target_y) + self.mouse.click() + + self.assertProperty(text_win, is_hidden=True) + + def test_window_buttons_unmaximize_button_works_for_window(self): + """Tests that the window button 'Unmaximize' actually unmaximizes a window.""" + text_win = self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + + self.panel.window_buttons.unmaximize.mouse_click() + + self.assertProperties(text_win, is_maximized=False, is_focused=True) + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_unmaximize_follows_fitts_law(self): + """Tests that the 'Unmaximize' button is conform to Fitts's Law. + + See bug #839690 + """ + text_win = self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + + button = self.panel.window_buttons.unmaximize + button.mouse_move_to() + target_x = button.x + button.width / 2 + target_y = self.screen_geo.get_monitor_geometry(self.panel_monitor)[1] + self.mouse.move(target_x, target_y) + sleep(1) + self.mouse.click() + + self.assertProperty(text_win, is_maximized=False) + + def test_window_buttons_close_button_works_for_hud(self): + """Tests that the window 'Close' actually closes the HUD.""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.panel.window_buttons.close.mouse_click() + self.assertThat(self.hud.visible, Eventually(Equals(False))) + + def test_minimize_button_disabled_for_hud(self): + """Minimize button must be disabled for the HUD.""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.assertThat(self.panel.window_buttons.minimize.enabled, Eventually(Equals(False))) + + def test_minimize_button_does_nothing_for_hud(self): + """Minimize button must not affect the Hud.""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.panel.window_buttons.minimize.mouse_click() + + self.assertThat(self.hud.visible, Eventually(Equals(True))) + + def test_maximize_button_disabled_for_hud(self): + """Maximize button must be disabled for the HUD.""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.assertThat(self.panel.window_buttons.maximize.enabled, Eventually(Equals(False))) + + def test_maximize_button_does_nothing_for_hud(self): + """Maximize button must not affect the Hud.""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.panel.window_buttons.maximize.mouse_click() + + self.assertThat(self.hud.visible, Eventually(Equals(True))) + + def test_hud_maximize_button_does_not_change_dash_form_factor(self): + """Clicking on the 'Maximize' button of the HUD must not change the dash + layout. + + See bug #939054 + """ + inital_form_factor = self.dash.view.form_factor + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.panel.window_buttons.maximize.mouse_click() + # long sleep here to make sure that any change that might happen will + # have already happened. + sleep(5) + self.assertThat(self.dash.view.form_factor, Equals(inital_form_factor)) + + def test_window_buttons_close_button_works_for_dash(self): + """Tests that the window 'Close' actually closes the Dash.""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + self.panel.window_buttons.close.mouse_click() + + self.assertThat(self.dash.visible, Eventually(Equals(False))) + + def test_minimize_button_disabled_for_dash(self): + """Tests that the 'Minimize' button is disabled for the dash.""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + self.assertThat(self.panel.window_buttons.minimize.enabled, Eventually(Equals(False))) + + def test_minimize_button_does_nothing_for_dash(self): + """Tests that the 'Minimize' button is disabled for the dash.""" + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + self.panel.window_buttons.minimize.mouse_click() + sleep(5) + self.assertThat(self.dash.visible, Eventually(Equals(True))) + + def test_window_buttons_maximization_buttons_works_for_dash(self): + """'Maximize' and 'Restore' buttons (when both enabled) must work as expected.""" + # Mega-TODO: + # + # This test is terrible. The docstring is terrible. The test id is terrible. + # Someone needs to split this into several smaller tests. However, I'm + # not doing that in this branch. Consider this an invitation to split + # this test out and make it suck less. + # + # For your sanity I have annotated it with comments. + self.dash.ensure_visible() + self.addCleanup(self.panel.window_buttons.close.mouse_click) + + unmaximize = self.panel.window_buttons.unmaximize + maximize = self.panel.window_buttons.maximize + + # "netbook" means "dash is maximised" + dash_maximised = (self.dash.view.form_factor == "netbook") + + # this if statement will trigger only when we're on very small screens, + # where it doesn't make sense to have the dash anything other than + # maximised. + if dash_maximised and not unmaximize.enabled: + unmaximize.mouse_click() + # nice long sleep to make sure that any changes have time to process. + sleep(5) + self.assertThat(self.dash.view.form_factor, Equals("netbook")) + else: + # we are able to resize the dash. + # maximise and unmaximise (restore) buttons are shown in the same place + # but only one is shown at once: + if maximize.visible: + active_button = maximize + inactive_button = unmaximize + else: + active_button = unmaximize + inactive_button = maximize + + self.assertThat(active_button.visible, Eventually(Equals(True))) + self.assertThat(active_button.sensitive, Eventually(Equals(True))) + self.assertThat(active_button.enabled, Eventually(Equals(True))) + self.assertThat(inactive_button.visible, Eventually(Equals(False))) + + self.addCleanup(inactive_button.mouse_click) + active_button.mouse_click() + + self.assertThat(inactive_button.visible, Eventually(Equals(True))) + self.assertThat(inactive_button.sensitive, Eventually(Equals(True))) + self.assertThat(inactive_button.enabled, Eventually(Equals(True))) + self.assertThat(active_button.visible, Eventually(Equals(False))) + + if dash_maximised: + self.assertThat(self.dash.view.form_factor, Eventually(Equals("desktop"))) + else: + self.assertThat(self.dash.view.form_factor, Eventually(Equals("netbook"))) + + self.addCleanup(active_button.mouse_click) + inactive_button.mouse_click() + + self.assertThat(active_button.visible, Eventually(Equals(True))) + self.assertThat(inactive_button.visible, Eventually(Equals(False))) + + if dash_maximised: + self.assertThat(self.dash.view.form_factor, Eventually(Equals("netbook"))) + else: + self.assertThat(self.dash.view.form_factor, Eventually(Equals("desktop"))) + + def test_minimize_button_disabled_for_non_minimizable_windows(self): + """Minimize button must be disabled for windows that don't support minimization.""" + text_win = self.open_new_application_window("Text Editor", + maximized=False, + move_to_monitor=True) + + self.keyboard.press_and_release("Ctrl+S") + self.addCleanup(self.keyboard.press_and_release, "Escape") + + wins = text_win.application.get_windows() + self.assertThat(len(wins), Equals(2)) + [target_win] = [w for w in wins if w.x_id != text_win.x_id] + self.move_window_to_panel_monitor(target_win, restore_position=False) + + self.keybinding("window/maximize") + self.assertProperty(target_win, is_maximized=True) + + self.assertThat(self.panel.window_buttons.close.enabled, Eventually(Equals(True))) + self.assertThat(self.panel.window_buttons.minimize.enabled, Eventually(Equals(False))) + + def test_window_buttons_show_when_indicator_active_and_mouse_over_panel(self): + """Window buttons must be shown when mouse is over panel area with an + indicator open. + """ + self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + + indicator = self.panel.indicators.get_indicator_by_name_hint("indicator-session-devices") + self.mouse_open_indicator(indicator) + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + self.panel.move_mouse_below_the_panel() + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + self.panel.move_mouse_over_grab_area() + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + + def test_window_buttons_show_when_holding_show_menu_key(self): + """Window buttons must show when we press the show-menu keybinding.""" + self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + self.keybinding_hold("panel/show_menus") + self.addCleanup(self.keybinding_release, "panel/show_menus") + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + + self.keybinding_release("panel/show_menus") + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_cant_accept_keynav_focus(self): + """On a mouse down event over the window buttons + you must still be able to type into the Hud. + + """ + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.keyboard.type("Hello") + self.panel.window_buttons.minimize.mouse_click() + self.keyboard.type("World") + + self.assertThat(self.hud.search_string, Eventually(Equals("HelloWorld"))) + + def test_double_click_unmaximize_window(self): + """Double clicking the grab area must unmaximize a maximized window.""" + gedit_win = self.open_new_application_window("Text Editor", maximized=True) + + self.panel.move_mouse_over_grab_area() + self.mouse.click() + self.mouse.click() + + self.assertThat(self.panel.title, Eventually(Equals(gedit_win.application.name))) + + +class PanelHoverTests(PanelTestsBase): + """Tests with the mouse pointer hovering the panel area.""" + + scenarios = _make_monitor_scenarios() + + def test_only_menus_show_for_restored_window_on_mouse_in_window_btn_area(self): + """Restored windows should only show menus when the mouse is in the window + button area. + """ + self.open_new_application_window("Calculator", + maximized=False, + move_to_monitor=True) + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_window_buttons() + + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_only_menus_show_for_restored_window_on_mouse_in_menu_area(self): + """Restored windows should only show menus when the mouse is in the window + menu area. + """ + self.open_new_application_window("Calculator", + maximized=False, + move_to_monitor=True) + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_menus() + + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_only_menus_show_for_restored_window_on_mouse_in_grab_area(self): + """Restored windows should only show menus when the mouse is in the panel + grab area. + """ + self.open_new_application_window("Calculator", + maximized=False, + move_to_monitor=True) + self.sleep_menu_settle_period() + + if self.panel.grab_area.width <= 0: + self.skipTest("Grab area is too small to run test!") + + self.panel.move_mouse_over_grab_area() + + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + + def test_hovering_over_indicators_does_not_show_app_menus(self): + """Hovering the mouse over the indicators must not show app menus.""" + self.open_new_application_window("Calculator", + maximized=False, + move_to_monitor=True) + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_menus() + # This assert is repeated from above, but we use it to make sure that + # the menus are shown before we move over the indicators. + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + + self.panel.move_mouse_over_indicators() + + self.assertThat(self.panel.menus_shown, Eventually(Equals(False))) + + def test_menus_show_for_maximized_window_on_mouse_in_btn_area(self): + """Menus and window buttons must be shown when the mouse is in the window + button area for a maximised application. + """ + self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_window_buttons() + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + + def test_menus_show_for_maximized_window_on_mouse_in_menu_area(self): + """Menus and window buttons must be shown when the mouse is in the menu + area for a maximised application. + """ + self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_menus() + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + + def test_menus_show_for_maximized_window_on_mouse_in_grab_area(self): + """Menus and window buttons must be shown when the mouse is in the grab + area for a maximised application. + """ + if self.panel.grab_area.width <= 0: + self.skipTest("Grab area is too small to run this test!") + + self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_grab_area() + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + self.assertTrue(self.panel.menus_shown, Eventually(Equals(True))) + + def test_menus_and_btns_hidden_with_mouse_over_indicators(self): + """Hovering the mouse over the indicators must hide the menus and window + buttons. + """ + self.open_new_application_window("Text Editor", + maximized=True, + move_to_monitor=True) + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_menus() + # We use this assert to make sure that the menus are visible before we + # move the mouse: + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(True))) + + self.panel.move_mouse_over_indicators() + + self.assertThat(self.panel.window_buttons_shown, Eventually(Equals(False))) + self.assertThat(self.panel.menus_shown, Eventually(Equals(False))) + + def test_hovering_indicators_open_menus(self): + """Opening an indicator entry, and then hovering on other entries must + open them. + """ + self.open_new_application_window("Text Editor") + entries = self.panel.get_indicator_entries(include_hidden_menus=True) + + self.assertThat(len(entries), GreaterThan(0)) + self.mouse_open_indicator(entries[0]) + + for entry in entries: + entry.mouse_move_to() + self.assertThat(entry.active, Eventually(Equals(True))) + self.assertThat(entry.menu_y, Eventually(NotEquals(0))) + + +class PanelMenuTests(PanelTestsBase): + + scenarios = _make_monitor_scenarios() + + def test_menus_are_added_on_new_application(self): + """Tests that menus are added when a new application is opened.""" + self.open_new_application_window("Calculator") + + refresh_fn = lambda: len(self.panel.menus.get_entries()) + self.assertThat(refresh_fn, Eventually(Equals(3))) + + menu_view = self.panel.menus + self.assertThat(lambda: menu_view.get_menu_by_label("_Calculator"), Eventually(NotEquals(None))) + self.assertThat(lambda: menu_view.get_menu_by_label("_Mode"), Eventually(NotEquals(None))) + self.assertThat(lambda: menu_view.get_menu_by_label("_Help"), Eventually(NotEquals(None))) + + def test_menus_are_not_shown_if_the_application_has_no_menus(self): + """Tests that if an application has no menus, then they are not + shown or added. + """ + # TODO: This doesn't test what it says on the tin. Setting MENUPROXY to '' + # just makes the menu appear inside the app. That's fine, but it's not + # what is described in the docstring or test id. + self.patch_environment("UBUNTU_MENUPROXY", "") + calc_win = self.open_new_application_window("Calculator") + + self.assertThat( + lambda: len(self.panel.menus.get_entries()), + Eventually(Equals(0)), + "Current panel entries are: %r" % self.panel.menus.get_entries()) + + self.panel.move_mouse_over_grab_area() + self.assertThat(self.panel.title, Eventually(Equals(calc_win.application.name))) + + def test_menus_shows_when_new_application_is_opened(self): + """This tests the menu discovery feature on new application.""" + + self.open_new_application_window("Calculator") + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + self.sleep_menu_settle_period() + self.assertThat(self.panel.menus_shown, Eventually(Equals(False))) + + def test_menus_dont_show_if_a_new_application_window_is_opened(self): + """This tests the menu discovery feature on new window for a know application.""" + self.open_new_application_window("Character Map") + self.sleep_menu_settle_period() + + self.start_app("Character Map") + sleep(self.panel.menus.fadein_duration / 1000.0) + # Not using Eventually here since this is time-critical. Need to work + # out a better way to do this. + self.assertThat(self.panel.menus_shown, Equals(False)) + + def test_menus_dont_show_for_restored_window_on_mouse_out(self): + """Restored window menus must not show when the mouse is outside the + panel menu area. + """ + self.open_new_application_window("Calculator") + self.sleep_menu_settle_period() + + self.assertThat(self.panel.menus_shown, Eventually(Equals(False))) + + def test_menus_show_for_restored_window_on_mouse_in(self): + """Restored window menus must show only when the mouse is over the panel + menu area. + """ + self.open_new_application_window("Calculator") + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_menus() + + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + + def test_menus_dont_show_for_maximized_window_on_mouse_out(self): + """Maximized window menus must not show when the mouse is outside the + panel menu area. + """ + self.open_new_application_window("Text Editor", maximized=True) + + self.assertThat(self.panel.menus_shown, Eventually(Equals(False))) + + def test_menus_show_for_maximized_window_on_mouse_in(self): + """Maximized window menus must only show when the mouse is over the + panel menu area. + """ + self.open_new_application_window("Text Editor", maximized=True) + self.sleep_menu_settle_period() + + self.panel.move_mouse_over_menus() + self.assertThat(self.panel.menus_shown, Eventually(Equals(True))) + + def test_menus_dont_show_with_dash(self): + """Tests that menus are not showing when opening the dash.""" + self.open_new_application_window("Text Editor", maximized=True) + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + self.assertThat(self.panel.menus_shown, Eventually(Equals(False))) + + + def test_menus_dont_show_with_hud(self): + """Tests that menus are not showing when opening the HUD.""" + self.open_new_application_window("Text Editor", maximized=True) + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.assertThat(self.panel.menus_shown, Eventually(Equals(False))) + + +class PanelIndicatorEntryTests(PanelTestsBase): + """Tests for the indicator entries, including both menu and indicators.""" + + scenarios = _make_monitor_scenarios() + + def open_app_and_get_menu_entry(self): + """Open the test app and wait for the menu entry to appear.""" + self.open_new_application_window("Calculator") + refresh_fn = lambda: len(self.panel.menus.get_entries()) + self.assertThat(refresh_fn, Eventually(GreaterThan(0))) + menu_entry = self.panel.menus.get_entries()[0] + return menu_entry + + def test_menu_opens_on_click(self): + """Tests that clicking on a menu entry, opens a menu.""" + menu_entry = self.open_app_and_get_menu_entry() + self.mouse_open_indicator(menu_entry) + + self.assertThat(menu_entry.active, Eventually(Equals(True))) + self.assertThat(menu_entry.menu_x, Eventually(Equals(menu_entry.x))) + self.assertThat(menu_entry.menu_y, Eventually(Equals(self.panel.height))) + + def test_menu_opens_closes_on_click(self): + """Clicking on an open menu entru must close it again.""" + menu_entry = self.open_app_and_get_menu_entry() + self.mouse_open_indicator(menu_entry) + + # This assert is for timing purposes only: + self.assertThat(menu_entry.active, Eventually(Equals(True))) + self.mouse.click() + + self.assertThat(menu_entry.active, Eventually(Equals(False))) + self.assertThat(menu_entry.menu_x, Eventually(Equals(0))) + self.assertThat(menu_entry.menu_y, Eventually(Equals(0))) + + def test_menu_closes_on_click_outside(self): + """Clicking outside an open menu must close it.""" + menu_entry = self.open_app_and_get_menu_entry() + self.mouse_open_indicator(menu_entry) + + # This assert is for timing purposes only: + self.assertThat(menu_entry.active, Eventually(Equals(True))) + target_x = menu_entry.menu_x + menu_entry.menu_width/2 + target_y = menu_entry.menu_y + menu_entry.menu_height + 10 + self.mouse.move(target_x, target_y) + self.mouse.click() + + self.assertThat(menu_entry.active, Eventually(Equals(False))) + self.assertThat(menu_entry.menu_x, Eventually(Equals(0))) + self.assertThat(menu_entry.menu_y, Eventually(Equals(0))) + + +class PanelKeyNavigationTests(PanelTestsBase): + + scenarios = _make_monitor_scenarios() + + def get_active_indicator(self): + """Get the active indicator in a safe manner. + + This method will wait until the active indicator has been set. + + """ + self.assertThat(self.panel.get_active_indicator, Eventually(NotEquals(None))) + return self.panel.get_active_indicator() + + def test_panel_first_menu_show_works(self): + """Pressing the open-menus keybinding must open the first indicator.""" + self.open_new_application_window("Calculator") + sleep(1) + self.keybinding("panel/open_first_menu") + self.addCleanup(self.keyboard.press_and_release, "Escape") + + open_indicator = self.get_active_indicator() + expected_indicator = self.panel.get_indicator_entries(include_hidden_menus=True)[0] + self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id))) + + self.keybinding("panel/open_first_menu") + self.assertThat(self.panel.get_active_indicator, Eventually(Equals(None))) + + def test_panel_menu_accelerators_work(self): + """Pressing a valid menu accelerator must open the correct menu item.""" + self.open_new_application_window("Calculator") + sleep(1) + self.keyboard.press_and_release("Alt+c") + self.addCleanup(self.keyboard.press_and_release, "Escape") + + open_indicator = self.get_active_indicator() + self.assertThat(open_indicator.label, Eventually(Equals("_Calculator"))) + + def test_panel_indicators_key_navigation_next_works(self): + """Right arrow key must open the next menu.""" + self.open_new_application_window("Calculator") + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) + + self.keybinding("panel/open_first_menu") + self.addCleanup(self.keyboard.press_and_release, "Escape") + + self.keybinding("panel/next_indicator") + open_indicator = self.get_active_indicator() + expected_indicator = available_indicators[1] + self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id))) + + def test_panel_indicators_key_navigation_prev_works(self): + """Left arrow key must open the previous menu.""" + self.open_new_application_window("Calculator") + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) + + self.keybinding("panel/open_first_menu") + self.addCleanup(self.keyboard.press_and_release, "Escape") + + self.keybinding("panel/prev_indicator") + open_indicator = self.get_active_indicator() + expected_indicator = available_indicators[-1] + + self.assertThat(open_indicator.entry_id, Eventually(Equals(expected_indicator.entry_id))) + + def test_mouse_does_not_break_key_navigation(self): + """Must be able to use the mouse to open indicators after they've been + opened with the keyboard. + """ + self.open_new_application_window("Calculator") + available_indicators = self.panel.get_indicator_entries(include_hidden_menus=True) + + self.keybinding("panel/open_first_menu") + self.addCleanup(self.keyboard.press_and_release, "Escape") + + available_indicators[2].mouse_move_to() + self.addCleanup(self.panel.move_mouse_below_the_panel) + + self.assertThat(available_indicators[2].active, Eventually(Equals(True))) + + self.keybinding("panel/prev_indicator") + self.assertThat(available_indicators[1].active, Eventually(Equals(True))) + + +class PanelGrabAreaTests(PanelTestsBase): + """Panel grab area tests.""" + + scenarios = _make_monitor_scenarios() + + def move_mouse_over_grab_area(self): + self.panel.move_mouse_over_grab_area() + self.addCleanup(self.panel.move_mouse_below_the_panel) + sleep(.1) + + def test_unmaximize_from_grab_area_works(self): + """Dragging a window down from the panel must unmaximize it.""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.move_mouse_over_grab_area() + self.mouse.press() + self.panel.move_mouse_below_the_panel() + self.mouse.release() + + self.assertProperty(text_win, is_maximized=False) + + def test_focus_the_maximized_window_works(self): + """Clicking on the grab area must put a maximized window in focus.""" + text_win = self.open_new_application_window("Text Editor", maximized=True) + calc_win = self.open_new_application_window("Calculator") + + self.assertProperty(text_win, is_focused=False) + self.assertProperty(calc_win, is_focused=True) + + self.move_mouse_over_grab_area() + self.mouse.click() + + self.assertProperty(text_win, is_focused=True) + + def test_lower_the_maximized_window_works(self): + """Middle-clicking on the panel grab area must lower a maximized window.""" + calc_win = self.open_new_application_window("Calculator") + text_win = self.open_new_application_window("Text Editor", maximized=True) + + self.assertProperty(text_win, is_focused=True) + self.assertProperty(calc_win, is_focused=False) + + self.move_mouse_over_grab_area() + self.mouse.click(2) + + self.assertProperty(calc_win, is_focused=True) + + def test_panels_dont_steal_keynav_foucs_from_hud(self): + """On a mouse click event on the panel you must still be able to type into the Hud.""" + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + self.keyboard.type("Hello") + self.move_mouse_over_grab_area() + self.mouse.click() + self.keyboard.type("World") + + self.assertThat(self.hud.search_string, Eventually(Equals("HelloWorld"))) + + +class PanelCrossMonitorsTests(PanelTestsBase): + """Multimonitor panel tests.""" + + def setUp(self): + super(PanelCrossMonitorsTests, self).setUp() + if self.screen_geo.get_num_monitors() < 2: + self.skipTest("This test requires a multimonitor setup") + + def test_panel_title_updates_moving_window(self): + """Panel must show the title of a restored window when moved to it's monitor.""" + calc_win = self.open_new_application_window("Calculator") + + prev_monitor = None + for monitor in range(0, self.screen_geo.get_num_monitors()): + if calc_win.monitor != monitor: + self.screen_geo.drag_window_to_monitor(calc_win, monitor) + + if prev_monitor: + prev_panel = self.panels.get_panel_for_monitor(prev_monitor) + self.assertThat(prev_panel.active, Eventually(Equals(False))) + + panel = self.panels.get_panel_for_monitor(monitor) + self.assertThat(panel.active, Eventually(Equals(True))) + self.assertThat(panel.title, Eventually(Equals(calc_win.application.name))) + + prev_monitor = monitor + + def test_window_buttons_dont_show_for_maximized_window_on_mouse_in(self): + """Window buttons must not show when the mouse is hovering the panel in + other monitors. + """ + self.open_new_application_window("Text Editor", maximized=True) + self.sleep_menu_settle_period() + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + panel.move_mouse_over_window_buttons() + + self.sleep_menu_settle_period() + + if self.panel_monitor == monitor: + self.assertThat(panel.window_buttons_shown, Eventually(Equals(True))) + else: + self.assertThat(panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_dont_show_in_other_monitors_when_dash_is_open(self): + """Window buttons must not show on the panels other than the one where + the dash is opened. + """ + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if self.dash.monitor == monitor: + self.assertThat(panel.window_buttons_shown, Eventually(Equals(True))) + else: + self.assertThat(panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_dont_show_in_other_monitors_when_hud_is_open(self): + """Window buttons must not show on the panels other than the one where + the hud is opened. + """ + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if self.hud.monitor == monitor: + self.assertThat(panel.window_buttons_shown, Eventually(Equals(True))) + else: + self.assertThat(panel.window_buttons_shown, Eventually(Equals(False))) + + def test_window_buttons_close_inactive_when_clicked_in_another_monitor(self): + """Clicking the close button must not affect the active maximized window + on another monitor. + + See bug #865701 + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + for monitor in range(self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if monitor != text_win.monitor: + panel.window_buttons.close.mouse_move_to() + panel.window_buttons.close.mouse_click() + self.assertThat(text_win.closed, Equals(False)) + + def test_window_buttons_minimize_inactive_when_clicked_in_another_monitor(self): + """Clicking the minimise button must not affect the active maximized + window on another monitor. + + See bug #865701 + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + for monitor in range(self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if monitor != text_win.monitor: + panel.window_buttons.minimize.mouse_click() + self.assertThat(text_win.is_hidden, Equals(False)) + + def test_window_buttons_unmaximize_inactive_when_clicked_in_another_monitor(self): + """Clicking the restore button must not affect the active maximized + window on another monitor. + + See bug #865701 + """ + text_win = self.open_new_application_window("Text Editor", maximized=True) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + if monitor != text_win.monitor: + panel.window_buttons.unmaximize.mouse_click() + self.assertThat(text_win.is_maximized, Equals(True)) + + def test_hovering_indicators_on_multiple_monitors(self): + """Opening an indicator entry and then hovering others entries must open them.""" + text_win = self.open_new_application_window("Text Editor") + panel = self.panels.get_panel_for_monitor(text_win.monitor) + indicator = panel.indicators.get_indicator_by_name_hint("indicator-session-devices") + self.mouse_open_indicator(indicator) + + for monitor in range(0, self.screen_geo.get_num_monitors()): + panel = self.panels.get_panel_for_monitor(monitor) + + entries = panel.get_indicator_entries(include_hidden_menus=True) + self.assertThat(len(entries), GreaterThan(0)) + + for entry in entries: + entry.mouse_move_to() + + if monitor != self.panel_monitor and entry.type == "menu": + # we're on the "other" monitor, so the menu should be hidden. + self.assertThat(entry.active, Eventually(Equals(False))) + self.assertThat(entry.visible, Eventually(Equals(False))) + self.assertThat(entry.menu_y, Eventually(Equals(0))) + else: + self.assertThat(entry.visible, Eventually(Equals(True))) + self.assertThat(entry.active, Eventually(Equals(True))) + self.assertThat(entry.menu_y, Eventually(NotEquals(0))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_quicklist.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_quicklist.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_quicklist.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_quicklist.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,403 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards, +# Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +import os.path +from testtools.matchers import Contains, Equals, NotEquals +from xdg.DesktopEntry import DesktopEntry +from time import sleep + +from unity.emulators.quicklist import QuicklistMenuItemLabel +from unity.tests import UnityTestCase + + +class QuicklistActionTests(UnityTestCase): + """Tests for quicklist actions.""" + + scenarios = [ + ('remmina', {'app_name': 'Remmina'}), + ] + + def open_quicklist_for_icon(self, launcher_icon): + """Open the quicklist for the given launcher icon. + + Returns the quicklist that was opened. + + """ + launcher = self.launcher.get_launcher_for_monitor(0) + launcher.click_launcher_icon(launcher_icon, button=3) + self.addCleanup(self.keyboard.press_and_release, "Escape") + self.assertThat(launcher_icon.get_quicklist, Eventually(NotEquals(None))) + return launcher_icon.get_quicklist() + + def test_quicklist_actions(self): + """Test that all actions present in the destop file are shown in the quicklist.""" + self.start_app(self.app_name) + + # load the desktop file from disk: + desktop_id = self.KNOWN_APPS[self.app_name]['desktop-file'] + desktop_file = os.path.join('/usr/share/applications', desktop_id) + de = DesktopEntry(desktop_file) + # get the launcher icon from the launcher: + launcher_icon = self.launcher.model.get_icon(desktop_id=desktop_id) + self.assertThat(launcher_icon, NotEquals(None)) + + # open the icon quicklist, and get all the text labels: + ql = self.open_quicklist_for_icon(launcher_icon) + ql_item_texts = [i.text for i in ql.items if type(i) is QuicklistMenuItemLabel] + + # iterate over all the actions from the desktop file, make sure they're + # present in the quicklist texts. + # FIXME, this doesn't work using a locale other than English. + actions = de.getActions() + for action in actions: + key = 'Desktop Action ' + action + self.assertThat(de.content, Contains(key)) + name = de.content[key]['Name'] + self.assertThat(ql_item_texts, Contains(name)) + + def test_quicklist_application_item_focus_last_active_window(self): + """This tests shows that when you activate a quicklist application item + only the last focused instance of that application is rasied. + + This is tested by opening 2 Mahjongg and a Calculator. + Then we activate the Calculator quicklist item. + Then we actiavte the Mahjongg launcher icon. + """ + char_win1 = self.start_app_window("Character Map") + calc_win = self.start_app_window("Calculator") + char_win2 = self.start_app_window("Character Map") + + self.assertVisibleWindowStack([char_win2, calc_win, char_win1]) + + char_icon = self.launcher.model.get_icon( + desktop_id=char_win1.application.desktop_file) + calc_icon = self.launcher.model.get_icon( + desktop_id=calc_win.application.desktop_file) + + calc_ql = self.open_quicklist_for_icon(calc_icon) + calc_ql.get_quicklist_application_item(calc_win.application.name).mouse_click() + + self.assertProperty(calc_win, is_focused=True) + self.assertVisibleWindowStack([calc_win, char_win2, char_win1]) + + char_ql = self.open_quicklist_for_icon(char_icon) + char_ql.get_quicklist_application_item(char_win1.application.name).mouse_click() + + self.assertProperty(char_win2, is_focused=True) + self.assertVisibleWindowStack([char_win2, calc_win, char_win1]) + + def test_quicklist_application_item_initiate_spread(self): + """This tests shows that when you activate a quicklist application item + when an application window is focused, the spread is initiated. + """ + char_win1 = self.start_app_window("Character Map") + char_win2 = self.start_app_window("Character Map") + char_app = char_win1.application + + self.assertVisibleWindowStack([char_win2, char_win1]) + self.assertProperty(char_win2, is_focused=True) + + char_icon = self.launcher.model.get_icon(desktop_id=char_app.desktop_file) + + char_ql = self.open_quicklist_for_icon(char_icon) + app_item = char_ql.get_quicklist_application_item(char_app.name) + + self.addCleanup(self.keybinding, "spread/cancel") + app_item.mouse_click() + self.assertThat(self.window_manager.scale_active, Eventually(Equals(True))) + self.assertThat(self.window_manager.scale_active_for_group, Eventually(Equals(True))) + + def test_quicklist_item_triggered_closes_dash(self): + """When any quicklist item is triggered it must close the dash.""" + + calc_win = self.start_app_window("Calculator") + self.assertProperty(calc_win, is_focused=True) + + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + + calc_icon = self.launcher.model.get_icon( + desktop_id=calc_win.application.desktop_file) + self.open_quicklist_for_icon(calc_icon) + + self.keyboard.press_and_release("Down") + self.keyboard.press_and_release("Enter") + self.assertThat(self.dash.visible, Eventually(Equals(False))) + + def test_quicklist_closes_when_hud_opens(self): + """When a quicklist is open you must still be able to open the Hud.""" + calc = self.start_app("Calculator") + + calc_icon = self.launcher.model.get_icon(desktop_id=calc.desktop_file) + self.open_quicklist_for_icon(calc_icon) + + self.hud.ensure_visible() + self.addCleanup(self.hud.ensure_hidden) + self.assertThat(self.hud.visible, Eventually(Equals(True))) + + def test_quicklist_closes_when_dash_opens(self): + """When the quicklist is open you must still be able to open the dash.""" + calc = self.start_app("Calculator") + + calc_icon = self.launcher.model.get_icon(desktop_id=calc.desktop_file) + self.open_quicklist_for_icon(calc_icon) + + self.dash.ensure_visible() + self.addCleanup(self.dash.ensure_hidden) + self.assertThat(self.dash.visible, Eventually(Equals(True))) + + def test_right_click_opens_quicklist_if_already_open(self): + """A right click to another icon in the launcher must + close the current open quicklist and open the other + icons quicklist. + lp:890991 + """ + + calc_win = self.start_app_window("Calculator") + mahj_win = self.start_app_window("Mahjongg") + + calc_icon = self.launcher.model.get_icon( + desktop_id=calc_win.application.desktop_file) + mahj_icon = self.launcher.model.get_icon( + desktop_id=mahj_win.application.desktop_file) + + calc_ql = self.open_quicklist_for_icon(calc_icon) + self.assertThat(calc_ql.active, Eventually(Equals(True))) + + mahj_ql = self.open_quicklist_for_icon(mahj_icon) + self.assertThat(mahj_ql.active, Eventually(Equals(True))) + self.assertThat(calc_ql.active, Eventually(Equals(False))) + + def test_right_clicking_same_icon_doesnt_reopen_ql(self): + """A right click to the same icon in the launcher must + not re-open the quicklist if already open. It must hide. + """ + + calc_win = self.start_app_window("Calculator") + + calc_icon = self.launcher.model.get_icon( + desktop_id=calc_win.application.desktop_file) + + calc_ql = self.open_quicklist_for_icon(calc_icon) + self.assertThat(calc_ql.active, Eventually(Equals(True))) + + calc_ql = self.open_quicklist_for_icon(calc_icon) + self.assertThat(calc_ql.active, Eventually(Equals(False))) + + +class QuicklistKeyNavigationTests(UnityTestCase): + """Tests for the quicklist key navigation.""" + + def setUp(self): + super(QuicklistKeyNavigationTests, self).setUp() + + self.ql_app = self.start_app("Text Editor") + + self.ql_launcher_icon = self.launcher.model.get_icon( + desktop_id=self.ql_app.desktop_file) + self.assertThat(self.ql_launcher_icon, NotEquals(None)) + + self.ql_launcher = self.launcher.get_launcher_for_monitor(0) + + def open_quicklist_with_mouse(self): + """Opens a quicklist with the mouse.""" + self.ql_launcher.click_launcher_icon(self.ql_launcher_icon, button=3) + self.addCleanup(self.keyboard.press_and_release, "Escape") + self.assertThat(self.ql_launcher_icon.get_quicklist, + Eventually(NotEquals(None))) + self.quicklist = self.ql_launcher_icon.get_quicklist() + self.quicklist.move_mouse_to_right() + self.assertThat(lambda: self.quicklist.selected_item, + Eventually(Equals(None))) + + def open_quicklist_with_keyboard(self): + """Opens a quicklist using the keyboard.""" + self.screen_geo.move_mouse_to_monitor(0) + self.ql_launcher.key_nav_start() + self.addCleanup(self.ql_launcher.key_nav_cancel) + + self.ql_launcher.keyboard_select_icon(tooltip_text=self.ql_app.name) + self.keybinding("launcher/keynav/open-quicklist") + self.addCleanup(self.keybinding, "launcher/keynav/close-quicklist") + + self.assertThat(self.ql_launcher_icon.get_quicklist, + Eventually(NotEquals(None))) + self.quicklist = self.ql_launcher_icon.get_quicklist() + self.assertThat(lambda: self.quicklist.selected_item, + Eventually(NotEquals(None))) + + def assertCorrectItemSelected(self, item): + """Ensure the item considers itself selected and that quicklist agrees.""" + self.assertThat(item.selected, Eventually(Equals(True))) + self.assertThat(self.quicklist.selected_item.id, Equals(item.id)) + + def test_keynav_selects_first_item_when_unselected(self): + """Home key MUST select the first selectable item in a quicklist.""" + self.open_quicklist_with_mouse() + + self.keybinding("quicklist/keynav/first") + + expected_item = self.quicklist.selectable_items[0] + self.assertCorrectItemSelected(expected_item) + + def test_keynav_selects_first_item_when_selected(self): + """Home key MUST select the first selectable item in a quicklist when + another item is selected. + """ + self.open_quicklist_with_mouse() + mouse_item = self.quicklist.selectable_items[-1] + mouse_item.mouse_move_to() + self.assertThat(mouse_item.selected, Eventually(Equals(True))) + + self.keybinding("quicklist/keynav/first") + + expected_item = self.quicklist.selectable_items[0] + self.assertCorrectItemSelected(expected_item) + + def test_keynav_next_selects_first_item_when_unselected(self): + """Down key MUST select the first valid item when nothing is selected.""" + self.open_quicklist_with_mouse() + + self.keybinding("quicklist/keynav/next") + + expected_item = self.quicklist.selectable_items[0] + self.assertCorrectItemSelected(expected_item) + + def test_keynav_selects_last_item_when_unselected(self): + """End key MUST select the last selectable item in a quicklist.""" + self.open_quicklist_with_mouse() + + self.keybinding("quicklist/keynav/last") + + expected_item = self.quicklist.selectable_items[-1] + self.assertCorrectItemSelected(expected_item) + + def test_keynav_selects_last_item_when_selected(self): + """End key MUST select the last selectable item in a quicklist when + another item is selected. + """ + self.open_quicklist_with_mouse() + mouse_item = self.quicklist.selectable_items[0] + mouse_item.mouse_move_to() + self.assertThat(mouse_item.selected, Eventually(Equals(True))) + + self.keybinding("quicklist/keynav/last") + + expected_item = self.quicklist.selectable_items[-1] + self.assertCorrectItemSelected(expected_item) + + def test_keynav_prev_selects_last_item_when_unselected(self): + """Up key MUST select the last valid item when nothing is selected.""" + self.open_quicklist_with_mouse() + + self.keybinding("quicklist/keynav/prev") + + expected_item = self.quicklist.selectable_items[-1] + self.assertCorrectItemSelected(expected_item) + + def test_launcher_keynav_selects_first_item(self): + """The first selectable item of the quicklist must be selected when + opening the quicklist using the launcher key navigation. + """ + self.open_quicklist_with_keyboard() + + expected_item = self.quicklist.selectable_items[0] + self.assertCorrectItemSelected(expected_item) + + def test_keynav_next_selection_works(self): + """Down key MUST select the next valid item.""" + self.open_quicklist_with_mouse() + + for item in self.quicklist.selectable_items: + self.keybinding("quicklist/keynav/next") + self.assertCorrectItemSelected(item) + + def test_keynav_prev_selection_works(self): + """Up key MUST select the previous valid item.""" + self.open_quicklist_with_mouse() + + for item in reversed(self.quicklist.selectable_items): + self.keybinding("quicklist/keynav/prev") + self.assertCorrectItemSelected(item) + + def test_keynav_prev_is_cyclic(self): + """Up key MUST select the last item, when the first one is selected.""" + self.open_quicklist_with_mouse() + + mouse_item = self.quicklist.selectable_items[0] + mouse_item.mouse_move_to() + self.assertThat(mouse_item.selected, Eventually(Equals(True))) + + self.keybinding("quicklist/keynav/prev") + expected_item = self.quicklist.selectable_items[-1] + self.assertCorrectItemSelected(expected_item) + + def test_keynav_next_is_cyclic(self): + """Down key MUST select the first item, when the last one is selected.""" + self.open_quicklist_with_mouse() + + mouse_item = self.quicklist.selectable_items[-1] + mouse_item.mouse_move_to() + self.assertThat(mouse_item.selected, Eventually(Equals(True))) + + self.keybinding("quicklist/keynav/next") + expected_item = self.quicklist.selectable_items[0] + self.assertCorrectItemSelected(expected_item) + + def test_keynav_mouse_interaction(self): + """Tests that the interaction between key-navigation and mouse works as + expected. See bug #911561. + """ + self.open_quicklist_with_mouse() + mouse_item = self.quicklist.selectable_items[-1] + mouse_item.mouse_move_to() + self.assertThat(mouse_item.selected, Eventually(Equals(True))) + + self.keybinding("quicklist/keynav/prev") + sleep(.1) + self.keybinding("quicklist/keynav/prev") + + key_item = self.quicklist.selectable_items[-3] + self.assertCorrectItemSelected(key_item) + + # Moving the mouse horizontally doesn't change the selection + self.mouse.move(mouse_item.x + mouse_item.width - 10, mouse_item.y + mouse_item.height / 2) + self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id)) + + # Moving the mouse outside doesn't change the selection + self.mouse.move(mouse_item.x + mouse_item.width + 50, mouse_item.y + mouse_item.height / 2) + self.assertThat(self.quicklist.selected_item.id, Equals(key_item.id)) + + # Moving the mouse to another entry, changes the selection + mouse_item = self.quicklist.selectable_items[-2] + mouse_item.mouse_move_to() + self.assertCorrectItemSelected(mouse_item) + + def test_moving_mouse_during_grab_select_correct_menuitem(self): + """Test that moving the mouse during grabbing selects the + correct menu item. See bug #1027955. + """ + self.open_quicklist_with_mouse() + mouse_item = self.quicklist.selectable_items[0] + mouse_item.mouse_move_to() + self.assertThat(mouse_item.selected, Eventually(Equals(True))) + + # Dragging the mouse horizontally doesn't change the selection + self.mouse.press() + self.addCleanup(self.mouse.release) + self.mouse.move(mouse_item.x + mouse_item.width - 10, mouse_item.y + mouse_item.height / 2) + self.assertThat(mouse_item.selected, Eventually(Equals(True))) + + # Moving the mouse down selects the next item + mouse_item = self.quicklist.selectable_items[1] + mouse_item.mouse_move_to() + self.assertThat(mouse_item.selected, Eventually(Equals(True))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_shortcut_hint.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_shortcut_hint.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_shortcut_hint.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_shortcut_hint.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,166 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Authors: Marco Trevisan (Treviño) +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +from testtools.matchers import Equals +from time import sleep + +from unity.emulators.shortcut_hint import ShortcutController +from unity.tests import UnityTestCase + + +class BaseShortcutHintTests(UnityTestCase): + """Base class for the shortcut hint tests""" + + def setUp(self): + super(BaseShortcutHintTests, self).setUp() + + self.DEFAULT_WIDTH = 970; + self.DEFAULT_HEIGHT = 680; + + self.shortcut_hint = self.get_shortcut_controller() + self.set_unity_option('shortcut_overlay', True) + self.skip_if_monitor_too_small() + sleep(1) + + def skip_if_monitor_too_small(self): + monitor = self.screen_geo.get_primary_monitor() + monitor_geo = self.screen_geo.get_monitor_geometry(monitor) + monitor_w = monitor_geo[2] + monitor_h = monitor_geo[3] + launcher_width = self.launcher.get_launcher_for_monitor(monitor).geometry[2] + panel_height = self.panels.get_panel_for_monitor(monitor).geometry[3] + + if ((monitor_w - launcher_width) <= self.DEFAULT_WIDTH or + (monitor_h - panel_height) <= self.DEFAULT_HEIGHT): + self.skipTest("This test requires a bigger screen, to show the ShortcutHint") + + def get_shortcut_controller(self): + controllers = ShortcutController.get_all_instances() + self.assertThat(len(controllers), Equals(1)) + return controllers[0] + + def get_launcher(self): + # We could parameterise this so all tests run on both monitors (if MM is + # set up), but I think it's fine to just always use monitor primary monitor: + monitor = self.screen_geo.get_primary_monitor() + return self.launcher.get_launcher_for_monitor(monitor) + + +class ShortcutHintTests(BaseShortcutHintTests): + """Tests for the shortcut hint functionality in isolation.""" + + def test_shortcut_hint_reveal(self): + """Test that the shortcut hint is shown.""" + self.shortcut_hint.show() + self.addCleanup(self.shortcut_hint.ensure_hidden) + self.assertThat(self.shortcut_hint.visible, Eventually(Equals(True))) + + def test_shortcut_hint_reveal_timeout(self): + """Shortcut hint must be shown after a sufficient timeout.""" + timeout = self.shortcut_hint.get_show_timeout() + self.shortcut_hint.show() + self.addCleanup(self.shortcut_hint.ensure_hidden) + + sleep(timeout/2.0) + self.assertThat(self.shortcut_hint.visible, Equals(False)) + # This should happen after 3/4 of 'timeout': + self.assertThat(self.shortcut_hint.visible, Eventually(Equals(True))) + + def test_shortcut_hint_unreveal(self): + """Shortcut hint must hide when keys are released.""" + self.shortcut_hint.ensure_visible() + self.shortcut_hint.hide() + self.assertThat(self.shortcut_hint.visible, Eventually(Equals(False))) + + def test_shortcut_hint_cancel(self): + """Shortcut hint must hide when cancelled.""" + self.shortcut_hint.ensure_visible() + self.shortcut_hint.cancel() + self.assertThat(self.shortcut_hint.visible, Eventually(Equals(False))) + + def test_shortcut_hint_no_blur(self): + """""" + self.shortcut_hint.ensure_visible() + self.addCleanup(self.shortcut_hint.ensure_hidden) + + self.assertThat(self.shortcut_hint.get_shortcut_view().bg_texture_is_valid, Eventually(Equals(True))) + + +class ShortcutHintInteractionsTests(BaseShortcutHintTests): + """Test the shortcuthint interactions with other Unity parts.""" + + def test_shortcut_hint_hide_using_unity_shortcuts(self): + """Unity shortcuts (like expo) must hide the shortcut hint.""" + self.shortcut_hint.ensure_visible() + self.addCleanup(self.shortcut_hint.ensure_hidden) + + self.keybinding_tap("expo/start") + self.addCleanup(self.keybinding, "expo/cancel") + + def test_shortcut_hint_hide_pressing_modifiers(self): + """Pressing a modifer key must hide the shortcut hint.""" + self.shortcut_hint.ensure_visible() + self.addCleanup(self.shortcut_hint.ensure_hidden) + + self.keyboard.press('Control') + + self.assertThat(self.shortcut_hint.visible, Eventually(Equals(False))) + + def test_launcher_switcher_next_doesnt_show_shortcut_hint(self): + """Super+Tab switcher cycling forward must not show shortcut hint.""" + switcher_timeout = self.shortcut_hint.get_show_timeout() + self.shortcut_hint.show() + self.addCleanup(self.shortcut_hint.ensure_hidden) + + self.keybinding("launcher/switcher/next") + self.keybinding("launcher/switcher/next") + self.addCleanup(self.keyboard.press_and_release, "Escape") + sleep(switcher_timeout * 2) + + self.assertThat(self.shortcut_hint.visible, Equals(False)) + + def test_launcher_switcher_prev_doesnt_show_shortcut_hint(self): + """Super+Tab switcher cycling backwards must not show shortcut hint.""" + switcher_timeout = self.shortcut_hint.get_show_timeout() + self.shortcut_hint.show() + self.addCleanup(self.shortcut_hint.ensure_hidden) + + self.keybinding("launcher/switcher/next") + self.addCleanup(self.keyboard.press_and_release, "Escape") + self.keybinding("launcher/switcher/next") + self.keybinding("launcher/switcher/prev") + sleep(switcher_timeout * 2) + + self.assertThat(self.shortcut_hint.visible, Equals(False)) + + def test_launcher_icons_hints_show_with_shortcut_hint(self): + """When the shortcut hint is shown also the launcer's icons hints should + be shown. + + """ + launcher = self.get_launcher() + self.shortcut_hint.ensure_visible() + self.addCleanup(self.shortcut_hint.ensure_hidden) + + self.assertThat(self.shortcut_hint.visible, Equals(True)) + self.assertThat(launcher.shortcuts_shown, Equals(True)) + + def test_shortcut_hint_shows_with_launcher_icons_hints(self): + """When the launcher icons hints are shown also the shortcut hint should + be shown. + + """ + launcher = self.get_launcher() + launcher.keyboard_reveal_launcher() + self.addCleanup(launcher.keyboard_unreveal_launcher) + + self.assertThat(launcher.shortcuts_shown, Eventually(Equals(True))) + self.assertThat(self.shortcut_hint.visible, Eventually(Equals(True))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_showdesktop.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_showdesktop.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_showdesktop.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_showdesktop.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,103 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2010 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from time import sleep + +from unity.tests import UnityTestCase + + +class ShowDesktopTests(UnityTestCase): + """Test the 'Show Desktop' functionality.""" + + def setUp(self): + super(ShowDesktopTests, self).setUp() + self.set_unity_log_level("unity.plugin", "DEBUG") + # we need this to let the unity models update after we shutdown apps + # before we start the next test. + sleep(2) + + def launch_test_apps(self): + """Launch character map and calculator apps, and return their windows.""" + char_win = self.start_app_window('Character Map', locale='C') + calc_win = self.start_app_window('Calculator', locale='C') + return (char_win, calc_win) + + def test_showdesktop_hides_apps(self): + """Show Desktop keyboard shortcut must hide applications.""" + test_windows = self.launch_test_apps() + + # show desktop, verify all windows are hidden: + self.window_manager.enter_show_desktop() + self.addCleanup(self.window_manager.leave_show_desktop) + + for win in test_windows: + self.assertProperty(win, is_valid=True) + self.assertProperty(win, is_hidden=True) + + def test_showdesktop_unhides_apps(self): + """Show desktop shortcut must re-show all hidden apps.""" + test_windows = self.launch_test_apps() + + # show desktop, verify all windows are hidden: + self.window_manager.enter_show_desktop() + self.addCleanup(self.window_manager.leave_show_desktop) + + for win in test_windows: + self.assertProperty(win, is_valid=True) + self.assertProperty(win, is_hidden=True) + + # un-show desktop, verify all windows are shown: + self.window_manager.leave_show_desktop() + + for win in test_windows: + self.assertProperty(win, is_valid=True) + self.assertProperty(win, is_hidden=False) + + def test_unhide_single_app(self): + """Un-hide a single app from launcher after hiding all apps.""" + charmap, calc = self.launch_test_apps() + + # show desktop, verify all windows are hidden: + self.window_manager.enter_show_desktop() + self.addCleanup(self.window_manager.leave_show_desktop) + + for win in (charmap, calc): + self.assertProperty(win, is_valid=True) + self.assertProperty(win, is_hidden=True) + + # We'll un-minimise the character map - find it's launcherIcon in the launcher: + charmap_icon = self.launcher.model.get_icon(desktop_id="gucharmap.desktop") + if charmap_icon: + self.launcher.get_launcher_for_monitor(0).click_launcher_icon(charmap_icon) + else: + self.fail("Could not find launcher icon in launcher.") + + self.assertProperty(charmap, is_hidden=False) + self.assertProperty(calc, is_hidden=True) + + # hide desktop - now all windows should be visible: + self.window_manager.leave_show_desktop() + + for win in (charmap, calc): + self.assertProperty(win, is_hidden=False) + + def test_showdesktop_switcher(self): + """Show desktop item in switcher should hide all hidden apps.""" + test_windows = self.launch_test_apps() + + # show desktop, verify all windows are hidden: + self.switcher.initiate() + self.switcher.select_icon(self.switcher.DIRECTION_BACKWARDS, tooltip_text="Show Desktop") + self.addCleanup(self.window_manager.leave_show_desktop) + self.switcher.select() + + for win in test_windows: + self.assertProperty(win, is_valid=True) + self.assertProperty(win, is_hidden=True) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_switcher.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_switcher.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_switcher.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_switcher.py 2012-08-31 21:45:54.000000000 +0000 @@ -0,0 +1,435 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2010 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from autopilot.matchers import Eventually +from autopilot.testcase import multiply_scenarios +import logging +from testtools.matchers import Equals, Contains, Not +from time import sleep + +from unity.emulators.switcher import SwitcherMode +from unity.tests import UnityTestCase + +logger = logging.getLogger(__name__) + +class SwitcherTestCase(UnityTestCase): + + scenarios = [ + ('show_desktop_icon_true', {'show_desktop_option': True}), + ('show_desktop_icon_false', {'show_desktop_option': False}), + ] + + def setUp(self): + super(SwitcherTestCase, self).setUp() + self.set_show_desktop(self.show_desktop_option) + + def set_show_desktop(self, state): + if type(state) is not bool: + raise TypeError("'state' must be boolean, not %r" % type(state)) + self.set_unity_option("disable_show_desktop", state) + self.assertThat(self.switcher.controller.show_desktop_disabled, Eventually(Equals(state))) + + def set_timeout_setting(self, state): + if type(state) is not bool: + raise TypeError("'state' must be boolean, not %r" % type(state)) + self.set_unity_option("alt_tab_timeout", state) + sleep(1) + + def start_applications(self, *args): + """Start some applications, returning their windows. + + If no applications are specified, the following will be started: + * Calculator + * Character Map + * Character Map + + Windows are always started in the order that they are specified (which + means the last specified application will *probably* be at the top of the + window stack after calling this method). Windows are returned in the same + order they are specified in. + + """ + if len(args) == 0: + args = ('Calculator', 'Character Map', 'Character Map') + windows = [] + for app in args: + windows.append(self.start_app_window(app)) + + return windows + + +class SwitcherTests(SwitcherTestCase): + """Test the switcher.""" + + def setUp(self): + super(SwitcherTests, self).setUp() + self.set_timeout_setting(False) + + def tearDown(self): + super(SwitcherTests, self).tearDown() + + def test_witcher_starts_in_normal_mode(self): + """Switcher must start in normal (i.e.- not details) mode.""" + self.start_app("Character Map") + + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + self.assertProperty(self.switcher, mode=SwitcherMode.NORMAL) + + def test_first_detail_mode_has_correct_label(self): + """Starting switcher in details mode must show the focused window title.""" + window = self.start_app_window("Text Editor") + title = window.title + + self.switcher.initiate(SwitcherMode.DETAIL) + self.addCleanup(self.switcher.terminate) + + self.assertThat(self.switcher.controller.view.label, Eventually(Equals(title))) + + def test_switcher_move_next(self): + """Test that pressing the next icon binding moves to the next icon""" + self.start_applications() + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + start = self.switcher.selection_index + self.switcher.next_icon() + + self.assertThat(self.switcher.selection_index, Eventually(Equals(start + 1))) + + def test_switcher_move_prev(self): + """Test that pressing the previous icon binding moves to the previous icon""" + self.start_applications() + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + start = self.switcher.selection_index + self.switcher.previous_icon() + + self.assertThat(self.switcher.selection_index, Eventually(Equals(start - 1))) + + def test_switcher_scroll_next(self): + """Test that scrolling the mouse wheel down moves to the next icon""" + self.start_applications() + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + start = self.switcher.selection_index + self.switcher.next_via_mouse() + + self.assertThat(self.switcher.selection_index, Eventually(Equals(start + 1))) + + def test_switcher_scroll_prev(self): + """Test that scrolling the mouse wheel up moves to the previous icon""" + self.start_applications() + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + start = self.switcher.selection_index + self.switcher.previous_via_mouse() + + self.assertThat(self.switcher.selection_index, Eventually(Equals(start - 1))) + + def test_switcher_arrow_key_does_not_init(self): + """Ensure that Alt+Right does not initiate switcher. + + Regression test for LP:?????? + + """ + self.keyboard.press_and_release('Alt+Right') + self.assertThat(self.switcher.visible, Equals(False)) + + def test_lazy_switcher_initiate(self): + """Inserting a long delay between the Alt press and the Tab tab must still + open the switcher. + + """ + self.start_app("Character Map") + + self.keybinding_hold("switcher/reveal_normal") + self.addCleanup(self.keybinding_release, "switcher/reveal_normal") + self.assertThat(self.switcher.visible, Eventually(Equals(False))) + sleep(5) + self.keybinding_tap("switcher/reveal_normal") + self.addCleanup(self.keybinding, "switcher/cancel") + self.assertThat(self.switcher.visible, Eventually(Equals(True))) + + def test_switcher_cancel(self): + """Pressing the switcher cancel keystroke must cancel the switcher.""" + self.start_app("Character Map") + + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + self.assertThat(self.switcher.visible, Eventually(Equals(True))) + self.switcher.cancel() + self.assertThat(self.switcher.visible, Eventually(Equals(False))) + + def test_lazy_switcher_cancel(self): + """Must be able to cancel the switcher after a 'lazy' initiation.""" + self.start_app("Character Map") + + self.keybinding_hold("switcher/reveal_normal") + self.addCleanup(self.keybinding_release, "switcher/reveal_normal") + self.assertThat(self.switcher.visible, Eventually(Equals(False))) + sleep(5) + self.keybinding_tap("switcher/reveal_normal") + self.assertThat(self.switcher.visible, Eventually(Equals(True))) + self.switcher.cancel() + self.assertThat(self.switcher.visible, Eventually(Equals(False))) + + def test_switcher_appears_on_monitor_with_focused_window(self): + """Tests that the switches appears on the correct monitor. + + This is defined as the monitor with a focused window. + + """ + # TODO - this test fails in multi-monitor setups. You can't use addCleanup + # a better way would be to have a scenario'd class for multi-monitor + # switcher tests. + num_monitors = self.screen_geo.get_num_monitors() + if num_monitors == 1: + self.skip("No point testing this on one monitor") + + charmap, calc, mahjongg = self.start_applications() + + for monitor in range(num_monitors): + self.screen_geo.drag_window_to_monitor(calc, monitor) + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + self.assertThat(self.switcher.controller.monitor, Eventually(Equals(monitor))) + + def test_switcher_alt_f4_is_disabled(self): + """Tests that alt+f4 does not work while switcher is active.""" + + win = self.start_app_window("Text Editor") + + self.switcher.initiate(SwitcherMode.DETAIL) + self.addCleanup(self.switcher.terminate) + + self.keyboard.press_and_release("Alt+F4") + # Need the sleep to allow the window time to close, for jenkins! + sleep(10) + self.assertProperty(win, is_valid=True) + + +class SwitcherWindowsManagementTests(SwitcherTestCase): + """Test the switcher window management.""" + + def test_switcher_raises_only_last_focused_window(self): + """Tests that when we do an alt+tab only the previously focused window is raised. + + This is tests by opening 2 Calculators and a Mahjongg. + Then we do a quick alt+tab twice. + Then we close the currently focused window. + + """ + char_win1, calc_win, char_win2 = self.start_applications("Character Map", "Calculator", "Character Map") + self.assertVisibleWindowStack([char_win2, calc_win, char_win1]) + + self.keybinding("switcher/reveal_normal") + self.assertProperty(calc_win, is_focused=True) + self.assertVisibleWindowStack([calc_win, char_win2, char_win1]) + + self.keybinding("switcher/reveal_normal") + self.assertProperty(char_win2, is_focused=True) + self.assertVisibleWindowStack([char_win2, calc_win, char_win1]) + + self.keybinding("window/close") + self.assertProperty(calc_win, is_focused=True) + self.assertVisibleWindowStack([calc_win, char_win1]) + + +class SwitcherDetailsTests(SwitcherTestCase): + """Test the details mode for the switcher.""" + + def setUp(self): + super(SwitcherDetailsTests, self).setUp() + self.set_timeout_setting(True) + + def test_details_mode_on_delay(self): + """Test that details mode activates on a timeout.""" + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + self.workspace.switch_to(1) + self.start_applications("Character Map", "Character Map", "Mahjongg") + + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + # Wait longer than details mode. + sleep(3) + self.assertProperty(self.switcher, mode=SwitcherMode.DETAIL) + + def test_no_details_for_apps_on_different_workspace(self): + """Tests that details mode does not initiates when there are multiple windows + + of an application spread across different workspaces. + Regression test for LP:933406. + + """ + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + self.workspace.switch_to(1) + self.start_app_window("Character Map") + self.workspace.switch_to(2) + self.start_applications("Character Map", "Mahjongg") + + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + # Wait longer than details mode. + sleep(3) + self.assertProperty(self.switcher, mode=SwitcherMode.NORMAL) + + +class SwitcherDetailsModeTests(SwitcherTestCase): + """Tests for the details mode of the switcher. + + Tests for initiation with both grave (`) and Down arrow. + + """ + + scenarios = multiply_scenarios(SwitcherTestCase.scenarios, + [ + ('initiate_with_grave', {'initiate_keycode': '`'}), + ('initiate_with_down', {'initiate_keycode': 'Down'}), + ] + ) + + def test_can_start_details_mode(self): + """Must be able to switch to details mode using selected scenario keycode. + + """ + self.start_app_window("Character Map") + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + self.keyboard.press_and_release(self.initiate_keycode) + + self.assertProperty(self.switcher, mode=SwitcherMode.DETAIL) + + def test_next_icon_from_last_detail_works(self): + """Pressing next while showing last switcher item in details mode + must select first item in the model in non-details mode. + + """ + self.start_app("Character Map") + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + while self.switcher.selection_index < len(self.switcher.icons) - 1: + self.switcher.next_icon() + self.keyboard.press_and_release(self.initiate_keycode) + sleep(0.5) + # Make sure we're at the end of the details list for this icon + possible_details = self.switcher.detail_current_count - 1 + while self.switcher.detail_selection_index < possible_details: + self.switcher.next_detail() + + self.switcher.next_icon() + self.assertThat(self.switcher.selection_index, Eventually(Equals(0))) + + def test_detail_mode_selects_last_active_window(self): + """The active selection in detail mode must be the last focused window. + If it was the currently active application type. + """ + char_win1, char_win2 = self.start_applications("Character Map", "Character Map") + self.assertVisibleWindowStack([char_win2, char_win1]) + + self.switcher.initiate() + while self.switcher.current_icon.tooltip_text != char_win2.application.name: + self.switcher.next_icon() + self.keyboard.press_and_release(self.initiate_keycode) + sleep(0.5) + self.switcher.select() + + self.assertProperty(char_win1, is_focused=True) + + +class SwitcherWorkspaceTests(SwitcherTestCase): + """Test Switcher behavior with respect to multiple workspaces.""" + + def test_switcher_shows_current_workspace_only(self): + """Switcher must show apps from the current workspace only.""" + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + + self.workspace.switch_to(1) + calc = self.start_app("Calculator") + self.workspace.switch_to(2) + char_map = self.start_app("Character Map") + + self.switcher.initiate() + self.addCleanup(self.switcher.terminate) + + get_icon_names = lambda: [i.tooltip_text for i in self.switcher.icons] + self.assertThat(get_icon_names, Eventually(Contains(char_map.name))) + self.assertThat(get_icon_names, Eventually(Not(Contains(calc.name)))) + + def test_switcher_all_mode_shows_all_apps(self): + """Test switcher 'show_all' mode shows apps from all workspaces.""" + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + + self.workspace.switch_to(1) + calc = self.start_app("Calculator") + self.workspace.switch_to(2) + char_map = self.start_app("Character Map") + + self.switcher.initiate(SwitcherMode.ALL) + self.addCleanup(self.switcher.terminate) + + get_icon_names = lambda: [i.tooltip_text for i in self.switcher.icons] + self.assertThat(get_icon_names, Eventually(Contains(calc.name))) + self.assertThat(get_icon_names, Eventually(Contains(char_map.name))) + + def test_switcher_can_switch_to_minimised_window(self): + """Switcher must be able to switch to a minimised window when there's + + another instance of the same application on a different workspace. + + """ + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + + # disable automatic gridding of the switcher after a timeout, since it makes + # it harder to write the tests. + self.set_unity_option("alt_tab_timeout", False) + + self.workspace.switch_to(1) + self.start_app("Character Map") + + self.workspace.switch_to(3) + char_win2 = self.start_app_window("Character Map") + self.keybinding("window/minimize") + self.assertProperty(char_win2, is_hidden=True) + + self.start_app("Calculator") + + self.switcher.initiate() + while self.switcher.current_icon.tooltip_text != char_win2.application.name: + self.switcher.next_icon() + self.switcher.select() + + self.assertProperty(char_win2, is_hidden=False) + + def test_switcher_is_disabled_when_wall_plugin_active(self): + """The switcher must not open when the wall plugin is active using ctrl+alt+.""" + + initial_workspace = self.workspace.current_workspace + self.addCleanup(self.workspace.switch_to, initial_workspace) + + self.workspace.switch_to(0) + sleep(1) + self.keyboard.press("Ctrl+Alt+Right") + self.addCleanup(self.keyboard.release, "Ctrl+Alt+Right") + sleep(1) + self.keybinding_hold_part_then_tap("switcher/reveal_normal") + self.addCleanup(self.switcher.terminate) + + self.assertThat(self.switcher.visible, Eventually(Equals(False))) diff -Nru unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_unity_logging.py unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_unity_logging.py --- unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_unity_logging.py 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/build/lib.linux-armv7l-2.7/unity/tests/test_unity_logging.py 2012-08-22 11:01:41.000000000 +0000 @@ -0,0 +1,69 @@ +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2012 Canonical +# Author: Thomi Richards +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. + +from __future__ import absolute_import + +from os import remove +from os.path import exists +from tempfile import mktemp +from testtools.matchers import Contains, Not +from time import sleep + + +from unity.emulators.unity import ( + start_log_to_file, + reset_logging, + set_log_severity, + log_unity_message, + ) +from unity.tests import UnityTestCase + + +class UnityLoggingTests(UnityTestCase): + """Tests for Unity's debug logging framework.""" + + def start_new_log_file(self): + fpath = mktemp() + start_log_to_file(fpath) + return fpath + + def test_new_file_created(self): + """Unity must create log file when we call start_log_to_file. + """ + fpath = self.start_new_log_file() + self.addCleanup(remove, fpath) + self.addCleanup(reset_logging) + sleep(1) + self.assertTrue(exists(fpath)) + + def test_messages_arrive_in_file(self): + fpath = self.start_new_log_file() + log_unity_message("WARNING", "This is a warning of things to come") + sleep(1) + reset_logging() + + with open(fpath, 'r') as f: + self.assertThat(f.read(), Contains("This is a warning of things to come")) + + def test_default_log_level_unchanged(self): + fpath = self.start_new_log_file() + log_unity_message("DEBUG", "This is some INFORMATION") + sleep(1) + reset_logging() + with open(fpath, 'r') as f: + self.assertThat(f.read(), Not(Contains("This is some INFORMATION"))) + + def test_can_change_log_level(self): + fpath = self.start_new_log_file() + set_log_severity("", "DEBUG") + self.addCleanup(set_log_severity, "", "INFO") + log_unity_message("DEBUG", "This is some more INFORMATION") + sleep(1) + reset_logging() + with open(fpath, 'r') as f: + self.assertThat(f.read(), Contains("This is some more INFORMATION")) diff -Nru unity-6.4.0/tests/autopilot/unity.egg-info/PKG-INFO unity-6.4.0/tests/autopilot/unity.egg-info/PKG-INFO --- unity-6.4.0/tests/autopilot/unity.egg-info/PKG-INFO 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/unity.egg-info/PKG-INFO 2012-09-01 20:44:02.000000000 +0000 @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: unity +Version: 1.0 +Summary: Unity autopilot tests. +Home-page: https://launchpad.net/unity +Author: Alex Launi +Author-email: alex.launi@canonical.com +License: GPLv3 +Description: UNKNOWN +Platform: UNKNOWN diff -Nru unity-6.4.0/tests/autopilot/unity.egg-info/SOURCES.txt unity-6.4.0/tests/autopilot/unity.egg-info/SOURCES.txt --- unity-6.4.0/tests/autopilot/unity.egg-info/SOURCES.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/unity.egg-info/SOURCES.txt 2012-09-01 20:44:02.000000000 +0000 @@ -0,0 +1,40 @@ +README +setup.py +unity/__init__.py +unity.egg-info/PKG-INFO +unity.egg-info/SOURCES.txt +unity.egg-info/dependency_links.txt +unity.egg-info/top_level.txt +unity/emulators/__init__.py +unity/emulators/dash.py +unity/emulators/hud.py +unity/emulators/icons.py +unity/emulators/launcher.py +unity/emulators/panel.py +unity/emulators/quicklist.py +unity/emulators/shortcut_hint.py +unity/emulators/switcher.py +unity/emulators/tooltip.py +unity/emulators/unity.py +unity/emulators/window_manager.py +unity/emulators/workspace.py +unity/tests/__init__.py +unity/tests/test_command_lens.py +unity/tests/test_dash.py +unity/tests/test_home_lens.py +unity/tests/test_hud.py +unity/tests/test_ibus.py +unity/tests/test_panel.py +unity/tests/test_quicklist.py +unity/tests/test_shortcut_hint.py +unity/tests/test_showdesktop.py +unity/tests/test_switcher.py +unity/tests/test_unity_logging.py +unity/tests/launcher/__init__.py +unity/tests/launcher/test_capture.py +unity/tests/launcher/test_icon_behavior.py +unity/tests/launcher/test_keynav.py +unity/tests/launcher/test_reveal.py +unity/tests/launcher/test_shortcut.py +unity/tests/launcher/test_switcher.py +unity/tests/launcher/test_visual.py \ No newline at end of file diff -Nru unity-6.4.0/tests/autopilot/unity.egg-info/dependency_links.txt unity-6.4.0/tests/autopilot/unity.egg-info/dependency_links.txt --- unity-6.4.0/tests/autopilot/unity.egg-info/dependency_links.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/unity.egg-info/dependency_links.txt 2012-09-01 20:44:02.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru unity-6.4.0/tests/autopilot/unity.egg-info/top_level.txt unity-6.4.0/tests/autopilot/unity.egg-info/top_level.txt --- unity-6.4.0/tests/autopilot/unity.egg-info/top_level.txt 1970-01-01 00:00:00.000000000 +0000 +++ unity-6.4.0/tests/autopilot/unity.egg-info/top_level.txt 2012-09-01 20:44:02.000000000 +0000 @@ -0,0 +1 @@ +unity