VulpesOS/gaia/apps/system/test/marionette/lib/app_install.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

213 lines
6.1 KiB
JavaScript
Executable file

'use strict';
/**
* A Marionette test helper for app installation flow.
*/
/**
* @constructor
* @param {Marionette.Client} client Marionette client to use.
*/
function AppInstall(client) {
this.client = client.scope({ searchTimeout: 200000 });
}
module.exports = AppInstall;
AppInstall.Selector = Object.freeze({
// General app install dialog
installDialog: '#app-install-dialog',
installButton: '#app-install-install-button',
addonWarning: '#app-install-dialog #system-addon-warning',
installToast: '#screen > gaia-toast.banner',
// Setup dialog after installation
setupDialog: '#setup-installed-app-dialog',
setupButton: '#setup-confirm-button',
// Ime Layout selection menu
imeDialog: '#ime-layout-dialog',
imeLayoutOption: '#ime-list li',
imeConfirmButton: '#ime-confirm-button'
});
AppInstall.prototype = {
get installDialog() {
return this.client.findElement(AppInstall.Selector.installDialog);
},
get installButton() {
return this.client.findElement(AppInstall.Selector.installButton);
},
get addonWarning() {
return this.client.findElement(AppInstall.Selector.addonWarning);
},
get setupDialog() {
return this.client.findElement(AppInstall.Selector.setupDialog);
},
get setupButton() {
return this.client.findElement(AppInstall.Selector.setupButton);
},
get imeDialog() {
return this.client.findElement(AppInstall.Selector.imeDialog);
},
get imeLayoutOption() {
return this.client.findElement(AppInstall.Selector.imeLayoutOption);
},
get imeConfirmButton() {
return this.client.findElement(AppInstall.Selector.imeConfirmButton);
},
_install: function(type, manifestURL, options) {
this.client.executeScript(function install(type, url) {
window.wrappedJSObject.navigator.mozApps[type](url);
}, [type, manifestURL]);
options = options || { allowInstall: true };
if (options.allowInstall) {
this.waitForDialog(this.installDialog);
// Wait for the install button visible both to user and the screen reader.
this.client.helper.waitForElement(this.installButton);
// Click install button on the app install dialog
this.installButton.click();
}
},
/**
* Install an app.
* @param {string} manifestURL The manifestURL of the app to be installed.
* @param {Object} [options] The options for installation.
* @param {boolean} [options.allowInstall=true] If true, allow the
* installation directly.
*/
installPackage: function installPackage(manifestURL, options) {
return this._install('installPackage', manifestURL, options);
},
/**
* Install an app.
* @param {string} manifestURL The manifestURL of the app to be installed.
* @param {Object} [options] The options for installation.
* @param {boolean} [options.allowInstall=true] If true, allow the
* installation directly.
*/
install: function install(manifestURL, options) {
return this._install('install', manifestURL, options);
},
/**
* Uninstall an app.
* @param {string} [manifestURL] The manifestURL of the app.
*/
uninstall: function(manifestURL) {
this.client.switchToFrame();
this.client.executeAsyncScript(function uninstall(url) {
var win = window.wrappedJSObject;
var mgmt = win.navigator.mozApps.mgmt;
mgmt.getAll().onsuccess = function(e) {
var app = e.target.result.find(function(app) {
return app.manifestURL === url;
});
mgmt.uninstall(app);
marionetteScriptFinished();
};
}, [manifestURL]);
},
/**
Checks for downloads without applying them.
*/
stageUpdate: function(manifestURL) {
// do it in chrome so we don't need to switch contexts...
var client = this.client.scope({ context: 'chrome' });
return client.executeAsyncScript(function(manifestURL) {
navigator.mozApps.mgmt.getAll().onsuccess = function(e) {
var list = e.target.result;
var app = list.find(function(app) {
return app.manifestURL === manifestURL;
});
var req = app.checkForUpdate();
req.onsuccess = req.onerror = function() {
marionetteScriptFinished();
};
};
}, [manifestURL]);
},
/**
Updates an installed app by it's manifest url.
@param {String} manifestURL for the application.
*/
update: function(manifestURL) {
// do it in chrome so we don't need to switch contexts...
var client = this.client.scope({ context: 'chrome' });
return client.executeAsyncScript(function(manifestURL) {
navigator.mozApps.mgmt.getAll().onsuccess = function(e) {
var list = e.target.result;
var app = list.find(function(app) {
return app.manifestURL === manifestURL;
});
var req = app.checkForUpdate();
req.onsuccess = function() {
app.download();
marionetteScriptFinished();
};
req.onerror = function() {
marionetteScriptFinished();
};
};
}, [manifestURL]);
},
/**
* Dismiss the app install toast banner.
*/
dismissToast: function() {
var toast = this.waitForToast();
toast.tap();
this.client.helper.waitForElementToDisappear(toast);
},
/**
* Wait for the app install toast banner.
*/
waitForToast: function() {
return this.client.helper.waitForElement(AppInstall.Selector.installToast);
},
/**
* Wait for the specified dialog to show up.
* @param {Marionette.Element} element The dialog element to wait for.
*/
waitForDialog: function waitForAppInstallDialog(element) {
return this.client.helper.waitForElement(element);
},
isAppInstalled: function(app) {
if (typeof app !== 'string') {
app = app.manifestURL;
}
var isInstalled = this.client.executeAsyncScript(function(url) {
var win = window.wrappedJSObject;
var mgmt = win.navigator.mozApps.mgmt;
mgmt.getAll().onsuccess = function(e) {
var matchedApp = e.target.result.find(function(app) {
return app.manifestURL === url;
});
marionetteScriptFinished(!!matchedApp);
};
}, [app]);
return isInstalled;
}
};