@@ -117,9 +117,11 @@ const Binary = require('./binary').Binary,
117117 Profile = require ( './profile' ) . Profile ,
118118 decodeProfile = require ( './profile' ) . decode ,
119119 executors = require ( '../executors' ) ,
120+ http = require ( '../http' ) ,
120121 httpUtil = require ( '../http/util' ) ,
121122 io = require ( '../io' ) ,
122123 capabilities = require ( '../lib/capabilities' ) ,
124+ command = require ( '../lib/command' ) ,
123125 logging = require ( '../lib/logging' ) ,
124126 promise = require ( '../lib/promise' ) ,
125127 webdriver = require ( '../lib/webdriver' ) ,
@@ -266,6 +268,23 @@ class Options {
266268 }
267269}
268270
271+
272+ /**
273+ * Enum of available command contexts.
274+ *
275+ * Command contexts are specific to Marionette, and may be used with the
276+ * {@link #context=} method. Contexts allow you to direct all subsequent
277+ * commands to either "content" (default) or "chrome". The latter gives
278+ * you elevated security permissions.
279+ *
280+ * @enum {string}
281+ */
282+ const Context = {
283+ CONTENT : "content" ,
284+ CHROME : "chrome" ,
285+ } ;
286+
287+
269288const GECKO_DRIVER_EXE =
270289 process . platform === 'win32' ? 'geckodriver.exe' : 'geckodriver' ;
271290
@@ -365,6 +384,36 @@ function normalizeProxyConfiguration(config) {
365384}
366385
367386
387+ /** @enum {string} */
388+ const ExtensionCommand = {
389+ GET_CONTEXT : 'getContext' ,
390+ SET_CONTEXT : 'setContext' ,
391+ } ;
392+
393+
394+ /**
395+ * Creates a command executor with support for Marionette's custom commands.
396+ * @param {!Promise<string> } url The server's URL.
397+ * @param {!command.Executor } The new command executor.
398+ */
399+ function createExecutor ( url ) {
400+ return new command . DeferredExecutor ( url . then ( url => {
401+ let client = new http . HttpClient ( url ) ;
402+ let executor = new http . Executor ( client ) ;
403+
404+ executor . defineCommand (
405+ ExtensionCommand . GET_CONTEXT ,
406+ 'GET' ,
407+ '/session/:sessionId/moz/context' ) ;
408+ executor . defineCommand (
409+ ExtensionCommand . SET_CONTEXT ,
410+ 'POST' ,
411+ '/session/:sessionId/moz/context' ) ;
412+
413+ return executor ;
414+ } ) ) ;
415+ }
416+
368417/**
369418 * A WebDriver client for Firefox.
370419 */
@@ -457,7 +506,7 @@ class Driver extends webdriver.WebDriver {
457506 } ;
458507 }
459508
460- let executor = executors . createExecutor ( serverUrl ) ;
509+ let executor = createExecutor ( serverUrl ) ;
461510 let driver = webdriver . WebDriver . createSession ( executor , caps , opt_flow ) ;
462511 super ( driver . getSession ( ) , executor , driver . controlFlow ( ) ) ;
463512
@@ -476,13 +525,46 @@ class Driver extends webdriver.WebDriver {
476525 */
477526 setFileDetector ( ) {
478527 }
528+
529+ /**
530+ * Get the context that is currently in effect.
531+ *
532+ * @return {!promise.Promise<Context> } Current context.
533+ */
534+ getContext ( ) {
535+ return this . schedule (
536+ new command . Command ( ExtensionCommand . GET_CONTEXT ) ,
537+ 'get WebDriver.context' ) ;
538+ }
539+
540+ /**
541+ * Changes target context for commands between chrome- and content.
542+ *
543+ * Changing the current context has a stateful impact on all subsequent
544+ * commands. The {@link Context.CONTENT} context has normal web
545+ * platform document permissions, as if you would evaluate arbitrary
546+ * JavaScript. The {@link Context.CHROME} context gets elevated
547+ * permissions that lets you manipulate the browser chrome itself,
548+ * with full access to the XUL toolkit.
549+ *
550+ * Use your powers wisely.
551+ *
552+ * @param {!promise.Promise<void> } ctx The context to switch to.
553+ */
554+ setContext ( ctx ) {
555+ return this . schedule (
556+ new command . Command ( ExtensionCommand . SET_CONTEXT )
557+ . setParameter ( "context" , ctx ) ,
558+ 'set WebDriver.context' ) ;
559+ }
479560}
480561
481562
482563// PUBLIC API
483564
484565
485566exports . Binary = Binary ;
567+ exports . Context = Context ;
486568exports . Driver = Driver ;
487569exports . Options = Options ;
488570exports . Profile = Profile ;
0 commit comments