mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-16 15:52:24 +03:00
132 lines
5.8 KiB
JavaScript
132 lines
5.8 KiB
JavaScript
/* 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/. */
|
|
|
|
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
const {ComponentUtils} = ChromeUtils.import("resource://gre/modules/ComponentUtils.jsm");
|
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
const {Dispatcher} = ChromeUtils.import("chrome://juggler/content/protocol/Dispatcher.js");
|
|
const {BrowserHandler} = ChromeUtils.import("chrome://juggler/content/protocol/BrowserHandler.js");
|
|
const {NetworkObserver} = ChromeUtils.import("chrome://juggler/content/NetworkObserver.js");
|
|
const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
|
|
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
|
const helper = new Helper();
|
|
|
|
const Cc = Components.classes;
|
|
const Ci = Components.interfaces;
|
|
|
|
const FRAME_SCRIPT = "chrome://juggler/content/content/main.js";
|
|
|
|
// Command Line Handler
|
|
function CommandLineHandler() {
|
|
};
|
|
|
|
CommandLineHandler.prototype = {
|
|
classDescription: "Sample command-line handler",
|
|
classID: Components.ID('{f7a74a33-e2ab-422d-b022-4fb213dd2639}'),
|
|
contractID: "@mozilla.org/remote/juggler;1",
|
|
_xpcom_categories: [{
|
|
category: "command-line-handler",
|
|
entry: "m-juggler"
|
|
}],
|
|
|
|
/* nsICommandLineHandler */
|
|
handle: async function(cmdLine) {
|
|
const jugglerFlag = cmdLine.handleFlagWithParam("juggler", false);
|
|
const jugglerPipeFlag = cmdLine.handleFlag("juggler-pipe", false);
|
|
if (!jugglerPipeFlag && (!jugglerFlag || isNaN(jugglerFlag)))
|
|
return;
|
|
const silent = cmdLine.preventDefault;
|
|
if (silent)
|
|
Services.startup.enterLastWindowClosingSurvivalArea();
|
|
|
|
const targetRegistry = new TargetRegistry();
|
|
new NetworkObserver(targetRegistry);
|
|
|
|
const loadFrameScript = () => {
|
|
Services.mm.loadFrameScript(FRAME_SCRIPT, true /* aAllowDelayedLoad */);
|
|
if (Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo).isHeadless) {
|
|
const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService);
|
|
const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
|
|
const uri = ioService.newURI('chrome://juggler/content/content/hidden-scrollbars.css', null, null);
|
|
styleSheetService.loadAndRegisterSheet(uri, styleSheetService.AGENT_SHEET);
|
|
}
|
|
};
|
|
|
|
// Force create hidden window here, otherwise its creation later closes the web socket!
|
|
Services.appShell.hiddenDOMWindow;
|
|
|
|
if (jugglerFlag) {
|
|
const port = parseInt(jugglerFlag, 10);
|
|
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
|
|
const WebSocketServer = require('devtools/server/socket/websocket-server');
|
|
this._server = Cc["@mozilla.org/network/server-socket;1"].createInstance(Ci.nsIServerSocket);
|
|
this._server.initSpecialConnection(port, Ci.nsIServerSocket.KeepWhenOffline | Ci.nsIServerSocket.LoopbackOnly, 4);
|
|
const token = helper.generateId();
|
|
this._server.asyncListen({
|
|
onSocketAccepted: async(socket, transport) => {
|
|
const input = transport.openInputStream(0, 0, 0);
|
|
const output = transport.openOutputStream(0, 0, 0);
|
|
const webSocket = await WebSocketServer.accept(transport, input, output, "/" + token);
|
|
const dispatcher = new Dispatcher(webSocket);
|
|
const browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, () => {
|
|
if (silent)
|
|
Services.startup.exitLastWindowClosingSurvivalArea();
|
|
});
|
|
dispatcher.rootSession().setHandler(browserHandler);
|
|
}
|
|
});
|
|
loadFrameScript();
|
|
dump(`Juggler listening on ws://127.0.0.1:${this._server.port}/${token}\n`);
|
|
} else if (jugglerPipeFlag) {
|
|
let browserHandler;
|
|
let pipeStopped = false;
|
|
const pipe = Cc['@mozilla.org/juggler/remotedebuggingpipe;1'].getService(Ci.nsIRemoteDebuggingPipe);
|
|
const connection = {
|
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIRemoteDebuggingPipeClient]),
|
|
receiveMessage(message) {
|
|
if (this.onmessage)
|
|
this.onmessage({ data: message });
|
|
},
|
|
disconnected() {
|
|
if (browserHandler)
|
|
browserHandler['Browser.close']();
|
|
},
|
|
send(message) {
|
|
if (pipeStopped) {
|
|
// We are missing the response to Browser.close,
|
|
// but everything works fine. Once we actually need it,
|
|
// we have to stop the pipe after the response is sent.
|
|
return;
|
|
}
|
|
pipe.sendMessage(message);
|
|
},
|
|
};
|
|
pipe.init(connection);
|
|
const dispatcher = new Dispatcher(connection);
|
|
browserHandler = new BrowserHandler(dispatcher.rootSession(), dispatcher, targetRegistry, () => {
|
|
if (silent)
|
|
Services.startup.exitLastWindowClosingSurvivalArea();
|
|
connection.onclose();
|
|
pipe.stop();
|
|
pipeStopped = true;
|
|
});
|
|
dispatcher.rootSession().setHandler(browserHandler);
|
|
loadFrameScript();
|
|
dump(`\nJuggler listening to the pipe\n`);
|
|
}
|
|
},
|
|
|
|
QueryInterface: ChromeUtils.generateQI([ Ci.nsICommandLineHandler ]),
|
|
|
|
// CHANGEME: change the help info as appropriate, but
|
|
// follow the guidelines in nsICommandLineHandler.idl
|
|
// specifically, flag descriptions should start at
|
|
// character 24, and lines should be wrapped at
|
|
// 72 characters with embedded newlines,
|
|
// and finally, the string should end with a newline
|
|
helpInfo : " --juggler Enable Juggler automation\n"
|
|
};
|
|
|
|
var NSGetFactory = ComponentUtils.generateNSGetFactory([CommandLineHandler]);
|