on xenial help sign in
Merge from trunk
d48475aMichael Terry
debian/changelog+44
@@ -4,6 +4,50 @@ unity8 (7.86+14.04.20140306-0ubuntu1) UNRELEASED; urgency=medium
4
4
5 -- Michael Terry <mterry@ubuntu.com> Wed, 02 Apr 2014 14:39:45 -0400
5 -- Michael Terry <mterry@ubuntu.com> Wed, 02 Apr 2014 14:39:45 -0400
6
6
7+unity8 (7.85+14.04.20140410.1-0ubuntu1) trusty; urgency=medium
8+
9+ [ Didier Roche ]
10+ * Resync trunk with previous revert upload
11+
12+ [ Michał Sawicz ]
13+ * Set the Qt.ImhNoPredictiveText flag on wifi password field, fixes
14+ lp:1291575 (LP: #1291575)
15+
16+ [ Albert Astals ]
17+ * Take into account the originY when specifying the delegate ranges
18+ Fixes bug #1300302 (LP: #1300302)
19+
20+ [ CI bot ]
21+ * Resync trunk
22+
23+ [ Allan LeSage ]
24+ * Swiping open an indicator must show its correct title--protect
25+ against lp:1253804 . (LP: #1253804)
26+
27+ [ Alexander Sack ]
28+ * Fix TypeError: issue seen in system_integration autopilot test on
29+ image 279. (LP: #1303685)
30+
31+ [ Bill Filler ]
32+ * Set the Qt.ImhNoPredictiveText flag on wifi password field, fixes
33+ lp:1291575 (LP: #1291575)
34+
35+ [ Leo Arias ]
36+ * Added a search autopilot helper.
37+
38+ [ Michael Terry ]
39+ * Provide a all-in-one script for getting a device to an unlocked
40+ state.
41+
42+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 10 Apr 2014 10:03:31 +0000
43+
44+unity8 (7.85+14.04.20140404.is.7.85+14.04.20140403.1-0ubuntu1) trusty; urgency=medium
45+
46+ * Revert to previous version as it's linked to latest sdk change which
47+ is making gallery-app AP tests failing on the CI dashboard
48+
49+ -- Didier Roche <didrocks@ubuntu.com> Tue, 08 Apr 2014 13:53:47 +0200
50+
7unity8 (7.85+14.04.20140404-0ubuntu1) trusty; urgency=low
51unity8 (7.85+14.04.20140404-0ubuntu1) trusty; urgency=low
8
52
9 [ Albert Astals ]
53 [ Albert Astals ]
debian/unity8-autopilot.install+1
@@ -1 +1,2 @@
1usr/lib/python*/*/unity*
1usr/lib/python*/*/unity*
2+usr/share/unity8/unlock-device
po/gl.po+1−1
@@ -14,7 +14,7 @@ msgstr ""
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17−"X-Launchpad-Export-Date: 2014-04-08 07:13+0000\n"
17+"X-Launchpad-Export-Date: 2014-04-09 07:31+0000\n"
18"X-Generator: Launchpad (build 16976)\n"
18"X-Generator: Launchpad (build 16976)\n"
19
19
20#: plugins/Unity/Launcher/launcheritem.cpp:43
20#: plugins/Unity/Launcher/launcheritem.cpp:43
po/unity8.pot+7−3
@@ -8,7 +8,7 @@ msgid ""
8msgstr ""
8msgstr ""
9"Project-Id-Version: unity8\n"
9"Project-Id-Version: unity8\n"
10"Report-Msgid-Bugs-To: \n"
10"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2014-03-25 16:48+0100\n"
11+"POT-Creation-Date: 2014-04-10 11:13-0400\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -84,7 +84,7 @@ msgstr ""
84msgid "See less"
84msgid "See less"
85msgstr ""
85msgstr ""
86
86
87−#: qml/Dash/DashApps.qml:38
87+#: qml/Dash/DashApps.qml:37
88msgid "Recent"
88msgid "Recent"
89msgstr ""
89msgstr ""
90
90
@@ -113,6 +113,10 @@ msgstr ""
113msgid "Send"
113msgid "Send"
114msgstr ""
114msgstr ""
115
115
116+#: qml/Greeter/Greeter.qml:151
117+msgid "Swipe to unlock"
118+msgstr ""
119+
116#: qml/Greeter/Lockscreen.qml:149
120#: qml/Greeter/Lockscreen.qml:149
117msgid "Emergency Call"
121msgid "Emergency Call"
118msgstr ""
122msgstr ""
@@ -158,7 +162,7 @@ msgstr ""
158msgid "Search"
162msgid "Search"
159msgstr ""
163msgstr ""
160
164
161−#: qml/Shell.qml:417
165+#: qml/Shell.qml:348
162#, qt-format
166#, qt-format
163msgid "Please enter %1"
167msgid "Please enter %1"
164msgstr ""
168msgstr ""
qml/Components/FilterGrid.qml+1
@@ -59,6 +59,7 @@ Item {
59 property alias cellHeight: iconTileGrid.cellHeight
59 property alias cellHeight: iconTileGrid.cellHeight
60 property alias delegateCreationBegin: iconTileGrid.delegateCreationBegin
60 property alias delegateCreationBegin: iconTileGrid.delegateCreationBegin
61 property alias delegateCreationEnd: iconTileGrid.delegateCreationEnd
61 property alias delegateCreationEnd: iconTileGrid.delegateCreationEnd
62+ readonly property alias originY: iconTileGrid.originY
62 readonly property alias flicking: iconTileGrid.flicking
63 readonly property alias flicking: iconTileGrid.flicking
63 readonly property alias moving: iconTileGrid.moving
64 readonly property alias moving: iconTileGrid.moving
64 readonly property alias pressDelay: iconTileGrid.pressDelay
65 readonly property alias pressDelay: iconTileGrid.pressDelay
qml/Components/ResponsiveGridView.qml+1
@@ -40,6 +40,7 @@ Item {
40 readonly property alias flicking: gridView.flicking
40 readonly property alias flicking: gridView.flicking
41 readonly property alias moving: gridView.moving
41 readonly property alias moving: gridView.moving
42 readonly property alias pressDelay: gridView.pressDelay
42 readonly property alias pressDelay: gridView.pressDelay
43+ readonly property alias originY: gridView.originY
43 property alias delegateCreationBegin: gridView.delegateCreationBegin
44 property alias delegateCreationBegin: gridView.delegateCreationBegin
44 property alias delegateCreationEnd: gridView.delegateCreationEnd
45 property alias delegateCreationEnd: gridView.delegateCreationEnd
45 property alias highlightIndex: gridView.highlightIndex
46 property alias highlightIndex: gridView.highlightIndex
qml/Dash/CardFilterGrid.qml+1
@@ -24,6 +24,7 @@ DashRenderer {
24 collapsedHeight: filterGrid.collapsedHeight
24 collapsedHeight: filterGrid.collapsedHeight
25 margins: filterGrid.margins
25 margins: filterGrid.margins
26 uncollapsedHeight: filterGrid.uncollapsedHeight
26 uncollapsedHeight: filterGrid.uncollapsedHeight
27+ originY: filterGrid.originY
27 verticalSpacing: units.gu(1)
28 verticalSpacing: units.gu(1)
28 currentItem: filterGrid.currentItem
29 currentItem: filterGrid.currentItem
29 height: filterGrid.height
30 height: filterGrid.height
qml/Dash/DashContent.qml+10−18
@@ -17,7 +17,6 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Unity 0.2
19import Unity 0.2
20−import Utils 0.1
21import "../Components"
20import "../Components"
22
21
23Item {
22Item {
@@ -189,30 +188,23 @@ Item {
189 width: parent.width
188 width: parent.width
190 style: DashContentTabBarStyle {}
189 style: DashContentTabBarStyle {}
191
190
192− SortFilterProxyModel {
191+ model: dashContentList.model
193− id: tabBarModel
194
192
195− model: dashContentList.model
196−
197− property int selectedIndex: -1
198− onSelectedIndexChanged: {
193+ onSelectedIndexChanged: {
199− if (dashContentList.currentIndex == -1 && tabBar.selectedIndex != -1) {
194+ if (dashContentList.currentIndex == -1 && tabBar.selectedIndex != -1) {
200− // TODO This together with the Timer below
195+ // TODO This together with the Timer below
201− // are a workaround for the first tab sometimes not showing the text.
196+ // are a workaround for the first tab sometimes not showing the text.
202− // But Tabs are going away in the future so not sure if makes
197+ // But Tabs are going away in the future so not sure if makes
203− // sense invetigating what's the problem at this stage
198+ // sense invetigating what's the problem at this stage
204− selectionModeTimer.restart();
199+ selectionModeTimer.restart();
205− }
206− dashContentList.currentIndex = selectedIndex;
207 }
200 }
201+ dashContentList.currentIndex = selectedIndex;
208 }
202 }
209
203
210− model: tabBarModel.count > 0 ? tabBarModel : null
211−
212 Connections {
204 Connections {
213 target: dashContentList
205 target: dashContentList
214 onCurrentIndexChanged: {
206 onCurrentIndexChanged: {
215− tabBarModel.selectedIndex = dashContentList.currentIndex
207+ tabBar.selectedIndex = dashContentList.currentIndex
216 }
208 }
217 }
209 }
218
210
qml/Dash/DashRenderer.qml+2
@@ -33,6 +33,8 @@ Item {
33
33
34 property var delegateCreationEnd: undefined
34 property var delegateCreationEnd: undefined
35
35
36+ property real originY: 0
37+
36 property real verticalSpacing: 0
38 property real verticalSpacing: 0
37
39
38 // The current item of the renderer
40 // The current item of the renderer
qml/Dash/GenericScopeView.qml+8−8
@@ -247,16 +247,16 @@ FocusScope {
247
247
248 if (item && item.hasOwnProperty("delegateCreationBegin")) {
248 if (item && item.hasOwnProperty("delegateCreationBegin")) {
249 if (baseItem.y + baseItem.height <= 0) {
249 if (baseItem.y + baseItem.height <= 0) {
250− // Not visible (item at top of the list)
250+ // Not visible (item at top of the list viewport)
251− item.delegateCreationBegin = baseItem.height
251+ item.delegateCreationBegin = item.originY + baseItem.height
252− item.delegateCreationEnd = baseItem.height
252+ item.delegateCreationEnd = item.originY + baseItem.height
253 } else if (baseItem.y >= categoryView.height) {
253 } else if (baseItem.y >= categoryView.height) {
254− // Not visible (item at bottom of the list)
254+ // Not visible (item at bottom of the list viewport)
255− item.delegateCreationBegin = 0
255+ item.delegateCreationBegin = item.originY
256− item.delegateCreationEnd = 0
256+ item.delegateCreationEnd = item.originY
257 } else {
257 } else {
258− item.delegateCreationBegin = Math.max(-baseItem.y, 0)
258+ item.delegateCreationBegin = item.originY + Math.max(-baseItem.y, 0)
259− item.delegateCreationEnd = Math.min(categoryView.height + item.delegateCreationBegin, baseItem.height)
259+ item.delegateCreationEnd = item.originY + Math.min(categoryView.height + item.delegateCreationBegin, baseItem.height)
260 }
260 }
261 }
261 }
262 }
262 }
qml/GreeterShell.qml+4−3
@@ -107,12 +107,13 @@ BasicShell {
107 Item {
107 Item {
108 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
108 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
109 id: greeterWrapper
109 id: greeterWrapper
110+ x: launcher.progress
110 width: parent.width
111 width: parent.width
111 height: parent.height
112 height: parent.height
112− x: launcher.progress
113+
113 Behavior on x {SmoothedAnimation{velocity: 600}}
114 Behavior on x {SmoothedAnimation{velocity: 600}}
114
115
115− readonly property real showProgress: x === 0 ? greeter.showProgress : (1 - x/width)
116+ readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
116 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
117 onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
117
118
118 Greeter {
119 Greeter {
@@ -216,8 +217,8 @@ BasicShell {
216 }
217 }
217 }
218 }
218 onDash: {
219 onDash: {
219− hide()
220 greeter.hideRight()
220 greeter.hideRight()
221+ hide()
221 }
222 }
222 onShowDashHome: greeter.show()
223 onShowDashHome: greeter.show()
223 }
224 }
qml/Notifications/NotificationMenuItemFactory.qml+2−1
@@ -65,7 +65,8 @@ Loader {
65 TextField {
65 TextField {
66 id: textfield
66 id: textfield
67
67
68+ // TODO using Qt.ImhNoPredictiveText here until lp #1291575 is fixed for ubuntu-ui-toolkit
68− inputMethodHints: Qt.ImhNoAutoUppercase
69+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
69 anchors.left: parent.left; anchors.right: parent.right
70 anchors.left: parent.left; anchors.right: parent.right
70 echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
71 echoMode: checkBox.checked ? TextInput.Normal : TextInput.Password
71 height: units.gu(5)
72 height: units.gu(5)
tests/autopilot/unity8/indicators/tests/__init__.py+17
@@ -0,0 +1,17 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity - Indicators Autopilot Test Suite
4+# Copyright (C) 2013, 2014 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
tests/autopilot/unity8/indicators/tests/test_indicators.py+68−12
@@ -1,7 +1,7 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
2#
3−# Unity - Indicators Autopilot Test Suite
3+# Unity Indicators Autopilot Test Suite
4−# Copyright (C) 2013 Canonical
4+# Copyright (C) 2013, 2014 Canonical
5#
5#
6# This program is free software: you can redistribute it and/or modify
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
7# it under the terms of the GNU General Public License as published by
@@ -15,19 +15,30 @@
15#
15#
16# You should have received a copy of the GNU General Public License
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18−#
19
18
20from __future__ import absolute_import
19from __future__ import absolute_import
21
20
21+from testscenarios import multiply_scenarios
22+
22from autopilot import platform
23from autopilot import platform
23−from testtools import skipIf
24
24
25−from unity8.shell.tests import UnityTestCase
25+from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
26
26
27
27
28class IndicatorTestCase(UnityTestCase):
28class IndicatorTestCase(UnityTestCase):
29
29
30− scenarios = [
30+ device_emulation_scenarios = _get_device_emulation_scenarios()
31+
32+ def setUp(self):
33+ if platform.model() == 'Desktop':
34+ self.skipTest('Test cannot be run on the desktop.')
35+ super(IndicatorTestCase, self).setUp()
36+ self.unity_proxy = self.launch_unity()
37+
38+
39+class IndicatorExistsTestCase(IndicatorTestCase):
40+
41+ indicator_scenarios = [
31 ('Bluetooth', dict(indicator_name='indicator-bluetooth')),
42 ('Bluetooth', dict(indicator_name='indicator-bluetooth')),
32 ('Datetime', dict(indicator_name='indicator-datetime')),
43 ('Datetime', dict(indicator_name='indicator-datetime')),
33 ('Location', dict(indicator_name='indicator-location')),
44 ('Location', dict(indicator_name='indicator-location')),
@@ -36,13 +47,58 @@ class IndicatorTestCase(UnityTestCase):
36 ('Power', dict(indicator_name='indicator-power')),
47 ('Power', dict(indicator_name='indicator-power')),
37 ('Sound', dict(indicator_name='indicator-sound')),
48 ('Sound', dict(indicator_name='indicator-sound')),
38 ]
49 ]
50+ scenarios = multiply_scenarios(
51+ indicator_scenarios,
52+ IndicatorTestCase.device_emulation_scenarios
53+ )
39
54
40− @skipIf(platform.image_codename() == 'Desktop',
41− "Unity8/phablet-only test!")
42 def setUp(self):
55 def setUp(self):
43− super(IndicatorTestCase, self).setUp()
56+ super(IndicatorExistsTestCase, self).setUp()
57+ if (platform.model() == 'Nexus 10' and
58+ self.indicator_name == 'indicator-bluetooth'):
59+ self.skipTest('Nexus 10 does not have bluetooth at the moment.')
44
60
45 def test_indicator_exists(self):
61 def test_indicator_exists(self):
46− unity_proxy = self.launch_unity()
62+ self.main_window._get_indicator_widget(
63+ self.indicator_name
64+ )
65+
66+
67+class IndicatorPageTitleMatchesWidgetTestCase(IndicatorTestCase):
68+
69+ indicator_scenarios = [
70+ ('Bluetooth', dict(indicator_name='indicator-bluetooth',
71+ title='Bluetooth')),
72+ ('Datetime', dict(indicator_name='indicator-datetime',
73+ title='Upcoming')),
74+ ('Location', dict(indicator_name='indicator-location',
75+ title='Location')),
76+ ('Messaging', dict(indicator_name='indicator-messages',
77+ title='Incoming')),
78+ ('Network', dict(indicator_name='indicator-network',
79+ title='Network')),
80+ ('Power', dict(indicator_name='indicator-power',
81+ title='Battery')),
82+ ('Sound', dict(indicator_name='indicator-sound',
83+ title='Sound')),
84+ ]
85+ scenarios = multiply_scenarios(
86+ indicator_scenarios,
87+ IndicatorTestCase.device_emulation_scenarios
88+ )
89+
90+ def setUp(self):
91+ super(IndicatorPageTitleMatchesWidgetTestCase, self).setUp()
92+ if (platform.model() == 'Nexus 10' and
93+ self.indicator_name == 'indicator-bluetooth'):
94+ self.skipTest('Nexus 10 does not have bluetooth at the moment.')
95+
96+ def test_indicator_page_title_matches_widget(self):
97+ """Swiping open an indicator must show its correct title.
98+
99+ See https://bugs.launchpad.net/ubuntu-ux/+bug/1253804 .
100+ """
101+ indicator_page = self.main_window.open_indicator_page(
47− indicator = self.main_window.get_indicator(self.indicator_name)
102+ self.indicator_name)
48− self.assertIsNotNone(indicator)
103+ self.assertTrue(indicator_page.visible)
104+ self.assertEqual(indicator_page.title, self.title)
tests/autopilot/unity8/shell/emulators/__init__.py+2−6
@@ -17,16 +17,12 @@
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
18#
19
19
20−from autopilot import input, introspection
20+from ubuntuuitoolkit import emulators as toolkit_emulators
21
21
22
22
23−class UnityEmulatorBase(introspection.CustomEmulatorBase):
23+class UnityEmulatorBase(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
24 """A base class for all unity emulators."""
24 """A base class for all unity emulators."""
25
25
26− def __init__(self, *args):
27− super(UnityEmulatorBase, self).__init__(*args)
28− self.pointing_device = input.Pointer(device=input.Touch.create())
29−
30
26
31class UnityEmulatorException(Exception):
27class UnityEmulatorException(Exception):
32 """Exception raised when there is an error with the Unity emulators."""
28 """Exception raised when there is an error with the Unity emulators."""
tests/autopilot/unity8/shell/emulators/dash.py+15
@@ -23,6 +23,8 @@ from unity8.shell import emulators
23
23
24from autopilot import logging as autopilot_logging
24from autopilot import logging as autopilot_logging
25from autopilot.introspection import dbus
25from autopilot.introspection import dbus
26+from testtools.matchers import MatchesAny, Equals
27+from ubuntuuitoolkit import emulators as toolkit_emulators
26
28
27
29
28logger = logging.getLogger(__name__)
30logger = logging.getLogger(__name__)
@@ -132,6 +134,19 @@ class Dash(emulators.UnityEmulatorBase):
132 self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
134 self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
133 self.dash_content_list.currentIndex.wait_for(original_index + 1)
135 self.dash_content_list.currentIndex.wait_for(original_index + 1)
134
136
137+ def enter_search_query(self, query):
138+ search_text_field = self._get_search_text_field()
139+ search_text_field.write(query)
140+ search_text_field.state.wait_for('idle')
141+
142+ def _get_search_text_field(self):
143+ page_header = self._get_page_header()
144+ search_container = page_header.select_single(
145+ 'QQuickItem', objectName='searchContainer')
146+ search_container.state.wait_for(
147+ MatchesAny(Equals('narrowActive'), Equals('active')))
148+ return search_container.select_single(toolkit_emulators.TextField)
149+
135
150
136class GenericScopeView(emulators.UnityEmulatorBase):
151class GenericScopeView(emulators.UnityEmulatorBase):
137 """Autopilot emulator for generic scopes."""
152 """Autopilot emulator for generic scopes."""
tests/autopilot/unity8/shell/emulators/main_window.py+32−2
@@ -20,6 +20,7 @@
20import logging
20import logging
21
21
22from autopilot import logging as autopilot_logging
22from autopilot import logging as autopilot_logging
23+from autopilot import input
23
24
24from unity8.shell import emulators
25from unity8.shell import emulators
25from unity8.shell.emulators.greeter import Greeter
26from unity8.shell.emulators.greeter import Greeter
@@ -87,12 +88,32 @@ class QQuickView(emulators.UnityEmulatorBase):
87 def get_pinentryField(self):
88 def get_pinentryField(self):
88 return self.select_single(objectName="pinentryField")
89 return self.select_single(objectName="pinentryField")
89
90
90− def get_indicator(self, indicator_name):
91+ def _get_indicator_widget(self, indicator_name):
91− return self.wait_select_single(
92+ return self.select_single(
92 'DefaultIndicatorWidget',
93 'DefaultIndicatorWidget',
93 objectName=indicator_name+'-widget'
94 objectName=indicator_name+'-widget'
94 )
95 )
95
96
97+ def _get_indicator_page(self, indicator_name):
98+ return self.select_single(
99+ 'DefaultIndicatorPage',
100+ objectName=indicator_name+'-page'
101+ )
102+
103+ @autopilot_logging.log_action(logger.info)
104+ def open_indicator_page(self, indicator_name):
105+ """Swipe to open the indicator, wait until it's open.
106+
107+ :returns: The indicator page.
108+ """
109+ widget = self._get_indicator_widget(indicator_name)
110+ start_x, start_y = input.get_center_point(widget)
111+ end_x = start_x
112+ end_y = self.height
113+ self.pointing_device.drag(start_x, start_y, end_x, end_y)
114+ self.wait_select_single('Indicators', fullyOpened=True)
115+ return self._get_indicator_page(indicator_name)
116+
96 def get_shell_background(self):
117 def get_shell_background(self):
97 return self.select_single(
118 return self.select_single(
98 "CrossFadeImage", objectName="backgroundImage")
119 "CrossFadeImage", objectName="backgroundImage")
@@ -113,3 +134,12 @@ class QQuickView(emulators.UnityEmulatorBase):
113 def get_current_focused_app_id(self):
134 def get_current_focused_app_id(self):
114 """Return the id of the focused application."""
135 """Return the id of the focused application."""
115 return self.select_single('Shell').focusedApplicationId
136 return self.select_single('Shell').focusedApplicationId
137+
138+ @autopilot_logging.log_action(logger.info)
139+ def search(self, query):
140+ search_indicator = self._get_search_indicator()
141+ self.pointing_device.click_object(search_indicator)
142+ self.get_dash().enter_search_query(query)
143+
144+ def _get_search_indicator(self):
145+ return self.select_single('SearchIndicator', objectName='search')
tests/autopilot/unity8/shell/tests/test_emulators.py+16
@@ -39,6 +39,22 @@ from unity8.shell import emulators, fixture_setup, tests
39from unity8.shell.emulators import dash as dash_emulators
39from unity8.shell.emulators import dash as dash_emulators
40
40
41
41
42+class MainWindowTestCase(tests.UnityTestCase):
43+
44+ scenarios = tests._get_device_emulation_scenarios()
45+
46+ def setUp(self):
47+ super(MainWindowTestCase, self).setUp()
48+ unity_proxy = self.launch_unity()
49+ process_helpers.unlock_unity(unity_proxy)
50+
51+ def test_search(self):
52+ self.main_window.search('Test')
53+ text_field = self.main_window.get_dash()._get_search_text_field()
54+ self.assertEqual(text_field.text, 'Test')
55+ self.assertEqual(text_field.state, 'idle')
56+
57+
42class DashBaseTestCase(tests.UnityTestCase):
58class DashBaseTestCase(tests.UnityTestCase):
43
59
44 scenarios = tests._get_device_emulation_scenarios()
60 scenarios = tests._get_device_emulation_scenarios()
tests/autopilot/unity8/shell/tests/test_system_integration.py+1−1
@@ -37,5 +37,5 @@ class SystemIntegrationTests(UnityTestCase):
37 self.launch_unity()
37 self.launch_unity()
38
38
39 # invoke policykit to check permissions
39 # invoke policykit to check permissions
40− pid = subprocess.check_output("pidof -s unity8", shell=True)
40+ pid = subprocess.check_output(["pidof", "-s", "unity8"], universal_newlines=True)
41 subprocess.check_call("pkcheck --action-id org.freedesktop.NetworkManager.enable-disable-network --process " + pid, shell=True)
41 subprocess.check_call("pkcheck --action-id org.freedesktop.NetworkManager.enable-disable-network --process " + pid, shell=True)
tools/CMakeLists.txt+2
@@ -9,3 +9,5 @@ qt5_use_modules(${SCOPE_TOOL} Qml Quick)
9install(TARGETS ${SCOPE_TOOL}
9install(TARGETS ${SCOPE_TOOL}
10 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
10 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
11 )
11 )
12+
13+install(FILES unlock-device DESTINATION ${SHELL_APP_DIR})
tools/unlock-devicenew file+36
@@ -0,0 +1,36 @@
1+#!/bin/bash
2+# -*- Mode: sh; indent-tabs-mode: nil; tab-width: 4 -*-
3+
4+# Our goal here is to get an Ubuntu Touch device into a testable unlocked state.
5+# This will include a reboot.
6+
7+WAIT_COMMAND="sleep 20"
8+
9+while getopts s:w: opt; do
10+ case $opt in
11+ s)
12+ export ANDROID_SERIAL=$OPTARG
13+ ;;
14+ w)
15+ WAIT_COMMAND=$OPTARG
16+ ;;
17+ esac
18+done
19+
20+LIGHTDM_CONFIG="
21+[SeatDefaults]
22+autologin-in-background=false
23+"
24+LIGHTDM_CONFIG_FILE="/etc/lightdm/lightdm.conf.d/99-unity8-greeter-unlock.conf"
25+
26+adb shell "echo '$LIGHTDM_CONFIG' > $LIGHTDM_CONFIG_FILE"
27+adb reboot
28+sleep 5
29+adb "wait-for-device"
30+
31+# Let session come up before we return control
32+eval "$WAIT_COMMAND"
33+
34+adb shell "rm -f $LIGHTDM_CONFIG_FILE"
35+
36+exit 0