Bug 1251701 - Store imported scripts in memory; r=jgriffin

This bug is also a dependency for scheduling Mn-e10s tests on Windows 7
(bug 1251351).

MozReview-Commit-ID: 2jE4C99d1MX

--HG--
extra : rebase_source : 96c9fad49538fdadcc8f001aeef5926e82419001
This commit is contained in:
Andreas Tolfsen 2016-02-29 18:52:30 +00:00
Родитель 3cda6dc514
Коммит 278e4c6847
9 изменённых файлов: 323 добавлений и 258 удалений

Просмотреть файл

@ -11,7 +11,6 @@ var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
@ -25,11 +24,12 @@ XPCOMUtils.defineLazyServiceGetter(
Cu.import("chrome://marionette/content/action.js");
Cu.import("chrome://marionette/content/atom.js");
Cu.import("chrome://marionette/content/interaction.js");
Cu.import("chrome://marionette/content/element.js");
Cu.import("chrome://marionette/content/error.js");
Cu.import("chrome://marionette/content/evaluate.js");
Cu.import("chrome://marionette/content/event.js");
Cu.import("chrome://marionette/content/frame.js");
Cu.import("chrome://marionette/content/error.js");
Cu.import("chrome://marionette/content/interaction.js");
Cu.import("chrome://marionette/content/modal.js");
Cu.import("chrome://marionette/content/proxy.js");
Cu.import("chrome://marionette/content/simpletest.js");
@ -121,10 +121,7 @@ this.GeckoDriver = function(appName, device, stopSignal, emulator) {
// chrome iframe that currently has focus
this.curFrame = null;
this.mainContentFrameId = null;
this.importedScripts = FileUtils.getFile("TmpD", ["marionetteChromeScripts"]);
this.importedScriptHashes = {};
this.importedScriptHashes[Context.CONTENT] = [];
this.importedScriptHashes[Context.CHROME] = [];
this.importedScripts = new evaluate.ScriptStorageService([Context.CHROME, Context.CONTENT]);
this.currentFrameElement = null;
this.testName = null;
this.mozBrowserClose = null;
@ -836,15 +833,7 @@ GeckoDriver.prototype.executeScriptInSandbox = function(
throw new TimeoutError("Please set a timeout");
}
if (this.importedScripts.exists()) {
let stream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
stream.init(this.importedScripts, -1, 0, 0);
let data = NetUtil.readInputStreamToString(stream, stream.available());
stream.close();
script = data + script;
}
script = this.importedScripts.for(Context.CHROME).concat(script);
let res = Cu.evalInSandbox(script, sandbox, "1.8", filename ? filename : "dummy file", 0);
if (directInject && !async &&
@ -2499,58 +2488,31 @@ GeckoDriver.prototype.getAppCacheStatus = function*(cmd, resp) {
resp.body.value = yield this.listener.getAppCacheStatus();
};
/**
* Import script to the JS evaluation runtime.
*
* Imported scripts are exposed in the contexts of all subsequent
* calls to {@code executeScript}, {@code executeAsyncScript}, and
* {@code executeJSScript} by prepending them to the evaluated script.
*
* Scripts can be cleared with the {@code clearImportedScripts} command.
*
* @param {string} script
* Script to include. If the script is byte-by-byte equal to an
* existing imported script, it is not imported.
*/
GeckoDriver.prototype.importScript = function*(cmd, resp) {
let script = cmd.parameters.script;
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
let result = {};
let data = converter.convertToByteArray(cmd.parameters.script, result);
let ch = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
ch.init(ch.MD5);
ch.update(data, data.length);
let hash = ch.finish(true);
// return if we've already imported this script
if (this.importedScriptHashes[this.context].indexOf(hash) > -1) {
return;
}
this.importedScriptHashes[this.context].push(hash);
switch (this.context) {
case Context.CHROME:
let file;
if (this.importedScripts.exists()) {
file = FileUtils.openFileOutputStream(this.importedScripts,
FileUtils.MODE_APPEND | FileUtils.MODE_WRONLY);
} else {
// the permission bits here don't actually get set (bug 804563)
this.importedScripts.createUnique(
Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("0666", 8));
file = FileUtils.openFileOutputStream(this.importedScripts,
FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE);
this.importedScripts.permissions = parseInt("0666", 8);
}
file.write(script, script.length);
file.close();
break;
case Context.CONTENT:
yield this.listener.importScript({script: script});
break;
}
this.importedScripts.for(this.context).add(script);
};
GeckoDriver.prototype.clearImportedScripts = function(cmd, resp) {
switch (this.context) {
case Context.CHROME:
this.deleteFile("marionetteChromeScripts");
break;
case Context.CONTENT:
this.deleteFile("marionetteContentScripts");
break;
}
/**
* Clear all scripts that are imported into the JS evaluation runtime.
*
* Scripts can be imported using the {@code importScript} command.
*/
GeckoDriver.prototype.clearImportedScripts = function*(cmd, resp) {
this.importedScripts.for(this.context).clear();
};
/**

Просмотреть файл

@ -0,0 +1,179 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const logger = Log.repository.getLogger("Marionette");
this.EXPORTED_SYMBOLS = ["evaluate"];
this.evaluate = {};
/**
* Stores scripts imported from the local end through the
* {@code GeckoDriver#importScript} command.
*
* Imported scripts are prepended to the script that is evaluated
* on each call to {@code GeckoDriver#executeScript},
* {@code GeckoDriver#executeAsyncScript}, and
* {@code GeckoDriver#executeJSScript}.
*
* Usage:
*
* let importedScripts = new evaluate.ScriptStorage();
* importedScripts.add(firstScript);
* importedScripts.add(secondScript);
*
* let scriptToEval = importedScripts.concat(script);
* // firstScript and secondScript are prepended to script
*
*/
evaluate.ScriptStorage = class extends Set {
/**
* Produce a string of all stored scripts.
*
* The stored scripts are concatenated into a string, with optional
* additional scripts then appended.
*
* @param {...string} addional
* Optional scripts to include.
*
* @return {string}
* Concatenated string consisting of stored scripts and additional
* scripts, in that order.
*/
concat(...additional) {
let rv = "";
for (let s of this) {
rv = s + rv;
}
for (let s of additional) {
rv = rv + s;
}
return rv;
}
toJson() {
return Array.from(this);
}
};
/**
* Service that enables the script storage service to be queried from
* content space.
*
* The storage can back multiple |ScriptStorage|, each typically belonging
* to a |Context|. Since imported scripts' scope are global and not
* scoped to the current browsing context, all imported scripts are stored
* in chrome space and fetched by content space as needed.
*
* Usage in chrome space:
*
* let service = new evaluate.ScriptStorageService(
* [Context.CHROME, Context.CONTENT]);
* let storage = service.for(Context.CHROME);
* let scriptToEval = storage.concat(script);
*
*/
evaluate.ScriptStorageService = class extends Map {
/**
* Create the service.
*
* An optional array of names for script storages to initially create
* can be provided.
*
* @param {Array.<string>=} initialStorages
* List of names of the script storages to create initially.
*/
constructor(initialStorages = []) {
super(initialStorages.map(name => [name, new evaluate.ScriptStorage()]));
}
/**
* Retrieve the scripts associated with the given context.
*
* @param {Context} context
* Context to retrieve the scripts from.
*
* @return {ScriptStorage}
* Scrips associated with given |context|.
*/
for(context) {
return this.get(context);
}
processMessage(msg) {
switch (msg.name) {
case "Marionette:getImportedScripts":
let storage = this.for.apply(this, msg.json);
return storage.toJson();
default:
throw new TypeError("Unknown message: " + msg.name);
}
}
// TODO(ato): The idea of services in chrome space
// can be generalised at some later time (see cookies.js:38).
receiveMessage(msg) {
try {
return this.processMessage(msg);
} catch (e) {
logger.error(e);
}
}
};
evaluate.ScriptStorageService.prototype.QueryInterface =
XPCOMUtils.generateQI([
Ci.nsIMessageListener,
Ci.nsISupportsWeakReference,
]);
/**
* Bridges the script storage in chrome space, to make it possible to
* retrieve a {@code ScriptStorage} associated with a given
* {@code Context} from content space.
*
* Usage in content space:
*
* let client = new evaluate.ScriptStorageServiceClient(chromeProxy);
* let storage = client.for(Context.CONTENT);
* let scriptToEval = storage.concat(script);
*
*/
evaluate.ScriptStorageServiceClient = class {
/**
* @param {proxy.SyncChromeSender} chromeProxy
* Proxy for communicating with chrome space.
*/
constructor(chromeProxy) {
this.chrome = chromeProxy;
}
/**
* Retrieve scripts associated with the given context.
*
* @param {Context} context
* Context to retrieve scripts from.
*
* @return {ScriptStorage}
* Scripts associated with given |context|.
*/
for(context) {
let scripts = this.chrome.getImportedScripts(context)[0];
return new evaluate.ScriptStorage(scripts);
}
};

Просмотреть файл

@ -222,6 +222,7 @@ frame.Manager = class {
mm.addWeakMessageListener("Marionette:switchToModalOrigin", this.driver);
mm.addWeakMessageListener("Marionette:switchedToFrame", this.driver);
mm.addWeakMessageListener("Marionette:getVisibleCookies", this.driver);
mm.addWeakMessageListener("Marionette:getImportedScripts", this.driver.importedScripts);
mm.addWeakMessageListener("Marionette:register", this.driver);
mm.addWeakMessageListener("Marionette:listenersAttached", this.driver);
mm.addWeakMessageListener("Marionette:getFiles", this.driver);
@ -252,6 +253,7 @@ frame.Manager = class {
mm.removeWeakMessageListener("Marionette:runEmulatorShell", this.driver.emulator);
mm.removeWeakMessageListener("Marionette:switchedToFrame", this.driver);
mm.removeWeakMessageListener("Marionette:getVisibleCookies", this.driver);
mm.removeWeakMessageListener("Marionette:getImportedScripts", this.driver.importedScripts);
mm.removeWeakMessageListener("Marionette:listenersAttached", this.driver);
mm.removeWeakMessageListener("Marionette:register", this.driver);
mm.removeWeakMessageListener("Marionette:getFiles", this.driver);

Просмотреть файл

@ -79,6 +79,13 @@ def expectedFailure(func):
raise _UnexpectedSuccess
return wrapper
def skip_if_chrome(target):
def wrapper(self, *args, **kwargs):
if self.marionette._send_message("getContext", key="value") == "chrome":
raise SkipTest("skipping test in chrome context")
return target(self, *args, **kwargs)
return wrapper
def skip_if_desktop(target):
def wrapper(self, *args, **kwargs):
if self.marionette.session_capabilities.get('b2g') is None:

Просмотреть файл

@ -3,140 +3,123 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
from marionette import MarionetteTestCase
from marionette.marionette_test import MarionetteTestCase, skip_if_chrome
from marionette_driver.errors import JavascriptException
class TestImportScript(MarionetteTestCase):
class TestImportScriptContent(MarionetteTestCase):
contexts = set(["chrome", "content"])
script_file = os.path.abspath(
os.path.join(__file__, os.path.pardir, "importscript.js"))
another_script_file = os.path.abspath(
os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
def setUp(self):
MarionetteTestCase.setUp(self)
for context in self.contexts:
with self.marionette.using_context(context):
self.marionette.clear_imported_scripts()
self.reset_context()
def clear_other_context(self):
self.marionette.set_context("chrome")
self.marionette.clear_imported_scripts()
def reset_context(self):
self.marionette.set_context("content")
def check_file_exists(self):
return self.marionette.execute_script("""
let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
return importedScripts.exists();
""", sandbox='system')
@property
def current_context(self):
return self.marionette._send_message("getContext", key="value")
def get_file_size(self):
return self.marionette.execute_script("""
let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
return importedScripts.fileSize;
""", sandbox='system')
@property
def other_context(self):
return self.contexts.copy().difference([self.current_context]).pop()
def is_defined(self, symbol):
return self.marionette.execute_script(
"return typeof %s != 'undefined'" % symbol)
def assert_defined(self, symbol, msg=None):
if msg is None:
msg = "Expected symbol %s to be defined" % symbol
self.assertTrue(self.is_defined(symbol), msg)
def assert_undefined(self, symbol, msg=None):
if msg is None:
msg = "Expected symbol %s to be undefined" % symbol
self.assertFalse(self.is_defined(symbol), msg)
def assert_scripts_cleared(self):
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
self.marionette.clear_imported_scripts()
self.assert_undefined("testFunc")
def test_import_script(self):
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
self.marionette.import_script(js)
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
self.marionette.import_script(self.script_file)
self.assertEqual(
"i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script(
"marionetteScriptFinished(testFunc());"))
def test_import_script_twice(self):
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
self.marionette.import_script(js)
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
self.assertTrue(self.check_file_exists())
file_size = self.get_file_size()
self.assertNotEqual(file_size, None)
self.marionette.import_script(js)
file_size = self.get_file_size()
self.assertEqual(file_size, self.get_file_size())
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
def test_import_two_scripts_twice(self):
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
self.marionette.import_script(js)
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
self.assertTrue(self.check_file_exists())
file_size = self.get_file_size()
self.assertNotEqual(file_size, None)
self.marionette.import_script(js)
# same script should not append to file
self.assertEqual(file_size, self.get_file_size())
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
self.marionette.import_script(js)
new_size = self.get_file_size()
# new script should append to file
self.assertNotEqual(file_size, new_size)
file_size = new_size
self.assertEqual("i'm yet another test function!",
self.marionette.execute_script("return testAnotherFunc();"))
self.assertEqual("i'm yet another test function!",
self.marionette.execute_async_script("marionetteScriptFinished(testAnotherFunc());"))
self.marionette.import_script(js)
# same script should not append to file
self.assertEqual(file_size, self.get_file_size())
# TODO(ato): Note that the WebDriver command primitives
# does not allow us to check what scripts have been imported.
# I suspect we must to do this through an xpcshell test.
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
def test_import_script_and_clear(self):
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
self.marionette.import_script(js)
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
self.marionette.clear_imported_scripts()
self.assertFalse(self.check_file_exists())
self.assertRaises(JavascriptException, self.marionette.execute_script, "return testFunc();")
self.assertRaises(JavascriptException, self.marionette.execute_async_script, "marionetteScriptFinished(testFunc());")
self.assert_scripts_cleared()
self.assert_undefined("testFunc")
with self.assertRaises(JavascriptException):
self.marionette.execute_script("return testFunc()")
with self.assertRaises(JavascriptException):
self.marionette.execute_async_script(
"marionetteScriptFinished(testFunc())")
def test_clear_scripts_in_other_context(self):
self.marionette.import_script(self.script_file)
self.assert_defined("testFunc")
def test_import_script_and_clear_in_chrome(self):
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
self.marionette.import_script(js)
self.assertTrue(self.check_file_exists())
file_size = self.get_file_size()
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
self.clear_other_context()
# clearing other context's script file should not affect ours
self.assertTrue(self.check_file_exists())
self.assertEqual(file_size, self.get_file_size())
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
with self.marionette.using_context(self.other_context):
self.marionette.clear_imported_scripts()
self.assert_undefined("testFunc")
def test_importing_another_script_and_check_they_append(self):
firstjs = os.path.abspath(
os.path.join(__file__, os.path.pardir, "importscript.js"))
secondjs = os.path.abspath(
os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
self.assert_defined("testFunc")
self.marionette.import_script(firstjs)
self.marionette.import_script(secondjs)
def test_multiple_imports(self):
self.marionette.import_script(self.script_file)
self.marionette.import_script(self.another_script_file)
self.assert_defined("testFunc")
self.assert_defined("testAnotherFunc")
self.assertEqual("i'm a test function!",
self.marionette.execute_script("return testFunc();"))
@skip_if_chrome
def test_imports_apply_globally(self):
self.marionette.navigate(
self.marionette.absolute_url("test_windows.html"))
original_window = self.marionette.current_window_handle
self.marionette.find_element("link text", "Open new window").click()
self.assertEqual("i'm yet another test function!",
self.marionette.execute_script("return testAnotherFunc();"))
windows = set(self.marionette.window_handles)
print "windows=%s" % windows
new_window = windows.difference([original_window]).pop()
self.marionette.switch_to_window(new_window)
class TestImportScriptChrome(TestImportScript):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_script_timeout(30000)
self.marionette.import_script(self.script_file)
self.marionette.close()
print "switching to original window: %s" % original_window
self.marionette.switch_to_window(original_window)
self.assert_defined("testFunc")
class TestImportScriptChrome(TestImportScriptContent):
def reset_context(self):
self.marionette.set_context("chrome")
def clear_other_context(self):
self.marionette.set_context("content")
self.marionette.clear_imported_scripts()
self.marionette.set_context("chrome")
def check_file_exists(self):
return self.marionette.execute_async_script("""
let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']);
marionetteScriptFinished(importedScripts.exists());
""")
def get_file_size(self):
return self.marionette.execute_async_script("""
let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']);
marionetteScriptFinished(importedScripts.fileSize);
""")

Просмотреть файл

@ -1,28 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
from marionette import MarionetteTestCase
class TestImportScriptContent(MarionetteTestCase):
def test_importing_script_then_reusing_it(self):
test_html = self.marionette.absolute_url("test_windows.html")
self.marionette.navigate(test_html)
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
self.current_window = self.marionette.current_window_handle
link = self.marionette.find_element("link text", "Open new window")
link.click()
windows = self.marionette.window_handles
windows.remove(self.current_window)
self.marionette.switch_to_window(windows[0])
self.marionette.import_script(js)
self.marionette.close()
self.marionette.switch_to_window(self.current_window)
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))

Просмотреть файл

@ -23,8 +23,6 @@ b2g = false
expected = fail
[test_import_script.py]
b2g = false
[test_import_script_reuse_window.py]
b2g = false
[test_click.py]
[test_click_chrome.py]
b2g = false

Просмотреть файл

@ -24,6 +24,7 @@ marionette.jar:
content/capture.js (capture.js)
content/cookies.js (cookies.js)
content/atom.js (atom.js)
content/evaluate.js (evaluate.js)
#ifdef ENABLE_TESTS
content/test.xul (harness/marionette/chrome/test.xul)
content/test2.xul (harness/marionette/chrome/test2.xul)

Просмотреть файл

@ -19,12 +19,12 @@ Cu.import("chrome://marionette/content/capture.js");
Cu.import("chrome://marionette/content/cookies.js");
Cu.import("chrome://marionette/content/element.js");
Cu.import("chrome://marionette/content/error.js");
Cu.import("chrome://marionette/content/evaluate.js");
Cu.import("chrome://marionette/content/event.js");
Cu.import("chrome://marionette/content/proxy.js");
Cu.import("chrome://marionette/content/interaction.js");
Cu.import("chrome://marionette/content/proxy.js");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -46,7 +46,6 @@ var capabilities = {};
var interactions = new Interactions(() => capabilities);
var actions = new action.Chain(checkForInterrupted);
var importedScripts = null;
// Contains the last file input element that was the target of
// sendKeysToElement.
@ -83,6 +82,7 @@ var multiLast = {};
var chrome = proxy.toChrome(sendSyncMessage.bind(this));
var cookies = new Cookies(() => curContainer.frame.document, chrome);
var importedScripts = new evaluate.ScriptStorageServiceClient(chrome);
Cu.import("resource://gre/modules/Log.jsm");
var logger = Log.repository.getLogger("Marionette");
@ -117,8 +117,6 @@ function registerSelf() {
if (register[0][1] == true) {
addMessageListener("MarionetteMainListener:emitTouchEvent", emitTouchEventForIFrame);
}
importedScripts = FileUtils.getDir('TmpD', [], false);
importedScripts.append('marionetteContentScripts');
startListeners();
let rv = {};
if (remotenessChange) {
@ -164,6 +162,10 @@ function emitTouchEventForIFrame(message) {
// Perhaps one could even conceive having a separate instance of
// CommandProcessor for the listener, because the code is mostly the same.
function dispatch(fn) {
if (typeof fn != "function") {
throw new TypeError("Provided dispatch handler is not a function");
}
return function(msg) {
let id = msg.json.command_id;
@ -270,7 +272,6 @@ function startListeners() {
addMessageListenerId("Marionette:deleteSession", deleteSession);
addMessageListenerId("Marionette:sleepSession", sleepSession);
addMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
addMessageListenerId("Marionette:importScript", importScript);
addMessageListenerId("Marionette:getAppCacheStatus", getAppCacheStatus);
addMessageListenerId("Marionette:setTestName", setTestName);
addMessageListenerId("Marionette:takeScreenshot", takeScreenshotFn);
@ -375,7 +376,6 @@ function deleteSession(msg) {
removeMessageListenerId("Marionette:deleteSession", deleteSession);
removeMessageListenerId("Marionette:sleepSession", sleepSession);
removeMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
removeMessageListenerId("Marionette:importScript", importScript);
removeMessageListenerId("Marionette:getAppCacheStatus", getAppCacheStatus);
removeMessageListenerId("Marionette:setTestName", setTestName);
removeMessageListenerId("Marionette:takeScreenshot", takeScreenshotFn);
@ -622,15 +622,9 @@ function executeScript(msg, directInject) {
try {
if (directInject) {
if (importedScripts.exists()) {
let stream = Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
stream.init(importedScripts, -1, 0, 0);
let data = NetUtil.readInputStreamToString(stream, stream.available());
stream.close();
script = data + script;
}
script = importedScripts.for("content").concat(script);
let res = Cu.evalInSandbox(script, sandbox, "1.8", filename ? filename : "dummy file" ,0);
sendSyncMessage("Marionette:shareData",
{log: elementManager.wrapValue(marionetteLogObj.getLogs())});
marionetteLogObj.clearLogs();
@ -653,14 +647,8 @@ function executeScript(msg, directInject) {
script = "var __marionetteFunc = function(){" + script + "};" +
"__marionetteFunc.apply(null, __marionetteParams);";
if (importedScripts.exists()) {
let stream = Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
stream.init(importedScripts, -1, 0, 0);
let data = NetUtil.readInputStreamToString(stream, stream.available());
stream.close();
script = data + script;
}
script = importedScripts.for("content").concat(script);
let res = Cu.evalInSandbox(script, sandbox, "1.8", filename ? filename : "dummy file", 0);
sendSyncMessage("Marionette:shareData",
{log: elementManager.wrapValue(marionetteLogObj.getLogs())});
@ -809,14 +797,7 @@ function executeWithCallback(msg, useFinish) {
try {
asyncTestRunning = true;
if (importedScripts.exists()) {
let stream = Cc["@mozilla.org/network/file-input-stream;1"].
createInstance(Ci.nsIFileInputStream);
stream.init(importedScripts, -1, 0, 0);
let data = NetUtil.readInputStreamToString(stream, stream.available());
stream.close();
scriptSrc = data + scriptSrc;
}
scriptSrc = importedScripts.for("content").concat(scriptSrc);
Cu.evalInSandbox(scriptSrc, sandbox, "1.8", filename ? filename : "dummy file", 0);
} catch (e) {
let err = new JavaScriptError(
@ -1763,26 +1744,6 @@ function emulatorCmdResult(msg) {
}
}
function importScript(msg) {
let command_id = msg.json.command_id;
let file;
if (importedScripts.exists()) {
file = FileUtils.openFileOutputStream(importedScripts,
FileUtils.MODE_APPEND | FileUtils.MODE_WRONLY);
}
else {
//Note: The permission bits here don't actually get set (bug 804563)
importedScripts.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE,
parseInt("0666", 8));
file = FileUtils.openFileOutputStream(importedScripts,
FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE);
importedScripts.permissions = parseInt("0666", 8); //actually set permissions
}
file.write(msg.json.script, msg.json.script.length);
file.close();
sendOk(command_id);
}
/**
* Perform a screen capture in content context.
*