@@ -1,555 +0,0 @@
1−# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2−#
3−# Unity Autopilot Test Suite
4−# Copyright (C) 2015 Canonical
5−#
6−# This program is free software: you can redistribute it and/or modify
7−# it under the terms of the GNU General Public License as published by
8−# the Free Software Foundation, either version 3 of the License, or
9−# (at your option) any later version.
10−#
11−# This program is distributed in the hope that it will be useful,
12−# but WITHOUT ANY WARRANTY; without even the implied warranty of
13−# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14−# GNU General Public License for more details.
15−#
16−# You should have received a copy of the GNU General Public License
17−# along with this program. If not, see <http://www.gnu.org/licenses/>.
18−#
19−
20−import logging
21−import re
22−
23−import autopilot
24−from autopilot import introspection
25−from ubuntuuitoolkit import UbuntuUIToolkitCustomProxyObjectBase
26−
27−from contextlib import contextmanager
28−
29−
30−logger = logging.getLogger(__name__)
31−
32−
33−@contextmanager
34−def override_proxy_timeout(proxy, timeout_seconds):
35− original_timeout = proxy._poll_time
36− try:
37− proxy._poll_time = timeout_seconds
38− yield proxy
39− finally:
40− proxy._poll_time = original_timeout
41−
42−
43−def get_wizard(current_page):
44− return current_page.get_root_instance().select_single(Wizard)
45−
46−
47−class Wizard(UbuntuUIToolkitCustomProxyObjectBase):
48− """High-level helper to navigate through the pages of the wizard"""
49−
50− def get_language_page(self):
51− return self.wait_select_single(
52− objectName='languagePage', visible='True')
53−
54− def get_current_page(self):
55− return self.wait_select_single('Page', visible='True')
56−
57− def get_sim_page(self):
58− return self.wait_select_single(
59− objectName='simPage', visible='True')
60−
61− def get_password_page(self):
62− return self.wait_select_single(
63− objectName='passwdPage', visible='True')
64−
65− def get_password_entry_page(self):
66− return self.wait_select_single(
67− objectName='passwdSetPage', visible='True')
68−
69− def get_confirm_password_page(self):
70− return self.wait_select_single(
71− objectName='passwdConfirmPage', visible='True')
72−
73− def get_wifi_connect_page(self):
74− return self.wait_select_single(
75− objectName='wifiPage', visible='True')
76−
77− def get_location_page(self):
78− return self.wait_select_single(
79− objectName='locationPage', visible='True')
80−
81− def get_reporting_page(self):
82− return self.wait_select_single(
83− objectName='reportingPage', visible='True')
84−
85− def get_finished_page(self):
86− return self.wait_select_single(
87− objectName='finishedPage', visible='True')
88−
89−
90−class WizardLanguagePage(UbuntuUIToolkitCustomProxyObjectBase):
91− """Helper class to interact with the language welcome page"""
92−
93− # This class was renamed from LanguagePage to WizardLanguagePage because
94− # there is a class with the same name in the system settings custom proxy
95− # objects. Reported in http://pad.lv/1422904. --elopio - 2015-02-17
96−
97− @classmethod
98− def validate_dbus_object(cls, path, state):
99− name = introspection.get_classname_from_path(path)
100− if name == b'Page':
101− if state['objectName'][1] == 'languagePage':
102− return True
103− return False
104−
105− def _get_language_button(self):
106− return self.select_single(
107− 'ComboButton', objectName='languageCombo')
108−
109− def _get_continue_button(self):
110− return self.select_single('StackButton', text='Continue')
111−
112− def _swipe_to_language(self, list, language):
113− """Swipe to the chosen language in the given list"""
114− list.swipe_to_top()
115− while not list.atYEnd:
116− try:
117− item = list.select_single(
118− 'LabelVisual', text=language, visible='True')
119− item.swipe_into_view()
120− return item
121− except introspection.dbus.StateNotFoundError:
122− list.swipe_to_show_more_below()
123− # item could not be found
124− raise introspection.dbus.StateNotFoundError
125−
126− @autopilot.logging.log_action(logger.info)
127− def select_language(self, language):
128− """Select a different language from the list"""
129− combo_button = self._get_language_button()
130− self.pointing_device.click_object(combo_button)
131− language_list = combo_button.wait_select_single(
132− 'UbuntuListView11', visible='True')
133− item = self._swipe_to_language(language_list, language)
134− self.pointing_device.click_object(item)
135−
136− def get_selected_language(self):
137− return self._get_language_button().get_properties()['text']
138−
139− @autopilot.logging.log_action(logger.info)
140− def continue_(self):
141− self.pointing_device.click_object(self._get_continue_button())
142− wizard = get_wizard(self)
143− next_page = wizard.get_current_page()
144− sim_inserted = True
145− if next_page.objectName == 'simPage':
146− # no sim is inserted
147− next_page = wizard.get_sim_page()
148− sim_inserted = False
149− else:
150− # sim is inserted
151− next_page = wizard.get_password_page()
152− return sim_inserted, next_page
153−
154−
155−class SimPage(UbuntuUIToolkitCustomProxyObjectBase):
156− """Helper class to interact with the no sim notification page"""
157−
158− @classmethod
159− def validate_dbus_object(cls, path, state):
160− name = introspection.get_classname_from_path(path)
161− if name == b'Page':
162− if state['objectName'][1] == 'simPage':
163− return True
164− return False
165−
166− def _get_back_button(self):
167− return self.select_single('StackButton', text='Back')
168−
169− def _get_skip_button(self):
170− return self.select_single('StackButton', text='Skip')
171−
172− @autopilot.logging.log_action(logger.info)
173− def back(self):
174− self.pointing_device.click_object(self._get_back_button())
175− return get_wizard(self).get_languge_page()
176−
177− @autopilot.logging.log_action(logger.info)
178− def skip(self):
179− self.pointing_device.click_object(self._get_skip_button())
180− return get_wizard(self).get_password_page()
181−
182−
183−class PasswordPage(UbuntuUIToolkitCustomProxyObjectBase):
184− """Helper class to interact with the password security page"""
185−
186− SECURITY_SWIPE = 'Swipe'
187− SECURITY_PASSCODE = 'Passcode'
188− SECURITY_PASSPHRASE = 'Passphrase'
189−
190− @classmethod
191− def validate_dbus_object(cls, path, state):
192− name = introspection.get_classname_from_path(path)
193− if name == b'Page':
194− if state['objectName'][1] == 'passwdPage':
195− return True
196− return False
197−
198− def _get_option_name(self, formatted_name):
199− # the option name is formatted as follows:
200− # need to read the name between bold tags
201− # '<b>Passcode</b> (4 digits only)'
202− formatted_pattern = re.compile(r'<b>(.*?)</b>.*',
203− re.IGNORECASE | re.DOTALL)
204− name = None
205− match = formatted_pattern.search(formatted_name)
206− if match:
207− name = match.group(1)
208− return name
209−
210− def _get_all_options(self):
211− return self.select_many('OptionSelectorDelegate')
212−
213− def _get_continue_button(self):
214− return self.select_single('StackButton', text='Continue')
215−
216− def _get_back_button(self):
217− return self.select_single('StackButton', text='Back')
218−
219− def _get_selected_option(self):
220− return self.select_single(
221− 'OptionSelectorDelegate', visible='True', selected='True')
222−
223− def get_selected_security_option(self):
224− name_fmt = self._get_selected_option().get_properties()['subText']
225− return self._get_option_name(name_fmt)
226−
227− @autopilot.logging.log_action(logger.info)
228− def select_security_option(self, selected_option):
229− options = self._get_all_options()
230− for option in options:
231− name = self._get_option_name(option.get_properties()['subText'])
232− if name == selected_option:
233− self.pointing_device.click_object(option)
234−
235− @autopilot.logging.log_action(logger.info)
236− def back(self, sim_inserted):
237− self.pointing_device.click_object(self._get_back_button())
238− wizard = get_wizard(self)
239− if sim_inserted:
240− page = wizard.get_languge_page()
241− else:
242− page = wizard.get_sim_page()
243− return page
244−
245− @autopilot.logging.log_action(logger.info)
246− def continue_(self):
247− option = self.get_selected_security_option()
248− self.pointing_device.click_object(self._get_continue_button())
249− wizard = get_wizard(self)
250− if option == self.SECURITY_SWIPE:
251− next_page = wizard.get_wifi_connect_page()
252− else:
253− next_page = wizard.get_password_entry_page()
254− return next_page
255−
256−
257−class PasswordEntryPage(UbuntuUIToolkitCustomProxyObjectBase):
258− """Helper class to interact with the pin entry page"""
259−
260− @classmethod
261− def validate_dbus_object(cls, path, state):
262− name = introspection.get_classname_from_path(path)
263− if name == b'Page':
264− if state['objectName'][1] == 'passwdSetPage':
265− return True
266− return False
267−
268− def _get_pinpad_button(self, char):
269− return self.select_single('PinPadButton', text=char)
270−
271− def _get_continue_button(self):
272− return self.select_single('StackButton', text='Continue')
273−
274− def _get_back_button(self):
275− return self.select_single('StackButton', text='Back')
276−
277− def _get_text_field(self):
278− return self.select_single('QQuickTextInput')
279−
280− @autopilot.logging.log_action(logger.info)
281− def enter_pin(self, pin):
282− for char in pin:
283− self.pointing_device.click_object(self._get_pinpad_button(char))
284− return get_wizard(self).get_confirm_password_page()
285−
286− @autopilot.logging.log_action(logger.info)
287− def enter_text(self, text):
288− self.pointing_device.click_object(self._get_text_field())
289− autopilot.input.Keyboard.create().type(text)
290−
291− @autopilot.logging.log_action(logger.info)
292− def back(self):
293− self.pointing_device.click_object(self._get_back_button())
294− return get_wizard(self).get_password_page()
295−
296− @autopilot.logging.log_action(logger.info)
297− def continue_(self):
298− autopilot.input.Keyboard.create().press_and_release('Enter')
299− return get_wizard(self).get_confirm_password_page()
300−
301−
302−class ConfirmPasswordPage(UbuntuUIToolkitCustomProxyObjectBase):
303− """Helper class to interact with the pin confirmation page"""
304−
305− @classmethod
306− def validate_dbus_object(cls, path, state):
307− name = introspection.get_classname_from_path(path)
308− if name == b'Page':
309− if state['objectName'][1] == 'passwdConfirmPage':
310− return True
311− return False
312−
313− def _get_pinpad_button(self, char):
314− return self.select_single('PinPadButton', text=char)
315−
316− def _get_continue_button(self):
317− return self.select_single('StackButton', text='Continue')
318−
319− def _get_back_button(self):
320− return self.select_single('StackButton', text='Back')
321−
322− def _get_text_field(self):
323− return self.select_single('QQuickTextInput')
324−
325− @autopilot.logging.log_action(logger.info)
326− def enter_pin(self, pin):
327− for char in pin:
328− self.pointing_device.click_object(self._get_pinpad_button(char))
329− return get_wizard(self).get_wifi_connect_page()
330−
331− @autopilot.logging.log_action(logger.info)
332− def enter_text(self, text):
333− self.pointing_device.click_object(self._get_text_field())
334− autopilot.input.Keyboard.create().type(text)
335−
336− @autopilot.logging.log_action(logger.info)
337− def back(self):
338− self.pointing_device.click_object(self._get_back_button())
339− return get_wizard(self).get_password_page()
340−
341− @autopilot.logging.log_action(logger.info)
342− def continue_(self):
343− autopilot.input.Keyboard.create().press_and_release('Enter')
344− return get_wizard(self).get_wifi_connect_page()
345−
346−
347−class WifiConnectPage(UbuntuUIToolkitCustomProxyObjectBase):
348− """Helper class to interact with the Wi-Fi network list page"""
349−
350− @classmethod
351− def validate_dbus_object(cls, path, state):
352− name = introspection.get_classname_from_path(path)
353− if name == b'Page':
354− if state['objectName'][1] == 'wifiPage':
355− return True
356− return False
357−
358− def _get_all_networks(self):
359− try:
360− networks = self.select_many('Standard', objectName='accessPoint',
361− visible='True')
362− except:
363− networks = []
364− return networks
365−
366− def _get_network(self, ssid):
367− return self.wait_select_single(
368− 'Standard', objectName='accessPoint', text=ssid, visible='True')
369−
370− def _get_network_checkbox(self, ssid):
371− return self._get_network(ssid).select_single(
372− 'CheckBox', visible='True')
373−
374− def _get_next_page(self):
375− wizard = get_wizard(self)
376− next_page = wizard.get_current_page()
377− locationPageEnabled = True
378− reportingPageEnabled = True
379− if next_page.objectName == 'locationPage':
380− next_page = wizard.get_location_page()
381− else:
382− locationPageEnabled = False
383− if next_page.objectName == 'reportingPage':
384− next_page = wizard.get_reporting_page()
385− else:
386− reportingPageEnabled = False
387− next_page = wizard.get_finished_page()
388− return locationPageEnabled, reportingPageEnabled, next_page
389−
390− def _get_notification(self, unity):
391− logger.info('Waiting longer for notification object')
392− with override_proxy_timeout(unity, 30):
393− return unity.wait_select_single(
394− Notification, objectName='notification1', visible='True')
395−
396− def _get_back_button(self):
397− return self.wait_select_single(
398− 'StackButton', text='Back', visible='True')
399−
400− def _get_continue_button(self):
401− return self.wait_select_single(
402− 'StackButton', text='Continue', visible='True')
403−
404− def _get_skip_button(self):
405− return self.wait_select_single(
406− 'StackButton', text='Skip', visible='True')
407−
408− def is_any_network_checked(self):
409− networks = self._get_all_networks()
410− for network in networks:
411− checkbox = network.select_single('CheckBox', visible='True')
412− if checkbox.get_properties()['checked']:
413− return True
414− return False
415−
416− def is_any_network_found(self):
417− num_neworks = len(self._get_all_networks())
418− return True if num_neworks > 0 else False
419−
420− def is_network_checked(self, ssid):
421− return self._get_network_checkbox(ssid).get_properties()['checked']
422−
423− @autopilot.logging.log_action(logger.info)
424− def select_network(self, unity, ssid):
425− self.pointing_device.click_object(self._get_network_checkbox(ssid))
426− return PasswordNotification(self._get_notification(unity))
427−
428− @autopilot.logging.log_action(logger.info)
429− def back(self):
430− self.pointing_device.click_object(self._get_back_button())
431− return get_wizard(self).get_password_page()
432−
433− @autopilot.logging.log_action(logger.info)
434− def skip(self):
435− self.pointing_device.click_object(self._get_skip_button())
436− return self._get_next_page()
437−
438− @autopilot.logging.log_action(logger.info)
439− def continue_(self):
440− self.pointing_device.click_object(self._get_continue_button())
441− return self._get_next_page()
442−
443−
444−class LocationPage(UbuntuUIToolkitCustomProxyObjectBase):
445− """Helper class to interact with the LocationPage"""
446−
447− @classmethod
448− def validate_dbus_object(cls, path, state):
449− name = introspection.get_classname_from_path(path)
450− if name == b'Page':
451− if state['objectName'][1] == 'locationPage':
452− return True
453− return False
454−
455− def _get_back_button(self):
456− return self.select_single('StackButton', text='Back')
457−
458− def _get_continue_button(self):
459− return self.select_single('StackButton', text='Continue')
460−
461− @autopilot.logging.log_action(logger.info)
462− def back(self):
463− self.pointing_device.click_object(self._get_back_button())
464− return get_wizard(self).get_wifi_connect_page()
465−
466− @autopilot.logging.log_action(logger.info)
467− def continue_(self):
468− self.pointing_device.click_object(self._get_continue_button())
469− return get_wizard(self).get_reporting_page()
470−
471−
472−class Notification(UbuntuUIToolkitCustomProxyObjectBase):
473− """Base class for notification objects"""
474− pass
475−
476−
477−class PasswordNotification(Notification):
478− """Helper class to interact with the password entry notification"""
479−
480− def __init__(self, notification):
481− self.notification = notification
482−
483− def _get_connect_button(self):
484− return self.notification.wait_select_single(
485− 'Button', text='Connect', objectName='notify_button0')
486−
487− def _get_cancel_buttoon(self):
488− return self.notification.wait_select_single(
489− 'Button', text='Cancel', objectName='notify_button1')
490−
491− def _get_text_field(self):
492− return self.notification.wait_select_single('TextField')
493−
494− @autopilot.logging.log_action(logger.info)
495− def enter_text(self, text):
496− self._get_text_field().write(text)
497−
498− @autopilot.logging.log_action(logger.info)
499− def connect(self):
500− self.notification.pointing_device.click_object(
501− self._get_connect_button())
502−
503− @autopilot.logging.log_action(logger.info)
504− def cancel(self):
505− self.notification.pointing_device.click_object(
506− self._get_cancel_buttoon())
507−
508−
509−class ReportingPage(UbuntuUIToolkitCustomProxyObjectBase):
510− """Helper class to interact with the reporting page"""
511−
512− @classmethod
513− def validate_dbus_object(cls, path, state):
514− name = introspection.get_classname_from_path(path)
515− if name == b'Page':
516− if state['objectName'][1] == 'reportingPage':
517− return True
518− return False
519−
520− def _get_continue_button(self):
521− return self.select_single('StackButton', text='Continue')
522−
523− def _get_back_button(self):
524− return self.select_single('StackButton', text='Back')
525−
526− @autopilot.logging.log_action(logger.info)
527− def back(self):
528− self.pointing_device.click_object(self._get_back_button())
529− return get_wizard(self).get_wifi_connect_page()
530−
531− @autopilot.logging.log_action(logger.info)
532− def continue_(self):
533− self.pointing_device.click_object(self._get_continue_button())
534− return get_wizard(self).get_finished_page()
535−
536−
537−class FinishedPage(UbuntuUIToolkitCustomProxyObjectBase):
538− """Helper class to interact with the finished page"""
539−
540− @classmethod
541− def validate_dbus_object(cls, path, state):
542− name = introspection.get_classname_from_path(path)
543− if name == b'Page':
544− if state['objectName'][1] == 'finishedPage':
545− return True
546− return False
547−
548− def _get_finish_button(self):
549− return self.wait_select_single(
550− 'StackButton', text='Finish', visible='True')
551−
552− @autopilot.logging.log_action(logger.info)
553− def finish(self):
554− self.pointing_device.click_object(self._get_finish_button())
555− self.wait_until_destroyed()