зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
3cda6dc514
Коммит
278e4c6847
|
@ -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.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче