Skip to content

Commit f84772d

Browse files
Bug 1168254 - merge pull request mozilla-b2g#30234 from huchengtw-moz:bug-1168254-app-install-manager-test-tv to mozilla-b2g:master
2 parents 820301a + d5e3955 commit f84772d

File tree

5 files changed

+292
-1
lines changed

5 files changed

+292
-1
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<title>Nothing</title>
7+
</head>
8+
9+
<body>
10+
Nothing here
11+
</body>
12+
</html>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "Hosted app for test",
3+
"description": "Hosted app for test",
4+
"launch_path": "/index.html",
5+
"fullscreen": true,
6+
"developer": {
7+
"name": "The Gaia Team",
8+
"url": "https://github.com/mozilla-b2g/gaia"
9+
}
10+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
'use strict';
2+
3+
var Keys = {
4+
'enter': '\ue006',
5+
'left': '\ue012',
6+
'right': '\ue014'
7+
};
8+
9+
var assert = require('chai').assert;
10+
var AppInstaller = require('./lib/app_install');
11+
var Server = require('../../../../shared/test/integration/server');
12+
13+
marionette('app install manager tests', function() {
14+
15+
var opts = {
16+
apps: {},
17+
hostOptions: {
18+
screen: {
19+
width: 1920,
20+
height: 1080
21+
}
22+
}
23+
};
24+
25+
var client = marionette.client({ profile: opts });
26+
var system;
27+
var appInstaller;
28+
var server;
29+
var serverManifestURL;
30+
31+
suiteSetup(function(done) {
32+
Server.create(__dirname + '/../apps/hosted-app', function(err, _server) {
33+
server = _server;
34+
serverManifestURL = server.url('manifest.webapp');
35+
done(err);
36+
});
37+
});
38+
39+
suiteTeardown(function() {
40+
server.stop();
41+
});
42+
43+
setup(function() {
44+
system = client.loader.getAppClass('smart-system', 'system', 'tv_apps');
45+
appInstaller = new AppInstaller(client);
46+
// Once the os-logo is disappeared, the first app is shown and focused. It
47+
// implies system is ready to go.
48+
client.helper.waitForElementToDisappear('#os-logo');
49+
});
50+
51+
test('install app', { devices: ['tv'] }, function() {
52+
// install app
53+
appInstaller.install(serverManifestURL);
54+
// press install button
55+
var installButton = client.helper.waitForElement(
56+
system.Selector.appInstallInstallButton);
57+
installButton.sendKeys(Keys.enter);
58+
// check app installed
59+
system.waitForAppInstalled(serverManifestURL);
60+
});
61+
62+
test('install app and cancel it', { devices: ['tv'] }, function() {
63+
// install app
64+
appInstaller.install(serverManifestURL);
65+
// press install button
66+
var cancelInstallButton = client.helper.waitForElement(
67+
system.Selector.appInstallCancelButton);
68+
69+
cancelInstallButton.sendKeys(Keys.left);
70+
assert.isTrue(cancelInstallButton.scriptWith(function(el) {
71+
return document.activeElement === el;
72+
}), 'cancel button should be focused.');
73+
74+
cancelInstallButton.sendKeys(Keys.enter);
75+
var cancelConfirmButton = client.helper.waitForElement(
76+
system.Selector.appCancelInstallConfirmButton);
77+
78+
assert.isTrue(cancelConfirmButton.scriptWith(function(el) {
79+
return document.activeElement === el;
80+
}), 'confirm button should be focused.');
81+
cancelConfirmButton.sendKeys(Keys.enter);
82+
83+
assert.isFalse(system.isAppInstalled(serverManifestURL),
84+
'app should not be installed');
85+
});
86+
87+
test('install app and uninstall it', { devices: ['tv'] }, function() {
88+
// install app
89+
appInstaller.install(serverManifestURL);
90+
var installButton = client.helper.waitForElement(
91+
system.Selector.appInstallInstallButton);
92+
installButton.sendKeys(Keys.enter);
93+
system.waitForAppInstalled(serverManifestURL);
94+
95+
// uninstall app
96+
appInstaller.uninstall(serverManifestURL);
97+
98+
// wait for dialog
99+
var confirmButton = client.helper.waitForElement(
100+
system.Selector.appUninstallConfirmButton);
101+
confirmButton.sendKeys(Keys.right);
102+
assert.isTrue(confirmButton.scriptWith(function(el) {
103+
return document.activeElement === el;
104+
}), 'confirm button should be focused.');
105+
// uninstall it
106+
confirmButton.sendKeys(Keys.enter);
107+
system.waitForAppUninstalled(serverManifestURL);
108+
});
109+
110+
test('uninstall and cancel it', { devices: ['tv'] }, function() {
111+
// install app
112+
appInstaller.install(serverManifestURL);
113+
var installButton = client.helper.waitForElement(
114+
system.Selector.appInstallInstallButton);
115+
installButton.sendKeys(Keys.enter);
116+
system.waitForAppInstalled(serverManifestURL);
117+
118+
appInstaller.uninstall(serverManifestURL);
119+
120+
var cancelButton = client.helper.waitForElement(
121+
system.Selector.appUninstallCancelButton);
122+
cancelButton.sendKeys(Keys.enter);
123+
124+
assert.isTrue(system.isAppInstalled(serverManifestURL),
125+
'app should be installed');
126+
});
127+
});
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
'use strict';
2+
3+
/**
4+
* A Marionette test helper for app installation flow.
5+
*/
6+
7+
/**
8+
* @constructor
9+
* @param {Marionette.Client} client Marionette client to use.
10+
*/
11+
function AppInstall(client) {
12+
this.client = client.scope({ searchTimeout: 200000 });
13+
}
14+
15+
module.exports = AppInstall;
16+
17+
AppInstall.prototype = {
18+
19+
_install: function(type, manifestURL) {
20+
this.client.executeScript(function install(type, url) {
21+
window.wrappedJSObject.navigator.mozApps[type](url);
22+
}, [type, manifestURL]);
23+
},
24+
25+
/**
26+
* Install an app.
27+
* @param {string} manifestURL The manifestURL of the app to be installed.
28+
* @param {Object} [options] The options for installation.
29+
*/
30+
installPackage: function install(manifestURL) {
31+
return this._install('installPackage', manifestURL);
32+
},
33+
34+
/**
35+
* Install an app.
36+
* @param {string} manifestURL The manifestURL of the app to be installed.
37+
* @param {Object} [options] The options for installation.
38+
*/
39+
install: function install(manifestURL) {
40+
return this._install('install', manifestURL);
41+
},
42+
43+
/**
44+
* Uninstall an app.
45+
* @param {string} [manifestURL] The manifestURL of the app.
46+
*/
47+
uninstall: function(manifestURL) {
48+
this.client.switchToFrame();
49+
50+
this.client.executeAsyncScript(function uninstall(url) {
51+
var win = window.wrappedJSObject;
52+
var mgmt = win.navigator.mozApps.mgmt;
53+
54+
mgmt.getAll().onsuccess = function(e) {
55+
var app = e.target.result.find(function(app) {
56+
return app.manifestURL === url;
57+
});
58+
59+
mgmt.uninstall(app);
60+
marionetteScriptFinished();
61+
};
62+
}, [manifestURL]);
63+
},
64+
65+
/**
66+
Checks for downloads without applying them.
67+
*/
68+
stageUpdate: function(manifestURL) {
69+
// do it in chrome so we don't need to switch contexts...
70+
var client = this.client.scope({ context: 'chrome' });
71+
return client.executeAsyncScript(function(manifestURL) {
72+
navigator.mozApps.mgmt.getAll().onsuccess = function(e) {
73+
var list = e.target.result;
74+
var app = list.find(function(app) {
75+
return app.manifestURL === manifestURL;
76+
});
77+
var req = app.checkForUpdate();
78+
req.onsuccess = req.onerror = function() {
79+
marionetteScriptFinished();
80+
};
81+
};
82+
}, [manifestURL]);
83+
},
84+
85+
/**
86+
Updates an installed app by it's manifest url.
87+
88+
@param {String} manifestURL for the application.
89+
*/
90+
update: function(manifestURL) {
91+
// do it in chrome so we don't need to switch contexts...
92+
var client = this.client.scope({ context: 'chrome' });
93+
return client.executeAsyncScript(function(manifestURL) {
94+
navigator.mozApps.mgmt.getAll().onsuccess = function(e) {
95+
var list = e.target.result;
96+
var app = list.find(function(app) {
97+
return app.manifestURL === manifestURL;
98+
});
99+
100+
var req = app.checkForUpdate();
101+
req.onsuccess = function() {
102+
app.download();
103+
marionetteScriptFinished();
104+
};
105+
106+
req.onerror = function() {
107+
marionetteScriptFinished();
108+
};
109+
};
110+
}, [manifestURL]);
111+
}
112+
};

