text: # 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/.
  
  from marionette import Wait
  from marionette import expected
  from marionette.by import By
  from gaiatest.apps.base import Base
  from gaiatest.apps.base import PageRegion
  from gaiatest.apps.email.regions.setup import SetupEmail
  from gaiatest.apps.email.regions.setup import ManualSetupEmail
  from gaiatest.apps.email.regions.settings import Settings
  from gaiatest.apps.email.regions.google import GoogleLogin
  
  
  class Email(Base):
  
      name = 'E-Mail'
  
      _email_locator = (By.CSS_SELECTOR, '#cardContainer .msg-header-item:not([data-index="-1"])')
      _syncing_locator = (By.CSS_SELECTOR, '#cardContainer .msg-messages-syncing > .small')
      _manual_setup_locator = (By.CSS_SELECTOR, '#cardContainer .sup-manual-config-btn')
      _message_list_locator = (By.CSS_SELECTOR, 'cards-message-list')
      _setup_account_info = (By.TAG_NAME, 'cards-setup-account-info')
      _setup_manual_config = (By.TAG_NAME, 'cards-setup-manual-config')
      _refresh_button_locator = (By.CLASS_NAME, 'msg-refresh-btn')
  
      def basic_setup_email(self, name, email, password):
  
          setup = SetupEmail(self.marionette)
          setup.type_name(name)
          setup.type_email(email)
  
          setup.tap_next()
  
          google_login = GoogleLogin(self.marionette)
  
          # check if the google autocomplete on email field works as expected
          assert google_login.email == email
  
          google_login.type_password(password)
          google_login.tap_sign_in()
  
          # approve access to your account
          google_login.wait_for_approve_access()
          google_login.tap_approve_access()
  
          self.apps.switch_to_displayed_app()
  
          setup.tap_account_prefs_next()
  
          setup.wait_for_setup_complete()
  
          setup.tap_continue()
          self.wait_for_message_list()
  
      def setup_IMAP_email(self, imap):
          basic_setup = SetupEmail(self.marionette)
          basic_setup.type_name(imap['name'])
          basic_setup.type_email(imap['email'])
  
          setup = self.tap_manual_setup()
  
          setup.select_account_type('IMAP+SMTP')
  
          setup.type_imap_hostname(imap['imap_hostname'])
          setup.type_imap_name(imap['imap_name'])
          setup.type_imap_password(imap['password'])
          setup.type_imap_port(imap['imap_port'])
  
          setup.type_smtp_hostname(imap['smtp_hostname'])
          setup.type_smtp_password(imap['password'])
          setup.type_smtp_name(imap['smtp_name'])
          setup.type_smtp_port(imap['smtp_port'])
  
          setup.tap_next()
          setup.check_for_emails_interval('20000')
  
          setup.tap_account_prefs_next()
  
          setup.wait_for_setup_complete()
          setup.tap_continue()
          self.wait_for_message_list()
  
      def setup_active_sync_email(self, active_sync):
          basic_setup = SetupEmail(self.marionette)
          basic_setup.type_name(active_sync['name'])
          basic_setup.type_email(active_sync['email'])
  
          setup = self.tap_manual_setup()
  
          setup.select_account_type('ActiveSync')
  
          setup.type_activesync_hostname(active_sync['active_sync_hostname'])
          setup.type_activesync_name(active_sync['active_sync_username'])
          setup.type_password(active_sync['password'])
  
          setup.tap_next()
  
          setup.check_for_emails_interval('20000')
          setup.tap_account_prefs_next()
  
          setup.wait_for_setup_complete()
          setup.tap_continue()
          self.wait_for_message_list()
  
      def delete_email_account(self, index):
  
          toolbar = self.header.tap_menu()
          toolbar.tap_settings()
          settings = Settings(self.marionette)
          account_settings = settings.email_accounts[index].tap()
          delete_confirmation = account_settings.tap_delete()
          delete_confirmation.tap_delete()
  
      def tap_manual_setup(self):
          manual_setup = Wait(self.marionette).until(
              expected.element_present(*self._manual_setup_locator))
          Wait(self.marionette).until(expected.element_displayed(manual_setup))
          manual_setup.tap()
          return ManualSetupEmail(self.marionette)
  
      def a11y_click_manual_setup(self):
          manual_setup = Wait(self.marionette).until(
              expected.element_present(*self._manual_setup_locator))
          Wait(self.marionette).until(expected.element_displayed(manual_setup))
          self.accessibility.click(manual_setup)
          return ManualSetupEmail(self.marionette)
  
      def a11y_navigate_to_manual_setup(self, name, email):
          setup = SetupEmail(self.marionette)
          setup.type_name(name)
          setup.type_email(email)
          setup = self.a11y_click_manual_setup()
  
      @property
      def header(self):
          return Header(self.marionette)
  
      @property
      def toolbar(self):
          return ToolBar(self.marionette)
  
      @property
      def mails(self):
          return [Message(self.marionette, mail) for mail in self.marionette.find_elements(*self._email_locator)]
  
      def wait_for_emails_to_sync(self):
          element = self.marionette.find_element(*self._refresh_button_locator)
          Wait(self.marionette).until(
              lambda m: element.get_attribute(
                  'data-state') == 'synchronized')
  
      def wait_for_message_list(self):
          element = self.marionette.find_element(*self._message_list_locator)
          Wait(self.marionette).until(
              lambda m: element.is_displayed() and
              element.location['x'] == 0)
  
      def wait_for_email(self, subject, timeout=120):
          Wait(self.marionette, timeout, interval=5).until(
              self.email_exists(self, subject))
  
      class email_exists(object):
  
          def __init__(self, app, subject):
              self.app = app
              self.subject = subject
  
          def __call__(self, marionette):
              if self.subject in [mail.subject for mail in self.app.mails]:
                  return True
              else:
                  self.app.toolbar.tap_refresh()
                  self.app.wait_for_emails_to_sync()
                  self.app.mails[0].scroll_to_message()
                  return False
  
  
  class Header(Base):
  
      _menu_button_locator = (By.CSS_SELECTOR, '.card.center .msg-folder-list-btn')
      _compose_button_locator = (By.CSS_SELECTOR, '.card.center .msg-compose-btn')
      _label_locator = (By.CSS_SELECTOR, '.card.center .msg-list-header-folder-label.header-label')
  
      def tap_menu(self):
          self.marionette.find_element(*self._menu_button_locator).tap()
          toolbar = ToolBar(self.marionette)
          Wait(self.marionette).until(lambda m: toolbar.is_visible)
          return toolbar
  
      def tap_compose(self):
          self.marionette.find_element(*self._compose_button_locator).tap()
          from gaiatest.apps.email.regions.new_email import NewEmail
          return NewEmail(self.marionette)
  
      @property
      def label(self):
          return self.marionette.find_element(*self._label_locator).text
  
      @property
      def is_menu_visible(self):
          return self.is_element_displayed(*self._menu_button_locator)
  
      @property
      def is_compose_visible(self):
          return self.is_element_displayed(*self._compose_button_locator)
  
  
  class ToolBar(Base):
      _toolbar_locator = (By.CSS_SELECTOR, '#cardContainer .card.center .fld-nav-toolbar')
      _refresh_locator = (By.CSS_SELECTOR, '#cardContainer .card.center .msg-refresh-btn')
      _search_locator = (By.CSS_SELECTOR, '#cardContainer .card.center .msg-search-btn')
      _edit_locator = (By.CSS_SELECTOR, '#cardContainer .card.center .msg-edit-btn')
      _settings_locator = (By.CSS_SELECTOR, '#cardContainer .card.center .fld-nav-settings-btn')
  
      def tap_refresh(self):
          refresh = Wait(self.marionette).until(
              expected.element_present(*self._refresh_locator))
          Wait(self.marionette).until(expected.element_displayed(refresh))
          refresh.tap()
  
      def tap_search(self):
          search = Wait(self.marionette).until(
              expected.element_present(*self._search_locator))
          Wait(self.marionette).until(expected.element_displayed(search))
          search.tap()
  
      def tap_edit(self):
          edit = Wait(self.marionette).until(
              expected.element_present(*self._edit_locator))
          Wait(self.marionette).until(expected.element_displayed(edit))
          edit.tap()
  
      def tap_settings(self):
          settings = Wait(self.marionette).until(
              expected.element_present(*self._settings_locator))
          Wait(self.marionette).until(expected.element_displayed(settings))
          settings.tap()
  
      @property
      def is_visible(self):
          return self.marionette.find_element(*self._toolbar_locator).location['x'] == 0
  
      @property
      def is_refresh_visible(self):
          return self.is_element_displayed(*self._refresh_locator)
  
      @property
      def is_search_visible(self):
          return self.is_element_displayed(*self._search_locator)
  
      @property
      def is_edit_visible(self):
          return self.is_element_displayed(*self._edit_locator)
  
      @property
      def is_settings_visible(self):
          return self.is_element_displayed(*self._settings_locator)
  
  
  class Message(PageRegion):
      _subject_locator = (By.CSS_SELECTOR, '.msg-header-subject')
      _senders_email_locator = (By.CSS_SELECTOR, '.msg-header-author')
  
      @property
      def subject(self):
          return self.root_element.find_element(*self._subject_locator).text
  
      @property
      def senders_email(self):
          return self.root_element.find_element(*self._senders_email_locator).text
  
      def scroll_to_message(self):
          self.marionette.execute_script("arguments[0].scrollIntoView(false);", [self.root_element])
  
      def tap_subject(self):
          subject = self.root_element.find_element(*self._subject_locator)
          Wait(self.marionette).until(expected.element_enabled(subject))
          subject.tap()
          from gaiatest.apps.email.regions.read_email import ReadEmail
          return ReadEmail(self.marionette)
  