Merge lp:~nskaggs/ubuntu-calendar-app/datepicker-test-fixes into lp:ubuntu-calendar-app
- datepicker-test-fixes
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Nicholas Skaggs |
Approved revision: | 215 |
Merged at revision: | 302 |
Proposed branch: | lp:~nskaggs/ubuntu-calendar-app/datepicker-test-fixes |
Merge into: | lp:ubuntu-calendar-app |
Diff against target: |
678 lines (+225/-249) 5 files modified
NewEvent.qml (+102/-89) TimePicker.qml (+0/-95) dateExt.js (+6/-0) tests/autopilot/calendar_app/emulators.py (+66/-11) tests/autopilot/calendar_app/tests/test_calendar.py (+51/-54) |
To merge this branch: | bzr merge lp:~nskaggs/ubuntu-calendar-app/datepicker-test-fixes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Mihir Soni | Pending | ||
David Planella | Pending | ||
Alan Pope πΊπ§π± π¦ | Pending | ||
Kunal Parmar | Pending | ||
Olivier Tilloy | Pending | ||
Review via email: mp+222369@code.launchpad.net |
This proposal supersedes a proposal from 2014-03-21.
Commit message
Add the native Ubuntu UI DatePicker.
convert new_event test to use datepicker and textfield helpers
Description of the change
Add the native Ubuntu UI DatePicker.
Also, allow to change the date value of the event.
In addition, I've converted the new_event test to using the datepicker and textfield autopilot helpers as well.
A workaround is found in the test; since the bug ignores the first input, we send an input and small sleep to clear and workaround this.
Kunal Parmar (pkunal-parmar) wrote : Posted in a previous version of this proposal | # |
David Planella (dpm) wrote : Posted in a previous version of this proposal | # |
Yohan, as Kunal is saying, could you do:
bzr merge lp:ubuntu-calendar-app
(resolve conflicts if there are any)
bzr commit -m"Merged from trunk"
bzr push lp:~yohanboniface/ubuntu-calendar-app/DatePicker
Then Launchpad should take care of updating the Merge Proposal for you.
Thanks!
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
I will do asap!
I'm in the train today, but will take time tonight or tomorrow morning for this and other comments from Kunal :)
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Done on this branch :)
Kunal Parmar (pkunal-parmar) wrote : Posted in a previous version of this proposal | # |
it seems there is still some merge issue, you seems to be removing reminder related support.
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
How do I check that?
Here is what I have:
ybon@edoardo:
Nothing to do.
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Ah, sorry, you meant I've made a mistake while merging in the past.
Still figuring out how to do a proper diff between to branches in Bazaar (but I can do it with "diff" command line).
Can you be a little more specific on what's missing?
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
OK, got it:
> //remove old reminder value
> var oldVisualReminder = event.detail(
> if(oldVisualRem
> event.removeDet
> }
>
> var oldAudibleReminder = event.detail(
> if(oldAudibleRe
> event.removeDet
> }
>
> var reminderTime = Defines.
> if( reminderTime !== 0 ) {
> var visualReminder = Qt.createQmlObj
> visualReminder.
> visualReminder.
> visualReminder.
> visualReminder.
> event.setDetail
>
> var audibleReminder = Qt.createQmlObj
> audibleReminder
> audibleReminder
> audibleReminder
> event.setDetail
> }
>
Commit to come.
Kunal Parmar (pkunal-parmar) wrote : Posted in a previous version of this proposal | # |
I dont know much bzr either, but you can get master and check diff using meld diff.
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Done, thanks for checking again :)
Olivier Tilloy (osomon) wrote : Posted in a previous version of this proposal | # |
The calendar_
Since autopilot emulators for the new picker components are not available yet, we have two options:
1) introspect the picker components in the test (essentially, write our own custom emulators for them as a temporary stopgap measure until the SDK team provide official emulators), this has the downside of being fragile in case the implementation changes on the UITK side
2) temporarily skip the test (decorating it with @unittest.skip, including a link to the bug report that tracks the need for official emulators)
Mihir Soni (mihirsoni) wrote : Posted in a previous version of this proposal | # |
Also,
as discussed in today's hangout.
we'll have to change the design of changing start end dateTime.
Kunal Parmar (pkunal-parmar) wrote : Posted in a previous version of this proposal | # |
287 + property var recurrenceValue: [ RecurrenceRule.
288 + RecurrenceRule.
289 + RecurrenceRule.
290 + RecurrenceRule.
291 + RecurrenceRule.
292 +
293 + property var recurrenceLabel: [ i18n.tr("Once"),
294 + i18n.tr("Daily"),
295 + i18n.tr("Weekly"),
296 + i18n.tr("Monthly"),
297 + i18n.tr("Yearly")];
This code also looks like from old branch. Please merge this changes as well.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:208
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Mihir Soni (mihirsoni) wrote : Posted in a previous version of this proposal | # |
Could you please merge with trunk and resolve the conflicts ?
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Done.
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:209
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : Posted in a previous version of this proposal | # |
Ybon,
Could you merge trunk into this branch so you get the fix for a bug that prevents the app from running correctly on the device [1]?
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:210
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
David Planella (dpm) wrote : Posted in a previous version of this proposal | # |
In order for this to pass, the autopilot test will need to be fixed too before we can merge it.
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Thanks for clarifying the needs, David.
I guess you are talking about the one I've commented on #206?
One question: last time I've raised this on IRC, there was no autopilot handler for the native Ubuntu UI DatePicker. Are you aware of any update on this side?
If not, are you expecting that I do this by hand?
Alan Pope πΊπ§π± π¦ (popey) wrote : Posted in a previous version of this proposal | # |
Have asked Leo Arias (elopio) to help us with this.
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Thanks popey :)
Alan Pope πΊπ§π± π¦ (popey) wrote : Posted in a previous version of this proposal | # |
Ok, Leo should have some time this week to work on this.
Leo Arias (elopio) wrote : Posted in a previous version of this proposal | # |
It's ready for review:
https:/
https:/
It would be nice if you could take a look and see if it works for your use cases.
Alan Pope πΊπ§π± π¦ (popey) wrote : Posted in a previous version of this proposal | # |
Seems the jenkins job on https:/
Alan Pope πΊπ§π± π¦ (popey) wrote : Posted in a previous version of this proposal | # |
Speaking to Leo, the above merge to datepicker-
Alan Pope πΊπ§π± π¦ (popey) wrote : Posted in a previous version of this proposal | # |
The ui toolkit merge appears to have landed now, so this can land.
Alan Pope πΊπ§π± π¦ (popey) wrote : Posted in a previous version of this proposal | # |
This needs re-merging with trunk.
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Given how much trunk as diverged and that bazaar is quite bugged on complex merges, I think the best option is to rerun by hand the commits on top of trunk on a new branch.
I will try to do that this week, but if someone want to take it⦠;)
David Planella (dpm) wrote : Posted in a previous version of this proposal | # |
> Given how much trunk as diverged and that bazaar is quite bugged on complex
> merges, I think the best option is to rerun by hand the commits on top of
> trunk on a new branch.
Thanks Yohan. Bzr should handle complex merges just fine, and this one shouldn't be too complex after all: it just happens that the two branches have diverged in time. Where I strongly disagree is that rerunning old commits by hand would be a better solution: I think it'd be much less work to let a VCS do the merge automatically and resolve any conflicts afterwards.
In fact, I've just had a go at it (*), and the result was the following:
Text conflict in NewEvent.qml
Text conflict in tests/autopilot
2 conflicts encountered.
So essentially conflicts in two files only. The one on the test_calendar.py is trivial to resolve. NewEvent.qml has 6 conflicts, some of which are simple to resolve, but ultimately, to be on the safe side, they require someone familiar with this branch to fix them.
> I will try to do that this week, but if someone want to take it⦠;)
Ultimately, the changes will need to be applied in your branch if we want to merge it, so it'd be great if you could update your branch (no one else has got the permissions to do so, unless they take it over, branch off it, and submit a new MP themselves). But please let us know if you need help on this.
(*) bzr branch lp:~yohanboniface/ubuntu-calendar-app/DatePicker
cd DatePicker
bzr merge lp:ubuntu-calendar-app
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Thanks for this, David. :)
Have you looked at the "{" in the merged files? I've just run the merge to have a look, and (sadly as often with bzr in my experience) they seem messed up to me in NewEvent.qml :/
In the past I've other bad experiences with automatic merges, like some pieces of code not being removed as expected.
David Planella (dpm) wrote : Posted in a previous version of this proposal | # |
So I've had a go at it, and while I cannot say whether in all automatic merges the braces are still matched, they seemed all ok to me on this one. I've merged to trunk and resolved all conflicts on a new branch I've just pushed to LP.
So would you mind doing a 'bzr merge lp:~dpm/ubuntu-calendar-app/DatePicker' onto your branch (it should apply cleanly), have a quick look over it, and then push to your branch?
Thanks!
ybon (yohanboniface) wrote : Posted in a previous version of this proposal | # |
Done!
Thanks *you* :)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:211
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Leo Arias (elopio) wrote : Posted in a previous version of this proposal | # |
I'm looking at the failing test so you won't need to skip it.
It seems to be failing in trunk too, so shouldn't be related to your branch.
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
Leo has pointed out there is a regression that exists in trunk; coming from the toolkit component or the app itself in regards to the textfield. Tapping the field doesn't set focus on the first tap.
I'm investigating the source of this regression.
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
The regression is caused by the additional button introduced in r300.
Something funny is occuring in the toolkit. The popover is not closing and eating the first event. I'm trying to put together a small example to demonstrate the issue.
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
The bug has been filed here: https:/
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
I think you can edit the newevent test to workaround the regression, but barring that please include the bug as the reason you are skipping the test.
Nicholas Skaggs (nskaggs) wrote : Posted in a previous version of this proposal | # |
Resubmitting after rebasing to trunk and fixing tests
- 214. By Nicholas Skaggs
-
rebase with trunk, add description and guest input
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:213
http://
Executed test runs:
FAILURE: http://
deb: http://
UNSTABLE: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:214
http://
Executed test runs:
FAILURE: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 215. By Nicholas Skaggs
-
use textfield and datepicker emulators, clean and simplify tests
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:215
http://
Executed test runs:
FAILURE: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:215
http://
Executed test runs:
None: http://
None: http://
None: http://
None: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:215
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:215
http://
Executed test runs:
UNSTABLE: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:215
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) : | # |
Preview Diff
1 | === modified file 'NewEvent.qml' |
2 | --- NewEvent.qml 2014-05-31 09:54:55 +0000 |
3 | +++ NewEvent.qml 2014-06-06 18:09:22 +0000 |
4 | @@ -23,6 +23,16 @@ |
5 | property alias scrollY: flickable.contentY |
6 | property bool isEdit: false |
7 | |
8 | + onStartDateChanged: { |
9 | + startDateInput.text = Qt.formatDateTime(startDate, "dd MMM yyyy"); |
10 | + startTimeInput.text = Qt.formatDateTime(startDate, "hh:mm"); |
11 | + } |
12 | + |
13 | + onEndDateChanged: { |
14 | + endDateInput.text = Qt.formatDateTime(endDate, "dd MMM yyyy"); |
15 | + endTimeInput.text = Qt.formatDateTime(endDate, "hh:mm"); |
16 | + } |
17 | + |
18 | Component.onCompleted: { |
19 | // If startDate is setted by argument we have to not change it |
20 | //Set the nearest current time. |
21 | @@ -38,7 +48,7 @@ |
22 | } |
23 | |
24 | if(event === null){ |
25 | - isEdit =false; |
26 | + isEdit = false; |
27 | addEvent(); |
28 | } |
29 | else{ |
30 | @@ -54,13 +64,10 @@ |
31 | startTime.text = Qt.formatDateTime(startDate, "dd MMM yyyy hh:mm"); |
32 | endTime.text = Qt.formatDateTime(endDate, "dd MMM yyyy hh:mm"); |
33 | } |
34 | - |
35 | //Editing Event |
36 | function editEvent(e) { |
37 | startDate =new Date(e.startDateTime); |
38 | endDate = new Date(e.endDateTime); |
39 | - startTime.text = Qt.formatDateTime(e.startDateTime, "dd MMM yyyy hh:mm"); |
40 | - endTime.text = Qt.formatDateTime(e.endDateTime, "dd MMM yyyy hh:mm"); |
41 | |
42 | if(e.displayLabel) { |
43 | titleEdit.text = e.displayLabel; |
44 | @@ -124,7 +131,7 @@ |
45 | //Save the new or Existing event |
46 | function saveToQtPim() { |
47 | internal.clearFocus() |
48 | - if ( startDate >= endDate ) { |
49 | + if ( startDate >= endDate && !allDayEventCheckbox.checked) { |
50 | PopupUtils.open(errorDlgComponent,root,{"text":i18n.tr("End time can't be before start time")}); |
51 | } else { |
52 | event.startDateTime = startDate; |
53 | @@ -192,6 +199,16 @@ |
54 | pageStack.pop(); |
55 | } |
56 | } |
57 | + |
58 | + function openDatePicker (element, caller, callerProperty, mode) { |
59 | + element.highlighted = true; |
60 | + var picker = PickerPanel.openDatePicker(caller, callerProperty, mode); |
61 | + if (!picker) return; |
62 | + picker.closed.connect(function () { |
63 | + element.highlighted = false; |
64 | + }); |
65 | + } |
66 | + |
67 | // Calucate default hour and minute for start and end time on event |
68 | function roundDate(date) { |
69 | var tempDate = new Date(date) |
70 | @@ -228,22 +245,6 @@ |
71 | } |
72 | } |
73 | |
74 | - Component { |
75 | - id: timePicker |
76 | - TimePicker { |
77 | - } |
78 | - } |
79 | - |
80 | - Rectangle { |
81 | - id: availableArea |
82 | - |
83 | - width: parent.width |
84 | - color: "red" |
85 | - opacity: 0.5 |
86 | - z: 100 |
87 | - } |
88 | - |
89 | - |
90 | Flickable{ |
91 | id: flickable |
92 | |
93 | @@ -288,13 +289,13 @@ |
94 | contentWidth: width |
95 | contentHeight: column.height |
96 | |
97 | - Column{ |
98 | + Column { |
99 | id: column |
100 | |
101 | width: parent.width |
102 | spacing: units.gu(1) |
103 | |
104 | - UbuntuShape{ |
105 | + UbuntuShape { |
106 | width:parent.width |
107 | height: timeColumn.height |
108 | |
109 | @@ -304,65 +305,77 @@ |
110 | anchors.centerIn: parent |
111 | spacing: units.gu(1) |
112 | |
113 | - NewEventEntryField{ |
114 | - id: dateField |
115 | - title: i18n.tr("Date") |
116 | - width: parent.width |
117 | - objectName: "dateInput" |
118 | - |
119 | - text: Qt.formatDateTime(startDate,"dd MMM yyyy"); |
120 | - |
121 | - MouseArea{ |
122 | - anchors.fill: parent |
123 | - onClicked: { |
124 | - } |
125 | - } |
126 | - } |
127 | - |
128 | - NewEventEntryField{ |
129 | - id: startTime |
130 | - title: i18n.tr("Start") |
131 | - width: parent.width |
132 | - objectName: "startTimeInput" |
133 | - |
134 | - text: Qt.formatDateTime(startDate, "dd MMM yyyy hh:mm"); |
135 | - |
136 | - MouseArea{ |
137 | - anchors.fill: parent |
138 | - onClicked: { |
139 | - internal.clearFocus() |
140 | - var popupObj = PopupUtils.open(timePicker,root,{"hour": startDate.getHours(),"minute":startDate.getMinutes()}); |
141 | - popupObj.accepted.connect(function(startHour, startMinute) { |
142 | - var newDate = startDate; |
143 | - newDate.setHours(startHour, startMinute); |
144 | - startDate = newDate; |
145 | - startTime.text = Qt.formatDateTime(startDate, "dd MMM yyyy hh:mm"); |
146 | - }) |
147 | - } |
148 | - } |
149 | - } |
150 | - |
151 | - ThinDivider{} |
152 | - |
153 | - NewEventEntryField{ |
154 | - id: endTime |
155 | - title: i18n.tr("End") |
156 | - width: parent.width |
157 | - objectName: "endTimeInput" |
158 | - |
159 | - text: Qt.formatDateTime(endDate,"dd MMM yyyy hh:mm"); |
160 | - |
161 | - MouseArea{ |
162 | - anchors.fill: parent |
163 | - onClicked: { |
164 | - internal.clearFocus() |
165 | - var popupObj = PopupUtils.open(timePicker,root,{"hour": endDate.getHours(),"minute":endDate.getMinutes()}); |
166 | - popupObj.accepted.connect(function(startHour, startMinute) { |
167 | - var newDate = endDate; |
168 | - newDate.setHours(startHour, startMinute); |
169 | - endDate = newDate; |
170 | - endTime.text = Qt.formatDateTime(endDate, "dd MMM yyyy hh:mm"); |
171 | - }) |
172 | + Item { |
173 | + width: parent.width |
174 | + height: startDateInput.height |
175 | + |
176 | + NewEventEntryField{ |
177 | + id: startDateInput |
178 | + title: i18n.tr("Start") |
179 | + objectName: "startDateInput" |
180 | + |
181 | + text: "" |
182 | + |
183 | + width: allDayEventCheckbox.checked ? parent.width : parent.width / 2 |
184 | + |
185 | + MouseArea{ |
186 | + anchors.fill: parent |
187 | + onClicked: openDatePicker(startDateInput, root, "startDate", "Years|Months|Days") |
188 | + } |
189 | + } |
190 | + |
191 | + NewEventEntryField{ |
192 | + id: startTimeInput |
193 | + title: i18n.tr("at") |
194 | + objectName: "startTimeInput" |
195 | + |
196 | + text: "" |
197 | + |
198 | + width: (parent.width / 2) - units.gu(1) |
199 | + anchors.right: parent.right |
200 | + visible: !allDayEventCheckbox.checked |
201 | + |
202 | + MouseArea{ |
203 | + anchors.fill: parent |
204 | + onClicked: openDatePicker(startTimeInput, root, "startDate", "Hours|Minutes") |
205 | + } |
206 | + } |
207 | + } |
208 | + |
209 | + Item { |
210 | + width: parent.width |
211 | + height: endDateInput.height |
212 | + visible: !allDayEventCheckbox.checked |
213 | + |
214 | + NewEventEntryField{ |
215 | + id: endDateInput |
216 | + title: i18n.tr("End") |
217 | + objectName: "endDateInput" |
218 | + |
219 | + text: "" |
220 | + |
221 | + width: parent.width / 2 |
222 | + |
223 | + MouseArea{ |
224 | + anchors.fill: parent |
225 | + onClicked: openDatePicker(endDateInput, root, "endDate", "Years|Months|Days") |
226 | + } |
227 | + } |
228 | + |
229 | + NewEventEntryField{ |
230 | + id: endTimeInput |
231 | + title: i18n.tr("at") |
232 | + objectName: "endTimeInput" |
233 | + |
234 | + text: "" |
235 | + |
236 | + width: (parent.width / 2) - units.gu(1) |
237 | + anchors.right: parent.right |
238 | + |
239 | + MouseArea{ |
240 | + anchors.fill: parent |
241 | + onClicked: openDatePicker(endTimeInput, root, "endDate", "Hours|Minutes") |
242 | + |
243 | } |
244 | } |
245 | } |
246 | @@ -382,14 +395,11 @@ |
247 | CheckBox { |
248 | id: allDayEventCheckbox |
249 | checked: false |
250 | - |
251 | - onCheckedChanged: { |
252 | - startTime.visible = !checked; |
253 | - endTime.visible = !checked; |
254 | - } |
255 | } |
256 | } |
257 | |
258 | + ThinDivider{} |
259 | + |
260 | NewEventEntryField{ |
261 | id: titleEdit |
262 | width: parent.width |
263 | @@ -410,6 +420,7 @@ |
264 | |
265 | TextArea{ |
266 | id: messageEdit |
267 | + objectName: "eventDescriptionInput" |
268 | width: parent.width |
269 | color: focus ? "#2C001E" : "#5D5D5D" |
270 | // default style |
271 | @@ -553,8 +564,10 @@ |
272 | titleEdit.focus = false |
273 | locationEdit.focus = false |
274 | personEdit.focus = false |
275 | - startTime.focus = false |
276 | - endTime.focus = false |
277 | + startDateInput.focus = false |
278 | + startTimeInput.focus = false |
279 | + endDateInput.focus = false |
280 | + endTimeInput.focus = false |
281 | messageEdit.focus = false |
282 | } |
283 | } |
284 | |
285 | === removed file 'TimePicker.qml' |
286 | --- TimePicker.qml 2013-10-07 12:56:19 +0000 |
287 | +++ TimePicker.qml 1970-01-01 00:00:00 +0000 |
288 | @@ -1,95 +0,0 @@ |
289 | -/* |
290 | - * Copyright (C) 2013 Michael Zanetti <michael_zanetti@gmx.net> |
291 | - * |
292 | - * This program is free software; you can redistribute it and/or modify |
293 | - * it under the terms of the GNU General Public License as published by |
294 | - * the Free Software Foundation; version 3. |
295 | - * |
296 | - * This program is distributed in the hope that it will be useful, |
297 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
298 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
299 | - * GNU General Public License for more details. |
300 | - * |
301 | - * You should have received a copy of the GNU General Public License |
302 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
303 | - */ |
304 | - |
305 | -import QtQuick 2.0 |
306 | -import Ubuntu.Components 0.1 |
307 | -import Ubuntu.Components.Popups 0.1 |
308 | - |
309 | -Dialog { |
310 | - id: root |
311 | - title: i18n.tr("Time") |
312 | - height: units.gu(100) |
313 | - |
314 | - property alias hour: hourScroller.currentIndex |
315 | - property alias minute: minuteScroller.currentIndex |
316 | - |
317 | - signal accepted(int hours, int minutes) |
318 | - signal rejected() |
319 | - |
320 | - QtObject { |
321 | - id: priv |
322 | - |
323 | - property date now: new Date() |
324 | - } |
325 | - |
326 | - contents: [ |
327 | - Row { |
328 | - height: units.gu(24) |
329 | - Scroller { |
330 | - id: hourScroller |
331 | - objectName: "hourScroller" |
332 | - anchors { |
333 | - top: parent.top |
334 | - bottom: parent.bottom |
335 | - } |
336 | - width: parent.width / 2 |
337 | - labelText: i18n.tr("Hour") |
338 | - |
339 | - min: 00 |
340 | - max: 23 |
341 | - currentIndex: priv.now.getHours() |
342 | - } |
343 | - Scroller { |
344 | - id: minuteScroller |
345 | - objectName: "minuteScroller" |
346 | - anchors { |
347 | - top: parent.top |
348 | - bottom: parent.bottom |
349 | - } |
350 | - width: parent.width / 2 |
351 | - labelText: i18n.tr("Minute") |
352 | - |
353 | - min: 00 |
354 | - max: 59 |
355 | - currentIndex: priv.now.getMinutes() |
356 | - } |
357 | - }, |
358 | - Row { |
359 | - spacing: units.gu(1) |
360 | - Button { |
361 | - objectName: "TimePickerCancelButton" |
362 | - text: i18n.tr("Cancel") |
363 | - onClicked: { |
364 | - root.rejected() |
365 | - PopupUtils.close(root) |
366 | - } |
367 | - width: (parent.width - parent.spacing) / 2 |
368 | - } |
369 | - Button { |
370 | - objectName: "TimePickerOKButton" |
371 | - text: i18n.tr("OK") |
372 | - color: "#dd4814" |
373 | - |
374 | - onClicked: { |
375 | - root.accepted(root.hour, root.minute) |
376 | - PopupUtils.close(root) |
377 | - } |
378 | - width: (parent.width - parent.spacing) / 2 |
379 | - } |
380 | - } |
381 | - |
382 | - ] |
383 | -} |
384 | |
385 | === modified file 'dateExt.js' |
386 | --- dateExt.js 2014-03-22 03:07:26 +0000 |
387 | +++ dateExt.js 2014-06-06 18:09:22 +0000 |
388 | @@ -90,6 +90,12 @@ |
389 | && this.getFullYear() === otherDay.getFullYear() ); |
390 | } |
391 | |
392 | +Date.prototype.mergeDate = function (d) { |
393 | + this.setFullYear(d.getFullYear()); |
394 | + this.setMonth(d.getMonth()); |
395 | + this.setDate(d.getDate()); |
396 | +} |
397 | + |
398 | function weekCount(year, month_number) { |
399 | var firstOfMonth = new Date(year, month_number, 1); |
400 | var lastOfMonth = new Date(year, month_number+1, 0); |
401 | |
402 | === modified file 'tests/autopilot/calendar_app/emulators.py' |
403 | --- tests/autopilot/calendar_app/emulators.py 2014-05-22 10:02:54 +0000 |
404 | +++ tests/autopilot/calendar_app/emulators.py 2014-06-06 18:09:22 +0000 |
405 | @@ -10,16 +10,48 @@ |
406 | |
407 | from autopilot.introspection import dbus |
408 | |
409 | -from ubuntuuitoolkit import emulators as toolkit_emulators |
410 | + |
411 | +from ubuntuuitoolkit import ( |
412 | + emulators as toolkit_emulators, |
413 | + pickers |
414 | +) |
415 | from dateutil import tz |
416 | |
417 | |
418 | +class NewEventEntryField(toolkit_emulators.TextField): |
419 | + """Autopilot helper for the NewEventEntryField component.""" |
420 | + |
421 | + |
422 | +#for now we are borrowing the textfield helper for the textarea |
423 | +#once the toolkit has a textarea helper this should be removed |
424 | +#https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1327354 |
425 | +class TextArea(toolkit_emulators.TextField): |
426 | + """Autopilot helper for the TextArea component.""" |
427 | + |
428 | + |
429 | class MainView(toolkit_emulators.MainView): |
430 | |
431 | """ |
432 | An emulator class that makes it easy to interact with the calendar-app. |
433 | """ |
434 | |
435 | + def set_picker(self, field, mode, value): |
436 | + #open picker |
437 | + self.pointing_device.click_object(field) |
438 | + # valid options are date or time; assume date if invalid/no option |
439 | + if mode == 'time': |
440 | + mode_value = 'Hours|Minutes' |
441 | + else: |
442 | + mode_value = 'Years|Months|Days' |
443 | + picker = self.wait_select_single( |
444 | + pickers.DatePicker, mode=mode_value, visible=True) |
445 | + if mode_value == 'Hours|Minutes': |
446 | + picker.pick_time(value) |
447 | + else: |
448 | + picker.pick_date(value) |
449 | + #close picker |
450 | + self.pointing_device.click_object(field) |
451 | + |
452 | def get_event_view(self): |
453 | return self.wait_select_single("EventView") |
454 | |
455 | @@ -52,34 +84,43 @@ |
456 | |
457 | def get_new_event_name_input_box(self): |
458 | new_event = self.get_new_event() |
459 | - return new_event.wait_select_single("NewEventEntryField", |
460 | + return new_event.wait_select_single(NewEventEntryField, |
461 | objectName="newEventName") |
462 | |
463 | def get_event_start_time_field(self): |
464 | new_event = self.get_new_event() |
465 | - return new_event.wait_select_single("NewEventEntryField", |
466 | + return new_event.wait_select_single(NewEventEntryField, |
467 | objectName="startTimeInput") |
468 | |
469 | + def get_event_start_date_field(self): |
470 | + new_event = self.get_new_event() |
471 | + return new_event.wait_select_single(NewEventEntryField, |
472 | + objectName="startDateInput") |
473 | + |
474 | + def get_event_end_date_field(self): |
475 | + new_event = self.get_new_event() |
476 | + return new_event.wait_select_single(NewEventEntryField, |
477 | + objectName="endDateInput") |
478 | + |
479 | def get_event_end_time_field(self): |
480 | new_event = self.get_new_event() |
481 | - return new_event.wait_select_single("NewEventEntryField", |
482 | + return new_event.wait_select_single(NewEventEntryField, |
483 | objectName="endTimeInput") |
484 | |
485 | def get_event_location_field(self): |
486 | new_event = self.get_new_event() |
487 | - return new_event.wait_select_single("NewEventEntryField", |
488 | + return new_event.wait_select_single(NewEventEntryField, |
489 | objectName="eventLocationInput") |
490 | |
491 | def get_event_people_field(self): |
492 | new_event = self.get_new_event() |
493 | - return new_event.wait_select_single("NewEventEntryField", |
494 | + return new_event.wait_select_single(NewEventEntryField, |
495 | objectName="eventPeopleInput") |
496 | |
497 | - def get_time_picker(self): |
498 | - try: |
499 | - return self.wait_select_single("TimePicker") |
500 | - except dbus.StateNotFoundError: |
501 | - return None |
502 | + def get_event_description_field(self): |
503 | + new_event = self.get_new_event() |
504 | + return new_event.wait_select_single(TextArea, |
505 | + objectName="eventDescriptionInput") |
506 | |
507 | def safe_swipe_view(self, direction, view, date): |
508 | """ |
509 | @@ -129,6 +170,20 @@ |
510 | def get_num_events(self): |
511 | return len(self.select_many("EventBubble")) |
512 | |
513 | + def get_event(self, title): |
514 | + """ Return an event by title |
515 | + """ |
516 | + events = self.select_many("EventBubble") |
517 | + for event in events: |
518 | + try: |
519 | + event_found = event.select_single("Label", text=title) |
520 | + except: |
521 | + continue |
522 | + if event_found: |
523 | + return event |
524 | + |
525 | + return 0 |
526 | + |
527 | def get_new_event_save_button(self): |
528 | new_event = self.get_new_event() |
529 | return new_event.wait_select_single("Button", |
530 | |
531 | === modified file 'tests/autopilot/calendar_app/tests/test_calendar.py' |
532 | --- tests/autopilot/calendar_app/tests/test_calendar.py 2014-05-23 11:36:56 +0000 |
533 | +++ tests/autopilot/calendar_app/tests/test_calendar.py 2014-06-06 18:09:22 +0000 |
534 | @@ -8,42 +8,16 @@ |
535 | """Calendar app autopilot tests.""" |
536 | |
537 | from __future__ import absolute_import |
538 | - |
539 | from autopilot.matchers import Eventually |
540 | - |
541 | -from testtools.matchers import Equals, Not, Is, NotEquals |
542 | +from testtools.matchers import Not, Is, NotEquals |
543 | +from calendar_app.tests import CalendarTestCase |
544 | |
545 | import time |
546 | - |
547 | -from calendar_app.tests import CalendarTestCase |
548 | +import datetime |
549 | |
550 | |
551 | class TestMainView(CalendarTestCase): |
552 | |
553 | - def _scroll_time_picker_to_time(self, picker, hours, minutes): |
554 | - # Scroll hours to selected value |
555 | - scroller = picker.select_single("Scroller", objectName="hourScroller") |
556 | - x = int(scroller.globalRect[0] + scroller.globalRect[2] / 2) |
557 | - y = int(scroller.globalRect[1] + 0.9 * scroller.globalRect[3]) |
558 | - self.pointing_device.move(x, y) |
559 | - while (scroller.currentIndex != hours): |
560 | - current_index = scroller.currentIndex |
561 | - self.pointing_device.click() |
562 | - self.assertThat(scroller.currentIndex, Eventually( |
563 | - Equals((current_index + 1) % 24))) |
564 | - |
565 | - # Scroll minutes to selected value |
566 | - scroller = picker.select_single("Scroller", |
567 | - objectName="minuteScroller") |
568 | - x = int(scroller.globalRect[0] + scroller.globalRect[2] / 2) |
569 | - y = int(scroller.globalRect[1] + 0.9 * scroller.globalRect[3]) |
570 | - self.pointing_device.move(x, y) |
571 | - while (scroller.currentIndex != minutes): |
572 | - current_index = scroller.currentIndex |
573 | - self.pointing_device.click() |
574 | - self.assertThat(scroller.currentIndex, Eventually( |
575 | - Equals((current_index + 1) % 60))) |
576 | - |
577 | def test_new_event(self): |
578 | """test add new event """ |
579 | #go to today |
580 | @@ -52,50 +26,73 @@ |
581 | header.click_action_button('todaybutton') |
582 | num_events = self.main_view.get_num_events() |
583 | |
584 | + # calculate some dates |
585 | + today = self.main_view.get_day_view().currentDay.datetime |
586 | + yesterday = today + datetime.timedelta(days=-1) |
587 | + tomorrow = today + datetime.timedelta(days=1) |
588 | + |
589 | + start_time = datetime.time(6, 5) |
590 | + end_time = datetime.time(11, 38) |
591 | + |
592 | #click on new event button |
593 | header = self.main_view.get_header() |
594 | header.click_action_button('neweventbutton') |
595 | self.assertThat(self.main_view.get_new_event, |
596 | Eventually(Not(Is(None)))) |
597 | |
598 | - #input a new event name |
599 | - eventTitle = "Test event " + str(int(time.time())) |
600 | + #due to https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1326963 |
601 | + #the first event triggered is ignored, so we trigger an event |
602 | + #and a small sleep to clear before continuing input |
603 | event_name_field = self.main_view.get_new_event_name_input_box() |
604 | self.pointing_device.click_object(event_name_field) |
605 | - self.assertThat(event_name_field.activeFocus, Eventually(Equals(True))) |
606 | - self.keyboard.type(eventTitle) |
607 | - self.assertThat(event_name_field.text, Eventually(Equals(eventTitle))) |
608 | + time.sleep(1) |
609 | + |
610 | + # Set the start date |
611 | + self.main_view.set_picker(self.main_view.get_event_start_date_field(), |
612 | + 'date', |
613 | + yesterday) |
614 | + |
615 | + # Set the end date |
616 | + self.main_view.set_picker(self.main_view.get_event_end_date_field(), |
617 | + 'date', |
618 | + tomorrow) |
619 | |
620 | # Set the start time |
621 | - start_time_field = self.main_view.get_event_start_time_field() |
622 | - self.pointing_device.click_object(start_time_field) |
623 | - picker = self.main_view.get_time_picker() |
624 | - self._scroll_time_picker_to_time(picker, 12, 28) |
625 | - ok = picker.select_single("Button", objectName="TimePickerOKButton") |
626 | - self.pointing_device.click_object(ok) |
627 | - |
628 | - ## Set the end time |
629 | - end_time_field = self.main_view.get_event_end_time_field() |
630 | - self.pointing_device.click_object(end_time_field) |
631 | - picker = self.main_view.get_time_picker() |
632 | - self._scroll_time_picker_to_time(picker, 13, 38) |
633 | - ok = picker.select_single("Button", objectName="TimePickerOKButton") |
634 | - self.pointing_device.click_object(ok) |
635 | + self.main_view.set_picker(self.main_view.get_event_start_time_field(), |
636 | + 'time', |
637 | + start_time) |
638 | + |
639 | + # Set the end time |
640 | + self.main_view.set_picker(self.main_view.get_event_end_time_field(), |
641 | + 'time', |
642 | + end_time) |
643 | + |
644 | + #input a new event name |
645 | + eventTitle = "Test event " + str(int(time.time())) |
646 | + self.main_view.get_new_event_name_input_box().write(eventTitle) |
647 | + |
648 | + #input description |
649 | + self.main_view.get_event_description_field(). \ |
650 | + write("My favorite test event") |
651 | |
652 | #input location |
653 | - location_field = self.main_view.get_event_location_field() |
654 | - self.pointing_device.click_object(location_field) |
655 | - self.assertThat(location_field.activeFocus, Eventually(Equals(True))) |
656 | - self.keyboard.type("My location") |
657 | - self.assertThat(location_field.text, Eventually(Equals("My location"))) |
658 | + self.main_view.get_event_location_field().write("England") |
659 | + |
660 | + #input guests |
661 | + self.main_view.get_event_people_field().write("me, myself, and I") |
662 | + |
663 | + #todo: iterate over all combinations |
664 | + #and include recurrence and reminders |
665 | |
666 | #click save button |
667 | save_button = self.main_view.get_new_event_save_button() |
668 | self.pointing_device.click_object(save_button) |
669 | |
670 | #verify that the event has been created in timeline |
671 | + self.main_view.switch_to_tab("dayTab") |
672 | header = self.main_view.get_header() |
673 | header.click_action_button('todaybutton') |
674 | - self.main_view.switch_to_tab("dayTab") |
675 | self.assertThat(self.main_view.get_num_events, |
676 | Eventually(NotEquals(num_events))) |
677 | + |
678 | + #todo: verify entered event data |
looks like you need to merge your branch with latest code.