tv_apps/smart-system/test/marionette/lib/system.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ System.URL = 'app://smart-system.gaiamobile.org/manifest.webapp';
1212

1313
System.Selector = Object.freeze({
1414
appChromeContextMenuContainer: '.appWindow.active .modal-dialog',
15-
appChromeContextMenuDialog: '.appWindow.active .contextmenu .modal-dialog'
15+
appChromeContextMenuDialog: '.appWindow.active .contextmenu .modal-dialog',
16+
appInstallCancelButton: '#app-install-cancel-button',
17+
appInstallInstallButton: '#app-install-install-button',
18+
appCancelInstallConfirmButton: '#app-install-confirm-cancel-button',
19+
appCanelInstallResumeButton: '#app-install-resume-button',
20+
appUninstallCancelButton: '#app-uninstall-cancel-button',
21+
appUninstallConfirmButton: '#app-uninstall-confirm-button'
1622
});
1723

1824
System.prototype = {
@@ -61,6 +67,30 @@ System.prototype = {
6167
}, [evt]);
6268
},
6369

70+
_waitForAppState: function(manifestURL, installed) {
71+
this.client.waitFor(function() {
72+
return this.client.executeScript(function(manifestURL, installed) {
73+
var apps = window.wrappedJSObject.applications;
74+
var hasApp = !!apps.installedApps[manifestURL];
75+
return hasApp === installed;
76+
}, [manifestURL, installed]);
77+
}.bind(this));
78+
},
79+
80+
waitForAppInstalled: function(manifestURL) {
81+
return this._waitForAppState(manifestURL, true);
82+
},
83+
84+
waitForAppUninstalled: function(manifestURL) {
85+
return this._waitForAppState(manifestURL, false);
86+
},
87+
88+
isAppInstalled: function(manifestURL) {
89+
return this.client.executeScript(function(manifestURL) {
90+
return !!window.wrappedJSObject.applications.installedApps[manifestURL];
91+
}, [manifestURL]);
92+
},
93+
6494
goHome: function() {
6595
this.client.switchToFrame();
6696
this.client.executeAsyncScript(function() {

0 commit comments

Comments
 (0)