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:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View 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)