Source code for gaiatest.apps.ftu.app

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import re
import time

from marionette_driver import expected, By, Wait
from gaiatest.apps.base import Base
from gaiatest.form_controls.binarycontrol import GaiaBinaryControl


[docs]class Ftu(Base): name = 'FTU' _next_button_locator = (By.ID, 'forward') # Step Languages section _section_languages_locator = (By.ID, 'languages') _listed_languages_locator = (By.CSS_SELECTOR, "#languages ul li") _language_locator = (By.CSS_SELECTOR, "#languages ul li[data-value='%s']") _language_input_locator = (By.CSS_SELECTOR, "#languages ul li gaia-radio[name='language.current'][value='%s']") _selected_language_input_locator = (By.CSS_SELECTOR, "#languages ul li gaia-radio:checked") # Step Cell data section _section_cell_data_locator = (By.ID, 'data_3g') _enable_data_checkbox_locator = (By.ID, 'data-connection-switch') # Step Wifi _section_wifi_locator = (By.ID, 'wifi') _found_wifi_networks_locator = (By.CSS_SELECTOR, 'ul#networks-list li') _password_input_locator = (By.ID, 'wifi_password') _join_network_locator = (By.ID, 'wifi-join-button') _loading_overlay_locator = (By.ID, 'loading-overlay') # Step Date & Time _section_date_time_locator = (By.ID, 'date_and_time') _timezone_continent_locator = (By.CSS_SELECTOR, '#time-form li:nth-child(1) > .change.icon.icon-dialog') _timezone_city_locator = (By.CSS_SELECTOR, '#time-form li:nth-child(2) > .change.icon.icon-dialog') _time_zone_title_locator = (By.ID, 'time-zone-title') # Step Geolocation _section_geolocation_locator = (By.ID, 'geolocation') _enable_geolocation_checkbox_locator = (By.ID, 'geolocation-switch') # Section Import contacts _section_import_contacts_locator = (By.ID, 'import_contacts') _import_from_sim_locator = (By.ID, 'sim-import-button') _sim_import_feedback_locator = (By.ID, 'statusMsg') # Step Firefox Accounts _section_firefox_accounts_locator = (By.ID, 'firefox_accounts') # Section late customization _section_late_customization_locator = (By.ID, 'late_customization') # Section Welcome Browser _section_welcome_browser_locator = (By.ID, 'welcome_browser') _metrics_basic_locator = (By.ID, 'metrics-basic') _metrics_enhanced_locator = (By.ID, 'metrics-enhanced') _metrics_none_locator = (By.ID, 'metrics-none') # Section Privacy Choices _section_browser_privacy_locator = (By.ID, 'browser_privacy') _email_field_locator = (By.CSS_SELECTOR, 'input[type="email"]') # Section Finish _section_finish_locator = (By.ID, 'finish-screen') _skip_tour_button_locator = (By.ID, 'skip-tutorial-button') _take_tour_button_locator = (By.ID, 'lets-go-button') # Section Tour _step_header_locator = (By.ID, 'tutorial-step-title') _tour_next_button_locator = (By.ID, 'forward-tutorial') _tour_back_button_locator = (By.ID, 'back-tutorial') # Section Tutorial Finish _section_tutorial_finish_locator = (By.ID, 'tutorial-finish-tiny') _lets_go_button_locator = (By.ID, 'tutorialFinished') # Pattern for import sim contacts message _pattern_contacts = re.compile("^No contacts detected on SIM to import$|^Imported one contact$|^Imported [0-9]+ contacts$") _pattern_contacts_0 = re.compile("^No contacts detected on SIM to import$") _pattern_contacts_1 = re.compile("^Imported one contact$") _pattern_contacts_N = re.compile("^Imported ([0-9]+) contacts$")
[docs] def launch(self): Base.launch(self) Wait(self.marionette).until(expected.element_displayed(*self._section_languages_locator))
@property def languages_list(self): return len(self.marionette.find_elements(*self._listed_languages_locator)) @property def selected_language(self): return self.marionette.find_element(*self._selected_language_input_locator).get_attribute( 'value')
[docs] def tap_language(self, language): self.marionette.find_element(self._language_locator[0], self._language_locator[1] % language).tap()
[docs] def a11y_click_language(self, language): self.accessibility.click(self.marionette.find_element(self._language_input_locator[0], self._language_input_locator[1] % language))
@property def is_take_tour_button_visible(self): return self.is_element_displayed(*self._take_tour_button_locator) @property def is_lets_go_button_visible(self): return self.is_element_displayed(*self._lets_go_button_locator)
[docs] def tap_next(self): next_button = Wait(self.marionette).until( expected.element_present(*self._next_button_locator)) Wait(self.marionette).until(expected.element_displayed(next_button)) Wait(self.marionette).until(expected.element_enabled(next_button)) # In b2g desktop builds, this sleep prevents intermittent failures time.sleep(0.2) next_button.tap()
[docs] def a11y_click_next(self): self.accessibility.click(self.marionette.find_element(*self._next_button_locator))
[docs] def tap_next_to_cell_data_section(self): self.tap_next() Wait(self.marionette).until(expected.element_displayed(*self._section_cell_data_locator))
[docs] def a11y_click_next_to_cell_data_section(self): self.a11y_click_next() Wait(self.marionette).until(expected.element_displayed(*self._section_cell_data_locator))
[docs] def enable_data(self): checkbox = Wait(self.marionette).until( expected.element_present(*self._enable_data_checkbox_locator)) Wait(self.marionette).until(expected.element_displayed(checkbox)) checkbox.tap()
[docs] def a11y_enable_data(self): checkbox = Wait(self.marionette).until( expected.element_present(*self._enable_data_checkbox_locator)) Wait(self.marionette).until(expected.element_displayed(checkbox)) self.accessibility.click(checkbox)
[docs] def tap_next_to_wifi_section(self): progress = self.marionette.find_element(*self._loading_overlay_locator) self.tap_next() Wait(self.marionette).until(expected.element_not_displayed(progress)) Wait(self.marionette).until(expected.element_displayed(*self._section_wifi_locator))
[docs] def a11y_click_next_to_wifi_section(self): self.a11y_click_next() Wait(self.marionette).until( expected.element_not_displayed(*self._loading_overlay_locator)) Wait(self.marionette).until(expected.element_displayed(*self._section_wifi_locator))
[docs] def wait_for_networks_available(self): Wait(self.marionette).until(lambda m: len(m.find_elements( *self._found_wifi_networks_locator)) > 0, message='No networks listed on screen')
[docs] def find_wifi_network(self, network_ssid): wifi_network_locator = (By.CSS_SELECTOR, '#networks-list li[data-ssid="%s"]' % network_ssid) wifi_network = Wait(self.marionette).until( expected.element_present(*wifi_network_locator)) self.marionette.execute_script("arguments[0].scrollIntoView(false);", [wifi_network]) Wait(self.marionette).until(expected.element_displayed(wifi_network)) return wifi_network
[docs] def connect_to_wifi(self, network_ssid, password, key_management=None): wifi_network = self.find_wifi_network(network_ssid) wifi_network.tap() # This is in the event we are using a Wifi Network that requires a password # We cannot be sure of this thus need the logic if key_management: password_element = Wait(self.marionette).until( expected.element_present(*self._password_input_locator)) Wait(self.marionette).until(expected.element_displayed(password_element)) password_element.send_keys(password) self.marionette.find_element(*self._join_network_locator).tap()
[docs] def a11y_connect_to_wifi(self, network_ssid, password, key_management=None): wifi_network = self.find_wifi_network(network_ssid) self.accessibility.click(wifi_network) # This is in the event we are using a Wifi Network that requires a password # We cannot be sure of this thus need the logic if key_management: password_element = Wait(self.marionette).until( expected.element_present(*self._password_input_locator)) Wait(self.marionette).until(expected.element_displayed(password_element)) password_element.send_keys(password) self.accessibility.click(self.marionette.find_element(*self._join_network_locator))
[docs] def tap_next_to_timezone_section(self): self.tap_next() Wait(self.marionette).until(expected.element_displayed(*self._section_date_time_locator))
[docs] def a11y_click_next_to_timezone_section(self): self.a11y_click_next() Wait(self.marionette).until(expected.element_displayed(*self._section_date_time_locator))
[docs] def set_timezone_continent(self, continent): element = Wait(self.marionette).until( expected.element_present(*self._timezone_continent_locator)) Wait(self.marionette).until(expected.element_displayed(element)) element.tap() self.select(continent)
[docs] def a11y_set_timezone_continent(self, continent): element = Wait(self.marionette).until( expected.element_present(*self._timezone_continent_locator)) Wait(self.marionette).until(expected.element_displayed(element)) self.accessibility.click(element) self.a11y_select(continent)
[docs] def set_timezone_city(self, city): element = Wait(self.marionette).until( expected.element_present(*self._timezone_city_locator)) Wait(self.marionette).until(expected.element_displayed(element)) element.tap() self.select(city)
[docs] def a11y_set_timezone_city(self, city): element = Wait(self.marionette).until( expected.element_present(*self._timezone_city_locator)) Wait(self.marionette).until(expected.element_displayed(element)) self.accessibility.click(element) self.a11y_select(city)
@property def timezone_title(self): return self.marionette.find_element(*self._time_zone_title_locator).text
[docs] def tap_next_to_geolocation_section(self): self.tap_next() Wait(self.marionette).until(expected.element_displayed(*self._section_geolocation_locator))
[docs] def a11y_click_next_to_geolocation_section(self): self.a11y_click_next() Wait(self.marionette).until(expected.element_displayed(*self._section_geolocation_locator))
[docs] def disable_geolocation(self): self._geolocation_switch.disable()
@property def is_geolocation_enabled(self): return self._geolocation_switch.is_checked @property def _geolocation_switch(self): return GaiaBinaryControl(self.marionette, self._enable_geolocation_checkbox_locator)
[docs] def a11y_disable_geolocation(self): element = Wait(self.marionette).until( expected.element_present(*self._enable_geolocation_checkbox_locator)) Wait(self.marionette).until(expected.element_displayed(element)) self.accessibility.click(element)
[docs] def tap_next_to_import_contacts_section(self): self.tap_next() Wait(self.marionette).until(expected.element_displayed(*self._section_import_contacts_locator))
[docs] def a11y_click_next_to_import_contacts_section(self): self.a11y_click_next() Wait(self.marionette).until(expected.element_displayed(*self._section_import_contacts_locator))
[docs] def tap_import_from_sim(self): self.marionette.find_element(*self._import_from_sim_locator).tap()
[docs] def wait_for_contacts_imported(self): feedback = self.marionette.find_element( *self._sim_import_feedback_locator) Wait(self.marionette).until( lambda m: self._pattern_contacts.match(feedback.text) is not None, message='Contact did not import from sim before timeout')
@property def count_imported_contacts(self): import_sim_message = self.marionette.find_element(*self._sim_import_feedback_locator).text import_sim_count = None if self._pattern_contacts_0.match(import_sim_message) is not None: import_sim_count = 0 elif self._pattern_contacts_1.match(import_sim_message) is not None: import_sim_count = 1 elif self._pattern_contacts_N.match(import_sim_message) is not None: count = self._pattern_contacts_N.match(import_sim_message).group(1) import_sim_count = int(count) return import_sim_count
[docs] def tap_next_to_firefox_accounts_section(self): self.tap_next() Wait(self.marionette).until( expected.element_displayed(*self._section_firefox_accounts_locator))
[docs] def a11y_click_next_to_firefox_accounts_section(self): self.a11y_click_next() Wait(self.marionette).until( expected.element_displayed(*self._section_firefox_accounts_locator))
[docs] def tap_next_to_late_customization_section(self): self.tap_next() Wait(self.marionette).until( expected.element_displayed(*self._section_late_customization_locator))
[docs] def tap_next_to_welcome_browser_section(self): self.tap_next() Wait(self.marionette).until( expected.element_displayed(*self._section_welcome_browser_locator))
[docs] def a11y_click_next_to_welcome_browser_section(self): self.a11y_click_next() Wait(self.marionette).until( expected.element_displayed(*self._section_welcome_browser_locator))
@property def is_metrics_basic_enabled(self): return self._metrics_basic_radio.is_checked
[docs] def enable_metrics_basic(self): self._metrics_basic_radio.enable()
@property def _metrics_basic_radio(self): return GaiaBinaryControl(self.marionette, self._metrics_basic_locator) @property def is_metrics_enhanced_enabled(self): return self._metrics_enhanced_radio.is_checked
[docs] def enable_metrics_enhanced(self): self._metrics_enhanced_radio.enable()
@property def _metrics_enhanced_radio(self): return GaiaBinaryControl(self.marionette, self._metrics_enhanced_locator) @property def is_metrics_none_enabled(self): return self._metrics_none_radio.is_checked
[docs] def enable_metrics_none(self): self._metrics_none_radio.enable()
@property def _metrics_none_radio(self): return GaiaBinaryControl(self.marionette, self._metrics_none_locator)
[docs] def tap_next_to_privacy_browser_section(self): self.tap_next() Wait(self.marionette).until( expected.element_displayed(*self._section_browser_privacy_locator))
[docs] def a11y_click_next_to_privacy_browser_section(self): self.a11y_click_next() Wait(self.marionette).until( expected.element_displayed(*self._section_browser_privacy_locator))
[docs] def enter_email_address(self, email): # TODO assert that this is preserved in the system somewhere. Currently it is not used self.marionette.find_element(*self._email_field_locator).send_keys(email) self.marionette.switch_to_frame() Wait(self.marionette).until(lambda m: self.keyboard.is_keyboard_displayed) self.apps.switch_to_displayed_app()
[docs] def tap_next_to_finish_section(self): self.tap_next() Wait(self.marionette).until(expected.element_displayed(*self._section_finish_locator))
[docs] def a11y_click_next_to_finish_section(self): self.a11y_click_next() Wait(self.marionette).until(expected.element_displayed(*self._section_finish_locator))
[docs] def tap_skip_tour(self): element = self.marionette.find_element(*self._skip_tour_button_locator) self.tap_element_from_system_app(element, add_statusbar_height=True)
[docs] def a11y_click_skip_tour(self): self.accessibility.click(self.marionette.find_element(*self._skip_tour_button_locator))
[docs] def run_ftu_setup_with_default_values(self): count = 0 while not self.is_element_displayed(*self._take_tour_button_locator): if self.is_element_displayed(*self._next_button_locator): self.tap_next() else: count = count + 1 if count > 5: break
[docs] def tap_take_tour(self): take_tour = Wait(self.marionette).until( expected.element_present(*self._take_tour_button_locator)) Wait(self.marionette).until(expected.element_displayed(take_tour)) Wait(self.marionette).until(expected.element_enabled(take_tour)) take_tour.tap()
@property def step1_header_text(self): header = Wait(self.marionette).until( expected.element_present(*self._step_header_locator)) Wait(self.marionette).until(expected.element_displayed(header)) return header.text
[docs] def tap_tour_next(self): next = Wait(self.marionette).until( expected.element_present(*self._tour_next_button_locator)) Wait(self.marionette).until(expected.element_displayed(next)) Wait(self.marionette).until(expected.element_enabled(next)) next.tap()
[docs] def tap_back(self): back = Wait(self.marionette).until( expected.element_present(*self._tour_back_button_locator)) Wait(self.marionette).until(expected.element_displayed(back)) back.tap()
@property def step2_header_text(self): header = Wait(self.marionette).until( expected.element_present(*self._step_header_locator)) Wait(self.marionette).until(expected.element_displayed(header)) return header.text @property def step3_header_text(self): header = Wait(self.marionette).until( expected.element_present(*self._step_header_locator)) Wait(self.marionette).until(expected.element_displayed(header)) return header.text @property def step4_header_text(self): header = Wait(self.marionette).until( expected.element_present(*self._step_header_locator)) Wait(self.marionette).until(expected.element_displayed(header)) return header.text @property def step5_header_text(self): header = Wait(self.marionette).until( expected.element_present(*self._step_header_locator)) Wait(self.marionette).until(expected.element_displayed(header)) return header.text @property def step6_header_text(self): header = Wait(self.marionette).until( expected.element_present(*self._step_header_locator)) Wait(self.marionette).until(expected.element_displayed(header)) return header.text
[docs] def wait_for_finish_tutorial_section(self): Wait(self.marionette).until(expected.element_displayed( Wait(self.marionette).until(expected.element_present( *self._section_tutorial_finish_locator))))
[docs] def tap_lets_go_button(self): element = self.marionette.find_element(*self._lets_go_button_locator) self.tap_element_from_system_app(element, add_statusbar_height=True)