VulpesOS/gaia/dev_apps/music-oga/test/marionette/lib/music.js
OverSu b38dea0597 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.
2026-09-30 23:13:03 +02:00

397 lines
10 KiB
JavaScript
Executable file

/* global require, module */
'use strict';
var assert = require('assert');
function Music(client, origin) {
this.client = client;
this.origin = origin || ('app://' + Music.DEFAULT_ORIGIN);
this.actions = client.loader.getActions();
}
module.exports = Music;
Music.DEFAULT_ORIGIN = 'music-oga.gaiamobile.org';
Music.Selector = Object.freeze({
messageOverlay: '#overlay',
firstTile: '.tile',
playlistsTab: '#tabs-playlists',
artistsTab: '#tabs-artists',
songsTab: '#tabs-songs',
albumsTab: '#tabs-albums',
playerCover: '#player-cover',
// search fields
searchField: '#views-search-input',
searchTiles: '#views-tiles-search',
searchTilesField: '#views-tiles-search-input',
searchList: '#views-list-search',
searchListField: '#views-list-search-input',
// search results
searchArtists: '#views-search-artists',
searchAlbums: '#views-search-albums',
searchTitles: '#views-search-titles',
searchNoResult: '#views-search-no-result',
tilesView: '#views-tiles',
listView: '#views-list',
viewsList: '#views-list-anchor',
sublistView: '#views-sublist',
viewsSublist: '#views-sublist-anchor',
sublistViewControls: '#views-sublist-header-controls',
firstListItem: '.list-item',
firstSong: '.list-item',
firstSongSublist: '#views-sublist .list-item',
playerView: '#views-player',
playButton: '#player-controls-play',
progressBar: '#player-seek-bar-progress',
shareButton: '#player-cover-share',
ratingBar: '#player-album-rating',
ratingStarsOn: 'button.star-on',
shareMenu: 'form[data-z-index-level="action-menu"]',
pickDoneButton: '#title-done',
header: '#title',
titleText: '#title-text',
sublistShuffleButton: '#views-sublist-controls-shuffle',
playerIcon: '#title-player'
});
Music.prototype = {
client: null,
get messageOverlay() {
return this.client.findElement(Music.Selector.messageOverlay);
},
get firstTile() {
return this.client.findElement(Music.Selector.firstTile);
},
get playlistsTab() {
return this.client.helper.waitForElement(Music.Selector.playlistsTab);
},
get artistsTab() {
return this.client.helper.waitForElement(Music.Selector.artistsTab);
},
get songsTab() {
return this.client.helper.waitForElement(Music.Selector.songsTab);
},
get albumsTab() {
return this.client.helper.waitForElement(Music.Selector.albumsTab);
},
get firstSong() {
return this.client.helper.waitForElement(Music.Selector.firstSong);
},
get firstSongSublist() {
return this.client.helper.waitForElement(Music.Selector.firstSongSublist);
},
// Helper for the getter.
_getListItems: function(selector) {
this.waitForAList(selector);
var list = this.client.findElement(selector);
assert.ok(list, 'Couldn\'t find element ' + selector);
var list_items = list.findElements('li.list-item', 'css selector');
assert.ok(list_items, 'Coudln\'t find list-items for ' + selector);
return list_items;
},
get firstListItem() {
return this.client.helper.waitForElement(Music.Selector.firstListItem);
},
get listItems() {
return this._getListItems(Music.Selector.viewsList);
},
get songs() {
return this._getListItems(Music.Selector.viewsSublist);
},
get playButton() {
return this.client.findElement(Music.Selector.playButton);
},
get shareButton() {
return this.client.findElement(Music.Selector.shareButton);
},
get title() {
var header = this.client.findElement(Music.Selector.header);
return header.findElement(Music.Selector.titleText);
},
get sublistShuffleButton() {
return this.client.helper.waitForElement(
Music.Selector.sublistShuffleButton);
},
// TODO(gareth): Move this shareMenu stuff into the helper.
get shareMenu() {
// Switch to the system app first.
this.client.switchToFrame();
return this.client.helper.waitForElement(Music.Selector.shareMenu);
},
get progressBar() {
return this.client.findElement(Music.Selector.progressBar);
},
get pickDoneButton() {
return this.client.findElement(Music.Selector.pickDoneButton);
},
get header() {
return this.client.findElement(Music.Selector.header);
},
get playerIcon() {
return this.client.findElement(Music.Selector.playerIcon);
},
get isPlaying() {
return this.playButton.getAttribute('class').indexOf('is-pause') === -1;
},
get songProgress() {
return parseFloat(this.progressBar.getAttribute('value'));
},
launch: function() {
this.client.switchToFrame();
this.client.apps.launch(this.origin);
this.client.apps.switchToApp(this.origin);
this.client.helper.waitForElement('body');
},
close: function() {
this.client.apps.close(this.origin);
},
switchToMe: function(options) {
options = options || {};
this.client.switchToFrame();
// Switch to music even when it is in background.
// We cannot use switchToApp here, because it will wait
// for the app to come to foreground.
if (options.background) {
var musicFrame = this.client.findElement('iframe[src*="' +
this.origin + '"]');
this.client.switchToFrame(musicFrame);
} else {
this.client.apps.switchToApp(this.origin);
}
},
waitForListEnumerate: function() {
this.client.waitFor(function() {
return this.client.executeScript(function() {
return window.wrappedJSObject.ListView.handle.state === 'complete';
});
}.bind(this));
},
waitFinishedScanning: function() {
this.client.waitFor(function() {
return this.client.executeScript(function() {
return window.wrappedJSObject.Database.initialScanComplete === true;
});
}.bind(this));
},
waitForFirstTile: function() {
this.client.helper.waitForElement(Music.Selector.firstTile);
},
waitForMessageOverlayShown: function(shouldBeShown) {
this.client.waitFor(function() {
var volumeShown = this.messageOverlay.displayed();
return volumeShown === shouldBeShown;
}.bind(this));
},
waitForAList: function(selector) {
this.client.waitFor(function() {
return this.client.findElement(selector).displayed();
}.bind(this));
},
// In sublist view.
// XXX allow in list view too.
waitForSongs: function(callback) {
this.client.waitFor(function() {
var songs = this.songs;
return callback(songs);
}.bind(this));
},
waitForListView: function() {
this.client.helper.waitForElement(Music.Selector.listView);
},
waitForSubListView: function() {
this.client.helper.waitForElement(Music.Selector.sublistView);
},
waitForPlayerView: function() {
this.client.helper.waitForElement(Music.Selector.playerView);
},
// Because bug 862156 so we couldn't get the correct displayed value for the
// player icon, instead we use the display property to check the visibility
// of the player icon.
checkPlayerIconShown: function(shouldBeShown) {
var display = this.playerIcon.cssProperty('display');
var result = (display !== 'none');
assert.equal(shouldBeShown, result);
},
showSearchInput: function(viewSelector) {
var tilesView = this.client.findElement(viewSelector);
var chain = this.actions.press(tilesView, 10, 10).perform();
chain.moveByOffset(0, 110).perform();
chain.release().perform();
},
searchArtists: function(searchTerm) {
this.search(Music.Selector.searchList, searchTerm);
},
searchTiles: function(searchTerm) {
this.search(Music.Selector.searchTiles, searchTerm);
},
search: function(viewSelector, searchTerm) {
this.client.findElement(viewSelector).tap();
var input = this.client.helper.waitForElement(Music.Selector.searchField);
assert.ok(input);
input.clear();
this.client.waitFor(input.displayed.bind(input));
input.sendKeys(searchTerm);
},
switchToArtistsView: function() {
this.artistsTab.tap();
},
switchToSongsView: function() {
this.songsTab.tap();
},
switchToAlbumsView: function() {
this.albumsTab.tap();
},
switchToPlaylistsView: function() {
this.playlistsTab.tap();
},
selectAlbum: function(name) {
var list_items = this.listItems;
list_items.filter(function (element) {
return element.findElement('.list-main-title', 'css selector')
.text() === name;
})[0].tap();
},
selectArtist: function(name) {
var list_items = this.listItems;
list_items.filter(function (element) {
return element.findElement('.list-single-title', 'css selector')
.text() === name;
})[0].tap();
},
selectPlaylist: function(name) {
var list_items = this.listItems;
list_items.filter(function (element) {
return element.findElement('.list-playlist-title', 'css selector')
.text() === name;
})[0].tap();
},
// only from a list (song list)
playFirstSong: function() {
this.firstSong.click();
},
// only from a sublist (artist, albums, playlists)
playFirstSongSublist: function() {
this.firstSongSublist.click();
},
tapPlayButton: function() {
this.actions.tap(this.playButton).perform();
},
tapHeaderActionButton: function() {
this.header.tap(25, 25);
},
showSongInfo: function() {
this.client.helper.waitForElement(Music.Selector.playerCover).click();
},
tapRating: function(rating) {
this.showSongInfo();
this.client.helper.waitForElement('button.rating-star[data-rating="' +
rating + '"]').tap();
},
shareWith: function(appName) {
// Allow findElement to fail quickly.
var quickly = this.client.scope({
searchTimeout: 50
});
var shareMenu;
// Wait until the share menu is displayed.
// Try to click the cover image followed by the share button in the case
// that it hides before we get a chance to click it.
this.client.waitFor(function() {
this.showSongInfo();
this.shareButton.tap();
this.client.switchToFrame();
try {
shareMenu = quickly.findElement(Music.Selector.shareMenu);
} catch(e) {
this.client.apps.switchToApp(this.origin);
return false;
}
var isDisplayed = shareMenu.displayed();
this.client.apps.switchToApp(this.origin);
return isDisplayed;
}.bind(this));
var list = this.shareMenu.findElements('button');
for (var i = 0; i < list.length; i++) {
if (list[i].text() === appName) {
list[i].tap();
return;
}
}
},
finishPick: function() {
this.actions.tap(this.pickDoneButton).perform();
}
};