Merge lp:~martin-borho/ubuntu-weather-app/LocationLookup into lp:ubuntu-weather-app/obsolete.trunk

Proposed by Martin Borho
Status: Merged
Approved by: Martin Borho
Approved revision: 138
Merged at revision: 133
Proposed branch: lp:~martin-borho/ubuntu-weather-app/LocationLookup
Merge into: lp:ubuntu-weather-app/obsolete.trunk
Diff against target: 631 lines (+212/-134)
7 files modified
components/LocationManagerSheet.qml (+67/-15)
components/SplashComponent.qml (+3/-1)
components/SwipeDelete.qml (+0/-65)
components/WeatherApi.js (+49/-7)
tests/autopilot/ubuntu_weather_app/tests/__init__.py (+1/-1)
tests/autopilot/ubuntu_weather_app/tests/test_locationmanager.py (+54/-7)
tests/autopilot/ubuntu_weather_app/tests/test_settings.py (+38/-38)
To merge this branch: bzr merge lp:~martin-borho/ubuntu-weather-app/LocationLookup
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Nicholas Skaggs (community) Approve
Review via email: mp+188781@code.launchpad.net

Commit message

added location lookup via geoip and geonames.org with test, added fixes for new removable ListItem and the changed LocalStorage path

Description of the change

* added location lookup, via geoip and geonames.org
* added autopilot test for location lookup
* removed SwipeDelete component due updated ListItem component, removed icon too
* fixed autopilot tests to work with new removable ListItem
* updated LocalStorage path in autopilot tests

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

