Merge lp:~dandrader/unity8/lp1116207 into lp:unity8
- lp1116207
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Daniel d'Andrada |
Approved revision: | 141 |
Merged at revision: | 133 |
Proposed branch: | lp:~dandrader/unity8/lp1116207 |
Merge into: | lp:unity8 |
Diff against target: |
693 lines (+403/-30) 17 files modified
Components/Stage.qml (+14/-0) Dash/DashHome.qml (+1/-0) Shell.qml (+25/-9) main.cpp (+1/-1) tests/mocks/CMakeLists.txt (+1/-0) tests/mocks/QMenuModel/CMakeLists.txt (+11/-0) tests/mocks/QMenuModel/QDBusActionGroup.qml (+27/-0) tests/mocks/QMenuModel/qmldir (+2/-0) tests/mocks/Ubuntu/Application/ApplicationManager.cpp (+6/-2) tests/mocks/Unity/CMakeLists.txt (+1/-0) tests/mocks/Unity/Notifications/CMakeLists.txt (+11/-0) tests/mocks/Unity/fake_scopes.cpp (+2/-2) tests/qmltests/CMakeLists.txt (+3/-0) tests/qmltests/Components/tst_Stage.qml (+1/-0) tests/qmltests/Dash/tst_Dash.qml (+4/-4) tests/qmltests/Dash/tst_DashContent.qml (+12/-12) tests/qmltests/tst_Shell.qml (+281/-0) |
To merge this branch: | bzr merge lp:~dandrader/unity8/lp1116207 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Michał Sawicz | Needs Fixing | ||
Nick Dedekind (community) | Approve | ||
Review via email:
|
Commit message
Give a visual feedback on right-edge drag with no running apps (LP: #1116207)
Description of the change
Fixes bug #1116207
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:115
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michał Sawicz (saviq) wrote : | # |
Hmm....
> VolumeControl.
Nick is preparing a removal of Overview.qml and friends, so that this won't be an issue in the end... But then instantiating the whole Shell.qml means we're loading everything down the tree, and with real plugins for most.
This will also most probably conflict with lp:~unity-team/unity8/refactor-wm-and-test/ which was done in parts so that we abstract window management for easier testing...
I wonder if this should be an autopilot test instead.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michał Sawicz (saviq) wrote : | # |
Ah, BTW couldn't you use Nick's export_qml* macros for the mock Unity plugin?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> Hmm....
>
> > VolumeControl.
>
> Nick is preparing a removal of Overview.qml and friends, so that this won't be
> an issue in the end... But then instantiating the whole Shell.qml means we're
> loading everything down the tree, and with real plugins for most.
Now, with fake plugins for all of the troublesome ones (e.g.: Ubuntu.Gestures is the real one as there's no sense in using a fake of it).
Have you seem how it looks like?
$ make tryShell
>
> This will also most probably conflict with lp:~unity-team/unity8/refactor-wm-
> and-test/ which was done in parts so that we abstract window management for
> easier testing...
Everything will change some day. If I wait until the final versions of things I will be out of work. I also consulted Gerry before starting this work.
>
> I wonder if this should be an autopilot test instead.
Please god nooooo!!!!!
I made this test also as a showcase of the many things you can do without the need for autopilot.
I'm testing the Shell component. I'm testing the code inside it, how it wires the many components together. Not the whole live system (with real, live, plugins, etc) and the logic in all components.
There's really absolutely no need for autopilot to test this bug fix. There's not a single advantage in using it for this test. We are only getting its drawbacks: Slowness. Not easy to run by the developer (he normally doesn't run it). Prone to be brittle and unreliable as you're bringing in a whole lot of variables not completely under your control or easily predictable (IPC, multiple processes, etc).
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> [...]
> Now, with fake plugins for all of the troublesome ones (e.g.: Ubuntu.Gestures
> is the real one as there's no sense in using a fake of it).
> [...]
s/Now/No
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> Ah, BTW couldn't you use Nick's export_qml* macros for the mock Unity plugin?
I tried, but it puts things in a path different from the one I'm using here.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:116
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:118
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:128
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Nick Dedekind (nick-dedekind) wrote : | # |
I still don't understand why we need the QMenuModel mock? It's not part of unity, so why we need to mock?
We've removed the overview now in any case.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Nick Dedekind (nick-dedekind) : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Nick Dedekind (nick-dedekind) wrote : | # |
181 - createMainStage
182 - createSideStage
190 + if (!m_mainStageCo
191 + createMainStage
200 + if (!m_sideStageCo
201 + createSideStage
Why the change?
We should probably also have a test which verifies that having an open app switches to the app rather than this new behaviour. And also that we will still have this new behaviour after closing all the apps
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Nick Dedekind (nick-dedekind) wrote : | # |
232 +install(FILES ${QMLFILES}
233 + DESTINATION ${SHELL_
234 + )
I don't think we want to install notification mock do we? Otherwise we wont have the real deal in autopilot tests. Will still work on build tests.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> I still don't understand why we need the QMenuModel mock? It's not part of
> unity, so why we need to mock?
Because the VolumeControl component used in Shell.qml uses QMenuModel and jenkins does not install it before running qmluitests as it's not a build dependency.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> 232 +install(FILES ${QMLFILES}
> 233 + DESTINATION ${SHELL_
> 234 + )
>
> I don't think we want to install notification mock do we? Otherwise we wont
> have the real deal in autopilot tests. Will still work on build tests.
Right, there's no need to install it for the Shell qmluitest to work.
Removed those linex.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> 181 - createMainStage
> 182 - createSideStage
>
> 190 + if (!m_mainStageCo
> 191 + createMainStage
>
> 200 + if (!m_sideStageCo
> 201 + createSideStage
>
> Why the change?
Because in the Shell test (i.e. uqmlscene binary) ApplicationManager was being created *before* the QQuickView (unlike in the unity8 binary) and therefore the assumptions made in createMainStage
By creating them lazily, only once they're needed (called from QML code), we ensure that those assumptions hold as those QML functions (ApplicationMan
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:129
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> We should probably also have a test which verifies that having an open app
> switches to the app rather than this new behaviour. And also that we will
> still have this new behaviour after closing all the apps
Done.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Nick Dedekind (nick-dedekind) wrote : | # |
> > I still don't understand why we need the QMenuModel mock? It's not part of
> > unity, so why we need to mock?
>
> Because the VolumeControl component used in Shell.qml uses QMenuModel and
> jenkins does not install it before running qmluitests as it's not a build
> dependency.
Right, well can we just add it to the build-deps then if it's needed.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> > > I still don't understand why we need the QMenuModel mock? It's not part of
> > > unity, so why we need to mock?
> >
> > Because the VolumeControl component used in Shell.qml uses QMenuModel and
> > jenkins does not install it before running qmluitests as it's not a build
> > dependency.
>
> Right, well can we just add it to the build-deps then if it's needed.
Done.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> > > > I still don't understand why we need the QMenuModel mock? It's not part
> of
> > > > unity, so why we need to mock?
> > >
> > > Because the VolumeControl component used in Shell.qml uses QMenuModel and
> > > jenkins does not install it before running qmluitests as it's not a build
> > > dependency.
> >
> > Right, well can we just add it to the build-deps then if it's needed.
>
> Done.
Commit rolled back as per discussion on IRC.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:137
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:138
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:138
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michał Sawicz (saviq) wrote : | # |
Test failures:
qmltestrunn
qmltestrunn
qmltestrunn
qmltestrunn
qmltestrunn
- 138. By Daniel d'Andrada
-
Fix whitespace issue.
- 139. By Daniel d'Andrada
-
Update Dash tests
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel d'Andrada (dandrader) wrote : | # |
> Test failures:
> qmltestrunner.
> qmltestrunner.
> qmltestrunner.
> qmltestrunner.
> qmltestrunner.
Done.
- 140. By Daniel d'Andrada
-
Update DashContent test
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:139
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 141. By Daniel d'Andrada
-
Make Shell test a bit more robust
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:140
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'Components/Stage.qml' |
2 | --- Components/Stage.qml 2013-06-28 19:32:16 +0000 |
3 | +++ Components/Stage.qml 2013-07-25 14:56:25 +0000 |
4 | @@ -39,6 +39,7 @@ |
5 | type == ApplicationInfo.MainStage ? applicationManager.mainStageApplications |
6 | : applicationManager.sideStageApplications |
7 | property bool fullyShown: false |
8 | + property bool fullyHidden: true |
9 | readonly property var focusedApplication: |
10 | type == ApplicationInfo.MainStage ? applicationManager.mainStageFocusedApplication |
11 | : applicationManager.sideStageFocusedApplication |
12 | @@ -249,6 +250,19 @@ |
13 | } |
14 | } |
15 | |
16 | + Connections { |
17 | + target: stage.applications |
18 | + onCountChanged: { __discardObsoleteScreenshots(); } |
19 | + ignoreUnknownSignals: true |
20 | + } |
21 | + onFullyHiddenChanged: { __discardObsoleteScreenshots(); } |
22 | + function __discardObsoleteScreenshots() { |
23 | + if (stage.fullyHidden && stage.applications && stage.applications.count == 0) { |
24 | + stage.focusedApplicationWhenUsingScreenshots = undefined; |
25 | + stage.__hideScreenshots(); |
26 | + } |
27 | + } |
28 | + |
29 | |
30 | SequentialAnimation { |
31 | id: showStartingApplicationAnimation |
32 | |
33 | === modified file 'Dash/DashHome.qml' |
34 | --- Dash/DashHome.qml 2013-07-09 11:44:08 +0000 |
35 | +++ Dash/DashHome.qml 2013-07-25 14:56:25 +0000 |
36 | @@ -26,6 +26,7 @@ |
37 | |
38 | ScopeView { |
39 | id: root |
40 | + objectName: "DashHome" |
41 | |
42 | onMovementStarted: listView.showHeader() |
43 | |
44 | |
45 | === modified file 'Shell.qml' |
46 | --- Shell.qml 2013-07-19 16:22:50 +0000 |
47 | +++ Shell.qml 2013-07-25 14:56:25 +0000 |
48 | @@ -36,8 +36,8 @@ |
49 | |
50 | // this is only here to select the width / height of the window if not running fullscreen |
51 | property bool tablet: false |
52 | - width: tablet ? units.gu(160) : ApplicationArguments.hasGeometry() ? ApplicationArguments.width() : units.gu(40) |
53 | - height: tablet ? units.gu(100) : ApplicationArguments.hasGeometry() ? ApplicationArguments.height() : units.gu(71) |
54 | + width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40) |
55 | + height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71) |
56 | |
57 | property real edgeSize: units.gu(2) |
58 | property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg" |
59 | @@ -129,11 +129,20 @@ |
60 | |
61 | Item { |
62 | id: underlay |
63 | + objectName: "underlay" |
64 | anchors.fill: parent |
65 | - visible: !(panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth) |
66 | - && (stages.fullyHidden |
67 | - || (stages.fullyShown && mainStage.usingScreenshots) |
68 | - || !stages.fullyShown && (mainStage.usingScreenshots || (sideStage.shown && sideStage.usingScreenshots))) |
69 | + |
70 | + // Whether the underlay is fully covered by opaque UI elements. |
71 | + property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth |
72 | + |
73 | + // Whether the user should see the topmost application surface (if there's one at all). |
74 | + property bool applicationSurfaceShouldBeSeen: |
75 | + (mainStage.applications && mainStage.applications.count > 0) |
76 | + && (!stages.fullyHidden && !mainStage.usingScreenshots) |
77 | + |
78 | + // NB! Application surfaces are stacked behing the shell one. So they can only be seen by the user |
79 | + // through the translucent parts of the shell surface. |
80 | + visible: !fullyCovered && !applicationSurfaceShouldBeSeen |
81 | |
82 | Image { |
83 | id: backgroundImage |
84 | @@ -151,6 +160,7 @@ |
85 | |
86 | Dash { |
87 | id: dash |
88 | + objectName: "dash" |
89 | |
90 | available: !greeter.shown && !lockscreen.shown |
91 | hides: [stages, launcher, panel.indicators] |
92 | @@ -178,7 +188,7 @@ |
93 | } |
94 | } |
95 | |
96 | - // FIXME: only necessary because stagesRevealer.animatedProgress and |
97 | + // FIXME: only necessary because stagesOuterContainer.showProgress and |
98 | // greeterRevealer.animatedProgress are not animated |
99 | Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }} |
100 | } |
101 | @@ -198,6 +208,7 @@ |
102 | |
103 | Showable { |
104 | id: stages |
105 | + objectName: "stages" |
106 | |
107 | x: width |
108 | |
109 | @@ -254,6 +265,7 @@ |
110 | |
111 | anchors.fill: parent |
112 | fullyShown: stages.fullyShown |
113 | + fullyHidden: stages.fullyHidden |
114 | shouldUseScreenshots: !fullyShown |
115 | rightEdgeEnabled: !sideStage.enabled |
116 | |
117 | @@ -338,7 +350,7 @@ |
118 | } |
119 | |
120 | DragHandle { |
121 | - id: stagesRevealer |
122 | + id: stagesDragHandle |
123 | |
124 | anchors.top: parent.top |
125 | anchors.bottom: parent.bottom |
126 | @@ -346,7 +358,11 @@ |
127 | |
128 | width: shell.edgeSize |
129 | direction: Direction.Leftwards |
130 | - enabled: mainStage.applications.count > 0 || sideStage.applications.count > 0 |
131 | + property bool haveApps: mainStage.applications.count > 0 || sideStage.applications.count > 0 |
132 | + |
133 | + maxTotalDragDistance: haveApps ? parent.width : parent.width * 0.7 |
134 | + // Make autocompletion impossible when !haveApps |
135 | + edgeDragEvaluator.minDragDistance: haveApps ? maxTotalDragDistance * 0.1 : Number.MAX_VALUE |
136 | } |
137 | } |
138 | } |
139 | |
140 | === modified file 'main.cpp' |
141 | --- main.cpp 2013-07-19 16:22:50 +0000 |
142 | +++ main.cpp 2013-07-25 14:56:25 +0000 |
143 | @@ -113,7 +113,7 @@ |
144 | view->setResizeMode(QQuickView::SizeRootObjectToView); |
145 | view->setTitle("Qml Phone Shell"); |
146 | view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory())); |
147 | - view->rootContext()->setContextProperty("ApplicationArguments", &qmlArgs); |
148 | + view->rootContext()->setContextProperty("applicationArguments", &qmlArgs); |
149 | if (args.contains(QLatin1String("-frameless"))) { |
150 | view->setFlags(Qt::FramelessWindowHint); |
151 | } |
152 | |
153 | === modified file 'tests/mocks/CMakeLists.txt' |
154 | --- tests/mocks/CMakeLists.txt 2013-07-04 11:45:01 +0000 |
155 | +++ tests/mocks/CMakeLists.txt 2013-07-25 14:56:25 +0000 |
156 | @@ -1,5 +1,6 @@ |
157 | add_subdirectory(libusermetrics) |
158 | add_subdirectory(LightDM) |
159 | +add_subdirectory(QMenuModel) |
160 | add_subdirectory(Ubuntu) |
161 | add_subdirectory(Unity) |
162 | add_subdirectory(HudClient) |
163 | |
164 | === added directory 'tests/mocks/QMenuModel' |
165 | === added file 'tests/mocks/QMenuModel/CMakeLists.txt' |
166 | --- tests/mocks/QMenuModel/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
167 | +++ tests/mocks/QMenuModel/CMakeLists.txt 2013-07-25 14:56:25 +0000 |
168 | @@ -0,0 +1,11 @@ |
169 | +file(GLOB QMLFILES |
170 | + *.qml |
171 | + *.js |
172 | + qmldir |
173 | +) |
174 | + |
175 | +# copy files into build directory for shadow builds |
176 | +add_custom_target(QMenuModelQmlFiles ALL |
177 | + COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR} |
178 | + DEPENDS ${QMLFILES} |
179 | +) |
180 | |
181 | === added file 'tests/mocks/QMenuModel/QDBusActionGroup.qml' |
182 | --- tests/mocks/QMenuModel/QDBusActionGroup.qml 1970-01-01 00:00:00 +0000 |
183 | +++ tests/mocks/QMenuModel/QDBusActionGroup.qml 2013-07-25 14:56:25 +0000 |
184 | @@ -0,0 +1,27 @@ |
185 | +/* |
186 | + * Copyright (C) 2013 Canonical, Ltd. |
187 | + * |
188 | + * Authors: |
189 | + * Daniel d'Andrada <daniel.dandrada@canonical.com> |
190 | + * |
191 | + * This program is free software; you can redistribute it and/or modify |
192 | + * it under the terms of the GNU General Public License as published by |
193 | + * the Free Software Foundation; version 3. |
194 | + * |
195 | + * This program is distributed in the hope that it will be useful, |
196 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
197 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
198 | + * GNU General Public License for more details. |
199 | + * |
200 | + * You should have received a copy of the GNU General Public License |
201 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
202 | + */ |
203 | + |
204 | +import QtQuick 2.0 |
205 | + |
206 | +QtObject { |
207 | + property int busType |
208 | + property string busName |
209 | + property string objectPath |
210 | + function start() {} |
211 | +} |
212 | |
213 | === added file 'tests/mocks/QMenuModel/qmldir' |
214 | --- tests/mocks/QMenuModel/qmldir 1970-01-01 00:00:00 +0000 |
215 | +++ tests/mocks/QMenuModel/qmldir 2013-07-25 14:56:25 +0000 |
216 | @@ -0,0 +1,2 @@ |
217 | +module QMenuModel |
218 | +QDBusActionGroup 0.1 QDBusActionGroup.qml |
219 | |
220 | === modified file 'tests/mocks/Ubuntu/Application/ApplicationManager.cpp' |
221 | --- tests/mocks/Ubuntu/Application/ApplicationManager.cpp 2013-07-16 20:45:13 +0000 |
222 | +++ tests/mocks/Ubuntu/Application/ApplicationManager.cpp 2013-07-25 14:56:25 +0000 |
223 | @@ -37,8 +37,6 @@ |
224 | , m_sideStage(0) |
225 | { |
226 | buildListOfAvailableApplications(); |
227 | - createMainStageComponent(); |
228 | - createSideStageComponent(); |
229 | } |
230 | |
231 | ApplicationManager::~ApplicationManager() |
232 | @@ -403,6 +401,9 @@ |
233 | |
234 | void ApplicationManager::createMainStage() |
235 | { |
236 | + if (!m_mainStageComponent) |
237 | + createMainStageComponent(); |
238 | + |
239 | // The assumptions I make here really should hold. |
240 | QQuickView *quickView = |
241 | qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]); |
242 | @@ -437,6 +438,9 @@ |
243 | |
244 | void ApplicationManager::createSideStage() |
245 | { |
246 | + if (!m_sideStageComponent) |
247 | + createSideStageComponent(); |
248 | + |
249 | // The assumptions I make here really should hold. |
250 | QQuickView *quickView = |
251 | qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]); |
252 | |
253 | === modified file 'tests/mocks/Unity/CMakeLists.txt' |
254 | --- tests/mocks/Unity/CMakeLists.txt 2013-07-11 09:09:20 +0000 |
255 | +++ tests/mocks/Unity/CMakeLists.txt 2013-07-25 14:56:25 +0000 |
256 | @@ -44,3 +44,4 @@ |
257 | ) |
258 | |
259 | add_subdirectory(Launcher) |
260 | +add_subdirectory(Notifications) |
261 | |
262 | === added file 'tests/mocks/Unity/Notifications/CMakeLists.txt' |
263 | --- tests/mocks/Unity/Notifications/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
264 | +++ tests/mocks/Unity/Notifications/CMakeLists.txt 2013-07-25 14:56:25 +0000 |
265 | @@ -0,0 +1,11 @@ |
266 | +file(GLOB QMLFILES |
267 | + *.qml |
268 | + *.js |
269 | + qmldir |
270 | +) |
271 | + |
272 | +# copy files into build directory for shadow builds |
273 | +add_custom_target(NotificationsQmlFiles ALL |
274 | + COMMAND cp ${QMLFILES} ${CMAKE_CURRENT_BINARY_DIR} |
275 | + DEPENDS ${QMLFILES} |
276 | +) |
277 | |
278 | === modified file 'tests/mocks/Unity/fake_scopes.cpp' |
279 | --- tests/mocks/Unity/fake_scopes.cpp 2013-06-12 15:03:07 +0000 |
280 | +++ tests/mocks/Unity/fake_scopes.cpp 2013-07-25 14:56:25 +0000 |
281 | @@ -52,8 +52,8 @@ |
282 | clear(); |
283 | addScope(new Scope("MockScope1", "People", true, this)); |
284 | addScope(new Scope("MockScope2", "Music", false, this)); |
285 | - addScope(new Scope("MockScope3", "Home", true, this)); |
286 | - addScope(new Scope("MockScope4", "Applications", true, this)); |
287 | + addScope(new Scope("home.scope", "Home", true, this)); |
288 | + addScope(new Scope("applications.scope", "Applications", true, this)); |
289 | addScope(new Scope("MockScope5", "Videos", true, this)); |
290 | |
291 | if (!m_loaded) { |
292 | |
293 | === modified file 'tests/qmltests/CMakeLists.txt' |
294 | --- tests/qmltests/CMakeLists.txt 2013-07-17 13:21:55 +0000 |
295 | +++ tests/qmltests/CMakeLists.txt 2013-07-25 14:56:25 +0000 |
296 | @@ -25,6 +25,9 @@ |
297 | set(qmltest_DEFAULT_TARGETS qmluitests) |
298 | set(qmltest_DEFAULT_NO_ADD_TEST TRUE) |
299 | set(qmltest_DEFAULT_PROPERTIES "") |
300 | + |
301 | +add_qml_test(. Shell IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS} |
302 | + ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single") |
303 | add_manual_qml_test(Components DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins) |
304 | add_qml_test(Components DraggingArea) |
305 | add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins) |
306 | |
307 | === modified file 'tests/qmltests/Components/tst_Stage.qml' |
308 | --- tests/qmltests/Components/tst_Stage.qml 2013-06-19 08:29:34 +0000 |
309 | +++ tests/qmltests/Components/tst_Stage.qml 2013-07-25 14:56:25 +0000 |
310 | @@ -161,6 +161,7 @@ |
311 | applicationManager: fakeAppManager |
312 | rightEdgeDraggingAreaWidth: units.gu(2) |
313 | fullyShown: true |
314 | + fullyHidden: false |
315 | newApplicationScreenshot: FakeApplicationScreenshot { |
316 | id: newAppScreenshot |
317 | parent: stage |
318 | |
319 | === modified file 'tests/qmltests/Dash/tst_Dash.qml' |
320 | --- tests/qmltests/Dash/tst_Dash.qml 2013-06-13 09:27:02 +0000 |
321 | +++ tests/qmltests/Dash/tst_Dash.qml 2013-07-25 14:56:25 +0000 |
322 | @@ -38,8 +38,8 @@ |
323 | scopeDelegateMapping: { |
324 | "MockScope1": "../tests/qmltests/Dash/qml/fake_scopeView1.qml", |
325 | "MockScope2": "../tests/qmltests/Dash/qml/fake_scopeView2.qml", |
326 | - "MockScope3": "../tests/qmltests/Dash/qml/fake_scopeView3.qml", |
327 | - "MockScope4": "../tests/qmltests/Dash/qml/fake_scopeView4.qml" |
328 | + "home.scope": "../tests/qmltests/Dash/qml/fake_scopeView3.qml", |
329 | + "applications.scope": "../tests/qmltests/Dash/qml/fake_scopeView4.qml" |
330 | } |
331 | genericScope: "../tests/qmltests/Dash/qml/fake_generic_scopeView.qml" |
332 | } |
333 | @@ -69,8 +69,8 @@ |
334 | return [ |
335 | { tag: "MockScope1", visualIndex: 0, shouldBeVisible: true }, |
336 | { tag: "MockScope2", visualIndex: -1, shouldBeVisible: false }, |
337 | - { tag: "MockScope3", visualIndex: 1, shouldBeVisible: true }, |
338 | - { tag: "MockScope4", visualIndex: 2, shouldBeVisible: true }, |
339 | + { tag: "home.scope", visualIndex: 1, shouldBeVisible: true }, |
340 | + { tag: "applications.scope", visualIndex: 2, shouldBeVisible: true }, |
341 | { tag: "MockScope5", visualIndex: 3, shouldBeVisible: true }, |
342 | ] |
343 | } |
344 | |
345 | === modified file 'tests/qmltests/Dash/tst_DashContent.qml' |
346 | --- tests/qmltests/Dash/tst_DashContent.qml 2013-06-13 15:26:39 +0000 |
347 | +++ tests/qmltests/Dash/tst_DashContent.qml 2013-07-25 14:56:25 +0000 |
348 | @@ -31,8 +31,8 @@ |
349 | property var scopeStatus: { |
350 | 'MockScope1': { 'movementStarted': 0, 'positionedAtBeginning': 0 }, |
351 | 'MockScope2': { 'movementStarted': 0, 'positionedAtBeginning': 0 }, |
352 | - 'MockScope3': { 'movementStarted': 0, 'positionedAtBeginning': 0 }, |
353 | - 'MockScope4': { 'movementStarted': 0, 'positionedAtBeginning': 0 }, |
354 | + 'home.scope': { 'movementStarted': 0, 'positionedAtBeginning': 0 }, |
355 | + 'applications.scope': { 'movementStarted': 0, 'positionedAtBeginning': 0 }, |
356 | 'MockScope5': { 'movementStarted': 0, 'positionedAtBeginning': 0 } |
357 | } |
358 | |
359 | @@ -55,8 +55,8 @@ |
360 | scopeDelegateMapping: { |
361 | "MockScope1": "../tests/qmltests/Dash/qml/fake_scopeView1.qml", |
362 | "MockScope2": "../tests/qmltests/Dash/qml/fake_scopeView2.qml", |
363 | - "MockScope3": "../tests/qmltests/Dash/qml/fake_scopeView3.qml", |
364 | - "MockScope4": "../tests/qmltests/Dash/qml/fake_scopeView4.qml" |
365 | + "home.scope": "../tests/qmltests/Dash/qml/fake_scopeView3.qml", |
366 | + "applications.scope": "../tests/qmltests/Dash/qml/fake_scopeView4.qml" |
367 | } |
368 | genericScope: "../tests/qmltests/Dash/qml/fake_generic_scopeView.qml" |
369 | } |
370 | @@ -68,11 +68,11 @@ |
371 | scopeStatus["MockScope2"].movementStarted = 0; |
372 | scopeStatus["MockScope2"].positionedAtBeginning = 0; |
373 | |
374 | - scopeStatus["MockScope3"].movementStarted = 0; |
375 | - scopeStatus["MockScope3"].positionedAtBeginning = 0; |
376 | + scopeStatus["home.scope"].movementStarted = 0; |
377 | + scopeStatus["home.scope"].positionedAtBeginning = 0; |
378 | |
379 | - scopeStatus["MockScope4"].movementStarted = 0; |
380 | - scopeStatus["MockScope4"].positionedAtBeginning = 0; |
381 | + scopeStatus["applications.scope"].movementStarted = 0; |
382 | + scopeStatus["applications.scope"].positionedAtBeginning = 0; |
383 | |
384 | scopeStatus["MockScope5"].movementStarted = 0; |
385 | scopeStatus["MockScope5"].positionedAtBeginning = 0; |
386 | @@ -127,8 +127,8 @@ |
387 | compare(movementStartedSpy.count, 1, "DashContent should have emitted movementStarted signal when content list did."); |
388 | compare(scopeStatus["MockScope1"].movementStarted, 1, "MockScope1 should have emitted movementStarted signal when content list did."); |
389 | compare(scopeStatus["MockScope2"].movementStarted, 1, "MockScope2 should have emitted movementStarted signal when content list did."); |
390 | - compare(scopeStatus["MockScope3"].movementStarted, 1, "MockScope3 should have emitted movementStarted signal when content list did."); |
391 | - compare(scopeStatus["MockScope4"].movementStarted, 1, "MockScope4 should have emitted movementStarted signal when content list did."); |
392 | + compare(scopeStatus["home.scope"].movementStarted, 1, "home.scope should have emitted movementStarted signal when content list did."); |
393 | + compare(scopeStatus["applications.scope"].movementStarted, 1, "applications.scope should have emitted movementStarted signal when content list did."); |
394 | compare(scopeStatus["MockScope5"].movementStarted, 1, "MockScope5 should have emitted movementStarted signal when content list did."); |
395 | } |
396 | |
397 | @@ -140,8 +140,8 @@ |
398 | dashContent.positionedAtBeginning(); |
399 | compare(scopeStatus["MockScope1"].positionedAtBeginning, 1, "MockScope1 should have emitted positionedAtBeginning signal when DashContent did."); |
400 | compare(scopeStatus["MockScope2"].positionedAtBeginning, 1, "MockScope2 should have emitted positionedAtBeginning signal when DashContent did."); |
401 | - compare(scopeStatus["MockScope3"].positionedAtBeginning, 1, "MockScope3 should have emitted positionedAtBeginning signal when DashContent did."); |
402 | - compare(scopeStatus["MockScope4"].positionedAtBeginning, 1, "MockScope4 should have emitted positionedAtBeginning signal when DashContent did."); |
403 | + compare(scopeStatus["home.scope"].positionedAtBeginning, 1, "home.scope should have emitted positionedAtBeginning signal when DashContent did."); |
404 | + compare(scopeStatus["applications.scope"].positionedAtBeginning, 1, "applications.scope should have emitted positionedAtBeginning signal when DashContent did."); |
405 | compare(scopeStatus["MockScope5"].positionedAtBeginning, 1, "MockScope5 should have emitted positionedAtBeginning signal when DashContent did."); |
406 | } |
407 | |
408 | |
409 | === added file 'tests/qmltests/tst_Shell.qml' |
410 | --- tests/qmltests/tst_Shell.qml 1970-01-01 00:00:00 +0000 |
411 | +++ tests/qmltests/tst_Shell.qml 2013-07-25 14:56:25 +0000 |
412 | @@ -0,0 +1,281 @@ |
413 | +/* |
414 | + * Copyright (C) 2013 Canonical, Ltd. |
415 | + * |
416 | + * Authors: |
417 | + * Daniel d'Andrada <daniel.dandrada@canonical.com> |
418 | + * |
419 | + * This program is free software; you can redistribute it and/or modify |
420 | + * it under the terms of the GNU General Public License as published by |
421 | + * the Free Software Foundation; version 3. |
422 | + * |
423 | + * This program is distributed in the hope that it will be useful, |
424 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
425 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
426 | + * GNU General Public License for more details. |
427 | + * |
428 | + * You should have received a copy of the GNU General Public License |
429 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
430 | + */ |
431 | + |
432 | +import QtQuick 2.0 |
433 | +import QtTest 1.0 |
434 | +import Ubuntu.Application 0.1 |
435 | +import Unity.Test 0.1 as UT |
436 | + |
437 | +import "../.." |
438 | + |
439 | +Item { |
440 | + width: shell.width |
441 | + height: shell.height |
442 | + |
443 | + QtObject { |
444 | + id: applicationArguments |
445 | + |
446 | + function hasGeometry() { |
447 | + return false; |
448 | + } |
449 | + |
450 | + function width() { |
451 | + return 0; |
452 | + } |
453 | + |
454 | + function height() { |
455 | + return 0; |
456 | + } |
457 | + } |
458 | + |
459 | + Shell { |
460 | + id: shell |
461 | + } |
462 | + |
463 | + UT.UnityTestCase { |
464 | + name: "Shell" |
465 | + when: windowShown |
466 | + |
467 | + function initTestCase() { |
468 | + // swipe away the greeter/lockscreen |
469 | + var touchX = shell.width - (shell.edgeSize / 2); |
470 | + var touchY = shell.height / 2; |
471 | + touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY); |
472 | + |
473 | + var dash = findChild(shell, "dash"); |
474 | + // wait until the animation has finished |
475 | + tryCompare(dash, "contentScale", 1.0); |
476 | + tryCompare(dash, "opacity", 1.0); |
477 | + } |
478 | + |
479 | + function cleanup() { |
480 | + // kill all (fake) running apps |
481 | + ApplicationManager.mainStageApplications.clear(); |
482 | + ApplicationManager.sideStageApplications.clear(); |
483 | + |
484 | + var dashHome = findChild(shell, "DashHome"); |
485 | + swipeUntilScopeViewIsReached(dashHome); |
486 | + } |
487 | + |
488 | + /* |
489 | + Test the effect of a right-edge drag on the dash in 3 situations: |
490 | + 1 - when no application has been launched yet |
491 | + 2 - when there's a minimized application |
492 | + 3 - after the last running application has been closed/stopped |
493 | + |
494 | + The behavior of Dash on 3 should be the same as on 1. |
495 | + */ |
496 | + function test_rightEdgeDrag() { |
497 | + checkRightEdgeDragWithNoRunningApps(); |
498 | + |
499 | + dragLauncherIntoView(); |
500 | + |
501 | + // Launch an app from the launcher |
502 | + tapOnAppIconInLauncher(); |
503 | + waitUntilApplicationWindowIsFullyVisible(); |
504 | + |
505 | + // Minimize the application we just launched |
506 | + swipeFromLeftEdge(); |
507 | + |
508 | + waitForUIToSettle(); |
509 | + |
510 | + checkRightEdgeDragWithMinimizedApp(); |
511 | + |
512 | + // Minimize that application once again |
513 | + swipeFromLeftEdge(); |
514 | + |
515 | + // kill it |
516 | + ApplicationManager.mainStageApplications.clear(); |
517 | + |
518 | + waitForUIToSettle(); |
519 | + |
520 | + // Right edge behavior should now be the same as before that app was launched |
521 | + checkRightEdgeDragWithNoRunningApps(); |
522 | + } |
523 | + |
524 | + /* |
525 | + Perform a right-edge drag when the Dash is being show and there are |
526 | + no running/minimized apps to be restored. |
527 | + |
528 | + The expected behavior is that an animation should be played to hint the |
529 | + user that his right-edge drag gesture has been successfully recognized |
530 | + but there is no application to be brought to foreground. |
531 | + */ |
532 | + function checkRightEdgeDragWithNoRunningApps() { |
533 | + var touchX = shell.width - (shell.edgeSize / 2); |
534 | + var touchY = shell.height / 2; |
535 | + |
536 | + var dash = findChild(shell, "dash"); |
537 | + // check that dash has normal scale and opacity |
538 | + compare(dash.contentScale, 1.0); |
539 | + compare(dash.opacity, 1.0); |
540 | + |
541 | + touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY, |
542 | + true /* beginTouch */, false /* endTouch */); |
543 | + |
544 | + // check that Dash has been scaled down and had its opacity reduced |
545 | + tryCompareFunction(function() { return dash.contentScale <= 0.9; }, true); |
546 | + tryCompareFunction(function() { return dash.opacity <= 0.5; }, true); |
547 | + |
548 | + touchRelease(shell, shell.width * 0.1, touchY); |
549 | + |
550 | + // and now everything should have gone back to normal |
551 | + tryCompare(dash, "contentScale", 1.0); |
552 | + tryCompare(dash, "opacity", 1.0); |
553 | + } |
554 | + |
555 | + /* |
556 | + Perform a right-edge drag when the Dash is being show and there is |
557 | + a running/minimized app to be restored. |
558 | + |
559 | + The expected behavior is that the dash should fade away and ultimately be |
560 | + made invisible once the gesture is finished as the restored app will now |
561 | + be on foreground. |
562 | + */ |
563 | + function checkRightEdgeDragWithMinimizedApp() { |
564 | + var touchX = shell.width - (shell.edgeSize / 2); |
565 | + var touchY = shell.height / 2; |
566 | + |
567 | + var dash = findChild(shell, "dash"); |
568 | + // check that dash has normal scale and opacity |
569 | + tryCompare(dash, "contentScale", 1.0); |
570 | + tryCompare(dash, "opacity", 1.0); |
571 | + |
572 | + touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY, |
573 | + true /* beginTouch */, false /* endTouch */); |
574 | + |
575 | + // check that Dash has been scaled down and had its opacity reduced |
576 | + tryCompareFunction(function() { return dash.contentScale <= 0.9; }, true); |
577 | + tryCompareFunction(function() { return dash.opacity <= 0.5; }, true); |
578 | + |
579 | + touchRelease(shell, shell.width * 0.1, touchY); |
580 | + |
581 | + // dash should have gone away, now that the app is on foreground |
582 | + tryCompare(dash, "visible", false); |
583 | + } |
584 | + |
585 | + // Wait for the whole UI to settle down |
586 | + function waitForUIToSettle() { |
587 | + waitUntilApplicationWindowIsFullyHidden(); |
588 | + var dashContentList = findChild(shell, "dashContentList"); |
589 | + tryCompare(dashContentList, "moving", false); |
590 | + } |
591 | + |
592 | + function dragLauncherIntoView() { |
593 | + var launcherPanel = findChild(shell, "launcherPanel"); |
594 | + verify(launcherPanel.x = - launcherPanel.width); |
595 | + swipeFromLeftEdge(); |
596 | + tryCompare(launcherPanel, "x", 0); |
597 | + } |
598 | + |
599 | + function tapOnAppIconInLauncher() { |
600 | + var launcherPanel = findChild(shell, "launcherPanel"); |
601 | + |
602 | + // pick the first icon, the one at the bottom. |
603 | + var appIcon = findChild(launcherPanel, "launcherDelegate0") |
604 | + |
605 | + // Swipe upwards over the launcher to ensure that this icon |
606 | + // at the bottom is not folded and faded away. |
607 | + var touchStartX = launcherPanel.width / 2; |
608 | + var touchStartY = launcherPanel.height / 2; |
609 | + touchFlick(launcherPanel, touchStartX, touchStartY, touchStartX, 0); |
610 | + tryCompare(launcherPanel, "moving", false); |
611 | + |
612 | + // NB tapping (i.e., using touch events) doesn't activate the icon... go figure... |
613 | + mouseClick(appIcon, appIcon.width / 2, appIcon.height / 2); |
614 | + } |
615 | + |
616 | + function waitUntilApplicationWindowIsFullyVisible() { |
617 | + var underlay = findChild(shell, "underlay"); |
618 | + tryCompare(underlay, "visible", false); |
619 | + } |
620 | + |
621 | + function waitUntilApplicationWindowIsFullyHidden() { |
622 | + var stages = findChild(shell, "stages"); |
623 | + tryCompare(stages, "fullyHidden", true); |
624 | + } |
625 | + |
626 | + function swipeUntilScopeViewIsReached(scopeView) { |
627 | + while (!itemIsOnScreen(scopeView)) { |
628 | + if (itemIsToLeftOfScreen(scopeView)) { |
629 | + swipeRightFromCenter(); |
630 | + } else { |
631 | + swipeLeftFromCenter(); |
632 | + } |
633 | + waitUntilItemStopsMoving(scopeView); |
634 | + } |
635 | + } |
636 | + |
637 | + function swipeFromLeftEdge() { |
638 | + var touchStartX = 2; |
639 | + var touchStartY = shell.height / 2; |
640 | + touchFlick(shell, touchStartX, touchStartY, shell.width * 0.75, touchStartY); |
641 | + } |
642 | + |
643 | + function swipeLeftFromCenter() { |
644 | + var touchStartX = shell.width / 2; |
645 | + var touchStartY = shell.height / 2; |
646 | + touchFlick(shell, touchStartX, touchStartY, 0, touchStartY); |
647 | + } |
648 | + |
649 | + function swipeRightFromCenter() { |
650 | + var touchStartX = shell.width / 2; |
651 | + var touchStartY = shell.height / 2; |
652 | + touchFlick(shell, touchStartX, touchStartY, shell.width, touchStartY); |
653 | + } |
654 | + |
655 | + function swipeUpFromCenter() { |
656 | + var touchStartX = shell.width / 2; |
657 | + var touchStartY = shell.height / 2; |
658 | + touchFlick(shell, touchStartX, touchStartY, touchStartX, 0); |
659 | + } |
660 | + |
661 | + function itemIsOnScreen(item) { |
662 | + var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height); |
663 | + |
664 | + return itemRectInShell.x >= 0 |
665 | + && itemRectInShell.y >= 0 |
666 | + && itemRectInShell.x + itemRectInShell.width <= shell.width |
667 | + && itemRectInShell.y + itemRectInShell.height <= shell.height; |
668 | + } |
669 | + |
670 | + function itemIsToLeftOfScreen(item) { |
671 | + var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height); |
672 | + return itemRectInShell.x < 0; |
673 | + } |
674 | + |
675 | + function waitUntilItemStopsMoving(item) { |
676 | + var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height); |
677 | + var previousX = itemRectInShell.x; |
678 | + var previousY = itemRectInShell.y; |
679 | + var isStill = false; |
680 | + |
681 | + do { |
682 | + wait(100); |
683 | + itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height); |
684 | + if (itemRectInShell.x == previousX && itemRectInShell.y == previousY) { |
685 | + isStill = true; |
686 | + } else { |
687 | + previousX = itemRectInShell.x; |
688 | + previousY = itemRectInShell.y; |
689 | + } |
690 | + } while (!isStill); |
691 | + } |
692 | + } |
693 | +} |
FAILED: Continuous integration, rev:112 jenkins. qa.ubuntu. com/job/ unity8- ci/284/ jenkins. qa.ubuntu. com/job/ generic- mediumtests- saucy/1180 jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- saucy/637 jenkins. qa.ubuntu. com/job/ unity8- saucy-armhf- ci/284 jenkins. qa.ubuntu. com/job/ unity8- saucy-armhf- ci/284/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ unity8- saucy-i386- ci/284 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- saucy/1184 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- saucy/1184/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- runner- saucy/1006
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ unity8- ci/284/ rebuild
http://