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,146 @@
/* global marionette, require, setup, suite, test */
'use strict';
var assert = require('assert');
var Fm = require('./lib/fm.js');
marionette('FM Radio test', function() {
var client = marionette.client({
profile: {},
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var fm;
setup(function() {
fm = new Fm(client);
fm.launch();
fm.waitForLoaded();
});
suite('FM Radio UI', function() {
test('Test basic UI', function() {
try {
var freq = fm.getCurrentFrequency();
assert.equal(freq, '87.5');
var dialFreq = fm.getDialFreq();
assert.equal(dialFreq, '87.5');
assert.equal(freq, dialFreq);
// test seek up and down
var startFreq = freq;
fm.seekUp();
freq = fm.getCurrentFrequency();
assert.notEqual(freq, startFreq);
dialFreq = fm.getDialFreq();
assert.equal(parseFloat(dialFreq), parseFloat(freq));
fm.seekDown();
freq = fm.getCurrentFrequency();
assert.equal(freq, startFreq);
dialFreq = fm.getDialFreq();
assert.equal(parseFloat(dialFreq), parseFloat(freq));
// see about the frequency being saved.
fm.seekUp();
startFreq = fm.getCurrentFrequency();
fm.close();
fm.launch();
fm.waitForLoaded();
freq = fm.getCurrentFrequency();
assert.equal(parseFloat(freq), parseFloat(startFreq));
} catch(e) {
assert.ok(false, e.stack);
}
});
});
suite('FM Radio favourites', function() {
test('Test favouriting', function() {
try {
fm.seekUp();
var isFav = fm.isFav();
assert.ok(!isFav, 'Frequency shouldn\'t have been favourited');
fm.fav();
isFav = fm.isFav();
assert.ok(isFav, 'Frequency should be favourited');
fm.close();
fm.launch();
fm.waitForLoaded();
isFav = fm.isFav();
assert.ok(isFav, 'Frequency should be favourited after reboot.');
// checking we have a selected favourite.
var elem = fm.selectedFavItem();
assert.ok(elem, 'Can\'t find selected favourite');
var freq = fm.getCurrentFrequency();
// checking the text content of the favourite.
var favFreq = fm.selectedFavItemText();
assert.equal(favFreq, freq,
'Current frequency and selected favourite do not match');
// checking the id of the favourite.
var id = elem.getAttribute('id');
favFreq = id.substring(id.indexOf('-') + 1);
assert.equal(
parseFloat(favFreq), parseFloat(freq),
'Current frequency and selected favourite ID do not match');
fm.seekUp();
var newFreq = fm.getCurrentFrequency();
assert.notEqual(freq, newFreq);
fm.fav();
assert.ok(fm.isFav());
// count number of favs. Should be 2.
var elems = client.findElement(Fm.Selector.favList).
findElements(Fm.Selector.favItem);
assert.equal(elems.length, 2);
favFreq = fm.selectedFavItemText();
assert.equal(favFreq, newFreq);
elem.tap();
assert.ok(fm.isFav());
favFreq = fm.selectedFavItemText();
assert.notEqual(favFreq, newFreq);
// remove the favourite.
fm.fav();
assert.ok(!fm.isFav());
// count number of favs. Should be 1.
elems = client.findElement(Fm.Selector.favList).
findElements(Fm.Selector.favItem);
assert.equal(elems.length, 1);
} catch(e) {
assert.ok(false, e.stack);
}
});
});
});

View file

@ -0,0 +1,141 @@
/* global require, module */
'use strict';
var assert = require('assert');
function Fm(client, origin) {
this.client = client;
this.origin = origin || ('app://' + Fm.DEFAULT_ORIGIN);
this.actions = client.loader.getActions();
}
module.exports = Fm;
Fm.DEFAULT_ORIGIN = 'fm.gaiamobile.org';
Fm.Selector = Object.freeze({
currentFrequency: '#frequency',
dialerContainer: '#dialer-container',
seekDown: '#frequency-op-seekdown',
seekUp: '#frequency-op-seekup',
powerSwitch: '#power-switch',
favButton: '#bookmark-button',
favList: '#fav-list',
favListContainer: '#fav-list-container',
favItemSelected: '.fav-list-item.selected',
favItemSelectedFreq:'.fav-list-item.selected .fav-list-frequency',
favItem: '.fav-list-item',
});
Fm.prototype = {
client: null,
get powerSwitch() {
return this.client.findElement(Fm.Selector.powerSwitch);
},
get favButton() {
return this.client.findElement(Fm.Selector.favButton);
},
get favListContainer() {
return this.client.findElement(Fm.Selector.favListContainer);
},
// debug function.
debugDocument: function() {
var debug = this.client.executeScript(function() {
return document.documentElement.innerHTML;
});
console.log('debug', debug);
},
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);
},
// since we can't get the child text isolated with marionette.
// You might want to call _trimFreqTextContent() on the result.
_getTextNodeContent: function(sel) {
return this.client.executeScript(function(sel) {
return document.querySelector(sel).firstChild.textContent;
}, [sel]);
},
// make sure we have just the frequency
_trimFreqTextContent: function(freq) {
// for some reason these unicode delimiters are inserted
// in the text node
return freq.trim().replace(/[\u2068\u2069]/g, '');
},
getCurrentFrequency: function() {
var elem = this.client.findElement(Fm.Selector.currentFrequency);
assert.ok(elem, 'Couldn\'t find frequency');
var freq = this._getTextNodeContent(Fm.Selector.currentFrequency);
return this._trimFreqTextContent(freq);
},
getDialFreq: function() {
var elem = this.client.findElement(Fm.Selector.dialerContainer);
assert.ok(elem, 'Couldn\'t find dialer container');
var dialFreq = elem.getAttribute('aria-valuenow');
return dialFreq;
},
seekDown: function() {
var elem = this.client.findElement(Fm.Selector.seekDown);
assert.ok(elem, 'Seek Down button not found');
elem.click();
this.client.waitFor(function() {
return !this.powerSwitch.getAttribute('data-seeking');
}.bind(this));
},
seekUp: function() {
var elem = this.client.findElement(Fm.Selector.seekUp);
assert.ok(elem, 'Seek Down button not found');
elem.click();
this.client.waitFor(function() {
return !this.powerSwitch.getAttribute('data-seeking');
}.bind(this));
},
fav: function() {
var elem = this.favButton;
elem.tap();
},
selectedFavItem: function() {
return this.favListContainer.findElement(Fm.Selector.favItemSelected);
},
selectedFavItemText: function() {
var freq = this._getTextNodeContent(Fm.Selector.favItemSelectedFreq);
return this._trimFreqTextContent(freq);
},
isFav: function() {
return this.favButton.getAttribute('data-bookmarked') == 'true';
},
waitForLoaded: function() {
this.client.waitFor(function() {
return this.powerSwitch.getAttribute('data-enabled');
}.bind(this));
}
};