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

No changes to the content.

tests/autopilot/unity8/settings_wizard/tests/test_settings_wizard.pynew file+31
@@ -0,0 +1,31 @@
1+
2+from unity8.settings_wizard import fixture_setup
3+from unity8.settings_wizard.emulators.settings_wizard import Wizard
4+from unity8.shell import tests
5+
6+DEFAULT_LANGUAGE = 'English (United States)'
7+
8+
9+class SkipThroughSettingsWizardTestCase(tests.UnityTestCase):
10+ """ Autopilot test for completing settings wizard """
11+
12+ def setUp(self):
13+ super().setUp()
14+ self.wizard_helper = self.useFixture(
15+ fixture_setup.SettingsWizard(True))
16+ self.unity = self.launch_unity()
17+ self.wizard = self._get_settings_wizard()
18+
19+ def _get_settings_wizard(self):
20+ return self.unity.wait_select_single(Wizard)
21+
22+ def _test_language_page(self):
23+ """ Get the language page, check the default language and continue """
24+ language_page = self.wizard.get_language_page()
25+ default_selection = language_page.get_selected_language()
26+ self.assertEqual(default_selection, DEFAULT_LANGUAGE)
27+ return language_page.continue_()
28+
29+ def test_skipping_through_wizard(self):
30+ """ Most basic test of the settings wizard. Skip all skipable pages """
31+ next_page = self._test_language_page()