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,138 @@
# 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.errors import NoSuchElementException
from gaiatest import GaiaApps
from gaiatest import Accessibility
class Base(object):
DEFAULT_APP_HOSTNAME = '.gaiamobile.org'
DEFAULT_PROTOCOL = 'app://'
def __init__(self, marionette):
self.marionette = marionette
self.apps = GaiaApps(self.marionette)
self.accessibility = Accessibility(self.marionette)
self.frame = None
self.entry_point = hasattr(self, 'entry_point') and self.entry_point or None
def launch(self, launch_timeout=None):
self.app = self.apps.launch(self.name, self.manifest_url, self.entry_point, launch_timeout=launch_timeout)
def is_element_present(self, by, locator):
self.marionette.set_search_timeout(0)
try:
self.marionette.find_element(by, locator)
return True
except NoSuchElementException:
return False
finally:
self.marionette.set_search_timeout(self.marionette.timeout or 10000)
def is_element_displayed(self, by, locator):
self.marionette.set_search_timeout(0)
try:
return self.marionette.find_element(by, locator).is_displayed()
except NoSuchElementException:
return False
finally:
self.marionette.set_search_timeout(self.marionette.timeout or 10000)
def find_select_item(self, match_string):
_list_item_locator = (By.CSS_SELECTOR, 'section.value-selector-container li label')
# have to go back to top level to get the B2G select box wrapper
self.marionette.switch_to_frame()
# TODO we should find something suitable to wait for, but this goes too
# fast against desktop builds causing intermittent failures
time.sleep(0.2)
Wait(self.marionette).until(expected.element_present(*_list_item_locator))
for item in self.marionette.find_elements(*_list_item_locator):
if match_string == item.text.encode('ascii','ignore').strip():
# We need to keep this because the Ok button may hang over the element and stop
# Marionette from scrolling the element entirely into view
self.marionette.execute_script('arguments[0].scrollIntoView(false);', [item])
return item
def wait_for_select_closed(self, by, locator):
Wait(self.marionette).until(expected.element_not_displayed(by, locator))
# now back to app
self.apps.switch_to_displayed_app()
# TODO we should find something suitable to wait for, but this goes too
# fast against desktop builds causing intermittent failures
# This sleep is necessary to make sure the select is completely faded out,
# see bug 1148154
time.sleep(1)
def select(self, match_string, tap_close=True):
# cheeky Select wrapper until Marionette has its own
# due to the way B2G wraps the app's select box we match on text
_close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm')
li = self.find_select_item(match_string)
li.tap()
# Tap close and wait for it to hide
if tap_close:
self.marionette.find_element(*_close_button_locator).tap()
self.wait_for_select_closed(*_close_button_locator)
def a11y_select(self, match_string):
# Accessibility specific select method
_close_button_locator = (By.CSS_SELECTOR, 'button.value-option-confirm')
li = self.find_select_item(match_string)
self.accessibility.click(li)
# A11y click close and wait for it to hide
self.accessibility.click(self.marionette.find_element(*_close_button_locator))
self.wait_for_select_closed(*_close_button_locator)
def tap_element_from_system_app(self, element=None, add_statusbar_height=False, x=None, y=None):
# Workaround for bug 1109213, where tapping on the button inside the app itself
# makes Marionette spew out NoSuchWindowException errors, see bug 1164078
cx = element.rect['x']
cy = element.rect['y']
cx += element.rect['width']//2 if x is None else x
cy += element.rect['height']//2 if y is None else y
from gaiatest.apps.system.app import System
system = System(self.marionette)
if add_statusbar_height:
cy = cy + system.status_bar.height
system.tap(cx, cy)
@property
def keyboard(self):
from gaiatest.apps.keyboard.app import Keyboard
return Keyboard(self.marionette)
@property
def manifest_url(self):
return '{}{}{}/manifest.webapp'.format(self.DEFAULT_PROTOCOL, self.__class__.__name__.lower(), self.DEFAULT_APP_HOSTNAME)
@property
def is_displayed(self):
return (self.apps.displayed_app.manifest_url == self.manifest_url and
self.apps.displayed_app.entry_point == self.entry_point)
def wait_to_be_displayed(self):
Wait(self.marionette).until(lambda m: self.is_displayed == True)
def wait_to_not_be_displayed(self):
Wait(self.marionette).until(lambda m: self.is_displayed == False)
class PageRegion(Base):
def __init__(self, marionette, element):
self.root_element = element
Base.__init__(self, marionette)