Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
0
gaia/tests/python/gaia-ui-tests/gaiatest/apps/homescreen/__init__.py
Executable file
0
gaia/tests/python/gaia-ui-tests/gaiatest/apps/homescreen/__init__.py
Executable file
161
gaia/tests/python/gaia-ui-tests/gaiatest/apps/homescreen/app.py
Executable file
161
gaia/tests/python/gaia-ui-tests/gaiatest/apps/homescreen/app.py
Executable file
|
|
@ -0,0 +1,161 @@
|
|||
# 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 time
|
||||
|
||||
from marionette_driver import expected, By, Wait
|
||||
from marionette_driver.marionette import Actions
|
||||
from marionette_driver.errors import NoSuchElementException
|
||||
|
||||
from gaiatest.apps.base import Base
|
||||
from gaiatest.apps.base import PageRegion
|
||||
from gaiatest.apps.homescreen.regions.bottom_bar import BottomBar
|
||||
|
||||
|
||||
class Homescreen(Base):
|
||||
|
||||
name = 'Default Home Screen'
|
||||
|
||||
_homescreen_icon_locator = (By.CSS_SELECTOR, 'gaia-grid .icon')
|
||||
_all_icons_locator = (By.TAG_NAME, 'gaia-app-icon')
|
||||
_edit_mode_locator = (By.CSS_SELECTOR, 'body.edit-mode')
|
||||
_search_bar_icon_locator = (By.ID, 'search-input')
|
||||
_landing_page_locator = (By.ID, 'icons')
|
||||
_bookmark_icons_locator = (By.CSS_SELECTOR, 'gaia-grid .bookmark')
|
||||
_divider_locator = (By.CSS_SELECTOR, 'section.divider')
|
||||
_divider_separator_locator = (By.CSS_SELECTOR, 'section.divider .separator > span')
|
||||
_exit_edit_mode_locator = (By.ID, 'exit-edit-mode')
|
||||
_body_dragging_locator = (By.CSS_SELECTOR, 'body.dragging')
|
||||
_apps_locator = (By.ID, 'apps')
|
||||
_app_icon_locator = (By.CSS_SELECTOR, 'gaia-app-icon[data-identifier="%s"]')
|
||||
_scollable_div_locator = (By.CSS_SELECTOR, '#apps-panel div.scrollable')
|
||||
|
||||
def wait_for_app_icon_present(self, app_manifest):
|
||||
Wait(self.marionette, timeout=30).until(lambda m: self.installed_app(app_manifest))
|
||||
|
||||
def wait_for_app_icon_not_present(self, app_manifest):
|
||||
def _app_is_not_found(_):
|
||||
try:
|
||||
self.installed_app(app_manifest)
|
||||
except NoSuchElementException:
|
||||
return True
|
||||
return False
|
||||
|
||||
Wait(self.marionette).until(_app_is_not_found)
|
||||
|
||||
def wait_for_bookmark_icon_not_present(self, bookmark_title):
|
||||
Wait(self.marionette).until(lambda m: self.bookmark(bookmark_title) is None)
|
||||
|
||||
def is_app_installed(self, app_manifest):
|
||||
"""Checks whether app is installed"""
|
||||
return self.installed_app(app_manifest) is not None
|
||||
|
||||
@property
|
||||
def is_at_topmost_position(self):
|
||||
position = self.marionette.execute_script("""
|
||||
return {x:arguments[0].scrollLeft, y: arguments[0].scrollTop}
|
||||
""", [self.marionette.find_element(*self._scollable_div_locator)])
|
||||
return (position['x'] == 0 and position['y'] == 0)
|
||||
|
||||
def scroll_to_icon(self, icon_position=0):
|
||||
app_icon = self.visible_apps[icon_position]
|
||||
self.marionette.execute_script(
|
||||
'arguments[0].scrollIntoView(true);', [app_icon.root_element])
|
||||
|
||||
def move_app_to_position(self, app_position, to_position):
|
||||
app = self.app_elements[app_position]
|
||||
destination_element = self.app_elements[to_position].root_element
|
||||
app.move_to(destination_element)
|
||||
|
||||
@property
|
||||
def app_elements(self):
|
||||
return [self.GaiaAppIcon(self.marionette, app_element)
|
||||
for app_element in self.marionette.find_elements(*self._all_icons_locator)]
|
||||
|
||||
@property
|
||||
def visible_apps(self):
|
||||
return [homescreen_element for homescreen_element in self.app_elements if homescreen_element.is_displayed]
|
||||
|
||||
def wait_for_number_of_apps(self, number_of_apps=1):
|
||||
Wait(self.marionette).until(lambda m: len(self.app_elements) >= number_of_apps)
|
||||
|
||||
def installed_app(self, app_manifest):
|
||||
apps_container = self.marionette.find_elements(*self._apps_locator)
|
||||
self.marionette.switch_to_shadow_root(apps_container)
|
||||
icon_locator = (self._app_icon_locator[0], self._app_icon_locator[1] % app_manifest)
|
||||
app_icon = self.marionette.find_element(*icon_locator)
|
||||
return self.GaiaAppIcon(self.marionette, app_icon)
|
||||
|
||||
def bookmark(self, bookmark_title):
|
||||
for root_el in self.marionette.find_elements(*self._bookmark_icons_locator):
|
||||
if root_el.text == bookmark_title:
|
||||
return self.GaiaAppIcon(self.marionette, root_el)
|
||||
|
||||
@property
|
||||
def number_of_columns(self):
|
||||
_icon_container_text = 'div.gaia-container-child:nth-child(%s)'
|
||||
#first element is always on the first column
|
||||
_first_icon_locator = (By.CSS_SELECTOR, _icon_container_text % str(1))
|
||||
# wait until the icons are fully drawn
|
||||
Wait(self.marionette).until(lambda m: self.marionette.find_element(*_first_icon_locator).rect['x'] != 0)
|
||||
base_x_axis = self.marionette.find_element(*_first_icon_locator).rect['x']
|
||||
has_row_changed = False
|
||||
column = 1
|
||||
while not has_row_changed:
|
||||
_icon_locator = (By.CSS_SELECTOR, _icon_container_text % str(column+1))
|
||||
if self.marionette.find_element(*_icon_locator).rect['x'] == base_x_axis:
|
||||
has_row_changed = True
|
||||
else:
|
||||
column += 1
|
||||
|
||||
return column
|
||||
|
||||
def delete_app(self, app_manifest):
|
||||
app = self.installed_app(app_manifest)
|
||||
app.activate_edit_mode()
|
||||
|
||||
return BottomBar(self.marionette).tap_remove()
|
||||
|
||||
class GaiaAppIcon(PageRegion):
|
||||
|
||||
@property
|
||||
def manifest_url(self):
|
||||
return self.root_element.get_attribute('data-identifier')
|
||||
|
||||
@property
|
||||
def is_app_installed(self):
|
||||
self.marionette.switch_to_shadow_root(self.root_element)
|
||||
app_installed = self.root_element.get_attribute('data-test-icon-url') == 'app-icon'
|
||||
self.marionette.switch_to_shadow_root()
|
||||
return app_installed
|
||||
|
||||
@property
|
||||
def is_displayed(self):
|
||||
return self.root_element.is_displayed()
|
||||
|
||||
def tap_icon(self):
|
||||
expected_manifest_url = self.manifest_url
|
||||
self.root_element.tap()
|
||||
Wait(self.marionette).until(lambda m: self.apps.displayed_app.manifest_url == expected_manifest_url)
|
||||
self.apps.switch_to_displayed_app()
|
||||
|
||||
def activate_edit_mode(self):
|
||||
self._start_long_press_action().\
|
||||
release().\
|
||||
perform()
|
||||
|
||||
def move_to(self, html_element):
|
||||
self._start_long_press_action().\
|
||||
move(html_element).\
|
||||
wait(1).\
|
||||
release().\
|
||||
wait(1).\
|
||||
perform()
|
||||
|
||||
def _start_long_press_action(self):
|
||||
self.marionette.execute_script('arguments[0].scrollIntoView(false);', [self.root_element])
|
||||
|
||||
return Actions(self.marionette).\
|
||||
press(self.root_element).\
|
||||
wait(3)
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
# 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 time
|
||||
|
||||
from marionette_driver import expected, By, Wait
|
||||
|
||||
from gaiatest.apps.base import Base
|
||||
|
||||
|
||||
class BookmarkMenu(Base):
|
||||
|
||||
name = "Bookmark"
|
||||
manifest_url = '{}bookmark{}/manifest.webapp'.format(Base.DEFAULT_PROTOCOL,Base.DEFAULT_APP_HOSTNAME)
|
||||
|
||||
# System app - add bookmark to homescreen dialog
|
||||
_add_bookmark_to_home_screen_frame_locator = (By.CSS_SELECTOR, 'iframe[src^="app://bookmark"][src$="save.html"]')
|
||||
_add_bookmark_to_home_screen_dialog_button_locator = (By.ID, 'done-button')
|
||||
_bookmark_title_input_locator = (By.ID, 'bookmark-title')
|
||||
|
||||
def __init__(self, marionette):
|
||||
Base.__init__(self, marionette)
|
||||
self.wait_to_be_displayed()
|
||||
self.apps.switch_to_displayed_app()
|
||||
|
||||
def tap_add_bookmark_to_home_screen_dialog_button(self):
|
||||
element = Wait(self.marionette).until(expected.element_present(
|
||||
*self._add_bookmark_to_home_screen_dialog_button_locator))
|
||||
Wait(self.marionette).until(expected.element_displayed(element))
|
||||
# This sleep is necessary for the button to react to the tap call
|
||||
time.sleep(0.2)
|
||||
self.tap_element_from_system_app(element)
|
||||
|
||||
# Wait for the Add to bookmark frame to be dismissed
|
||||
self.wait_to_not_be_displayed()
|
||||
self.apps.switch_to_displayed_app()
|
||||
|
||||
def type_bookmark_title(self, value):
|
||||
element = self.marionette.find_element(
|
||||
*self._bookmark_title_input_locator)
|
||||
|
||||
# Wait for the default value to load into the input field
|
||||
Wait(self.marionette).until(lambda m: element.get_attribute('value') != '')
|
||||
element.clear()
|
||||
|
||||
self.keyboard.send(value)
|
||||
self.keyboard.dismiss()
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# 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 gaiatest import GaiaApps
|
||||
from gaiatest.apps.base import PageRegion
|
||||
|
||||
|
||||
class BottomBar(PageRegion):
|
||||
_bottom_bar_locator = (By.ID, 'bottombar')
|
||||
_remove_locator = (By.ID, 'remove')
|
||||
_done_locator = (By.ID, 'done')
|
||||
|
||||
def __init__(self, marionette):
|
||||
GaiaApps(marionette).switch_to_displayed_app()
|
||||
root = Wait(marionette).until(
|
||||
expected.element_present(*self._bottom_bar_locator))
|
||||
Wait(marionette).until(expected.element_displayed(root))
|
||||
|
||||
window_height = marionette.execute_script('return window.wrappedJSObject.innerHeight')
|
||||
Wait(marionette).until(lambda m: int(root.rect['y'] + root.size['height']) == window_height)
|
||||
|
||||
PageRegion.__init__(self, marionette, root)
|
||||
|
||||
def tap_remove(self):
|
||||
self.root_element.find_element(*self._remove_locator).tap()
|
||||
|
||||
from gaiatest.apps.homescreen.regions.confirm_dialog import ConfirmDialog
|
||||
return ConfirmDialog(self.marionette)
|
||||
|
||||
def tap_exit_edit_mode(self):
|
||||
self.apps.switch_to_displayed_app()
|
||||
self.root_element = self.marionette.find_element(*self._bottom_bar_locator)
|
||||
self.root_element.find_element(*self._done_locator).tap()
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# 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 time
|
||||
|
||||
from marionette_driver import expected, By, Wait
|
||||
|
||||
from gaiatest.apps.base import Base
|
||||
from gaiatest.apps.homescreen.regions.bottom_bar import BottomBar
|
||||
|
||||
|
||||
class ConfirmDialog(Base):
|
||||
|
||||
_confirm_button_locator = (By.CSS_SELECTOR, 'gaia-confirm .confirm')
|
||||
|
||||
def tap_confirm(self, bookmark=False):
|
||||
# TODO add a good wait here when Bug 1008961 is resolved
|
||||
time.sleep(1)
|
||||
if not bookmark:
|
||||
self.marionette.switch_to_frame()
|
||||
confirm = Wait(self.marionette).until(expected.element_present(
|
||||
*self._confirm_button_locator))
|
||||
Wait(self.marionette).until(expected.element_displayed(confirm))
|
||||
confirm.tap()
|
||||
|
||||
return BottomBar(self.marionette)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# 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 time
|
||||
|
||||
from marionette_driver import expected, By, Wait
|
||||
|
||||
from gaiatest.apps.base import Base
|
||||
|
||||
|
||||
class ConfirmInstall(Base):
|
||||
|
||||
_confirm_install_button_locator = (By.ID, 'app-install-install-button')
|
||||
|
||||
def tap_confirm(self):
|
||||
# TODO add a good wait here when Bug 1008961 is resolved
|
||||
self.marionette.switch_to_frame()
|
||||
confirm = Wait(self.marionette).until(expected.element_present(
|
||||
*self._confirm_install_button_locator))
|
||||
Wait(self.marionette).until(expected.element_displayed(confirm))
|
||||
confirm.tap()
|
||||
self.apps.switch_to_displayed_app()
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# 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 gaiatest.apps.base import Base
|
||||
|
||||
|
||||
class PermissionDialog(Base):
|
||||
|
||||
_permission_dialog_locator = (By.ID, 'permission-dialog')
|
||||
_permission_dialog_message_locator = (By.ID, 'permission-message')
|
||||
_permission_confirm_button_locator = (By.ID, 'permission-yes')
|
||||
_permission_dismiss_button_locator = (By.ID, 'permission-no')
|
||||
|
||||
def wait_for_permission_dialog_displayed(self):
|
||||
Wait(self.marionette).until(expected.element_displayed(
|
||||
Wait(self.marionette).until(expected.element_present(
|
||||
*self._permission_dialog_locator))))
|
||||
|
||||
@property
|
||||
def permission_dialog_message(self):
|
||||
return self.marionette.find_element(*self._permission_dialog_message_locator).text
|
||||
|
||||
def tap_to_confirm_permission(self):
|
||||
self.marionette.find_element(*self._permission_confirm_button_locator).tap()
|
||||
from gaiatest.apps.system.app import System
|
||||
return System(self.marionette)
|
||||
|
||||
def tap_to_dismiss_permission(self):
|
||||
self.marionette.find_element(*self._permission_dismiss_button_locator).tap()
|
||||
Loading…
Reference in a new issue