Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
306 lines
13 KiB
Python
Executable file
306 lines
13 KiB
Python
Executable file
# 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_driver import expected, By, Wait
|
|
from marionette_driver.errors import (NoSuchElementException,
|
|
StaleElementException)
|
|
from marionette_driver.marionette import Actions
|
|
|
|
from gaiatest.apps.base import Base
|
|
from gaiatest.apps.base import PageRegion
|
|
from gaiatest.apps.calendar.regions.event_details import EventDetails
|
|
|
|
|
|
class Calendar(Base):
|
|
|
|
name = 'Calendar'
|
|
|
|
_current_month_year_locator = (By.ID, 'current-month-year')
|
|
_current_month_day_agenda_locator = (By.ID, 'month-day-agenda')
|
|
_current_monthly_calendar_locator = (By.ID, 'month-view')
|
|
_add_event_button_locator = (By.XPATH, "//a[@href='/event/add/']")
|
|
|
|
_month_display_button_locator = (By.XPATH, "//a[@href='/month/']")
|
|
_week_display_button_locator = (By.XPATH, "//a[@href='/week/']")
|
|
_day_display_button_locator = (By.XPATH, "//a[@href='/day/']")
|
|
_day_view_locator = (By.ID, 'day-view')
|
|
_week_view_locator = (By.ID, 'week-view')
|
|
|
|
_time_views_locator = (By.ID, 'time-views')
|
|
_modify_event_view_locator = (By.ID, 'modify-event-view')
|
|
_event_view_locator = (By.ID, 'event-view')
|
|
_time_header_locator = (By.ID, 'time-header')
|
|
|
|
_create_account_button_locator = (By.CLASS_NAME, 'create-account')
|
|
_create_account_header_locator = (By.ID, 'create-account-header')
|
|
_create_account_view_locator = (By.ID, 'create-account-view')
|
|
_create_account_preset_locator = (By.CSS_SELECTOR,
|
|
'#create-account-presets a')
|
|
|
|
_modify_account_header_locator = (By.ID, 'modify-account-header')
|
|
_modify_account_view_locator = (By.ID, 'modify-account-view')
|
|
|
|
_settings_locator = (By.ID, 'settings')
|
|
|
|
_advanced_settings_view_locator = (By.ID, 'advanced-settings-view')
|
|
_advanced_settings_done_button_locator = (By.XPATH, "//a[@href='/settings/']")
|
|
|
|
_event_list_date_locator = (By.ID, 'event-list-date')
|
|
_event_list_empty_locator = (By.ID, 'empty-message')
|
|
_event_locator = (By.CLASS_NAME, 'event')
|
|
_today_locator = (By.CSS_SELECTOR, '.month.active .present')
|
|
_tomorrow_locator = (By.CSS_SELECTOR, '.month.active .present + li > .day')
|
|
|
|
_day_view_all_day_button = (By.CSS_SELECTOR,
|
|
'.day-view .md__allday:nth-child(2) .md__allday-events')
|
|
_day_view_event_link = (By.CSS_SELECTOR, '.day-view .md__day:nth-child(2) .md__event')
|
|
|
|
def launch(self):
|
|
Base.launch(self)
|
|
# empty message is only displayed after first MonthsDay#render,
|
|
# so we are sure app is "ready" after that
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._event_list_empty_locator))))
|
|
|
|
@property
|
|
def current_month_year(self):
|
|
return self.marionette.find_element(*self._current_month_year_locator).text
|
|
|
|
@property
|
|
def current_month_day(self):
|
|
return self.marionette.find_element(*self._current_month_day_agenda_locator).get_attribute('data-date')
|
|
|
|
@property
|
|
def event_list_date(self):
|
|
return self.marionette.find_element(*self._event_list_date_locator).text
|
|
|
|
@property
|
|
def events(self):
|
|
return [self.Event(marionette=self.marionette, element=event)
|
|
for event in self.marionette.find_elements(*self._event_locator)]
|
|
|
|
def wait_for_events(self, number_to_wait_for=1):
|
|
Wait(self.marionette).until(lambda m: len(m.find_elements(*self._event_locator)) == number_to_wait_for)
|
|
|
|
def event(self, title):
|
|
for event in self.events:
|
|
if event.title == title:
|
|
return event
|
|
|
|
@property
|
|
def accounts(self):
|
|
return [account for account in self.marionette.find_elements(
|
|
*self._create_account_preset_locator)]
|
|
|
|
def account(self, preset):
|
|
for account in self.accounts:
|
|
if account.get_attribute('data-provider') == preset:
|
|
return account
|
|
|
|
@property
|
|
def settings(self):
|
|
return self.Settings(marionette=self.marionette,
|
|
element=self.marionette.find_elements(*self._settings_locator))
|
|
|
|
def wait_for_new_event(self):
|
|
from gaiatest.apps.calendar.regions.event import NewEvent
|
|
new_event = NewEvent(self.marionette)
|
|
new_event.wait_for_panel_to_load()
|
|
return new_event
|
|
|
|
def a11y_click_add_event_button(self):
|
|
self.accessibility.click(self.marionette.find_element(*self._add_event_button_locator))
|
|
return self.wait_for_new_event()
|
|
|
|
def tap_add_event_button(self):
|
|
self.marionette.find_element(*self._add_event_button_locator).tap()
|
|
return self.wait_for_new_event()
|
|
|
|
def a11y_click_week_display_button(self):
|
|
self.accessibility.click(self.marionette.find_element(*self._week_display_button_locator))
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._week_view_locator))))
|
|
|
|
def tap_week_display_button(self):
|
|
self.marionette.find_element(*self._week_display_button_locator).tap()
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._week_view_locator))))
|
|
|
|
def a11y_click_month_display_button(self):
|
|
self.accessibility.click(self.marionette.find_element(*self._month_display_button_locator))
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._current_monthly_calendar_locator))))
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._current_month_day_agenda_locator))))
|
|
|
|
def a11y_click_day_display_button(self):
|
|
self.accessibility.click(self.marionette.find_element(*self._day_display_button_locator))
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._day_view_locator))))
|
|
|
|
def tap_day_display_button(self):
|
|
self.marionette.find_element(*self._day_display_button_locator).tap()
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._day_view_locator))))
|
|
|
|
def displayed_events_in_month_view(self):
|
|
return self.marionette.find_element(*self._get_events_locator_in_month_view()).text
|
|
|
|
def displayed_events_in_week_view(self, data_date):
|
|
return self.marionette.find_element(*self._get_events_locator_in_week_view(data_date)).text
|
|
|
|
def displayed_events_in_day_view(self, data_date):
|
|
return self.marionette.find_element(*self._get_events_locator_in_day_view(data_date)).text
|
|
|
|
def _get_events_locator_in_day_view(self, data_date):
|
|
return (By.CSS_SELECTOR,
|
|
"#day-view .md__day[data-date*='%s'] .md__event" % data_date)
|
|
|
|
def _get_events_locator_in_month_view(self):
|
|
return (By.CSS_SELECTOR,
|
|
'#event-list .event')
|
|
|
|
def _get_events_locator_in_week_view(self, data_date):
|
|
return (By.CSS_SELECTOR,
|
|
"#week-view .md__day[data-date*='%s'] .md__event" % data_date)
|
|
|
|
def a11y_click_other_day(self, next, previous):
|
|
try:
|
|
# Try clicking tomorrow
|
|
self.accessibility.click(self.marionette.find_element(*self._tomorrow_locator))
|
|
return next
|
|
except NoSuchElementException:
|
|
# Tomorrow is next week or month, try clicking yesterday.
|
|
yesterday = self.marionette.execute_script(
|
|
"return arguments[0].previousSibling.querySelector('.day');",
|
|
[self.marionette.find_element(*self._today_locator)])
|
|
self.accessibility.click(yesterday)
|
|
return previous
|
|
|
|
def a11y_click_header(self, header, selector):
|
|
self.accessibility.execute_async_script(
|
|
"Accessibility.click(arguments[0].shadowRoot.querySelector('%s'));" % selector,
|
|
[header])
|
|
|
|
def wait_fot_settings_drawer_animation(self):
|
|
el = self.marionette.find_element(*self.settings._settings_drawer_locator)
|
|
Wait(self.marionette).until(lambda m: el.get_attribute('data-animstate') == 'done')
|
|
|
|
def a11y_click_create_account_back(self):
|
|
self.a11y_click_header(self.marionette.find_element(*self._create_account_header_locator),
|
|
'button.action-button')
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._advanced_settings_view_locator))))
|
|
|
|
def a11y_click_modify_account_back(self):
|
|
self.a11y_click_header(self.marionette.find_element(*self._modify_account_header_locator),
|
|
'button.action-button')
|
|
Wait(self.marionette).until(expected.element_displayed(
|
|
Wait(self.marionette).until(expected.element_present(
|
|
*self._create_account_view_locator))))
|
|
|
|
def a11y_click_settings(self):
|
|
self.a11y_click_header(self.marionette.find_element(*self._time_header_locator),
|
|
'button.action-button')
|
|
self.wait_fot_settings_drawer_animation()
|
|
|
|
def a11y_click_close_settings(self):
|
|
self.a11y_click_header(self.marionette.find_element(
|
|
*self.settings._settings_header_locator), 'button.action-button')
|
|
self.wait_fot_settings_drawer_animation()
|
|
|
|
def a11y_create_event(self, title):
|
|
new_event = self.a11y_click_add_event_button()
|
|
# create a new event
|
|
new_event.a11y_fill_event_title(title)
|
|
new_event.a11y_click_save_event()
|
|
self.wait_for_events(1)
|
|
|
|
def a11y_click_day_view_event(self):
|
|
self.accessibility.click(self.marionette.find_element(*self._day_view_event_link))
|
|
el = self.marionette.find_element(*self._event_view_locator)
|
|
Wait(self.marionette).until(expected.element_displayed(el))
|
|
return EventDetails(self.marionette)
|
|
|
|
def flick_to_next_month(self):
|
|
self._flick_to_month('next')
|
|
|
|
def flick_to_previous_month(self):
|
|
self._flick_to_month('previous')
|
|
|
|
def a11y_wheel_to_next_month(self):
|
|
self._a11y_wheel_to_month('left')
|
|
|
|
def a11y_wheel_to_previous_month(self):
|
|
self._a11y_wheel_to_month('right')
|
|
|
|
def _a11y_wheel_to_month(self, direction):
|
|
self.accessibility.wheel(self.marionette.find_element(
|
|
*self._current_monthly_calendar_locator), direction)
|
|
|
|
def _flick_to_month(self, direction):
|
|
"""Flick current monthly calendar to next or previous month.
|
|
|
|
@param direction: flick to next month if direction='next', else flick to previous month
|
|
"""
|
|
action = Actions(self.marionette)
|
|
|
|
month = self.marionette.find_element(
|
|
*self._current_monthly_calendar_locator)
|
|
month_year = self.current_month_year
|
|
|
|
x_start = (month.size['width'] / 100) * (direction == 'next' and 90 or 10)
|
|
x_end = (month.size['width'] / 100) * (direction == 'next' and 10 or 90)
|
|
y_start = month.size['height'] / 4
|
|
y_end = month.size['height'] / 4
|
|
|
|
action.flick(month, x_start, y_start, x_end, y_end, 200).perform()
|
|
|
|
Wait(self.marionette).until(lambda m: self.current_month_year != month_year)
|
|
|
|
class Settings(PageRegion):
|
|
|
|
_calendar_local_locator = (By.CSS_SELECTOR, '#calendar-local-first .pack-checkbox')
|
|
_calendar_local_checkbox_locator = (By.CSS_SELECTOR,
|
|
'#calendar-local-first input[type="checkbox"]')
|
|
_advanced_settings_button_locator = (By.CSS_SELECTOR, '.settings')
|
|
_settings_header_locator = (By.ID, 'settings-header')
|
|
_settings_drawer_locator = (By.CLASS_NAME, 'settings-drawer')
|
|
|
|
def wait_for_calendar_unchecked(self, timeout=None):
|
|
checkbox = self.marionette.find_element(*self._calendar_local_checkbox_locator)
|
|
Wait(self.marionette, timeout).until(expected.element_not_selected(checkbox))
|
|
|
|
def wait_for_a11y_calendar_unchecked(self, timeout=None):
|
|
Wait(self.marionette, timeout, ignored_exceptions=StaleElementException).until(
|
|
lambda m: not self.marionette.find_element(
|
|
*self._calendar_local_locator).get_attribute('aria-selected'))
|
|
|
|
class Event(PageRegion):
|
|
|
|
_title_locator = (By.TAG_NAME, 'h5')
|
|
_location_locator = (By.CLASS_NAME, 'location')
|
|
_event_view_locator = (By.ID, 'event-view')
|
|
|
|
@property
|
|
def title(self):
|
|
return self.root_element.find_element(*self._title_locator).text
|
|
|
|
@property
|
|
def location(self):
|
|
return self.root_element.find_element(*self._location_locator).text
|
|
|
|
def a11y_click(self):
|
|
self.accessibility.click(self.root_element)
|
|
el = self.marionette.find_element(*self._event_view_locator)
|
|
Wait(self.marionette).until(expected.element_displayed(el))
|
|
return EventDetails(self.marionette)
|