Merge lp:~acerisara/ubuntu-calendar-app/bottom-edge-autopilot into lp:ubuntu-calendar-app

Proposed by Andrea Cerisara
Status: Superseded
Proposed branch: lp:~acerisara/ubuntu-calendar-app/bottom-edge-autopilot
Merge into: lp:ubuntu-calendar-app
Diff against target: 656 lines (+474/-13)
7 files modified
DayView.qml (+10/-1)
MonthView.qml (+8/-2)
NewEvent.qml (+8/-3)
PageWithBottomEdge.qml (+407/-0)
WeekView.qml (+9/-1)
calendar.qml (+5/-2)
tests/autopilot/calendar_app/__init__.py (+27/-4)
To merge this branch: bzr merge lp:~acerisara/ubuntu-calendar-app/bottom-edge-autopilot
Reviewer Review Type Date Requested Status
Nicholas Skaggs Pending
Review via email: mp+244229@code.launchpad.net

This proposal has been superseded by a proposal from 2014-12-09.

Commit message

New event autopilot tests: opening the page with bottom edge button.

Description of the change

The autopilot tests for the new event page are now using the bottom edge button. WIP, tests are currently failing: it seems that when opening the page with the bottom edge button the calendar is not always set to "Personal".

To post a comment you must log in.

Unmerged revisions

561. By Andrea Cerisara

