Merge lp:~veebers/stock-ticker-mobile-app/mock-server-for-testing into lp:stock-ticker-mobile-app
- mock-server-for-testing
- Merge into trunk
Proposed by
Christopher Lee
Status: | Superseded |
---|---|
Proposed branch: | lp:~veebers/stock-ticker-mobile-app/mock-server-for-testing |
Merge into: | lp:stock-ticker-mobile-app |
Diff against target: |
637 lines (+293/-75) 9 files modified
Add_Stocks_page.qml (+2/-2) Current_charts_page.qml (+1/-0) Stock_Ticker.qml (+31/-4) tests/autopilot/stock_ticker/emulators.py (+20/-18) tests/autopilot/stock_ticker/mock_data_server.py (+144/-0) tests/autopilot/stock_ticker/tests/__init__.py (+21/-10) tests/autopilot/stock_ticker/tests/test_Management_page.py (+17/-12) tests/autopilot/stock_ticker/tests/test_Subtabs.py (+49/-27) tests/autopilot/stock_ticker/tests/test_Toolbar_actions.py (+8/-2) |
To merge this branch: | bzr merge lp:~veebers/stock-ticker-mobile-app/mock-server-for-testing |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stock Ticker Developers | Pending | ||
Review via email: mp+194969@code.launchpad.net |
This proposal has been superseded by a proposal from 2013-11-13.
Commit message
Introduce a mock http server for use in testing
Description of the change
Introduce a mock http server for use in testing (no need to hit external network).
Modify application so that it can take a data source url as an argument (enabling use of the mock server).
To post a comment you must log in.
Unmerged revisions
- 76. By Christopher Lee
-
Initial server working
- 75. By Christopher Lee
-
Further additions to assist in mocking server.
- 74. By Christopher Lee
-
Enable being able to use a different datasource.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Add_Stocks_page.qml' |
2 | --- Add_Stocks_page.qml 2013-08-28 03:15:07 +0000 |
3 | +++ Add_Stocks_page.qml 2013-11-13 01:54:57 +0000 |
4 | @@ -27,6 +27,7 @@ |
5 | property string active_search_tick: "" |
6 | property string before_after_space: "00" |
7 | // This is used as two varibles > 0 is for has space at begining of line in `function update_search_text` |
8 | + property string dataServerUrl: "http://d.yimg.com/autoc.finance.yahoo.com/" // Can be overwritten for testing. |
9 | |
10 | Timer { |
11 | id: reloadTrigger |
12 | @@ -55,7 +56,6 @@ |
13 | |
14 | function text_change_handler() { |
15 | log("text_change_handler()") |
16 | - |
17 | // Find the current word the user is editing by spaces before and after current word at cursor |
18 | var cursor_to_end = addStockTextField.text.substr(addStockTextField.cursorPosition).split(' ') |
19 | var cursor_to_begining = addStockTextField.text.substr(0, addStockTextField.cursorPosition+cursor_to_end[0].length).split(' ') |
20 | @@ -73,7 +73,7 @@ |
21 | matchIndicator = true |
22 | active_search_tick = search_word |
23 | before_after_space = before_after |
24 | - xhr.open("GET","http://d.yimg.com/autoc.finance.yahoo.com/autoc?query="+search_word+"&callback=YAHOO.Finance.SymbolSuggest.ssCallback", true); |
25 | + xhr.open("GET", dataServerUrl + "autoc?query="+search_word+"&callback=YAHOO.Finance.SymbolSuggest.ssCallback", true); |
26 | xhr.onreadystatechange = function() |
27 | { |
28 | if ( xhr.readyState == xhr.DONE) { |
29 | |
30 | === modified file 'Current_charts_page.qml' |
31 | --- Current_charts_page.qml 2013-09-04 01:51:45 +0000 |
32 | +++ Current_charts_page.qml 2013-11-13 01:54:57 +0000 |
33 | @@ -20,6 +20,7 @@ |
34 | import "javascript/graph.js" as Graph |
35 | |
36 | Rectangle { |
37 | + objectName: "chartDetails" |
38 | property var canvas_object |
39 | onVisibleChanged: visible && displayDayInfo() |
40 | // color: "#FCFCFC" |
41 | |
42 | === modified file 'Stock_Ticker.qml' |
43 | --- Stock_Ticker.qml 2013-10-09 20:13:18 +0000 |
44 | +++ Stock_Ticker.qml 2013-11-13 01:54:57 +0000 |
45 | @@ -24,6 +24,17 @@ |
46 | |
47 | |
48 | MainView { |
49 | + Arguments { |
50 | + id: args |
51 | + |
52 | + Argument { |
53 | + name: "dataserver" |
54 | + help: "Server to use for retrieving data (Useful for testing.)" |
55 | + required: false |
56 | + valueNames: ["URL"] |
57 | + } |
58 | + } |
59 | + |
60 | // objectName for functional testing purposes (autopilot-qt5) |
61 | objectName: "stockTicker" |
62 | applicationName: "com.ubuntu.stock-ticker-mobile" |
63 | @@ -47,13 +58,26 @@ |
64 | |
65 | property int dummyTextWidth // Holds the width of the percent sign in Stock_Component_Main |
66 | |
67 | - property string serverDomain: "http://www.surgemcgee.com:8080/" |
68 | -// property string serverDomain: "http://localhost:8080/" |
69 | + property string serverDomain: get_data_server() ? get_data_server() : "http://www.surgemcgee.com:8080/" |
70 | + property string dataServer: get_data_server() ? get_data_server() : "http://finance.yahoo.com/" |
71 | |
72 | function log(message) { |
73 | console.log("["+applicationName+"] "+message) |
74 | } |
75 | |
76 | + // If no dataserver argument passed returns undefined, otherwise returns a cleaned up URL. |
77 | + function get_data_server() { |
78 | + var server = args.values.dataserver; |
79 | + if (server === undefined) |
80 | + return undefined |
81 | + if (server.substr(0, 7) !== "http://") |
82 | + server = "http://" + server |
83 | + if (server.slice(-1) !== "/") |
84 | + server += "/" |
85 | + |
86 | + return server |
87 | + } |
88 | + |
89 | property string quoteParams: "?f=sabl1vpghojkc8dre7j1n&s=" |
90 | property var database: new Store.IndurateDatabase({name: "SockTickerMobile", version: "1.0", description: "The Stock Ticker core application database", size: 4}, LocalStorage) |
91 | property var userTable: database.initTable(primaryTable, false, function(msg){ console.log(msg) }) |
92 | @@ -413,7 +437,7 @@ |
93 | |
94 | XmlListModel { |
95 | id: newsFeed |
96 | - source: "http://finance.yahoo.com/rss/headline?s="+chartTick |
97 | + source: dataServer + "rss/headline?s=" +chartTick |
98 | query: "/rss/channel/item" |
99 | XmlRole { name: "title"; query: "title/string()" } |
100 | XmlRole { name: "description"; query: "description/string()" } |
101 | @@ -672,7 +696,10 @@ |
102 | width: parent.width - 10 // Subtract the main program border amount here |
103 | height: parent.height |
104 | anchors.horizontalCenter: parent.horizontalCenter |
105 | - Add_Stocks_page { id: addStocksTab } |
106 | + Add_Stocks_page { |
107 | + id: addStocksTab |
108 | + dataServerUrl: get_data_server() ? get_data_server() : Add_Stocks_page.dataServerUrl |
109 | + } |
110 | } |
111 | } |
112 | } |
113 | |
114 | === modified file 'tests/autopilot/stock_ticker/emulators.py' |
115 | --- tests/autopilot/stock_ticker/emulators.py 2013-10-10 18:51:45 +0000 |
116 | +++ tests/autopilot/stock_ticker/emulators.py 2013-11-13 01:54:57 +0000 |
117 | @@ -19,19 +19,20 @@ |
118 | from ubuntuuitoolkit import emulators as toolkit_emulators |
119 | |
120 | |
121 | -class MainView(toolkit_emulators.MainView): |
122 | +class Stock(toolkit_emulators.MainView): |
123 | |
124 | def move_subtabs_bar_up(self): |
125 | """Moves the subtabs bar to a different location""" |
126 | - qmlView = self.select("QQuickView") |
127 | - sub_bar = self.select("QQuickRectangle", objectName='subTabsBar') |
128 | + sub_bar = self.select_single( |
129 | + "QQuickRectangle", |
130 | + objectName='subTabsBar') |
131 | button_width = sub_bar.select_single( |
132 | 'UbuntuShape', objectName='detailsTab').width |
133 | self.pointing_device.move_to_object(sub_bar) |
134 | |
135 | self.pointing_device.drag( |
136 | self.pointing_device.x-button_width-5, self.pointing_device.y, |
137 | - self.pointing_device.x-button_width-5, qmlView.height*0.3) |
138 | + self.pointing_device.x-button_width-5, self.height*0.3) |
139 | |
140 | def flick_page_up(self, obj): |
141 | """Moves the pointer around the charts sub tab""" |
142 | @@ -61,23 +62,24 @@ |
143 | |
144 | def after_program_fully_loaded(self): |
145 | """ |
146 | - Returns when all of the applications ActivityIndicator.running |
147 | - state is False. |
148 | + Blocks until all of the applications ActivityIndicator.running state |
149 | + are False. |
150 | + |
151 | + :raises AssertionError: if the running states take longer than 10 sec |
152 | + to transition to False |
153 | + |
154 | """ |
155 | |
156 | - add_activity_indicator = self.select( |
157 | + add_activity_indicator = self.select_single( |
158 | 'ActivityIndicator', objectName='addActivityIndicator') |
159 | - current_activity_indicator = self.select( |
160 | + current_activity_indicator = self.select_single( |
161 | 'ActivityIndicator', objectName='currentActivityIndicator') |
162 | - charts_activity_indicator = self.select( |
163 | + charts_activity_indicator = self.select_single( |
164 | 'ActivityIndicator', objectName='chartsActivityIndicator') |
165 | - news_activity_indicator = self.select( |
166 | + news_activity_indicator = self.select_single( |
167 | 'ActivityIndicator', objectName='newsActivityIndicator') |
168 | - self.assertThat(add_activity_indicator.running, |
169 | - Eventually(Equals(False))) |
170 | - self.assertThat(current_activity_indicator.running, |
171 | - Eventually(Equals(False))) |
172 | - self.assertThat(charts_activity_indicator.running, |
173 | - Eventually(Equals(False))) |
174 | - self.assertThat(news_activity_indicator.running, |
175 | - Eventually(Equals(False))) |
176 | + |
177 | + add_activity_indicator.running.wait_for(False) |
178 | + current_activity_indicator.running.wait_for(False) |
179 | + charts_activity_indicator.running.wait_for(False) |
180 | + news_activity_indicator.running.wait_for(False) |
181 | |
182 | === added file 'tests/autopilot/stock_ticker/mock_data_server.py' |
183 | --- tests/autopilot/stock_ticker/mock_data_server.py 1970-01-01 00:00:00 +0000 |
184 | +++ tests/autopilot/stock_ticker/mock_data_server.py 2013-11-13 01:54:57 +0000 |
185 | @@ -0,0 +1,144 @@ |
186 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
187 | +# |
188 | +# Copyright (C) 2013 Canonical Ltd |
189 | +# |
190 | +# This program is free software: you can redistribute it and/or modify |
191 | +# it under the terms of the GNU General Public License version 3 as |
192 | +# published by the Free Software Foundation. |
193 | +# |
194 | +# This program is distributed in the hope that it will be useful, |
195 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
196 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
197 | +# GNU General Public License for more details. |
198 | +# |
199 | +# You should have received a copy of the GNU General Public License |
200 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
201 | + |
202 | +import BaseHTTPServer |
203 | +import errno |
204 | +import os |
205 | +import socket |
206 | +import threading |
207 | +from textwrap import dedent |
208 | +import re |
209 | + |
210 | + |
211 | +class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
212 | + """Simple HTTP request handler that mocks data and requests for testing.""" |
213 | + |
214 | + def _send_xml(self, xml): |
215 | + self.send_response(200) |
216 | + self.send_header("Content-Type", "application/xml") |
217 | + self.end_headers() |
218 | + self.wfile.write( |
219 | + '<?xml version="1.0" encoding="UTF-8"?>{content}'.format( |
220 | + content=xml |
221 | + ) |
222 | + ) |
223 | + |
224 | + def _send_json(self, json): |
225 | + self.send_response(200) |
226 | + self.send_header( |
227 | + "Content-Type", |
228 | + "application/x-javascript; charset=utf-8" |
229 | + ) |
230 | + self.end_headers() |
231 | + self.wfile.write(json) |
232 | + |
233 | + def send_stock_data(self): |
234 | + match_check = re.compile("\&s=[\+]+goo") |
235 | + if match_check.search(self.path) is not None: |
236 | + google_stock_data = dedent( |
237 | + '<stockInfo>' |
238 | + '<currentStats stkent0="GOOG" ' |
239 | + 'stkent1="1040.66" stkent2="1009.50" stkent3="1010.59" ' |
240 | + 'stkent4="1112778" stkent5="1016.03" stkent6="1008.00" ' |
241 | + 'stkent7="1015.93" stkent8="1009.51" stkent9="636.00" ' |
242 | + 'stkent10="1041.52" stkent11="N/A - N/A" stkent12="0.00" ' |
243 | + 'stkent13="27.65" stkent14="44.06" stkent15="337.6B" ' |
244 | + 'stkent16="Google Inc."/>' |
245 | + '</stockInfo>' |
246 | + ) |
247 | + self._send_xml(google_stock_data) |
248 | + else: |
249 | + self._send_xml('<stockInfo></stockInfo>') |
250 | + |
251 | + def send_autocomplete_data(self): |
252 | + """Build up a response for the autocomplete. |
253 | + |
254 | + Pad-out the wanted data with dummy data |
255 | + |
256 | + """ |
257 | + google_result = dedent( |
258 | + '{"symbol":"GOOG","name": "Google Inc.","exch": "NMS","type": "S",' |
259 | + '"exchDisp":"NASDAQ","typeDisp":"Equity"}' |
260 | + ) |
261 | + dummy_result = dedent( |
262 | + '{"symbol":"DUMM","name": "Dummy Inc.","exch": "NMS","type": "S",' |
263 | + '"exchDisp":"NASDAQ","typeDisp":"Equity"}' |
264 | + ) |
265 | + result_list = "{google},{dummies}".format( |
266 | + google=google_result, |
267 | + dummies=",".join([dummy_result for x in range(9)]) |
268 | + ) |
269 | + json = dedent( |
270 | + 'YAHOO.Finance.SymbolSuggest.ssCallback(' |
271 | + '{"ResultSet":{"Query":"goo","Result":' |
272 | + '[' |
273 | + '%s' |
274 | + ']}})' |
275 | + % result_list |
276 | + ) |
277 | + self._send_json(json) |
278 | + |
279 | + def do_GET(self): |
280 | + try: |
281 | + if self.path.startswith("/?f"): |
282 | + self.send_stock_data() |
283 | + elif self.path.startswith("/rss/2.0/headline"): |
284 | + self._send_xml('<rss version="2.0"><channel/></rss>') |
285 | + elif self.path.startswith("/autoc"): |
286 | + self.send_autocomplete_data() |
287 | + else: |
288 | + self.send_response(200) |
289 | + self.end_headers() |
290 | + self.wfile.write("[[[[ UNKNOWN ]]]]") |
291 | + except IOError as e: |
292 | + pass |
293 | + |
294 | +class HTTPServerInAThread(threading.Thread): |
295 | + """Simple custom HTTP server run in a separate thread.""" |
296 | + |
297 | + def __init__(self): |
298 | + super(HTTPServerInAThread, self).__init__() |
299 | + port = 12345 |
300 | + self.server = None |
301 | + while self.server is None: |
302 | + try: |
303 | + self.server = BaseHTTPServer.HTTPServer( |
304 | + ("", port), |
305 | + HTTPRequestHandler |
306 | + ) |
307 | + except socket.error as error: |
308 | + if (error.errno == errno.EADDRINUSE): |
309 | + print "Port %d is already in use" % port |
310 | + port += 1 |
311 | + else: |
312 | + print os.strerror(error.errno) |
313 | + raise |
314 | + self.server.allow_reuse_address = True |
315 | + |
316 | + @property |
317 | + def port(self): |
318 | + return self.server.server_port |
319 | + |
320 | + def run(self): |
321 | + print "now serving on port %d" % self.port |
322 | + self.server.serve_forever() |
323 | + |
324 | + def shutdown(self): |
325 | + self.server.shutdown() |
326 | + self.server.server_close() |
327 | + |
328 | + |
329 | +__all__ = ["HTTPServerInAThread"] |
330 | |
331 | === modified file 'tests/autopilot/stock_ticker/tests/__init__.py' |
332 | --- tests/autopilot/stock_ticker/tests/__init__.py 2013-10-10 18:13:37 +0000 |
333 | +++ tests/autopilot/stock_ticker/tests/__init__.py 2013-11-13 01:54:57 +0000 |
334 | @@ -26,7 +26,7 @@ |
335 | from autopilot.testcase import AutopilotTestCase |
336 | |
337 | from ubuntuuitoolkit import emulators as toolkit_emulators |
338 | -from stock_ticker import emulators |
339 | +from stock_ticker import emulators, mock_data_server |
340 | |
341 | logger = logging.getLogger(__name__) |
342 | |
343 | @@ -41,7 +41,7 @@ |
344 | scenarios = [('with touch', dict(input_device_class=Touch))] |
345 | |
346 | local_location = "../../Stock_Ticker.qml" |
347 | - installed_location = "/usr/share/stock-ticker-mobile-app/Stock_Tickers.qml" |
348 | + installed_location = "/usr/share/stock-ticker-mobile-app/Stock_Ticker.qml" |
349 | sqlite_dir = os.path.expanduser( |
350 | "~/.local/share/com.ubuntu.stock-ticker-mobile/Databases") |
351 | backup_dir = sqlite_dir + ".backup" |
352 | @@ -54,32 +54,43 @@ |
353 | self.temp_move_sqlite_db() |
354 | self.addCleanup(self.restore_sqlite_db) |
355 | |
356 | + self.server = mock_data_server.HTTPServerInAThread() |
357 | + self.server.start() |
358 | + self.addCleanup(self.server.shutdown) |
359 | + |
360 | + url = self._get_data_server_url() |
361 | if os.path.exists(self.local_location): |
362 | - self.launch_test_local() |
363 | + self.launch_test_local(url) |
364 | elif os.path.exists(self.installed_location): |
365 | - self.launch_test_installed() |
366 | + self.launch_test_installed(url) |
367 | else: |
368 | - self.launch_test_click() |
369 | - |
370 | - def launch_test_local(self): |
371 | + self.launch_test_click(url) |
372 | + |
373 | + def _get_data_server_url(self): |
374 | + return "http://localhost:%s" % self.server.port |
375 | + |
376 | + def launch_test_local(self, server_url): |
377 | self.app = self.launch_test_application( |
378 | "qmlscene", |
379 | self.local_location, |
380 | + "--dataserver=%s" % server_url, |
381 | app_type='qt', |
382 | emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase) |
383 | |
384 | - def launch_test_installed(self): |
385 | + def launch_test_installed(self, server_url): |
386 | self.app = self.launch_test_application( |
387 | "qmlscene", |
388 | self.installed_location, |
389 | "--desktop_file_hint=/usr/share/applications/" |
390 | "stock-ticker-app.desktop", |
391 | + "--dataserver=%s" % server_url, |
392 | app_type='qt', |
393 | emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase) |
394 | |
395 | - def launch_test_click(self): |
396 | + def launch_test_click(self, server_url): |
397 | self.app = self.launch_click_package( |
398 | "com.ubuntu.stock-ticker-mobile", |
399 | + "--dataserver=%s" % server_url, |
400 | emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase) |
401 | |
402 | def temp_move_sqlite_db(self): |
403 | @@ -113,4 +124,4 @@ |
404 | |
405 | @property |
406 | def main_view(self): |
407 | - return self.app.select_single(emulators.MainView) |
408 | + return self.app.select_single(emulators.Stock, objectName="stockTicker") |
409 | |
410 | === modified file 'tests/autopilot/stock_ticker/tests/test_Management_page.py' |
411 | --- tests/autopilot/stock_ticker/tests/test_Management_page.py 2013-10-10 18:51:45 +0000 |
412 | +++ tests/autopilot/stock_ticker/tests/test_Management_page.py 2013-11-13 01:54:57 +0000 |
413 | @@ -23,6 +23,7 @@ |
414 | from __future__ import absolute_import |
415 | |
416 | from testtools.matchers import Equals |
417 | +from autopilot.introspection.dbus import StateNotFoundError |
418 | from autopilot.matchers import Eventually |
419 | from stock_ticker.tests import StockTickerTestCase |
420 | |
421 | @@ -95,19 +96,23 @@ |
422 | management_delegate = \ |
423 | management_listview.get_children()[0].get_children() |
424 | |
425 | - cmpy_index = -1 |
426 | + # Find the newly added row and list item. |
427 | + target_row = None |
428 | for o in management_delegate: |
429 | - add_list_item = o.select_single( |
430 | - 'QQuickText', objectName='companyNameText') |
431 | - cmpy_index += 1 |
432 | - if add_list_item and hasattr(add_list_item, 'text'): |
433 | - if add_list_item.text == 'Google Inc.': |
434 | - break |
435 | - |
436 | - self.assertThat(add_list_item.text, Eventually(Equals('Google Inc.'))) |
437 | - |
438 | - remove_button = management_delegate[cmpy_index].select_single( |
439 | - 'QQuickItem', objectName='removeButton') |
440 | + try: |
441 | + o.select_single( |
442 | + 'QQuickText', |
443 | + objectName='companyNameText', |
444 | + text="Google Inc." |
445 | + ) |
446 | + target_row = o |
447 | + break |
448 | + except StateNotFoundError: |
449 | + pass |
450 | + |
451 | + remove_button = target_row.select_single( |
452 | + 'QQuickItem', |
453 | + objectName='removeButton') |
454 | self.pointing_device.click_object(remove_button) |
455 | |
456 | self.assertThat(management_listview.count, |
457 | |
458 | === modified file 'tests/autopilot/stock_ticker/tests/test_Subtabs.py' |
459 | --- tests/autopilot/stock_ticker/tests/test_Subtabs.py 2013-10-10 18:51:45 +0000 |
460 | +++ tests/autopilot/stock_ticker/tests/test_Subtabs.py 2013-11-13 01:54:57 +0000 |
461 | @@ -42,7 +42,7 @@ |
462 | |
463 | tabs = self.app.select_single("Tabs", objectName="rootTabs") |
464 | |
465 | - self.main_view.switch_to_tab(0) |
466 | + self.main_view.switch_to_tab_by_index(0) |
467 | self.assertThat(tabs.selectedTabIndex, Eventually(Equals(0))) |
468 | |
469 | self.main_view.after_program_fully_loaded() |
470 | @@ -54,29 +54,38 @@ |
471 | details_button = sub_bar.select_single( |
472 | 'UbuntuShape', objectName='detailsTab') |
473 | |
474 | - subtab_pages = self.app.select_single( |
475 | - 'QQuickItem', objectName='currentRectSizer').get_children() |
476 | + tabs_container = self.app.select_single( |
477 | + 'QQuickItem', objectName='currentRectSizer') |
478 | + chart_details = tabs_container.select_single( |
479 | + "Current", |
480 | + objectName="chartDetails") |
481 | + details_listview = tabs_container.select_single( |
482 | + "QQuickListView", |
483 | + objectName="detailsListView") |
484 | + |
485 | + # Ensure toolbar is hidden so we can interact with buttons |
486 | + self.main_view.close_toolbar() |
487 | |
488 | self.pointing_device.click_object(details_button) |
489 | - self.assertThat(subtab_pages[2].visible, Eventually(Equals(True))) |
490 | + self.assertThat(details_listview.visible, Eventually(Equals(True))) |
491 | |
492 | self.pointing_device.click_object(charts_button) |
493 | |
494 | - self.assertThat(subtab_pages[2].visible, Eventually(Equals(False))) |
495 | - self.assertThat(subtab_pages[1].visible, Eventually(Equals(True))) |
496 | + self.assertThat(details_listview.visible, Eventually(Equals(False))) |
497 | + self.assertThat(chart_details.visible, Eventually(Equals(True))) |
498 | |
499 | chart_dot = self.app.select_single( |
500 | 'QQuickImage', objectName='chartDot') |
501 | chart_info = self.app.select_single( |
502 | 'QQuickText', objectName='dayInfoText') |
503 | |
504 | - self.pointing_device.click_object(subtab_pages[1]) |
505 | + self.pointing_device.click_object(chart_details) |
506 | |
507 | dot_x = chart_dot.x |
508 | info_text = chart_info.text |
509 | |
510 | self.main_view.move_subtabs_bar_up() |
511 | - self.main_view.flick_page_right(subtab_pages[1]) |
512 | + self.main_view.flick_page_right(chart_details) |
513 | |
514 | self.assertThat(chart_dot.x, NotEquals(dot_x)) |
515 | self.assertThat(chart_info.text, NotEquals(info_text)) |
516 | @@ -90,7 +99,7 @@ |
517 | |
518 | tabs = self.app.select_single("Tabs", objectName="rootTabs") |
519 | |
520 | - self.main_view.switch_to_tab(0) |
521 | + self.main_view.switch_to_tab_by_index(0) |
522 | self.assertThat(tabs.selectedTabIndex, Eventually(Equals(0))) |
523 | |
524 | self.main_view.after_program_fully_loaded() |
525 | @@ -103,19 +112,25 @@ |
526 | details_button = sub_bar.select_single( |
527 | 'UbuntuShape', objectName='detailsTab') |
528 | |
529 | - subtab_pages = self.app.select_single( |
530 | - 'QQuickItem', objectName='currentRectSizer').get_children() |
531 | + tabs_container = self.app.select_single( |
532 | + 'QQuickItem', objectName='currentRectSizer') |
533 | + news_listview = tabs_container.select_single( |
534 | + "QQuickListView", |
535 | + objectName="newsListView") |
536 | + details_listview = tabs_container.select_single( |
537 | + "QQuickListView", |
538 | + objectName="detailsListView") |
539 | + |
540 | + # Ensure toolbar is hidden so we can interact with buttons |
541 | + self.main_view.close_toolbar() |
542 | |
543 | self.pointing_device.click_object(news_button) |
544 | - self.assertThat(subtab_pages[3].visible, Eventually(Equals(True))) |
545 | + self.assertThat(news_listview.visible, Eventually(Equals(True))) |
546 | |
547 | self.pointing_device.click_object(details_button) |
548 | |
549 | - self.assertThat(subtab_pages[3].visible, Eventually(Equals(False))) |
550 | - self.assertThat(subtab_pages[2].visible, Eventually(Equals(True))) |
551 | - |
552 | - details_listview = self.app.select_single( |
553 | - 'QQuickListView', objectName='detailsListView') |
554 | + self.assertThat(news_listview.visible, Eventually(Equals(False))) |
555 | + self.assertThat(details_button.visible, Eventually(Equals(True))) |
556 | |
557 | contentY = details_listview.contentY |
558 | |
559 | @@ -123,7 +138,7 @@ |
560 | Eventually(Equals(details_listview.contentY))) |
561 | |
562 | self.main_view.move_subtabs_bar_up() |
563 | - self.main_view.hold_page_down(subtab_pages[2]) |
564 | + self.main_view.hold_page_down(details_listview) |
565 | |
566 | self.assertThat(details_listview.contentY, |
567 | Eventually(NotEquals(contentY))) |
568 | @@ -151,26 +166,33 @@ |
569 | details_button = sub_bar.select_single( |
570 | 'UbuntuShape', objectName='detailsTab') |
571 | |
572 | - subtab_pages = self.app.select_single( |
573 | - 'QQuickItem', objectName='currentRectSizer').get_children() |
574 | + tabs_container = self.app.select_single( |
575 | + 'QQuickItem', |
576 | + objectName='currentRectSizer') |
577 | + |
578 | + news_listview = tabs_container.select_single( |
579 | + "QQuickListView", |
580 | + objectName="newsListView") |
581 | + details_listview = tabs_container.select_single( |
582 | + "QQuickListView", |
583 | + objectName="detailsListView") |
584 | + |
585 | + self.main_view.close_toolbar() |
586 | |
587 | self.pointing_device.click_object(details_button) |
588 | - self.assertThat(subtab_pages[2].visible, Eventually(Equals(True))) |
589 | + self.assertThat(details_listview.visible, Eventually(Equals(True))) |
590 | |
591 | self.pointing_device.click_object(news_button) |
592 | |
593 | - self.assertThat(subtab_pages[2].visible, Eventually(Equals(False))) |
594 | - self.assertThat(subtab_pages[3].visible, Eventually(Equals(True))) |
595 | - |
596 | - news_listview = self.app.select_single( |
597 | - 'QQuickListView', objectName='newsListView') |
598 | + self.assertThat(details_listview.visible, Eventually(Equals(False))) |
599 | + self.assertThat(news_listview.visible, Eventually(Equals(True))) |
600 | |
601 | contentY = news_listview.contentY |
602 | |
603 | self.assertThat(news_listview.contentY, Eventually(Equals(contentY))) |
604 | |
605 | self.main_view.move_subtabs_bar_up() |
606 | - self.main_view.hold_page_down(subtab_pages[3]) |
607 | + self.main_view.hold_page_down(news_listview) |
608 | |
609 | self.assertThat(news_listview.contentY, |
610 | Eventually(NotEquals(contentY))) |
611 | |
612 | === modified file 'tests/autopilot/stock_ticker/tests/test_Toolbar_actions.py' |
613 | --- tests/autopilot/stock_ticker/tests/test_Toolbar_actions.py 2013-10-10 18:51:45 +0000 |
614 | +++ tests/autopilot/stock_ticker/tests/test_Toolbar_actions.py 2013-11-13 01:54:57 +0000 |
615 | @@ -70,7 +70,10 @@ |
616 | reset_dialog = self.app.select_single( |
617 | 'Dialog', objectName='resetDataDialog') |
618 | self.pointing_device.click_object( |
619 | - reset_dialog.select_single('Button', objectName='resetConfirm')) |
620 | + reset_dialog.select_single( |
621 | + 'Button', |
622 | + objectName='resetConfirm', |
623 | + text="Reset Current Profile")) |
624 | |
625 | self.main_view.close_toolbar() |
626 | |
627 | @@ -88,7 +91,10 @@ |
628 | reset_dialog_a = self.app.select_single( |
629 | 'Dialog', objectName='resetDataDialog') |
630 | self.pointing_device.click_object( |
631 | - reset_dialog_a.select_single('Button', objectName='resetConfirm')) |
632 | + reset_dialog_a.select_single( |
633 | + 'Button', |
634 | + objectName='resetConfirm', |
635 | + text="Reset Current Profile")) |
636 | |
637 | self.main_view.close_toolbar() |
638 |