I love the changes! It feels so much nicer to use

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) :
review: Approve (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
138. By Martin Borho

and another one for jenkins

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Loïc Minier (lool) wrote :

It would have been better not to hardcode the new pathname... Now these tests may only run with the updated SDK, not the "old" one which means they need to land together.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'components/LocationManagerSheet.qml'
2--- components/LocationManagerSheet.qml 2013-09-29 14:24:43 +0000
3+++ components/LocationManagerSheet.qml 2013-10-04 07:54:12 +0000
4@@ -40,6 +40,27 @@
5 Theme.palette.selected.backgroundText = "#656565"
6 }
7
8+ WorkerScript {
9+ id: lookupWorker
10+ source: Qt.resolvedUrl("./WeatherApi.js")
11+ onMessage: {
12+ lookupIndicator.running = false;
13+ if(!messageObject.error) {
14+ if(messageObject.result.locations && messageObject.result.locations.length > 0) {
15+ var location = messageObject.result.locations[0];
16+ currentLocationItem.detectedLocation = location;
17+ currentLocationLabel.text = location.name
18+ currentLocationAreaLabel.text = location.adminName1
19+ locationLookupItem.visible = false
20+ currentLocationItem.visible = true;
21+ }
22+ } else {
23+ console.log("search: "+messageObject.error.msg+" / "+messageObject.error.request.url)
24+ httpFailedLookup.show();
25+ }
26+ }
27+ }
28+
29 function loadData() {
30 storage.getLocations(fillLocationsList);
31 }
32@@ -96,9 +117,12 @@
33 }
34 ListItem.Standard {
35 id: locationLookupItem
36+ objectName: "LocationLookupItem"
37 progression: true
38 Label {
39- text: i18n.tr("Lookup location")+" (Dummy)"
40+ id: locationLookupItemLabel
41+ text: i18n.tr("Scan for location")
42+ visible: !lookupIndicator.running
43 anchors {
44 verticalCenter: parent.verticalCenter
45 left: parent.left
46@@ -106,26 +130,52 @@
47 }
48 fontSize: "large"
49 }
50- onClicked: {
51- print("TODO: lookup current location")
52- visible = false
53- currentLocationItem.visible = true;
54+ ActivityIndicator {
55+ id: lookupIndicator
56+ objectName: "LookupIndicator"
57+ running:false
58+ anchors.verticalCenter: parent.verticalCenter
59+ anchors.left: parent.left
60+ anchors.leftMargin: units.gu(3)
61+ }
62+ onClicked: {
63+ lookupIndicator.running = true;
64+ lookupWorker.sendMessage({
65+ action: "getGeoIp",
66+ params: {}
67+ })
68 }
69 }
70 ListItem.Standard {
71 id: currentLocationItem
72+ objectName: "CurrentLocationItem"
73+ property var detectedLocation: null;
74 visible: false
75 Label {
76- text: "London"
77+ id: currentLocationLabel
78+ objectName: "CurrentLocationLabel"
79+ text: ""
80 anchors {
81- verticalCenter: parent.verticalCenter
82+ top: parent.top
83+ topMargin: units.gu(0.5)
84 left: parent.left
85 leftMargin: units.gu(3)
86 }
87 fontSize: "large"
88 }
89+ Label {
90+ id: currentLocationAreaLabel
91+ text: ""
92+ anchors {
93+ top: currentLocationLabel.bottom
94+ bottom: parent.bottom
95+ left: parent.left
96+ leftMargin: units.gu(3)
97+ }
98+ fontSize: "small"
99+ }
100 control: Button {
101- objectName: "currentLocationItem"
102+ objectName: "LookupItemAddButton"
103 id: lookupItemAddButton
104 anchors.verticalCenter: parent.verticalCenter
105 // TRANSLATORS: this is the button to add a location (city) that has been
106@@ -134,8 +184,9 @@
107 MouseArea {
108 anchors.fill: parent
109 onClicked: {
110- // add dummy location
111- addLocation({"coord":{"lon":"-0.12574","lat":"51.50853"},"timezone":{"gmtOffset":0,"dstOffset":1,"timeZoneId":"Europe/London"},"population":7556900,"adminName2":"Greater London","name":"London","country":"GB","countryName":"United Kingdom","adminName1":"England","adminName3":"","services":{"geonames":2643743},"areaLabel":"England, Greater London, United Kingdom"})
112+ if(currentLocationItem.detectedLocation) {
113+ addLocation(currentLocationItem.detectedLocation)
114+ }
115 lookupItemAddButton.visible = false;
116 }
117 }
118@@ -200,11 +251,6 @@
119 location = JSON.parse(JSON.stringify(location));
120 locationsRemoved.append(location)
121 locationModel.remove(index)
122-
123- }
124- backgroundIndicator: SwipeDelete {
125- id: swipeDelete
126- state: swipingState
127 }
128 }
129 footer: ListItem.Standard {
130@@ -284,5 +330,11 @@
131 AddLocationSheet {
132 id:addLocationSheet
133 }
134+
135+ SplashComponent {
136+ id: httpFailedLookup
137+ objectName: "HTTPFailedLookup"
138+ message: i18n.tr("Couldn't specify your current location, please try later again!")
139+ }
140 }
141 }
142
143=== modified file 'components/SplashComponent.qml'
144--- components/SplashComponent.qml 2013-09-21 17:38:36 +0000
145+++ components/SplashComponent.qml 2013-10-04 07:54:12 +0000
146@@ -30,8 +30,10 @@
147 top: parent.top
148 topMargin:units.gu(15)
149 }
150+ property string message: i18n.tr("Couldn't load weather data, please try later again!")
151+
152 Label {
153- text: i18n.tr("Couldn't load weather data, please try later again!")
154+ text: message
155 anchors.centerIn: parent
156 width: parent.width-units.gu(3)
157 fontSize: "medium"
158
159=== removed file 'components/SwipeDelete.qml'
160--- components/SwipeDelete.qml 2013-07-21 11:04:02 +0000
161+++ components/SwipeDelete.qml 1970-01-01 00:00:00 +0000
162@@ -1,65 +0,0 @@
163-/*
164- * Copyright (C) 2013 Canonical Ltd
165- *
166- * This program is free software: you can redistribute it and/or modify
167- * it under the terms of the GNU General Public License version 3 as
168- * published by the Free Software Foundation.
169- *
170- * This program is distributed in the hope that it will be useful,
171- * but WITHOUT ANY WARRANTY; without even the implied warranty of
172- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
173- * GNU General Public License for more details.
174- *
175- * You should have received a copy of the GNU General Public License
176- * along with this program. If not, see <http://www.gnu.org/licenses/>.
177- *
178- * Authored by: Nekhelesh Ramananthan <krnekhelesh@gmail.com>
179- */
180-
181-import QtQuick 2.0
182-import Ubuntu.Components 0.1
183-
184-Rectangle {
185- id: swipeBackgroundItem
186-
187- anchors.fill: parent
188- color: Theme.palette.normal.base
189-
190- Image {
191- id: swipeDeleteIcon
192-
193- property int slidingMargin: units.gu(10)
194-
195- anchors.fill: parent
196- verticalAlignment: Image.AlignVCenter
197- fillMode: Image.Pad
198- }
199-
200- Label {
201- id: swipeBackgroundText
202-
203- property int slidingMargin: units.gu(3)
204-
205- anchors.fill: parent
206- verticalAlignment: Text.AlignVCenter
207- color: Theme.palette.normal.baseText
208- }
209-
210- states: [
211- State {
212- name: "SwipingRight"
213- PropertyChanges { target: swipeBackgroundText; anchors.rightMargin: swipeBackgroundText.slidingMargin
214- anchors.leftMargin: 0; horizontalAlignment: Text.AlignRight; text: i18n.tr("Delete") }
215- PropertyChanges { target: swipeDeleteIcon; anchors.rightMargin: swipeDeleteIcon.slidingMargin
216- anchors.leftMargin: 0; horizontalAlignment: Image.AlignRight; source: Qt.resolvedUrl("../resources/images/trash_icon.png")}
217- },
218-
219- State {
220- name: "SwipingLeft"
221- PropertyChanges { target: swipeBackgroundText; anchors.rightMargin: 0; anchors.leftMargin: swipeBackgroundText.slidingMargin
222- horizontalAlignment: Text.AlignLeft; text: i18n.tr("Delete") }
223- PropertyChanges { target: swipeDeleteIcon; anchors.rightMargin: 0; source: Qt.resolvedUrl("../resources/images/trash_icon.png")
224- anchors.leftMargin: swipeDeleteIcon.slidingMargin; horizontalAlignment: Image.AlignLeft }
225- }
226- ]
227-}
228
229=== modified file 'components/WeatherApi.js'
230--- components/WeatherApi.js 2013-09-28 10:32:31 +0000
231+++ components/WeatherApi.js 2013-10-04 07:54:12 +0000
232@@ -80,6 +80,32 @@
233 }
234 }
235
236+var GeoipApi = (function() {
237+ var _baseUrl = "http://geoip.ubuntu.com/lookup";
238+ return {
239+ getLatLong: function(params, apiCaller, onSuccess, onError) {
240+ var request = { type: "geolookup",url: _baseUrl},
241+ resultHandler = (function(request, xmlDoc) {
242+ var coords = {},
243+ childNodes = xmlDoc.childNodes;
244+ for(var i=0;i<childNodes.length;i++) {
245+ if(childNodes[i].nodeName === "Latitude") {
246+ coords.lat = childNodes[i].firstChild.nodeValue;
247+ } else if(childNodes[i].nodeName === "Longitude") {
248+ coords.lon = childNodes[i].firstChild.nodeValue;
249+ }
250+ }
251+ onSuccess(coords);
252+ }),
253+ retryHandler = (function(err) {
254+ console.log("geolookup retry of "+err.request.url);
255+ apiCaller(request, resultHandler, onError);
256+ });
257+ apiCaller(request, resultHandler, retryHandler);
258+ }
259+ }
260+})();
261+
262 var GeonamesApi = (function() {
263 /**
264 provides neccessary methods for requesting and preparing data from Geonames.org
265@@ -124,7 +150,7 @@
266 };
267 if(mode === "point") {
268 request = { type: "search",
269- url: _baseUrl+ "findNearbyJSON?style=full&username="+encodeURIComponent(_username)
270+ url: _baseUrl+ "findNearbyPlaceNameJSON?style=full&username="+encodeURIComponent(_username)
271 +"&lat="+encodeURIComponent(params.coords.lat)+"&lng="+encodeURIComponent(params.coords.lon)
272 +_addParams}
273 } else {
274@@ -294,9 +320,9 @@
275 getData: function(params, apiCaller, onSuccess, onError) {
276 var urls = _getUrls(params),
277 handlerMap = {
278- current: { type: "current",url: urls.current},//_getCurrentUrl(params)},//_baseUrl + "weather?id="+params.location.service_id+"&units="+params.units},
279+ current: { type: "current",url: urls.current},
280 daily: { type: "daily",url: urls.daily},
281- forecast: { type: "forecast", url: urls.forecast}},//_baseUrl + "forecast?id="+params.location.service_id+"&units="+params.units}},
282+ forecast: { type: "forecast", url: urls.forecast}},
283 response = {
284 location: params.location,
285 db: (params.db) ? params.db : null,
286@@ -350,10 +376,13 @@
287 xmlHttp.onreadystatechange = function () {
288 try {
289 if (xmlHttp.readyState == 4) {
290- //console.log(xmlHttp.responseText);
291- var json = JSON.parse(xmlHttp.responseText);
292 if(xmlHttp.status === 200) {
293- onSuccess(request,json);
294+ if(xmlHttp.responseXML) {
295+ onSuccess(request, xmlHttp.responseXML.documentElement);
296+ } else {
297+ var json = JSON.parse(xmlHttp.responseText);
298+ onSuccess(request,json);
299+ }
300 } else {
301 onError({
302 msg: "wrong response http code, got "+xmlHttp.status,
303@@ -371,6 +400,16 @@
304 //
305 return {
306 //
307+ geoLookup: function(params, onSuccess, onError) {
308+ var service = _getService('geoip'),
309+ geoNameService = _getService('geonames'),
310+ lookupHandler = function(data) {
311+ print("Geolookup: "+JSON.stringify(data))
312+ geoNameService.search("point", {coords:data}, _sendRequest, onSuccess, onError);
313+ };
314+ service.getLatLong(params, _sendRequest, lookupHandler, onError)
315+ },
316+ //
317 search: function(mode, params, onSuccess, onError) {
318 var service = _getService('geonames');
319 service.search(mode, params, _sendRequest, onSuccess, onError);
320@@ -383,7 +422,8 @@
321 }
322 })({
323 "openweathermap": OpenWeatherMapApi,
324- "geonames": GeonamesApi
325+ "geonames": GeonamesApi,
326+ "geoip": GeoipApi
327 });
328
329 /**
330@@ -414,6 +454,8 @@
331 WeatherApi.search("name", message.params, finished, onError);
332 } else if(message.action === "searchByPoint") {
333 WeatherApi.search("point", message.params, finished, onError);
334+ } else if(message.action === "getGeoIp") {
335+ WeatherApi.geoLookup(message.params, finished, onError);
336 } else if(message.action === "updateData") {
337 var locLength = message.params.locations.length,
338 locUpdated = 0,
339
340=== removed file 'resources/images/trash_icon@16.png'
341Binary files resources/images/trash_icon@16.png 2013-07-21 11:00:01 +0000 and resources/images/trash_icon@16.png 1970-01-01 00:00:00 +0000 differ
342=== modified file 'tests/autopilot/ubuntu_weather_app/tests/__init__.py'
343--- tests/autopilot/ubuntu_weather_app/tests/__init__.py 2013-09-29 14:26:37 +0000
344+++ tests/autopilot/ubuntu_weather_app/tests/__init__.py 2013-10-04 07:54:12 +0000
345@@ -107,7 +107,7 @@
346 """
347
348 def find_db(self):
349- dbs_path = os.path.expanduser("~/.local/share/Qt Project/QtQmlViewer/QML/OfflineStorage/Databases/")
350+ dbs_path = os.path.expanduser("~/.local/share/ubuntu-weather-app/Databases/")
351 if not os.path.exists(dbs_path):
352 return None
353
354
355=== modified file 'tests/autopilot/ubuntu_weather_app/tests/test_locationmanager.py'
356--- tests/autopilot/ubuntu_weather_app/tests/test_locationmanager.py 2013-09-28 11:31:43 +0000
357+++ tests/autopilot/ubuntu_weather_app/tests/test_locationmanager.py 2013-10-04 07:54:12 +0000
358@@ -191,7 +191,48 @@
359 errorLabel = self.main_window.get_object('Label', 'noCityError')
360 self.assertThat(errorLabel.visible, Eventually(Equals(True)))
361
362-
363+ def test_location_lookup(self):
364+ """Tests the location lookup"""
365+ # start lookup
366+ self.assertThat(lambda: self.main_window.get_object('Standard', 'LocationLookupItem'), Eventually(Not(Is(None))))
367+ lookupItem = self.main_window.get_object('Standard', 'LocationLookupItem')
368+ self.pointing_device.click_object(lookupItem)
369+
370+ # wait for result
371+ load_indicator = self.main_window.get_object('ActivityIndicator', 'LookupIndicator')
372+ self.assertThat(load_indicator.running, Eventually(Equals(False), timeout=120))
373+
374+ # check a location was found
375+ self.assertThat(lambda: self.main_window.get_object('Label', 'CurrentLocationLabel'), Eventually(Not(Is(None))))
376+ location = self.main_window.get_object('Label', 'CurrentLocationLabel')
377+ self.assertThat(location.text, Eventually(Not(Equals(""))))
378+ location_name = location.text
379+
380+ # add location
381+ self.assertThat(lambda: self.main_window.get_object('Button', 'LookupItemAddButton'), Eventually(Not(Is(None))))
382+ add_button = self.main_window.get_object('Button', 'LookupItemAddButton')
383+ self.pointing_device.click_object(add_button)
384+
385+ # LocationManagerPage should be visible and "London" added
386+ self.assertThat(lambda: self.main_window.get_object('QQuickListView', 'LocationList'), Eventually(Not(Is(None))))
387+ locationList = self.main_window.get_object('QQuickListView', 'LocationList')
388+ self.assertThat(lambda: self.main_window.get_object('Label', 'existingLocation0'), Eventually(Not(Is(None))))
389+ addedItem = self.main_window.get_object('Label', "existingLocation0")
390+ self.assertThat(addedItem.text, Eventually(Equals(location_name)))
391+ self._click_sheet_confirm()
392+
393+ # back to locations, wait till data is loaded
394+ load_indicator = self.main_window.get_object('ActivityIndicator', 'LoadingSpinner')
395+ self.assertThat(load_indicator.running, Eventually(Equals(False), timeout=120))
396+
397+ # only location is there
398+ loadingPage = self.main_window.get_object("Tabs", "rootTabs")
399+ self.assertThat(loadingPage.visible, Eventually(Equals(True)))
400+ tabObjects = self.main_window.get_objects('LocationTab','LocationTab')
401+ self.assertEqual(1, len(tabObjects))
402+
403+
404+
405 class TestLocationManagerWithLocation(WeatherTestCase, DatabaseMixin, SheetMixin):
406 def setUp(self):
407 self.clean_db()
408@@ -210,15 +251,21 @@
409 """Swipe right to delete the first location"""
410 number_of_locations = self._get_number_of_locations()
411 self.assertThat(lambda: self.app.select_single('Standard', objectName='existingLocationItem0'), Eventually(Not(Is(None))))
412- firstLocation = self.app.select_single("Standard", objectName="existingLocationItem0")
413+ first_location = self.app.select_single("Standard", objectName="existingLocationItem0")
414
415- x, y, w, h = firstLocation.globalRect
416+ x, y, w, h = first_location.globalRect
417 tx = x + (w / 8)
418 ty = y + (h / 2)
419- self.pointing_device.drag(tx, ty, tx + (w - w / 8), ty)
420- self.assertThat(
421- self._get_number_of_locations(),
422- Eventually(Equals(number_of_locations-1)))
423+ self.pointing_device.drag(tx, ty, tx + w/4*3 , ty)
424+
425+ self.assertThat(lambda: first_location.select_many('Label')[2].visible, Eventually(Not(Is(None))))
426+ trashcanLabel = first_location.select_many('Label')[2]
427+ timeout = 0
428+ while timeout < 10 and first_location.select_many('Label') and self.app.select_single("Standard", objectName="existingLocationItem0"):
429+ self.pointing_device.click_object(trashcanLabel)
430+ sleep(1)
431+ timeout += 1
432+ self.assertThat(lambda: self._get_number_of_locations(), Eventually(Equals(number_of_locations-1)))
433
434 def _get_number_of_locations(self):
435 qqlw = self.app.select_single("ComposerSheet").select_single("QQuickListView")
436
437=== modified file 'tests/autopilot/ubuntu_weather_app/tests/test_settings.py'
438--- tests/autopilot/ubuntu_weather_app/tests/test_settings.py 2013-09-29 14:26:37 +0000
439+++ tests/autopilot/ubuntu_weather_app/tests/test_settings.py 2013-10-04 07:54:12 +0000
440@@ -31,14 +31,14 @@
441
442 def _move_pointer_around(self):
443 """Helper method to move the pointer around, to assure selector is opened"""
444- self.assertThat(lambda: self.main_window.get_object('ComposerSheet', 'SettingsSheet'), Eventually(Not(Is(None))))
445- sheet = self.main_window.get_object('ComposerSheet', 'SettingsSheet')
446+ self.assertThat(lambda: self.main_window.select_single('ComposerSheet', objectName='SettingsSheet'), Eventually(Not(Is(None))))
447+ sheet = self.main_window.select_single('ComposerSheet', objectName='SettingsSheet')
448 self.pointing_device.move_to_object(sheet)
449
450 def _check_units(self, units):
451 """Checks selected units by values from the first location tab"""
452- self.assertThat(lambda: self.main_window.get_objects('QQuickText', 'CurrentTempText'), Eventually(Not(Is(None))))
453- current_temps = self.main_window.get_objects('QQuickText', 'CurrentTempText')
454+ self.assertThat(lambda: self.main_window.select_many('QQuickText', objectName='CurrentTempText'), Eventually(Not(Is(None))))
455+ current_temps = self.main_window.select_many('QQuickText', objectName='CurrentTempText')
456 if units == "imperial":
457 self.assertThat(current_temps[0].text, Eventually(Equals(u'57')))
458 self.assertThat(current_temps[1].text, Eventually(Equals(u'69')))
459@@ -48,12 +48,12 @@
460
461 def _check_wind_units(self, wind_units):
462 """Checks selected units by values from the first location tab"""
463- self.assertThat(lambda: self.main_window.get_objects('WeatherDetailComponent', 'WindSpeedValue')[0], Eventually(Not(Is(None))))
464- wind_component = self.main_window.get_objects('WeatherDetailComponent', 'WindSpeedValue')[0]
465- self.assertThat(lambda: wind_component.get_object('QQuickText', 'WeatherDetailUnit'), Eventually(Not(Is(None))))
466- wind_unit = wind_component.get_object('QQuickText', 'WeatherDetailUnit')
467- self.assertThat(lambda: wind_component.get_object('QQuickText', 'WeatherDetailValue'), Eventually(Not(Is(None))))
468- wind_value = wind_component.get_object('QQuickText', 'WeatherDetailValue')
469+ self.assertThat(lambda: self.main_window.select_many('WeatherDetailComponent', objectName='WindSpeedValue')[0], Eventually(Not(Is(None))))
470+ wind_component = self.main_window.select_many('WeatherDetailComponent', objectName='WindSpeedValue')[0]
471+ self.assertThat(lambda: wind_component.select_single('QQuickText', objectName='WeatherDetailUnit'), Eventually(Not(Is(None))))
472+ wind_unit = wind_component.select_single('QQuickText', objectName='WeatherDetailUnit')
473+ self.assertThat(lambda: wind_component.select_single('QQuickText', objectName='WeatherDetailValue'), Eventually(Not(Is(None))))
474+ wind_value = wind_component.select_single('QQuickText', objectName='WeatherDetailValue')
475 if wind_units == "mph":
476 self.assertThat(wind_unit.text, Eventually(Equals(u'mph SE')))
477 self.assertThat(wind_value.text, Eventually(Equals(u'9')))
478@@ -63,12 +63,12 @@
479
480 def _check_precipitation_units(self, pre_units):
481 """Checks selected units by values from the first location tab"""
482- self.assertThat(lambda: self.main_window.get_objects('WeatherDetailComponent', 'PrecipitationValue')[0], Eventually(Not(Is(None))))
483- component = self.main_window.get_objects('WeatherDetailComponent', 'PrecipitationValue')[0]
484- self.assertThat(lambda: component.get_object('QQuickText', 'WeatherDetailUnit'), Eventually(Not(Is(None))))
485- unit = component.get_object('QQuickText', 'WeatherDetailUnit')
486- self.assertThat(lambda: component.get_object('QQuickText', 'WeatherDetailValue'), Eventually(Not(Is(None))))
487- value = component.get_object('QQuickText', 'WeatherDetailValue')
488+ self.assertThat(lambda: self.main_window.select_many('WeatherDetailComponent', objectName='PrecipitationValue')[0], Eventually(Not(Is(None))))
489+ component = self.main_window.select_many('WeatherDetailComponent', objectName='PrecipitationValue')[0]
490+ self.assertThat(lambda: component.select_many('QQuickText', objectName='WeatherDetailUnit'), Eventually(Not(Is(None))))
491+ unit = component.select_single('QQuickText', objectName='WeatherDetailUnit')
492+ self.assertThat(lambda: component.select_single('QQuickText', objectName='WeatherDetailValue'), Eventually(Not(Is(None))))
493+ value = component.select_single('QQuickText', objectName='WeatherDetailValue')
494 if pre_units == "in":
495 self.assertThat(unit.text, Eventually(Equals(u'in')))
496 self.assertThat(value.text, Eventually(Equals(u'0.18')))
497@@ -83,8 +83,8 @@
498 self._open_settings_sheet()
499
500 # open the value selector
501- self.assertThat(lambda: self.main_window.get_object('OptionSelector', 'UnitsSelector'), Eventually(Not(Is(None))))
502- units_selector = self.main_window.get_object('OptionSelector', "UnitsSelector")
503+ self.assertThat(lambda: self.main_window.select_single('OptionSelector', objectName='UnitsSelector'), Eventually(Not(Is(None))))
504+ units_selector = self.main_window.select_single('OptionSelector', objectName="UnitsSelector")
505 self.assertThat(units_selector.selectedIndex, Eventually(Equals(0)))
506 self.assertThat(lambda: units_selector.select_many('ShapeItem')[1], Eventually(Not(Is(None))))
507 current_option = units_selector.select_many('ShapeItem')[1]
508@@ -99,14 +99,14 @@
509 self._click_sheet_confirm()
510
511 # wait for reload and check the imperial values
512- load_indicator = self.main_window.get_object('ActivityIndicator', 'LoadingSpinner')
513+ load_indicator = self.main_window.select_single('ActivityIndicator', objectName='LoadingSpinner')
514 self.assertThat(load_indicator.running, Eventually(Equals(False)))
515 self._check_units('imperial')
516
517 # switch back to metric values again
518 self._open_settings_sheet()
519- self.assertThat(lambda: self.main_window.get_object('OptionSelector', 'UnitsSelector'), Eventually(Not(Is(None))))
520- units_selector = self.main_window.get_object('OptionSelector', "UnitsSelector")
521+ self.assertThat(lambda: self.main_window.select_single('OptionSelector', objectName='UnitsSelector'), Eventually(Not(Is(None))))
522+ units_selector = self.main_window.select_single('OptionSelector', objectName="UnitsSelector")
523 self.assertThat(units_selector.selectedIndex, Eventually(Equals(1)))
524 self.assertThat(lambda: units_selector.select_many('ShapeItem')[2], Eventually(Not(Is(None))))
525 current_option = units_selector.select_many('ShapeItem')[2]
526@@ -125,7 +125,7 @@
527 self._click_sheet_confirm()
528
529 # wait for reload and check the metric values again
530- load_indicator = self.main_window.get_object('ActivityIndicator', 'LoadingSpinner')
531+ load_indicator = self.main_window.select_single('ActivityIndicator', objectName='LoadingSpinner')
532 self.assertThat(load_indicator.running, Eventually(Equals(False)))
533 self._check_units('metric')
534
535@@ -137,8 +137,8 @@
536 self._open_settings_sheet()
537
538 # open the temp value selector
539- self.assertThat(lambda: self.main_window.get_object('OptionSelector', 'UnitsSelector'), Eventually(Not(Is(None))))
540- units_selector = self.main_window.get_object('OptionSelector', "UnitsSelector")
541+ self.assertThat(lambda: self.main_window.select_single('OptionSelector', objectName='UnitsSelector'), Eventually(Not(Is(None))))
542+ units_selector = self.main_window.select_single('OptionSelector', objectName="UnitsSelector")
543 self.assertThat(units_selector.selectedIndex, Eventually(Equals(0)))
544 self.assertThat(lambda: units_selector.select_many('ShapeItem')[1], Eventually(Not(Is(None))))
545 current_option = units_selector.select_many('ShapeItem')[1]
546@@ -152,8 +152,8 @@
547 self.assertThat(units_selector.selectedIndex, Eventually(Equals(1)))
548
549 # open the wind value selector
550- self.assertThat(lambda: self.main_window.get_object('OptionSelector', 'WindUnitsSelector'), Eventually(Not(Is(None))))
551- units_selector = self.main_window.get_object('OptionSelector', "WindUnitsSelector")
552+ self.assertThat(lambda: self.main_window.select_single('OptionSelector', objectName='WindUnitsSelector'), Eventually(Not(Is(None))))
553+ units_selector = self.main_window.select_single('OptionSelector', objectName="WindUnitsSelector")
554 self.assertThat(units_selector.selectedIndex, Eventually(Equals(0)))
555 self.pointing_device.click_object(units_selector)
556
557@@ -176,8 +176,8 @@
558 self._open_settings_sheet()
559
560 # open the wind value selector
561- self.assertThat(lambda: self.main_window.get_object('OptionSelector', 'WindUnitsSelector'), Eventually(Not(Is(None))))
562- units_selector = self.main_window.get_object('OptionSelector', "WindUnitsSelector")
563+ self.assertThat(lambda: self.main_window.select_single('OptionSelector', objectName='WindUnitsSelector'), Eventually(Not(Is(None))))
564+ units_selector = self.main_window.select_single('OptionSelector', objectName="WindUnitsSelector")
565 self.assertThat(units_selector.selectedIndex, Eventually(Equals(0)))
566 self.assertThat(lambda: units_selector.select_many('ShapeItem')[1], Eventually(Not(Is(None))))
567 current_option = units_selector.select_many('ShapeItem')[1]
568@@ -192,14 +192,14 @@
569 self._click_sheet_confirm()
570
571 # wait for reload and check the mph values
572- load_indicator = self.main_window.get_object('ActivityIndicator', 'LoadingSpinner')
573+ load_indicator = self.main_window.select_single('ActivityIndicator', objectName='LoadingSpinner')
574 self.assertThat(load_indicator.running, Eventually(Equals(False)))
575 self._check_wind_units('mph')
576
577 # switch back to kmh values again
578 self._open_settings_sheet()
579- self.assertThat(lambda: self.main_window.get_object('OptionSelector', 'WindUnitsSelector'), Eventually(Not(Is(None))))
580- units_selector = self.main_window.get_object('OptionSelector', "WindUnitsSelector")
581+ self.assertThat(lambda: self.main_window.select_single('OptionSelector', objectName='WindUnitsSelector'), Eventually(Not(Is(None))))
582+ units_selector = self.main_window.select_single('OptionSelector', objectName="WindUnitsSelector")
583 self.assertThat(units_selector.selectedIndex, Eventually(Equals(1)))
584 self.assertThat(lambda: units_selector.select_many('ShapeItem')[2], Eventually(Not(Is(None))))
585 current_option = units_selector.select_many('ShapeItem')[2]
586@@ -218,7 +218,7 @@
587 self._click_sheet_confirm()
588
589 # wait for reload and check the metric values again
590- load_indicator = self.main_window.get_object('ActivityIndicator', 'LoadingSpinner')
591+ load_indicator = self.main_window.select_single('ActivityIndicator', objectName='LoadingSpinner')
592 self.assertThat(load_indicator.running, Eventually(Equals(False)))
593 self._check_wind_units('kmh')
594
595@@ -229,8 +229,8 @@
596 self._open_settings_sheet()
597
598 # open the precipitation value selector
599- self.assertThat(lambda: self.main_window.get_object('OptionSelector', 'PrecipitationUnitsSelector'), Eventually(Not(Is(None))))
600- units_selector = self.main_window.get_object('OptionSelector', "PrecipitationUnitsSelector")
601+ self.assertThat(lambda: self.main_window.select_single('OptionSelector', objectName='PrecipitationUnitsSelector'), Eventually(Not(Is(None))))
602+ units_selector = self.main_window.select_single('OptionSelector', objectName="PrecipitationUnitsSelector")
603 self.assertThat(units_selector.selectedIndex, Eventually(Equals(0)))
604 self.assertThat(lambda: units_selector.select_many('ShapeItem')[1], Eventually(Not(Is(None))))
605 current_option = units_selector.select_many('ShapeItem')[1]
606@@ -245,14 +245,14 @@
607 self._click_sheet_confirm()
608
609 # wait for reload and check the inch values
610- load_indicator = self.main_window.get_object('ActivityIndicator', 'LoadingSpinner')
611+ load_indicator = self.main_window.select_single('ActivityIndicator', objectName='LoadingSpinner')
612 self.assertThat(load_indicator.running, Eventually(Equals(False)))
613 self._check_wind_units('in')
614
615 # switch back to mm values again
616 self._open_settings_sheet()
617- self.assertThat(lambda: self.main_window.get_object('OptionSelector', 'PrecipitationUnitsSelector'), Eventually(Not(Is(None))))
618- units_selector = self.main_window.get_object('OptionSelector', "PrecipitationUnitsSelector")
619+ self.assertThat(lambda: self.main_window.select_single('OptionSelector', objectName='PrecipitationUnitsSelector'), Eventually(Not(Is(None))))
620+ units_selector = self.main_window.select_single('OptionSelector', objectName="PrecipitationUnitsSelector")
621 self.assertThat(units_selector.selectedIndex, Eventually(Equals(1)))
622 self.assertThat(lambda: units_selector.select_many('ShapeItem')[2], Eventually(Not(Is(None))))
623 current_option = units_selector.select_many('ShapeItem')[2]
624@@ -271,7 +271,7 @@
625 self._click_sheet_confirm()
626
627 # wait for reload and check the metric values again
628- load_indicator = self.main_window.get_object('ActivityIndicator', 'LoadingSpinner')
629+ load_indicator = self.main_window.select_single('ActivityIndicator', objectName='LoadingSpinner')
630 self.assertThat(load_indicator.running, Eventually(Equals(False)))
631 self._check_precipitation_units('mm')
632

Subscribers

People subscribed via source and target branches