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,88 @@
# 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
from gaiatest.apps.music_oga.regions.list_view import ListView
class Music(Base):
name = 'Music OGA'
manifest_url = '{}music-oga{}/manifest.webapp'.format(Base.DEFAULT_PROTOCOL, Base.DEFAULT_APP_HOSTNAME)
_loading_spinner_locator = (By.ID, 'spinner-overlay')
_music_tiles_locator = (By.CSS_SELECTOR, '#views-tiles-anchor > div')
_views_locator = (By.ID, 'views')
_tabs_locator = (By.ID, 'tabs')
_empty_music_title_locator = (By.ID, 'overlay-title')
_empty_music_text_locator = (By.ID, 'overlay-text')
_albums_tab_locator = (By.ID, 'tabs-albums')
_songs_tab_locator = (By.ID, 'tabs-songs')
_artists_tab_locator = (By.ID, 'tabs-artists')
_title_locator = (By.ID, 'title-text')
def launch(self):
Base.launch(self)
Wait(self.marionette).until(expected.element_not_displayed(
*self._loading_spinner_locator))
def wait_for_music_tiles_displayed(self):
Wait(self.marionette).until(expected.element_displayed(
*self._music_tiles_locator))
def wait_for_empty_message_to_load(self):
element = self.marionette.find_element(*self._empty_music_title_locator)
Wait(self.marionette).until(lambda m: not element.text == '')
def wait_for_view_displayed(self, view_name):
title = self.marionette.find_element(*self._title_locator)
Wait(self.marionette).until(expected.element_displayed(title))
Wait(self.marionette).until(lambda m: title.text == view_name)
@property
def empty_music_title(self):
return self.marionette.find_element(*self._empty_music_title_locator).text
@property
def empty_music_text(self):
return self.marionette.find_element(*self._empty_music_text_locator).text
@property
def views(self):
return self.marionette.find_element(*self._views_locator)
@property
def tabs(self):
return self.marionette.find_element(*self._tabs_locator)
def tap_albums_tab(self):
element = Wait(self.marionette).until(
expected.element_present(*self._albums_tab_locator))
Wait(self.marionette).until(expected.element_displayed(element))
element.tap()
return ListView(self.marionette)
def tap_songs_tab(self):
element = Wait(self.marionette).until(
expected.element_present(*self._songs_tab_locator))
Wait(self.marionette).until(expected.element_displayed(element))
element.tap()
return ListView(self.marionette)
def tap_artists_tab(self):
element = Wait(self.marionette).until(
expected.element_present(*self._artists_tab_locator))
Wait(self.marionette).until(expected.element_displayed(element))
element.tap()
return ListView(self.marionette)
def a11y_click_albums_tab(self):
element = Wait(self.marionette).until(
expected.element_present(*self._albums_tab_locator))
Wait(self.marionette).until(expected.element_displayed(element))
self.accessibility.click(element)
return ListView(self.marionette)

View file

@ -0,0 +1,50 @@
# 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, PageRegion
from gaiatest.apps.music_oga.regions.sublist_view import SublistView
from gaiatest.apps.music_oga.regions.player_view import PlayerView
class ListView(Base):
_view_locator = (By.ID, 'views')
_list_item_locator = (By.CSS_SELECTOR, '.list-item')
def __init__(self, marionette):
Base.__init__(self, marionette)
Wait(self.marionette).until(
lambda m: self.marionette.find_element(*self._view_locator).get_attribute('class') != 'scrolling')
@property
def media(self):
elements = Wait(self.marionette).until(
expected.elements_present(*self._list_item_locator))
Wait(self.marionette).until(expected.element_displayed(elements[0]))
return [Media(self.marionette, element) for element in elements]
class Media(PageRegion):
_media_link_locator = (By.TAG_NAME, 'a')
def tap_first_album(self):
self.marionette.find_element(*self._media_link_locator).tap()
return SublistView(self.marionette)
def tap_first_song(self):
self.marionette.find_element(*self._media_link_locator).tap()
return PlayerView(self.marionette)
def tap_first_artist(self):
self.marionette.find_element(*self._media_link_locator).tap()
return SublistView(self.marionette)
def a11y_click_first_album(self):
self.accessibility.click(
self.marionette.find_element(*self._media_link_locator))
return SublistView(self.marionette)

