From 9f386bdf5a781698a878d9c2f47f3d6be76dbadb Mon Sep 17 00:00:00 2001 From: Jonathan Griffin Date: Mon, 4 May 2015 09:49:08 -0700 Subject: [PATCH] Bug 1149618 - Implement push_permission in Marionette, r=dburns --- .../client/marionette/marionette_test.py | 1 + .../client/marionette/runner/base.py | 3 +- .../marionette/runner/mixins/reporting.py | 6 +- .../tests/unit/test_getactiveframe_oop.py | 2 +- .../tests/unit/test_switch_remote_frame.py | 9 +-- .../driver/marionette_driver/marionette.py | 62 +++++++++++++++++++ 6 files changed, 72 insertions(+), 11 deletions(-) diff --git a/testing/marionette/client/marionette/marionette_test.py b/testing/marionette/client/marionette/marionette_test.py index bf6ed1f5f2a..30329b5e6a9 100644 --- a/testing/marionette/client/marionette/marionette_test.py +++ b/testing/marionette/client/marionette/marionette_test.py @@ -646,6 +646,7 @@ class MarionetteTestCase(CommonTestCase): def tearDown(self): if not self.marionette.check_for_crash(): self.marionette.set_context("content") + self.marionette.clear_imported_scripts() self.marionette.execute_script("log('TEST-END: %s:%s')" % (self.filepath.replace('\\', '\\\\'), self.methodName)) self.marionette.test_name = None diff --git a/testing/marionette/client/marionette/runner/base.py b/testing/marionette/client/marionette/runner/base.py index 787858f297c..d0b0924b1f8 100644 --- a/testing/marionette/client/marionette/runner/base.py +++ b/testing/marionette/client/marionette/runner/base.py @@ -493,6 +493,7 @@ class BaseMarionetteOptions(OptionParser): class BaseMarionetteTestRunner(object): textrunnerclass = MarionetteTextTestRunner + driverclass = Marionette def __init__(self, address=None, emulator=None, emulator_binary=None, emulator_img=None, emulator_res='480x800', homedir=None, @@ -696,7 +697,7 @@ class BaseMarionetteTestRunner(object): return kwargs def start_marionette(self): - self.marionette = Marionette(**self._build_kwargs()) + self.marionette = self.driverclass(**self._build_kwargs()) def launch_test_container(self): if self.marionette.session is None: diff --git a/testing/marionette/client/marionette/runner/mixins/reporting.py b/testing/marionette/client/marionette/runner/mixins/reporting.py index 40b57de1c0e..392d45d0387 100644 --- a/testing/marionette/client/marionette/runner/mixins/reporting.py +++ b/testing/marionette/client/marionette/runner/mixins/reporting.py @@ -255,13 +255,13 @@ class HTMLReportingTestResultMixin(object): self.marionette.set_context(self.marionette.CONTEXT_CONTENT) debug['source'] = self.marionette.page_source self.marionette.switch_to_frame() + self.marionette.push_permission('settings-read', True) + self.marionette.push_permission('settings-api-read', True) debug['settings'] = json.dumps(self.marionette.execute_async_script(""" -SpecialPowers.addPermission('settings-read', true, document); -SpecialPowers.addPermission('settings-api-read', true, document); var req = window.navigator.mozSettings.createLock().get('*'); req.onsuccess = function() { marionetteScriptFinished(req.result); -}""", special_powers=True), sort_keys=True, indent=4, separators=(',', ': ')) +}""", sandbox='system'), sort_keys=True, indent=4, separators=(',', ': ')) except: logger = get_default_logger() logger.warning('Failed to gather test failure debug.', exc_info=True) diff --git a/testing/marionette/client/marionette/tests/unit/test_getactiveframe_oop.py b/testing/marionette/client/marionette/tests/unit/test_getactiveframe_oop.py index 29b6619157b..d43b62a1c04 100644 --- a/testing/marionette/client/marionette/tests/unit/test_getactiveframe_oop.py +++ b/testing/marionette/client/marionette/tests/unit/test_getactiveframe_oop.py @@ -29,7 +29,7 @@ class TestGetActiveFrameOOP(MarionetteTestCase): def test_active_frame_oop(self): self.marionette.navigate(self.marionette.absolute_url("test.html")) - self.marionette.execute_script("SpecialPowers.addPermission('browser', true, document)") + self.marionette.push_permission('browser', True) # Create first OOP frame self.marionette.execute_script(""" diff --git a/testing/marionette/client/marionette/tests/unit/test_switch_remote_frame.py b/testing/marionette/client/marionette/tests/unit/test_switch_remote_frame.py index 1e0e176c554..c164a6126e1 100644 --- a/testing/marionette/client/marionette/tests/unit/test_switch_remote_frame.py +++ b/testing/marionette/client/marionette/tests/unit/test_switch_remote_frame.py @@ -33,8 +33,7 @@ class TestSwitchRemoteFrame(MarionetteTestCase): def test_remote_frame(self): self.marionette.navigate(self.marionette.absolute_url("test.html")) - self.marionette.execute_async_script( - "SpecialPowers.pushPermissions([{'type': 'browser', 'allow': true, 'context': document}], marionetteScriptFinished);") + self.marionette.push_permission('browser', True) self.marionette.execute_script(""" let iframe = document.createElement("iframe"); SpecialPowers.wrap(iframe).mozbrowser = true; @@ -55,8 +54,7 @@ class TestSwitchRemoteFrame(MarionetteTestCase): def test_remote_frame_revisit(self): # test if we can revisit a remote frame (this takes a different codepath) self.marionette.navigate(self.marionette.absolute_url("test.html")) - self.marionette.execute_async_script( - "SpecialPowers.pushPermissions([{'type': 'browser', 'allow': true, 'context': document}], marionetteScriptFinished);") + self.marionette.push_permission('browser', True) self.marionette.execute_script(""" let iframe = document.createElement("iframe"); SpecialPowers.wrap(iframe).mozbrowser = true; @@ -89,8 +87,7 @@ class TestSwitchRemoteFrame(MarionetteTestCase): def test_we_can_switch_to_a_remote_frame_by_index(self): # test if we can revisit a remote frame (this takes a different codepath) self.marionette.navigate(self.marionette.absolute_url("test.html")) - self.marionette.execute_async_script( - "SpecialPowers.pushPermissions([{'type': 'browser', 'allow': true, 'context': document}], marionetteScriptFinished);") + self.marionette.push_permission('browser', True) self.marionette.execute_script(""" let iframe = document.createElement("iframe"); SpecialPowers.wrap(iframe).mozbrowser = true; diff --git a/testing/marionette/driver/marionette_driver/marionette.py b/testing/marionette/driver/marionette_driver/marionette.py index 11085ebca03..75eb888a440 100644 --- a/testing/marionette/driver/marionette_driver/marionette.py +++ b/testing/marionette/driver/marionette_driver/marionette.py @@ -787,6 +787,68 @@ class Marionette(object): typing.append(val[i]) return typing + def push_permission(self, perm_type, allow): + with self.using_context('content'): + perm = self.execute_script(""" + let allow = arguments[0]; + if (allow) + allow = Components.interfaces.nsIPermissionManager.ALLOW_ACTION; + else + allow = Components.interfaces.nsIPermissionManager.DENY_ACTION; + let perm_type = arguments[1]; + + Components.utils.import("resource://gre/modules/Services.jsm"); + window.wrappedJSObject.permChanged = false; + window.wrappedJSObject.permObserver = function(subject, topic, data) { + if (topic == "perm-changed") { + let permission = subject.QueryInterface(Components.interfaces.nsIPermission); + if (perm_type == permission.type) { + Services.obs.removeObserver(window.wrappedJSObject.permObserver, "perm-changed"); + window.wrappedJSObject.permChanged = true; + } + } + }; + Services.obs.addObserver(window.wrappedJSObject.permObserver, + "perm-changed", false); + + let value = { + 'url': document.nodePrincipal.URI.spec, + 'appId': document.nodePrincipal.appId, + 'isInBrowserElement': document.nodePrincipal.isInBrowserElement, + 'type': perm_type, + 'action': allow + }; + return value; + """, script_args=[allow, perm_type], sandbox='system') + + with self.using_context('chrome'): + waiting = self.execute_script(""" + Components.utils.import("resource://gre/modules/Services.jsm"); + let perm = arguments[0]; + let secMan = Services.scriptSecurityManager; + let principal = secMan.getAppCodebasePrincipal(Services.io.newURI(perm.url, null, null), + perm.appId, perm.isInBrowserElement); + let testPerm = Services.perms.testPermissionFromPrincipal(principal, perm.type, perm.action); + if (testPerm == perm.action) { + return false; + } + Services.perms.addFromPrincipal(principal, perm.type, perm.action); + return true; + """, script_args=[perm]) + + with self.using_context('content'): + if waiting: + self.execute_async_script(""" + waitFor(marionetteScriptFinished, function() { + return window.wrappedJSObject.permChanged; + }); + """, sandbox='system') + else: + self.execute_script(""" + Components.utils.import("resource://gre/modules/Services.jsm"); + Services.obs.removeObserver(window.wrappedJSObject.permObserver, "perm-changed"); + """, sandbox='system') + def enforce_gecko_prefs(self, prefs): """ Checks if the running instance has the given prefs. If not, it will kill the