/** * Support logic to run a test file as an installed app. This file is derived * from dom/requestsync/tests/test_basic_app.html but uses * DOMApplicationRegistry in a chrome script (shim_app_as_test_chrome.js) to * directly install the apps instead of mozApps.install because mozApps.install * can't install privileged/certified apps. (This is the same mechanism used by * the Firefox OS Gaia email app's backend test runner.) * * You really only want to do this if your test cares about the app's origin * or you REALLY want to double-check AvailableIn and other WebIDL-provided * security mechanisms. * * If you trust WebIDL, your life may be made significantly easier by just * setting the pref "dom.ignore_webidl_scope_checks" to true, which makes * BindingUtils.cpp's IsInPrivilegedApp and IsInCertifiedApp return true no * matter what *on the main thread*. You are potentially out of luck on * workers since at the time of writing this since the values stored on * WorkerPrivateParent are based on the app status and ignore the pref. * * TO USE THIS: * * Make sure you have the usual header boilerplate: * * * * You also want to add this file! * * * In your script body, issue a call like so: * runAppTest({ * appFile: 'testapp_downloads_adopt_download.html', * appManifest: 'testapp_downloads_adopt_download.manifest', * appType: 'certified', * extraPrefs: { * set: [["dom.mozDownloads.enabled", true]] * } * }); * * You shouldn't be adding other stuff to that file. Instead, you want * everything in your testapp_*.html file. And you probably just want to copy * and paste from an existing one of those... */ var gManifestURL; var gApp; var gOptions; // Load the chrome script. var gChromeHelper = SpecialPowers.loadChromeScript( SimpleTest.getTestFileURL('shim_app_as_test_chrome.js')); function installApp() { info("installing app"); var useOrigin = document.location.origin; gChromeHelper.sendAsyncMessage( 'install', { origin: useOrigin, manifestURL: SimpleTest.getTestFileURL(gOptions.appManifest), }); } function installedApp(appInfo) { gApp = appInfo; ok(!!appInfo, 'installed app'); runTests(); } gChromeHelper.addMessageListener('installed', installedApp); function uninstallApp() { info('uninstalling app'); gChromeHelper.sendAsyncMessage('uninstall', gApp); } function uninstalledApp(success) { ok(success, 'uninstalled app'); runTests(); } gChromeHelper.addMessageListener('uninstalled', uninstalledApp); function testApp() { var cleanupFrame; var handleTestMessage = function(message) { if (/^OK/.exec(message)) { ok(true, "Message from app: " + message); } else if (/^KO/.exec(message)) { ok(false, "Message from app: " + message); } else if (/^INFO/.exec(message)) { info("Message from app: " + message.substring(5)); } else if (/^DONE$/.exec(message)) { ok(true, "Messaging from app complete"); cleanupFrame(); runTests(); } }; // Bug 1097479 means that embed-webapps does not work if you are already // OOP, as we are for b2g. So we need to have the chrome script run our // app in a sibling iframe to the one we're living in. When that bug is // fixed or we are run in a non-b2g context, we can set this value to false // or otherwise conditionalize based on behaviour. var needSiblingIframeHack = true; if (needSiblingIframeHack) { gChromeHelper.sendAsyncMessage('run', gApp); gChromeHelper.addMessageListener('appMessage', handleTestMessage); gChromeHelper.addMessageListener('appError', function(data) { ok(false, "Error in app frame: " + data.message); }); cleanupFrame = function() { gChromeHelper.sendAsyncMessage('close', {}); }; } else { var ifr = document.createElement('iframe'); ifr.setAttribute('mozbrowser', 'true'); ifr.setAttribute('mozapp', gApp.manifestURL); cleanupFrame = function() { ifr.removeEventListener('mozbrowsershowmodalprompt', listener); domParent.removeChild(ifr); }; // Set us up to listen for messages from the app. var listener = function(e) { var message = e.detail.message; // e.detail.message; handleTestMessage(message); }; // This event is triggered when the app calls "alert". ifr.addEventListener('mozbrowsershowmodalprompt', listener, false); ifr.addEventListener('mozbrowsererror', function(evt) { ok(false, "Error in app frame: " + evt.detail); }); ifr.setAttribute('src', gApp.manifest.launch_path); var domParent = document.getElementById('content'); if (!domParent) { document.createElement('div'); document.body.insertBefore(domParent, document.body.firstChild); } domParent.appendChild(ifr); } } var tests = [ // Permissions function() { info("pushing permissions"); SpecialPowers.pushPermissions( [{ "type": "browser", "allow": 1, "context": document }, { "type": "embed-apps", "allow": 1, "context": document }, { "type": "webapps-manage", "allow": 1, "context": document } ], runTests); }, // Preferences function() { info("pushing preferences: " + gOptions.extraPrefs.set); SpecialPowers.pushPrefEnv({ "set": gOptions.extraPrefs.set }, runTests); }, function() { info("enabling use of mozbrowser"); //SpecialPowers.setAllAppsLaunchable(true); SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true); runTests(); }, // No confirmation needed when an app is installed function() { SpecialPowers.autoConfirmAppInstall(function() { SpecialPowers.autoConfirmAppUninstall(runTests); }); }, // Installing the app installApp, // Run tests in app testApp, // Uninstall the app uninstallApp, ]; function runTests() { if (!tests.length) { ok(true, 'DONE!'); SimpleTest.finish(); return; } var test = tests.shift(); test(); } SimpleTest.waitForExplicitFinish(); function runAppTest(options) { gOptions = options; var href = document.location.href; gManifestURL = href.substring(0, href.lastIndexOf('/') + 1) + options.appManifest; runTests(); }