View file

@ -0,0 +1,71 @@
# 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 gaiatest.apps.base import Base
class PlayerView(Base):
_audio_locator = (By.ID, 'player-audio')
_player_seek_elapsed_locator = (By.ID, 'player-seek-elapsed')
_player_controls_play_locator = (By.ID, 'player-controls-play')
_cover_image_locator = (By.CSS_SELECTOR, '.cover-image.visible')
_cover_share_locator = (By.ID, 'player-cover-share')
_rating_view_locator = (By.ID, 'player-album-rating')
_stars_on_locator = (By.CSS_SELECTOR, '.rating-star.star-on')
def tap_play(self):
self.marionette.find_element(*self._player_controls_play_locator).tap()
def tap_cover_in_player_view(self):
self.marionette.find_element(*self._cover_image_locator).tap()
Wait(self.marionette).until(expected.element_displayed(
Wait(self.marionette).until(expected.element_present(*self._rating_view_locator))))
def tap_share_button(self):
self.tap_cover_in_player_view()
self.marionette.find_element(*self._cover_share_locator).tap()
from gaiatest.apps.system.regions.activities import Activities
return Activities(self.marionette)
def _get_star_locator(self, rating):
return By.CSS_SELECTOR, '.rating-star[data-rating="%s"]' % rating
def tap_star(self, rate):
"""
give rating. (After tapping the cover to make the ratings overlay appear)
"""
self.tap_cover_in_player_view()
Wait(self.marionette).until(expected.element_displayed(*self._get_star_locator(rate)))
self.marionette.find_element(*self._get_star_locator(rate)).tap()
@property
def star_rating(self):
return len(self.marionette.find_elements(*self._stars_on_locator))
@property
def player_elapsed_time(self):
Wait(self.marionette).until(expected.element_displayed(
Wait(self.marionette).until(expected.element_present(*self._player_seek_elapsed_locator))))
return time.strptime(self.marionette.find_element(*self._player_seek_elapsed_locator).text, '%M:%S')
def is_player_playing(self):
# get 4 timestamps during approx. 1 sec
# ensure that newer timestamp has greater value than previous one
timestamps = []
for i in range(4):
timestamps.append(self.player_current_timestamp)
time.sleep(.25)
return all([timestamps[i - 1] < timestamps[i] for i in range(1, 3)])
@property
def player_current_timestamp(self):
player = self.marionette.find_element(*self._audio_locator)
return float(player.get_attribute('currentTime'))

View file

@ -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/.
from marionette_driver import expected, By, Wait
from marionette_driver.marionette import Actions
from gaiatest.apps.base import Base
from gaiatest.apps.music_oga.regions.player_view import PlayerView
class SublistView(Base):
_song_number_locator = (By.CSS_SELECTOR, 'bdi.list-song-index')
_play_control_locator = (By.ID, 'views-sublist-controls-play')
def __init__(self, marionette):
Base.__init__(self, marionette)
element = self.marionette.find_element(*self._song_number_locator)
Wait(self.marionette).until(lambda m: element.location['x'] == 0)
def tap_play(self):
play = Wait(self.marionette).until(
expected.element_present(*self._play_control_locator))
# TODO: Change this to a simple tap when bug 862156 is fixed
Actions(self.marionette).tap(play).perform()
return PlayerView(self.marionette)

View file

@ -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
from gaiatest.apps.music_oga.regions.player_view import PlayerView
class TileView(Base):
_main_tile_locator = (By.CSS_SELECTOR, '.main-tile')
_sub_tile_locator = (By.CSS_SELECTOR, '.sub-tile')
def __init__(self, marionette):
Base.__init__(self, marionette)
# there are two type of tiles - main and sub. There should be at least one main tile
Wait(self.marionette).until(expected.element_displayed(
*self._main_tile_locator))
def tap_main_song(self):
self.marionette.find_element(*self._main_tile_locator).tap()
return PlayerView(self.marionette)
def tap_sub_song(self, order):
sub_tiles = Wait(self.marionette).until(
expected.elements_present(*self._sub_tile_locator))
sub_tiles[order].tap()
return PlayerView(self.marionette)