Bug 1149618 - Remove SpecialPowers from Marionette, r=dburns

This commit is contained in:
Jonathan Griffin 2015-05-18 16:36:15 -07:00
parent d6a44b8e13
commit ac2f6d8d6e
18 changed files with 284 additions and 296 deletions

View File

@ -276,9 +276,24 @@ class B2GRemoteAutomation(Automation):
if 'b2g' not in session:
raise Exception("bad session value %s returned by start_session" % session)
if self.context_chrome:
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
else:
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
self.marionette.execute_script("""
let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
Components.utils.import("resource://gre/modules/Services.jsm");
Services.prefs.setBoolPref(SECURITY_PREF, true);
if (!testUtils.hasOwnProperty("specialPowersObserver")) {
let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.js",
testUtils);
testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
testUtils.specialPowersObserver.init();
testUtils.specialPowersObserver._loadFrameScript();
}
""")
if not self.context_chrome:
self.marionette.set_context(self.marionette.CONTEXT_CONTENT)
# run the script that starts the tests

View File

@ -109,8 +109,8 @@ class ResourceUriFileReader:
}
CODE_OPEN_CHANNEL_BY_URI = '''
var Cc = SpecialPowers.Cc;
var Ci = SpecialPowers.Ci;
var Cc = Components.classes;
var Ci = Components.interfaces;
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
global.uri = '%(uri)s';
@ -129,8 +129,8 @@ class ResourceUriFileReader:
'''
CODE_READ_CONTENT = '''
var Cc = SpecialPowers.Cc;
var Ci = SpecialPowers.Ci;
var Cc = Components.classes;
var Ci = Components.interfaces;
var zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader);
var inputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
@ -155,7 +155,9 @@ class ResourceUriFileReader:
return cls.URI_PREFIX + cls.URI_PATH[filename]
def __init__(self, marionette):
self.runjs = lambda x: marionette.execute_script(x, new_sandbox=False)
self.runjs = lambda x: marionette.execute_script(x,
new_sandbox=False,
sandbox='system')
def read_file(self, filename):
"""Read file and return the contents as string."""
@ -210,7 +212,9 @@ class JSHintEngine:
for line in config.splitlines()])
# Set global (JSHINT, options, global) in js environment.
self.runjs = lambda x: marionette.execute_script(x, new_sandbox=False)
self.runjs = lambda x: marionette.execute_script(x,
new_sandbox=False,
sandbox='system')
self.runjs(self.CODE_INIT_JSHINT %
{'script': script, 'config_string': repr(config)})

View File

@ -238,8 +238,7 @@ class B2GUpdateTestCase(MarionetteTestCase):
self.print_status(status, os.path.basename(path))
results = self.marionette.execute_async_script(data,
script_args=[self.testvars],
special_powers=True)
script_args=[self.testvars])
self.handle_results(path, stage, results)
def handle_results(self, path, stage, results):

View File

@ -502,6 +502,24 @@ setReq.onerror = function() {
'iframe[src*="app://test-container.gaiamobile.org/index.html"]'
))
def setup_SpecialPowers_observer(self):
self.marionette.set_context("chrome")
self.marionette.execute_script("""
let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
Components.utils.import("resource://gre/modules/Services.jsm");
Services.prefs.setBoolPref(SECURITY_PREF, true);
if (!testUtils.hasOwnProperty("specialPowersObserver")) {
let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.js",
testUtils);
testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
testUtils.specialPowersObserver.init();
testUtils.specialPowersObserver._loadFrameScript();
}
""")
def run_js_test(self, filename, marionette=None):
'''
Run a JavaScript test file and collect its set of assertions
@ -537,6 +555,23 @@ setReq.onerror = function() {
context = context.group(3)
else:
context = 'content'
if 'SpecialPowers' in js:
self.setup_SpecialPowers_observer()
if context == 'content':
js = "var SpecialPowers = window.wrappedJSObject.SpecialPowers;\n" + js
else:
marionette.execute_script("""
if (typeof(SpecialPowers) == 'undefined') {
let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://specialpowers/content/specialpowersAPI.js");
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserverAPI.js");
loader.loadSubScript("chrome://specialpowers/content/ChromePowers.js");
}
""")
marionette.set_context(context)
if context != 'chrome':
@ -555,7 +590,6 @@ setReq.onerror = function() {
results = marionette.execute_js_script(
js,
args,
special_powers=True,
inactivity_timeout=inactivity_timeout,
filename=os.path.basename(filename)
)

View File

@ -3,29 +3,31 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette import MarionetteTestCase
from marionette_driver.by import By
class TestGetActiveFrameOOP(MarionetteTestCase):
def setUp(self):
super(TestGetActiveFrameOOP, self).setUp()
self.oop_by_default = self.marionette.execute_script("""
try {
return SpecialPowers.getBoolPref('dom.ipc.browser_frames.oop_by_default');
}
catch(e) {}
""")
self.mozBrowserFramesEnabled = self.marionette.execute_script("""
try {
return SpecialPowers.getBoolPref('dom.mozBrowserFramesEnabled');
}
catch(e) {}
""")
self.marionette.execute_script("""
SpecialPowers.setBoolPref('dom.ipc.browser_frames.oop_by_default', true);
""")
self.marionette.execute_script("""
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', true);
""")
with self.marionette.using_context('chrome'):
self.oop_by_default = self.marionette.execute_script("""
try {
return Services.prefs.getBoolPref('dom.ipc.browser_frames.oop_by_default');
}
catch(e) {}
""")
self.mozBrowserFramesEnabled = self.marionette.execute_script("""
try {
return Services.prefs.getBoolPref('dom.mozBrowserFramesEnabled');
}
catch(e) {}
""")
self.marionette.execute_script("""
Services.prefs.setBoolPref('dom.ipc.browser_frames.oop_by_default', true);
""")
self.marionette.execute_script("""
Services.prefs.setBoolPref('dom.mozBrowserFramesEnabled', true);
""")
def test_active_frame_oop(self):
self.marionette.navigate(self.marionette.absolute_url("test.html"))
@ -34,9 +36,9 @@ class TestGetActiveFrameOOP(MarionetteTestCase):
# Create first OOP frame
self.marionette.execute_script("""
let iframe1 = document.createElement("iframe");
SpecialPowers.wrap(iframe1).mozbrowser = true;
SpecialPowers.wrap(iframe1).remote = true;
iframe1.id = "remote_iframe1";
iframe1.setAttribute('remote', true);
iframe1.setAttribute('mozbrowser', true);
iframe1.style.height = "100px";
iframe1.style.width = "100%%";
iframe1.src = "%s";
@ -48,7 +50,8 @@ class TestGetActiveFrameOOP(MarionetteTestCase):
self.assertTrue("test.html" in self.marionette.get_url())
# Switch to iframe1, get active frame
self.marionette.switch_to_frame('remote_iframe1')
frame = self.marionette.find_element(By.ID, 'remote_iframe1')
self.marionette.switch_to_frame(frame)
active_frame1 = self.marionette.get_active_frame()
self.assertNotEqual(active_frame1.id, None)
@ -61,8 +64,8 @@ class TestGetActiveFrameOOP(MarionetteTestCase):
self.marionette.switch_to_frame()
self.marionette.execute_script("""
let iframe2 = document.createElement("iframe");
SpecialPowers.wrap(iframe2).mozbrowser = true;
SpecialPowers.wrap(iframe2).remote = true;
iframe2.setAttribute('mozbrowser', true);
iframe2.setAttribute('remote', true);
iframe2.id = "remote_iframe2";
iframe2.style.height = "100px";
iframe2.style.width = "100%%";
@ -71,7 +74,8 @@ class TestGetActiveFrameOOP(MarionetteTestCase):
""" % self.marionette.absolute_url("test_oop_2.html"))
# Switch to iframe2, get active frame
self.marionette.switch_to_frame('remote_iframe2')
frame2 = self.marionette.find_element(By.ID, 'remote_iframe2')
self.marionette.switch_to_frame(frame2)
active_frame2 = self.marionette.get_active_frame()
self.assertNotEqual(active_frame2.id, None)
@ -92,19 +96,20 @@ class TestGetActiveFrameOOP(MarionetteTestCase):
# print self.marionette.page_source
def tearDown(self):
if self.oop_by_default is None:
self.marionette.execute_script("""
SpecialPowers.clearUserPref('dom.ipc.browser_frames.oop_by_default');
""")
else:
self.marionette.execute_script("""
SpecialPowers.setBoolPref('dom.ipc.browser_frames.oop_by_default', %s);
""" % 'true' if self.oop_by_default else 'false')
if self.mozBrowserFramesEnabled is None:
self.marionette.execute_script("""
SpecialPowers.clearUserPref('dom.mozBrowserFramesEnabled');
""")
else:
self.marionette.execute_script("""
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', %s);
""" % 'true' if self.mozBrowserFramesEnabled else 'false')
with self.marionette.using_context('chrome'):
if self.oop_by_default is None:
self.marionette.execute_script("""
Services.prefs.clearUserPref('dom.ipc.browser_frames.oop_by_default');
""")
else:
self.marionette.execute_script("""
Services.prefs.setBoolPref('dom.ipc.browser_frames.oop_by_default', %s);
""" % 'true' if self.oop_by_default else 'false')
if self.mozBrowserFramesEnabled is None:
self.marionette.execute_script("""
Services.prefs.clearUserPref('dom.mozBrowserFramesEnabled');
""")
else:
self.marionette.execute_script("""
Services.prefs.setBoolPref('dom.mozBrowserFramesEnabled', %s);
""" % 'true' if self.mozBrowserFramesEnabled else 'false')

View File

@ -17,17 +17,17 @@ class TestImportScript(MarionetteTestCase):
def check_file_exists(self):
return self.marionette.execute_script("""
let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
return importedScripts.exists();
""", special_powers=True)
""", sandbox='system')
def get_file_size(self):
return self.marionette.execute_script("""
let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let FileUtils = Components.utils.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
return importedScripts.fileSize;
""", special_powers=True)
""", sandbox='system')
def test_import_script(self):
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))

View File

@ -10,46 +10,51 @@ class TestLog(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.enforce_gecko_prefs({"marionette.test.bool": True, "marionette.test.string": "testing", "marionette.test.int": 3})
self.marionette.set_context('chrome')
def test_preferences_are_set(self):
bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.bool');")
string_value = self.marionette.execute_script("return SpecialPowers.getCharPref('marionette.test.string');")
int_value = self.marionette.execute_script("return SpecialPowers.getIntPref('marionette.test.int');")
bool_value = self.marionette.execute_script("return Services.prefs.getBoolPref('marionette.test.bool');")
string_value = self.marionette.execute_script("return Services.prefs.getCharPref('marionette.test.string');")
int_value = self.marionette.execute_script("return Services.prefs.getIntPref('marionette.test.int');")
self.assertTrue(bool_value)
self.assertEqual(string_value, "testing")
self.assertEqual(int_value, 3)
def test_change_preset(self):
bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.bool');")
bool_value = self.marionette.execute_script("return Services.prefs.getBoolPref('marionette.test.bool');")
self.assertTrue(bool_value)
self.marionette.enforce_gecko_prefs({"marionette.test.bool": False})
bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.bool');")
self.marionette.set_context('chrome')
bool_value = self.marionette.execute_script("return Services.prefs.getBoolPref('marionette.test.bool');")
self.assertFalse(bool_value)
def test_clean_profile(self):
self.marionette.restart(clean=True)
with self.assertRaisesRegexp(JavascriptException, "Error getting pref"):
bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.bool');")
self.marionette.set_context('chrome')
with self.assertRaisesRegexp(JavascriptException, "NS_ERROR_UNEXPECTED"):
bool_value = self.marionette.execute_script("return Services.prefs.getBoolPref('marionette.test.bool');")
def test_can_restart_the_browser(self):
self.marionette.enforce_gecko_prefs({"marionette.test.restart": True})
self.marionette.restart()
bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.restart');")
self.marionette.set_context('chrome')
bool_value = self.marionette.execute_script("return Services.prefs.getBoolPref('marionette.test.restart');")
self.assertTrue(bool_value)
def test_in_app_restart_the_browser(self):
self.marionette.execute_script("SpecialPowers.setBoolPref('marionette.test.restart', true);")
self.marionette.execute_script("Services.prefs.setBoolPref('marionette.test.restart', true);")
# A "soft" restart initiated inside the application should keep track of this pref.
self.marionette.restart(in_app=True)
self.marionette.set_context('chrome')
bool_value = self.marionette.execute_script("""
return SpecialPowers.getBoolPref('marionette.test.restart');
return Services.prefs.getBoolPref('marionette.test.restart');
""")
self.assertTrue(bool_value)
bool_value = self.marionette.execute_script("""
SpecialPowers.setBoolPref('marionette.test.restart', false);
return SpecialPowers.getBoolPref('marionette.test.restart');
Services.prefs.setBoolPref('marionette.test.restart', false);
return Services.prefs.getBoolPref('marionette.test.restart');
""")
self.assertFalse(bool_value)

View File

@ -1,35 +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/.
from marionette import MarionetteTestCase
class TestSpecialPowersContent(MarionetteTestCase):
testpref = "testing.marionette.contentcharpref"
testvalue = "blabla"
def test_prefs(self):
result = self.marionette.execute_script("""
SpecialPowers.setCharPref("%(pref)s", "%(value)s");
return SpecialPowers.getCharPref("%(pref)s")
""" % {'pref': self.testpref, 'value': self.testvalue}, special_powers=True);
self.assertEqual(result, self.testvalue)
def test_prefs_after_navigate(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
self.test_prefs()
class TestSpecialPowersChrome(TestSpecialPowersContent):
testpref = "testing.marionette.chromecharpref"
testvalue = "blabla"
def setUp(self):
super(TestSpecialPowersChrome, self).setUp()
self.marionette.set_context("chrome")
def test_prefs_after_navigate(self):
pass

View File

@ -8,22 +8,24 @@ from marionette import MarionetteTestCase
class TestSwitchRemoteFrame(MarionetteTestCase):
def setUp(self):
super(TestSwitchRemoteFrame, self).setUp()
self.oop_by_default = self.marionette.execute_script("""
try {
return SpecialPowers.getBoolPref('dom.ipc.browser_frames.oop_by_default');
}
catch(e) {}
""")
self.mozBrowserFramesEnabled = self.marionette.execute_script("""
try {
return SpecialPowers.getBoolPref('dom.mozBrowserFramesEnabled');
}
catch(e) {}
""")
self.marionette.execute_async_script(
'SpecialPowers.pushPrefEnv({"set": [["dom.ipc.browser_frames.oop_by_default", true], ["dom.mozBrowserFramesEnabled", true]]}, marionetteScriptFinished);')
with self.marionette.using_context('chrome'):
self.oop_by_default = self.marionette.execute_script("""
try {
return Services.prefs.getBoolPref('dom.ipc.browser_frames.oop_by_default');
}
catch(e) {}
""")
self.mozBrowserFramesEnabled = self.marionette.execute_script("""
try {
return Services.prefs.getBoolPref('dom.mozBrowserFramesEnabled');
}
catch(e) {}
""")
self.marionette.execute_script("""
Services.prefs.setBoolPref("dom.ipc.browser_frames.oop_by_default", true);
Services.prefs.setBoolPref("dom.mozBrowserFramesEnabled", true);
""")
self.multi_process_browser = self.marionette.execute_script("""
try {
return Services.appinfo.browserTabsRemoteAutostart;
@ -31,13 +33,20 @@ class TestSwitchRemoteFrame(MarionetteTestCase):
return false;
}""")
def is_main_process(self):
return self.marionette.execute_script("""
return Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULRuntime).
processType == Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
""", sandbox='system')
def test_remote_frame(self):
self.marionette.navigate(self.marionette.absolute_url("test.html"))
self.marionette.push_permission('browser', True)
self.marionette.execute_script("""
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
SpecialPowers.wrap(iframe).remote = true;
iframe.setAttribute('mozbrowser', true);
iframe.setAttribute('remote', true);
iframe.id = "remote_iframe";
iframe.style.height = "100px";
iframe.style.width = "100%%";
@ -46,9 +55,7 @@ class TestSwitchRemoteFrame(MarionetteTestCase):
""" % self.marionette.absolute_url("test.html"))
remote_iframe = self.marionette.find_element("id", "remote_iframe")
self.marionette.switch_to_frame(remote_iframe)
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
main_process = self.is_main_process()
self.assertFalse(main_process)
def test_remote_frame_revisit(self):
@ -57,8 +64,8 @@ class TestSwitchRemoteFrame(MarionetteTestCase):
self.marionette.push_permission('browser', True)
self.marionette.execute_script("""
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
SpecialPowers.wrap(iframe).remote = true;
iframe.setAttribute('mozbrowser', true);
iframe.setAttribute('remote', true);
iframe.id = "remote_iframe";
iframe.style.height = "100px";
iframe.style.width = "100%%";
@ -67,21 +74,15 @@ class TestSwitchRemoteFrame(MarionetteTestCase):
""" % self.marionette.absolute_url("test.html"))
self.marionette.switch_to_frame(self.marionette.find_element("id",
"remote_iframe"))
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
main_process = self.is_main_process()
self.assertFalse(main_process)
self.marionette.switch_to_frame()
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
main_process = self.is_main_process()
should_be_main_process = not self.multi_process_browser
self.assertEqual(main_process, should_be_main_process)
self.marionette.switch_to_frame(self.marionette.find_element("id",
"remote_iframe"))
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
main_process = self.is_main_process()
self.assertFalse(main_process)
def test_we_can_switch_to_a_remote_frame_by_index(self):
@ -90,8 +91,8 @@ class TestSwitchRemoteFrame(MarionetteTestCase):
self.marionette.push_permission('browser', True)
self.marionette.execute_script("""
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
SpecialPowers.wrap(iframe).remote = true;
iframe.setAttribute('mozbrowser', true);
iframe.setAttribute('remote', true);
iframe.id = "remote_iframe";
iframe.style.height = "100px";
iframe.style.width = "100%%";
@ -99,36 +100,31 @@ class TestSwitchRemoteFrame(MarionetteTestCase):
document.body.appendChild(iframe);
""" % self.marionette.absolute_url("test.html"))
self.marionette.switch_to_frame(0)
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
main_process = self.is_main_process()
self.assertFalse(main_process)
self.marionette.switch_to_frame()
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
main_process = self.is_main_process()
should_be_main_process = not self.multi_process_browser
self.assertEqual(main_process, should_be_main_process)
self.marionette.switch_to_frame(0)
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
main_process = self.is_main_process()
self.assertFalse(main_process)
def tearDown(self):
if self.oop_by_default is None:
self.marionette.execute_script("""
SpecialPowers.clearUserPref('dom.ipc.browser_frames.oop_by_default');
""")
else:
self.marionette.execute_async_script(
'SpecialPowers.pushPrefEnv({"set": [["dom.ipc.browser_frames.oop_by_default", %s]]}, marionetteScriptFinished);' %
('true' if self.oop_by_default else 'false'))
if self.mozBrowserFramesEnabled is None:
self.marionette.execute_script("""
SpecialPowers.clearUserPref('dom.mozBrowserFramesEnabled');
""")
else:
self.marionette.execute_async_script(
'SpecialPowers.pushPrefEnv({"set": [["dom.mozBrowserFramesEnabled", %s]]}, marionetteScriptFinished);' %
('true' if self.mozBrowserFramesEnabled else 'false'))
with self.marionette.using_context('chrome'):
if self.oop_by_default is None:
self.marionette.execute_script("""
Services.prefs.clearUserPref('dom.ipc.browser_frames.oop_by_default');
""")
else:
self.marionette.execute_async_script(
"Services.prefs.setBoolPref('dom.ipc.browser_frames.oop_by_default', %s);" %
('true' if self.oop_by_default else 'false'))
if self.mozBrowserFramesEnabled is None:
self.marionette.execute_script("""
Services.prefs.clearUserPref('dom.mozBrowserFramesEnabled');
""")
else:
self.marionette.execute_async_script(
"Services.prefs.setBoolPref('dom.mozBrowserFramesEnabled', %s);" %
('true' if self.mozBrowserFramesEnabled else 'false'))

View File

@ -94,7 +94,6 @@ browser = false
[test_simpletest_sanity.py]
[test_simpletest_chrome.js]
[test_simpletest_timeout.js]
[test_specialpowers.py]
[test_anonymous_content.py]
b2g = false
[test_switch_frame.py]

View File

@ -45,7 +45,6 @@ this.EXPORTED_SYMBOLS = ["GeckoDriver", "Context"];
const FRAME_SCRIPT = "chrome://marionette/content/listener.js";
const BROWSER_STARTUP_FINISHED = "browser-delayed-startup-finished";
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
const CLICK_TO_START_PREF = "marionette.debugging.clicktostart";
const CONTENT_LISTENER_PREF = "marionette.contentListener";
@ -53,7 +52,6 @@ const logger = Log.repository.getLogger("Marionette");
const uuidGen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
const globalMessageManager = Cc["@mozilla.org/globalmessagemanager;1"]
.getService(Ci.nsIMessageBroadcaster);
let specialpowers = {};
// This is used to prevent newSession from returning before the telephony
// API's are ready; see bug 792647. This assumes that marionette-server.js
@ -130,7 +128,6 @@ this.GeckoDriver = function(appName, device, emulator) {
this.currentFrameElement = null;
this.testName = null;
this.mozBrowserClose = null;
this.enabled_security_pref = false;
this.sandboxes = {};
// frame ID of the current remote frame, used for mozbrowserclose events
this.oopFrameId = null;
@ -510,25 +507,6 @@ GeckoDriver.prototype.newSession = function(cmd, resp) {
this.setSessionCapabilities(cmd.parameters.capabilities);
this.scriptTimeout = 10000;
// SpecialPowers requires insecure automation-only features that we
// put behind a pref
let sec = false;
try {
sec = Services.prefs.getBoolPref(SECURITY_PREF);
} catch (e) {}
if (!sec) {
this.enabled_security_pref = true;
Services.prefs.setBoolPref(SECURITY_PREF, true);
}
if (!specialpowers.hasOwnProperty("specialPowersObserver")) {
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.js",
specialpowers);
specialpowers.specialPowersObserver = new specialpowers.SpecialPowersObserver();
specialpowers.specialPowersObserver.init();
specialpowers.specialPowersObserver._loadFrameScript();
}
let registerBrowsers = this.registerPromise();
let browserListening = this.listeningPromise();
@ -705,15 +683,14 @@ GeckoDriver.prototype.getContext = function(cmd, resp) {
* Window in which we will execute code.
* @param {Marionette} mn
* Marionette test instance.
* @param {Object} args
* Arguments given by client.
* @param {boolean} sp
* True to enable special powers in the sandbox, false not to.
* @param {string} sandboxName
* The name for the sandbox. If 'system', create the sandbox
* with elevated privileges.
*
* @return {nsIXPCComponents_utils_Sandbox}
* Returns the sandbox.
*/
GeckoDriver.prototype.createExecuteSandbox = function(win, mn, sp, sandboxName) {
GeckoDriver.prototype.createExecuteSandbox = function(win, mn, sandboxName) {
let principal = win;
if (sandboxName == 'system') {
principal = Cc["@mozilla.org/systemprincipal;1"].
@ -735,15 +712,6 @@ GeckoDriver.prototype.createExecuteSandbox = function(win, mn, sp, sandboxName)
sb.isSystemMessageListenerReady = () => systemMessageListenerReady;
if (sp) {
let pow = [
"chrome://specialpowers/content/specialpowersAPI.js",
"chrome://specialpowers/content/SpecialPowersObserverAPI.js",
"chrome://specialpowers/content/ChromePowers.js",
];
pow.map(s => loader.loadSubScript(s, sb));
}
this.sandboxes[sandboxName] = sb;
};
@ -821,7 +789,6 @@ GeckoDriver.prototype.execute = function(cmd, resp, directInject) {
script,
newSandbox,
args,
specialPowers,
filename,
line} = cmd.parameters;
let sandboxName = cmd.parameters.sandbox || 'default';
@ -839,7 +806,6 @@ GeckoDriver.prototype.execute = function(cmd, resp, directInject) {
args: args,
newSandbox: newSandbox,
timeout: scriptTimeout,
specialPowers: specialPowers,
filename: filename,
line: line,
sandboxName: sandboxName
@ -880,7 +846,6 @@ GeckoDriver.prototype.execute = function(cmd, resp, directInject) {
this.createExecuteSandbox(
win,
marionette,
specialPowers,
sandboxName);
if (!this.sandboxes[sandboxName]) {
return;
@ -957,7 +922,6 @@ GeckoDriver.prototype.executeJSScript = function(cmd, resp) {
timeout: cmd.parameters.scriptTimeout ?
cmd.parameters.scriptTimeout : this.scriptTimeout,
inactivityTimeout: cmd.parameters.inactivityTimeout,
specialPowers: cmd.parameters.specialPowers,
filename: cmd.parameters.filename,
line: cmd.parameters.line,
sandboxName: cmd.parameters.sandbox || 'default',
@ -987,7 +951,6 @@ GeckoDriver.prototype.executeWithCallback = function(cmd, resp, directInject) {
newSandbox,
inactivityTimeout,
scriptTimeout,
specialPowers,
filename,
line} = cmd.parameters;
let sandboxName = cmd.parameters.sandbox || 'default';
@ -1007,7 +970,6 @@ GeckoDriver.prototype.executeWithCallback = function(cmd, resp, directInject) {
newSandbox: newSandbox,
timeout: scriptTimeout,
inactivityTimeout: inactivityTimeout,
specialPowers: specialPowers,
filename: filename,
line: line,
sandboxName: sandboxName,
@ -1085,8 +1047,7 @@ GeckoDriver.prototype.executeWithCallback = function(cmd, resp, directInject) {
scriptTimeout,
this.heartbeatCallback,
this.testName);
this.createExecuteSandbox(win, marionette,
specialPowers, sandboxName);
this.createExecuteSandbox(win, marionette, sandboxName);
}
if (!this.sandboxes[sandboxName]) {
return;
@ -2439,7 +2400,6 @@ GeckoDriver.prototype.sessionTearDown = function(cmd, resp) {
winEn.getNext().messageManager.removeDelayedFrameScript(FRAME_SCRIPT);
}
this.curBrowser.frameManager.removeSpecialPowers();
this.curBrowser.frameManager.removeMessageManagerListeners(
globalMessageManager);
}
@ -2879,6 +2839,23 @@ GeckoDriver.prototype.receiveMessage = function(message) {
false);
return true;
case "Marionette:getFiles":
// Generates file objects to send back to the content script
// for handling file uploads.
let val = message.json.value;
let command_id = message.json.command_id;
Cu.importGlobalProperties(["File"]);
try {
let file = new File(val);
this.sendAsync("receiveFiles",
{file: file, command_id: command_id});
} catch (e) {
let err = `File not found: ${val}`;
this.sendAsync("receiveFiles",
{error: err, command_id: command_id});
}
break;
case "Marionette:emitTouchEvent":
globalMessageManager.broadcastAsyncMessage(
"MarionetteMainListener:emitTouchEvent", message.json);

View File

@ -1401,9 +1401,9 @@ class Marionette(object):
return unwrapped
def execute_js_script(self, script, script_args=None, async=True,
new_sandbox=True, special_powers=False,
script_timeout=None, inactivity_timeout=None,
filename=None, sandbox='default'):
new_sandbox=True, script_timeout=None,
inactivity_timeout=None, filename=None,
sandbox='default'):
if script_args is None:
script_args = []
args = self.wrapArguments(script_args)
@ -1413,7 +1413,6 @@ class Marionette(object):
args=args,
async=async,
newSandbox=new_sandbox,
specialPowers=special_powers,
scriptTimeout=script_timeout,
inactivityTimeout=inactivity_timeout,
filename=filename,
@ -1421,7 +1420,7 @@ class Marionette(object):
return self.unwrapValue(response)
def execute_script(self, script, script_args=None, new_sandbox=True,
special_powers=False, sandbox='default', script_timeout=None):
sandbox='default', script_timeout=None):
'''
Executes a synchronous JavaScript script, and returns the result (or None if the script does return a value).
@ -1431,11 +1430,6 @@ class Marionette(object):
:param script: A string containing the JavaScript to execute.
:param script_args: A list of arguments to pass to the script.
:param special_powers: Whether or not you want access to SpecialPowers
in your script. Set to False by default because it shouldn't really
be used, since you already have access to chrome-level commands if you
set context to chrome and do an execute_script. This method was added
only to help us run existing Mochitests.
:param sandbox: A tag referring to the sandbox you wish to use; if
you specify a new tag, a new sandbox will be created. If you use the
special tag 'system', the sandbox will be created using the system
@ -1498,7 +1492,6 @@ class Marionette(object):
args=args,
newSandbox=new_sandbox,
sandbox=sandbox,
specialPowers=special_powers,
scriptTimeout=script_timeout,
line=int(frame[1]),
filename=os.path.basename(frame[0]))
@ -1506,7 +1499,7 @@ class Marionette(object):
def execute_async_script(self, script, script_args=None, new_sandbox=True,
sandbox='default', script_timeout=None,
special_powers=False, debug_script=False):
debug_script=False):
'''
Executes an asynchronous JavaScript script, and returns the result (or None if the script does return a value).
@ -1516,11 +1509,6 @@ class Marionette(object):
:param script: A string containing the JavaScript to execute.
:param script_args: A list of arguments to pass to the script.
:param special_powers: Whether or not you want access to SpecialPowers
in your script. Set to False by default because it shouldn't really
be used, since you already have access to chrome-level commands if you
set context to chrome and do an execute_script. This method was added
only to help us run existing Mochitests.
:param sandbox: A tag referring to the sandbox you wish to use; if
you specify a new tag, a new sandbox will be created. If you use the
special tag 'system', the sandbox will be created using the system
@ -1555,7 +1543,6 @@ class Marionette(object):
args=args,
newSandbox=new_sandbox,
sandbox=sandbox,
specialPowers=special_powers,
scriptTimeout=script_timeout,
line=int(frame[1]),
filename=os.path.basename(frame[0]),

View File

@ -37,8 +37,7 @@ class SelectionManager(object):
if self._input_or_textarea():
# We must unwrap sel so that DOMRect could be returned to Python
# side.
return '''var sel = SpecialPowers.wrap(arguments[0]).editor.selection;
sel = SpecialPowers.unwrap(sel);'''
return '''var sel = arguments[0].editor.selection;'''
else:
return '''var sel = window.getSelection();'''
@ -50,7 +49,8 @@ class SelectionManager(object):
for i in range(offset):
self.element.marionette.execute_script(
cmd, script_args=[self.element, direction])
cmd, script_args=[self.element, direction],
sandbox='system')
def move_caret_to_front(self):
'''Move caret in the element to the front of the content.'''
@ -83,13 +83,17 @@ class SelectionManager(object):
'''
cmd = self.js_selection_cmd() +\
'''return sel.getRangeAt(%d).getClientRects();''' % idx
return self.element.marionette.execute_script(cmd, script_args=[self.element])
return self.element.marionette.execute_script(cmd,
script_args=[self.element],
sandbox='system')
def range_count(self):
'''Get selection's range count'''
cmd = self.js_selection_cmd() +\
'''return sel.rangeCount;'''
return self.element.marionette.execute_script(cmd, script_args=[self.element])
return self.element.marionette.execute_script(cmd,
script_args=[self.element],
sandbox='system')
def _selection_location_helper(self, location_type):
'''Return the start and end location of the selection in the element.
@ -200,4 +204,6 @@ class SelectionManager(object):
'''Return the selected portion of the content in the element.'''
cmd = self.js_selection_cmd() +\
'''return sel.toString();'''
return self.element.marionette.execute_script(cmd, script_args=[self.element])
return self.element.marionette.execute_script(cmd,
script_args=[self.element],
sandbox='system')

View File

@ -13,7 +13,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
let specialpowers = {};
//list of OOP frames that has the frame script loaded
let remoteFrames = [];
@ -120,11 +119,6 @@ FrameManager.prototype = {
let oopFrame = this.getOopFrame(winId, frameId);
let mm = this.getFrameMM(winId, frameId);
if (!specialpowers.hasOwnProperty("specialPowersObserver")) {
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.js",
specialpowers);
}
// See if this frame already has our frame script loaded in it;
// if so, just wake it up.
for (let i = 0; i < remoteFrames.length; i++) {
@ -142,11 +136,6 @@ FrameManager.prototype = {
this.currentRemoteFrame = frame;
this.addMessageManagerListeners(mm);
if (!frame.specialPowersObserver) {
frame.specialPowersObserver = new specialpowers.SpecialPowersObserver();
frame.specialPowersObserver.init(mm);
}
mm.sendAsyncMessage("Marionette:restart");
return oopFrame.id;
}
@ -163,9 +152,6 @@ FrameManager.prototype = {
mm.loadFrameScript(FRAME_SCRIPT, true, true);
aFrame.specialPowersObserver = new specialpowers.SpecialPowersObserver();
aFrame.specialPowersObserver.init(mm);
return oopFrame.id;
},
@ -182,20 +168,6 @@ FrameManager.prototype = {
this.handledModal = false;
},
/**
* This function removes any SpecialPowersObservers from OOP frames.
*/
removeSpecialPowers: function FM_removeSpecialPowers() {
for (let i = 0; i < remoteFrames.length; i++) {
let frame = remoteFrames[i];
if (frame.specialPowersObserver) {
frame.specialPowersObserver.uninit();
frame.specialPowersObserver = null;
}
}
},
/**
* Adds message listeners to the server,
* listening for messages from content frame scripts.
@ -220,6 +192,7 @@ FrameManager.prototype = {
mm.addWeakMessageListener("Marionette:deleteCookie", this.server);
mm.addWeakMessageListener("Marionette:register", this.server);
mm.addWeakMessageListener("Marionette:listenersAttached", this.server);
mm.addWeakMessageListener("Marionette:getFiles", this.server);
mm.addWeakMessageListener("MarionetteFrame:handleModal", this);
mm.addWeakMessageListener("MarionetteFrame:getCurrentFrameId", this);
mm.addWeakMessageListener("MarionetteFrame:getInterruptedState", this);
@ -248,6 +221,7 @@ FrameManager.prototype = {
mm.removeWeakMessageListener("Marionette:deleteCookie", this.server);
mm.removeWeakMessageListener("Marionette:listenersAttached", this.server);
mm.removeWeakMessageListener("Marionette:register", this.server);
mm.removeWeakMessageListener("Marionette:getFiles", this.server);
mm.removeWeakMessageListener("MarionetteFrame:handleModal", this);
mm.removeWeakMessageListener("MarionetteFrame:getCurrentFrameId", this);
}

View File

@ -27,9 +27,6 @@ loader.loadSubScript("chrome://marionette/content/ChromeUtils.js", utils);
loader.loadSubScript("chrome://marionette/content/atoms.js", utils);
loader.loadSubScript("chrome://marionette/content/sendkeys.js", utils);
loader.loadSubScript("chrome://specialpowers/content/specialpowersAPI.js");
loader.loadSubScript("chrome://specialpowers/content/specialpowers.js");
let marionetteLogObj = new MarionetteLogObj();
let isB2G = false;
@ -46,6 +43,10 @@ let accessibility = new Accessibility();
let actions = new ActionChain(utils, checkForInterrupted);
let importedScripts = null;
// Contains the last file input element that was the target of
// sendKeysToElement.
let fileInputElement;
// A dict of sandboxes used this session
let sandboxes = {};
// The name of the current sandbox
@ -196,6 +197,7 @@ let isElementEnabledFn = dispatch(isElementEnabled);
* Start all message listeners
*/
function startListeners() {
addMessageListenerId("Marionette:receiveFiles", receiveFiles);
addMessageListenerId("Marionette:newSession", newSession);
addMessageListenerId("Marionette:executeScript", executeScript);
addMessageListenerId("Marionette:executeAsyncScript", executeAsyncScript);
@ -300,6 +302,7 @@ function restart(msg) {
* Removes all listeners
*/
function deleteSession(msg) {
removeMessageListenerId("Marionette:receiveFiles", receiveFiles);
removeMessageListenerId("Marionette:newSession", newSession);
removeMessageListenerId("Marionette:executeScript", executeScript);
removeMessageListenerId("Marionette:executeAsyncScript", executeAsyncScript);
@ -487,14 +490,6 @@ function createExecuteContentSandbox(win, timeout) {
}
});
let specialPowersFn;
if (typeof win.wrappedJSObject.SpecialPowers != "undefined") {
specialPowersFn = () => win.wrappedJSObject.SpecialPowers;
} else {
specialPowersFn = () => new SpecialPowers(win);
}
XPCOMUtils.defineLazyGetter(sandbox, "SpecialPowers", specialPowersFn);
sandbox.asyncComplete = (obj, id) => {
if (id == asyncTestCommandId) {
curFrame.removeEventListener("unload", onunload, false);
@ -650,6 +645,28 @@ function executeAsyncScript(msg) {
executeWithCallback(msg);
}
/**
* Receive file objects from chrome in order to complete a
* sendKeysToElement action on a file input element.
*/
function receiveFiles(msg) {
if ('error' in msg.json) {
let err = new InvalidArgumentError(msg.json.error);
sendError(err, msg.json.command_id);
return;
}
if (!fileInputElement) {
let err = new InvalidElementStateError("receiveFiles called with no valid fileInputElement");
sendError(err, msg.json.command_id);
return;
}
let fs = Array.prototype.slice.call(fileInputElement.files);
fs.push(msg.json.file);
fileInputElement.mozSetFileArray(fs);
fileInputElement = null;
sendOk(msg.json.command_id);
}
/**
* Execute pure JS test. Handles both async and sync cases.
*/
@ -1537,31 +1554,12 @@ function sendKeysToElement(msg) {
let el = elementManager.getKnownElement(msg.json.id, curFrame);
if (el.type == "file") {
let p = val.join("");
// for some reason using mozSetFileArray doesn't work with e10s
// enabled (probably a bug), but a workaround is to elevate the element's
// privileges with SpecialPowers
//
// this extra branch can be removed when the e10s bug 1149998 is fixed
if (isRemoteBrowser()) {
let fs = Array.prototype.slice.call(el.files);
let file;
try {
file = new File(p);
} catch (e) {
let err = new InvalidArgumentError(`File not found: ${val}`);
sendError(err, command_id);
return;
}
fs.push(file);
let wel = new SpecialPowers(utils.window).wrap(el);
wel.mozSetFileArray(fs);
} else {
sendSyncMessage("Marionette:setElementValue", {value: p}, {element: el});
}
sendOk(command_id);
fileInputElement = el;
// In e10s, we can only construct File objects in the parent process,
// so pass the filename to driver.js, which in turn passes them back
// to this frame script in receiveFiles.
sendSyncMessage("Marionette:getFiles",
{value: p, command_id: command_id});
} else {
utils.sendKeysToElement(curFrame, el, val, sendOk, sendError, command_id);
}

View File

@ -29,7 +29,6 @@ loader.loadSubScript("chrome://marionette/content/frame-manager.js");
const logger = Log.repository.getLogger("Marionette");
this.EXPORTED_SYMBOLS = ["MarionetteServer"];
const SPECIAL_POWERS_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
const CONTENT_LISTENER_PREF = "marionette.contentListener";
/**

View File

@ -29,6 +29,10 @@ if (cm) {
cm.deleteCategoryEntry("update-timer", "nsUpdateService", false);
}
let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
Components.utils.import("resource://gre/modules/Services.jsm");
Services.prefs.setBoolPref(SECURITY_PREF, true);
function openWindow(aEvent) {
var popupIframe = aEvent.detail.frameElement;
popupIframe.id = 'popupiframe';
@ -97,6 +101,11 @@ if (outOfProcess) {
if (chrome) {
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
if (typeof(SpecialPowers) == 'undefined') {
loader.loadSubScript("chrome://specialpowers/content/specialpowersAPI.js");
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserverAPI.js");
loader.loadSubScript("chrome://specialpowers/content/ChromePowers.js");
}
loader.loadSubScript("chrome://mochikit/content/browser-test.js");
b2gStart();
}

View File

@ -220,6 +220,22 @@ class B2GMochitest(MochitestUtilsMixin):
Services.io.offline = false;
""")
self.marionette.execute_script("""
let SECURITY_PREF = "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer";
Components.utils.import("resource://gre/modules/Services.jsm");
Services.prefs.setBoolPref(SECURITY_PREF, true);
if (!testUtils.hasOwnProperty("specialPowersObserver")) {
let loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserver.js",
testUtils);
testUtils.specialPowersObserver = new testUtils.SpecialPowersObserver();
testUtils.specialPowersObserver.init();
testUtils.specialPowersObserver._loadFrameScript();
}
""")
if options.chrome:
self.app_ctx.dm.removeDir(self.remote_chrome_test_dir)
self.app_ctx.dm.mkDir(self.remote_chrome_test_dir)