New event autopilot tests: opening the page with bottom edge button

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'DayView.qml'
2--- DayView.qml 2014-11-06 13:57:42 +0000
3+++ DayView.qml 2014-12-09 21:47:26 +0000
4@@ -21,12 +21,13 @@
5 import "dateExt.js" as DateExt
6 import "ViewType.js" as ViewType
7
8-Page{
9+PageWithBottomEdge {
10 id: dayViewPage
11 objectName: "dayViewPage"
12
13 property var currentDay: new Date()
14 property bool isCurrentPage: false
15+ property var eventModel;
16
17 signal dateSelected(var date);
18
19@@ -60,6 +61,14 @@
20 }
21 }
22
23+ reloadBottomEdgePage: true
24+ bottomEdgeTitle : i18n.tr("New Event")
25+ bottomEdgePageComponent : NewEvent {
26+ model: eventModel
27+ date: currentDay
28+ }
29+
30+
31 Column {
32 anchors.fill: parent
33 anchors.topMargin: units.gu(1)
34
35=== modified file 'MonthView.qml'
36--- MonthView.qml 2014-10-22 18:39:27 +0000
37+++ MonthView.qml 2014-12-09 21:47:26 +0000
38@@ -20,12 +20,12 @@
39 import "dateExt.js" as DateExt
40 import "colorUtils.js" as Color
41
42-Page {
43+PageWithBottomEdge {
44 id: monthViewPage
45 objectName: "monthViewPage"
46
47 property var currentMonth: DateExt.today();
48-
49+ property var eventModel;
50 signal dateSelected(var date);
51
52 Keys.forwardTo: [monthViewPath]
53@@ -58,6 +58,12 @@
54 }
55 }
56
57+ bottomEdgeTitle : i18n.tr("New Event")
58+ bottomEdgePageComponent : NewEvent{
59+ model: eventModel
60+ date : new Date()
61+ }
62+
63 PathViewBase{
64 id: monthViewPath
65 objectName: "monthViewPath"
66
67=== modified file 'NewEvent.qml'
68--- NewEvent.qml 2014-11-27 17:46:47 +0000
69+++ NewEvent.qml 2014-12-09 21:47:26 +0000
70@@ -44,6 +44,11 @@
71
72 signal eventAdded(var event);
73
74+ onDateChanged: {
75+ startDateTimeInput.dateTime = date;
76+ adjustEndDateToStartDate();
77+ }
78+
79 onStartDateChanged: {
80 startDateTimeInput.dateTime = startDate;
81 adjustEndDateToStartDate()
82@@ -109,7 +114,7 @@
83 event = Qt.createQmlObject("import QtOrganizer 5.0; Event { }", Qt.application,"NewEvent.qml");
84 //Create fresh Recurrence Object.
85 rule = Qt.createQmlObject("import QtOrganizer 5.0; RecurrenceRule {}", event.recurrence,"EventRepetition.qml");
86- selectCalendar(model.defaultCollection().collectionId);
87+ selectCalendar(model.defaultCollection().collectionId);
88 }
89
90 //Editing Event
91@@ -277,8 +282,8 @@
92 scrollAnimation.start()
93 }
94
95- width: parent.width
96- height: parent.height
97+ width: parent ? parent.width : 0
98+ height: parent ? parent.height : 0
99
100 title: isEdit ? i18n.tr("Edit Event"):i18n.tr("New Event")
101
102
103=== added file 'PageWithBottomEdge.qml'
104--- PageWithBottomEdge.qml 1970-01-01 00:00:00 +0000
105+++ PageWithBottomEdge.qml 2014-12-09 21:47:26 +0000
106@@ -0,0 +1,407 @@
107+/*
108+ * Copyright (C) 2014 Canonical, Ltd.
109+ *
110+ * This program is free software; you can redistribute it and/or modify
111+ * it under the terms of the GNU General Public License as published by
112+ * the Free Software Foundation; version 3.
113+ *
114+ * This program is distributed in the hope that it will be useful,
115+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
116+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
117+ * GNU General Public License for more details.
118+ *
119+ * You should have received a copy of the GNU General Public License
120+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
121+ */
122+
123+/*
124+ Example:
125+
126+ MainView {
127+ objectName: "mainView"
128+
129+ applicationName: "com.ubuntu.developer.boiko.bottomedge"
130+
131+ width: units.gu(100)
132+ height: units.gu(75)
133+
134+ Component {
135+ id: pageComponent
136+
137+ PageWithBottomEdge {
138+ id: mainPage
139+ title: i18n.tr("Main Page")
140+
141+ Rectangle {
142+ anchors.fill: parent
143+ color: "white"
144+ }
145+
146+ bottomEdgePageComponent: Page {
147+ title: "Contents"
148+ anchors.fill: parent
149+ //anchors.topMargin: contentsPage.flickable.contentY
150+
151+ ListView {
152+ anchors.fill: parent
153+ model: 50
154+ delegate: ListItems.Standard {
155+ text: "One Content Item: " + index
156+ }
157+ }
158+ }
159+ bottomEdgeTitle: i18n.tr("Bottom edge action")
160+ }
161+ }
162+
163+ PageStack {
164+ id: stack
165+ Component.onCompleted: stack.push(pageComponent)
166+ }
167+ }
168+
169+*/
170+
171+import QtQuick 2.2
172+import Ubuntu.Components 1.1
173+
174+Page {
175+ id: page
176+
177+ property alias bottomEdgePageComponent: edgeLoader.sourceComponent
178+ property alias bottomEdgePageSource: edgeLoader.source
179+ property alias bottomEdgeTitle: tipLabel.text
180+ property bool bottomEdgeEnabled: true
181+ property int bottomEdgeExpandThreshold: page.height * 0.2
182+ property int bottomEdgeExposedArea: bottomEdge.state !== "expanded" ? (page.height - bottomEdge.y - bottomEdge.tipHeight) : _areaWhenExpanded
183+ property bool reloadBottomEdgePage: true
184+
185+ readonly property alias bottomEdgePage: edgeLoader.item
186+ readonly property bool isReady: ((bottomEdge.y === 0) && bottomEdgePageLoaded && edgeLoader.item.active)
187+ readonly property bool isCollapsed: (bottomEdge.y === page.height)
188+ readonly property bool bottomEdgePageLoaded: (edgeLoader.status == Loader.Ready)
189+
190+ property bool _showEdgePageWhenReady: false
191+ property int _areaWhenExpanded: 0
192+
193+ signal bottomEdgeReleased()
194+ signal bottomEdgeDismissed()
195+
196+
197+ function showBottomEdgePage(source, properties)
198+ {
199+ edgeLoader.setSource(source, properties)
200+ _showEdgePageWhenReady = true
201+ }
202+
203+ function setBottomEdgePage(source, properties)
204+ {
205+ edgeLoader.setSource(source, properties)
206+ }
207+
208+ function _pushPage()
209+ {
210+ if (edgeLoader.status === Loader.Ready) {
211+ edgeLoader.item.active = true
212+ page.pageStack.push(edgeLoader.item)
213+ if (edgeLoader.item.flickable) {
214+ edgeLoader.item.flickable.contentY = -page.header.height
215+ edgeLoader.item.flickable.returnToBounds()
216+ }
217+ if (edgeLoader.item.ready)
218+ edgeLoader.item.ready()
219+ }
220+ }
221+
222+
223+ Component.onCompleted: {
224+ // avoid a binding on the expanded height value
225+ var expandedHeight = height;
226+ _areaWhenExpanded = expandedHeight;
227+ }
228+
229+ onActiveChanged: {
230+ if (active) {
231+ bottomEdge.state = "collapsed"
232+ }
233+ }
234+
235+ onBottomEdgePageLoadedChanged: {
236+ if (_showEdgePageWhenReady && bottomEdgePageLoaded) {
237+ bottomEdge.state = "expanded"
238+ _showEdgePageWhenReady = false
239+ }
240+ }
241+
242+ Rectangle {
243+ id: bgVisual
244+
245+ color: "black"
246+ anchors.fill: page
247+ opacity: 0.7 * ((page.height - bottomEdge.y) / page.height)
248+ z: 1
249+ }
250+
251+ UbuntuShape {
252+ id: tip
253+ objectName: "bottomEdgeTip"
254+
255+ property bool hidden: (activeFocus === false) || ((bottomEdge.y - units.gu(1)) < tip.y)
256+
257+ enabled: mouseArea.enabled
258+ visible: page.bottomEdgeEnabled
259+ anchors {
260+ bottom: parent.bottom
261+ horizontalCenter: bottomEdge.horizontalCenter
262+ bottomMargin: hidden ? - height + units.gu(1) : -units.gu(1)
263+ Behavior on bottomMargin {
264+ SequentialAnimation {
265+ // wait some msecs in case of the focus change again, to avoid flickering
266+ PauseAnimation {
267+ duration: 300
268+ }
269+ UbuntuNumberAnimation {
270+ duration: UbuntuAnimation.SnapDuration
271+ }
272+ }
273+ }
274+ }
275+
276+ z: 1
277+ width: tipLabel.paintedWidth + units.gu(6)
278+ height: bottomEdge.tipHeight + units.gu(1)
279+ color: Theme.palette.normal.overlay
280+ Label {
281+ id: tipLabel
282+
283+ anchors {
284+ top: parent.top
285+ left: parent.left
286+ right: parent.right
287+ }
288+ height: bottomEdge.tipHeight
289+ verticalAlignment: Text.AlignVCenter
290+ horizontalAlignment: Text.AlignHCenter
291+ opacity: tip.hidden ? 0.0 : 1.0
292+ Behavior on opacity {
293+ UbuntuNumberAnimation {
294+ duration: UbuntuAnimation.SnapDuration
295+ }
296+ }
297+ }
298+ }
299+
300+ Rectangle {
301+ id: shadow
302+
303+ anchors {
304+ left: parent.left
305+ right: parent.right
306+ bottom: parent.bottom
307+ }
308+ height: units.gu(1)
309+ z: 1
310+ opacity: 0.0
311+ gradient: Gradient {
312+ GradientStop { position: 0.0; color: "transparent" }
313+ GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.2) }
314+ }
315+ }
316+
317+ MouseArea {
318+ id: mouseArea
319+
320+ property real previousY: -1
321+ property string dragDirection: "None"
322+
323+ preventStealing: true
324+ drag {
325+ axis: Drag.YAxis
326+ target: bottomEdge
327+ minimumY: bottomEdge.pageStartY
328+ maximumY: page.height
329+ }
330+ enabled: edgeLoader.status == Loader.Ready
331+ visible: page.bottomEdgeEnabled
332+
333+ anchors {
334+ left: parent.left
335+ right: parent.right
336+ bottom: parent.bottom
337+
338+ }
339+ height: bottomEdge.tipHeight
340+ z: 1
341+
342+ onReleased: {
343+ page.bottomEdgeReleased()
344+ if ((dragDirection === "BottomToTop") &&
345+ bottomEdge.y < (page.height - bottomEdgeExpandThreshold - bottomEdge.tipHeight)) {
346+ bottomEdge.state = "expanded"
347+ } else {
348+ bottomEdge.state = "collapsed"
349+ }
350+ previousY = -1
351+ dragDirection = "None"
352+ }
353+
354+ onPressed: {
355+ previousY = mouse.y
356+ tip.forceActiveFocus()
357+ }
358+
359+ onMouseYChanged: {
360+ var yOffset = previousY - mouseY
361+ // skip if was a small move
362+ if (Math.abs(yOffset) <= units.gu(2)) {
363+ return
364+ }
365+ previousY = mouseY
366+ dragDirection = yOffset > 0 ? "BottomToTop" : "TopToBottom"
367+ }
368+ }
369+
370+ Rectangle {
371+ id: bottomEdge
372+ objectName: "bottomEdge"
373+
374+ readonly property int tipHeight: units.gu(3)
375+ readonly property int pageStartY: 0
376+
377+ z: 1
378+ color: Theme.palette.normal.background
379+ clip: true
380+ anchors {
381+ left: parent.left
382+ right: parent.right
383+ }
384+ height: page.height
385+ y: height
386+ visible: !page.isCollapsed
387+ state: "collapsed"
388+ states: [
389+ State {
390+ name: "collapsed"
391+ PropertyChanges {
392+ target: bottomEdge
393+ y: bottomEdge.height
394+ }
395+ },
396+ State {
397+ name: "expanded"
398+ PropertyChanges {
399+ target: bottomEdge
400+ y: bottomEdge.pageStartY
401+ }
402+ },
403+ State {
404+ name: "floating"
405+ when: mouseArea.drag.active
406+ PropertyChanges {
407+ target: shadow
408+ opacity: 1.0
409+ }
410+ }
411+ ]
412+
413+ transitions: [
414+ Transition {
415+ to: "expanded"
416+ SequentialAnimation {
417+ alwaysRunToEnd: true
418+
419+ SmoothedAnimation {
420+ target: bottomEdge
421+ property: "y"
422+ duration: UbuntuAnimation.FastDuration
423+ easing.type: Easing.Linear
424+ }
425+ SmoothedAnimation {
426+ target: edgeLoader
427+ property: "anchors.topMargin"
428+ to: - units.gu(4)
429+ duration: UbuntuAnimation.FastDuration
430+ easing.type: Easing.Linear
431+ }
432+ SmoothedAnimation {
433+ target: edgeLoader
434+ property: "anchors.topMargin"
435+ to: 0
436+ duration: UbuntuAnimation.FastDuration
437+ easing: UbuntuAnimation.StandardEasing
438+ }
439+ ScriptAction {
440+ script: page._pushPage()
441+ }
442+ }
443+ },
444+ Transition {
445+ from: "expanded"
446+ to: "collapsed"
447+ SequentialAnimation {
448+ alwaysRunToEnd: true
449+
450+ ScriptAction {
451+ script: {
452+ Qt.inputMethod.hide()
453+ edgeLoader.item.parent = edgeLoader
454+ edgeLoader.item.anchors.fill = edgeLoader
455+ edgeLoader.item.active = false
456+ }
457+ }
458+ SmoothedAnimation {
459+ target: bottomEdge
460+ property: "y"
461+ duration: UbuntuAnimation.SlowDuration
462+ }
463+ ScriptAction {
464+ script: {
465+ // destroy current bottom page
466+ if (page.reloadBottomEdgePage) {
467+ edgeLoader.active = false
468+ // tip will receive focus on page active true
469+ } else {
470+ tip.forceActiveFocus()
471+ }
472+
473+ // notify
474+ page.bottomEdgeDismissed()
475+
476+ edgeLoader.active = true
477+ }
478+ }
479+ }
480+ },
481+ Transition {
482+ from: "floating"
483+ to: "collapsed"
484+ SmoothedAnimation {
485+ target: bottomEdge
486+ property: "y"
487+ duration: UbuntuAnimation.FastDuration
488+ }
489+ }
490+ ]
491+
492+ Loader {
493+ id: edgeLoader
494+
495+ asynchronous: true
496+ anchors.fill: parent
497+ //WORKAROUND: The SDK move the page contents down to allocate space for the header we need to avoid that during the page dragging
498+ Binding {
499+ target: edgeLoader.status === Loader.Ready ? edgeLoader : null
500+ property: "anchors.topMargin"
501+ value: edgeLoader.item && edgeLoader.item.flickable ? edgeLoader.item.flickable.contentY : 0
502+ when: !page.isReady
503+ }
504+
505+ onLoaded: {
506+ tip.forceActiveFocus()
507+ if (page.isReady && edgeLoader.item.active !== true) {
508+ page._pushPage()
509+ }
510+ }
511+ }
512+ }
513+}
514
515=== modified file 'WeekView.qml'
516--- WeekView.qml 2014-11-06 13:57:42 +0000
517+++ WeekView.qml 2014-12-09 21:47:26 +0000
518@@ -21,13 +21,14 @@
519 import "dateExt.js" as DateExt
520 import "ViewType.js" as ViewType
521
522-Page{
523+PageWithBottomEdge{
524 id: weekViewPage
525 objectName: "weekViewPage"
526
527 property var dayStart: new Date();
528 property var firstDay: dayStart.weekStart(Qt.locale().firstDayOfWeek);
529 property bool isCurrentPage: false
530+ property var eventModel;
531
532 signal dateSelected(var date);
533
534@@ -61,6 +62,13 @@
535 font.capitalization: Font.Capitalize
536 }
537 }
538+ reloadBottomEdgePage: true
539+ bottomEdgeTitle : i18n.tr("New Event")
540+
541+ bottomEdgePageComponent : NewEvent {
542+ model: eventModel
543+ date: dayStart
544+ }
545
546 Column {
547 anchors.fill: parent
548
549=== modified file 'calendar.qml'
550--- calendar.qml 2014-11-08 11:26:37 +0000
551+++ calendar.qml 2014-12-09 21:47:26 +0000
552@@ -95,7 +95,6 @@
553 footerColor: "#ECECEC"
554 anchorToKeyboard: true
555
556-
557 PageStack {
558 id: pageStack
559
560@@ -360,6 +359,7 @@
561 source: tabs.selectedTab == monthTab ? Qt.resolvedUrl("MonthView.qml"):""
562 onLoaded: {
563 item.currentMonth = tabs.currentDay.midnight();
564+ item.eventModel = eventModel
565 }
566
567 anchors{
568@@ -374,6 +374,7 @@
569 tabs.currentDay = date;
570 tabs.selectedTabIndex = dayTab.index;
571 }
572+
573 }
574 }
575 }
576@@ -389,6 +390,7 @@
577 onLoaded: {
578 item.isCurrentPage= Qt.binding(function() { return tabs.selectedTab == weekTab })
579 item.dayStart = tabs.currentDay;
580+ item.eventModel = eventModel
581 }
582
583 anchors{
584@@ -402,7 +404,6 @@
585 onDayStartChanged: {
586 tabs.currentDay = weekViewLoader.item.dayStart;
587 }
588-
589 onDateSelected: {
590 tabs.currentDay = date;
591 tabs.selectedTabIndex = dayTab.index;
592@@ -422,6 +423,8 @@
593 onLoaded: {
594 item.isCurrentPage= Qt.binding(function() { return tabs.selectedTab == dayTab })
595 item.currentDay = tabs.currentDay;
596+ item.eventModel = eventModel
597+
598 }
599
600 anchors{
601
602=== modified file 'tests/autopilot/calendar_app/__init__.py'
603--- tests/autopilot/calendar_app/__init__.py 2014-11-30 19:13:27 +0000
604+++ tests/autopilot/calendar_app/__init__.py 2014-12-09 21:47:26 +0000
605@@ -18,7 +18,7 @@
606
607 import logging
608 from time import sleep
609-
610+from autopilot.introspection import dbus
611 import datetime
612 import autopilot.logging
613 import ubuntuuitoolkit
614@@ -114,6 +114,27 @@
615 logger.debug('The Day View page is already opened.')
616 return self.get_day_view(day_tab)
617
618+ def open_new_event_page(self):
619+ """Bring the new event page to the screen"""
620+ self.visible.wait_for(True)
621+ try:
622+ button = self.wait_select_single(objectName='bottomEdgeTip')
623+ button.visible.wait_for(True)
624+
625+ start_x = (button.globalRect.x +
626+ (button.globalRect.width * 0.5))
627+
628+ start_y = (button.globalRect.y +
629+ (button.height * 0.2))
630+
631+ stop_y = start_y - (self.height * 0.7)
632+ self.pointing_device.drag(start_x, start_y,
633+ start_x, stop_y, rate=3)
634+
635+ except dbus.StateNotFoundError:
636+ logger.error('BottomEdge element not found.')
637+ raise
638+
639 @autopilot.logging.log_action(logger.info)
640 def go_to_new_event(self):
641 """Open the page to add a new event.
642@@ -121,9 +142,11 @@
643 :return: The New Event page.
644
645 """
646- header = self.get_header()
647- header.click_action_button('neweventbutton')
648- return self.wait_select_single(NewEvent, objectName='newEventPage')
649+
650+ self.open_new_event_page()
651+ page = self.wait_select_single(NewEvent, objectName='newEventPage')
652+ page.visible.wait_for(True)
653+ return page
654
655 def set_picker(self, field, mode, value):
656 # open picker

Subscribers

People subscribed via source and target branches

to status/vote changes: