web-ext 6.8.0 → 7.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -8
- package/bin/web-ext.js +13 -0
- package/index.js +12 -0
- package/lib/cmd/build.js +226 -0
- package/lib/cmd/build.js.map +1 -0
- package/lib/cmd/docs.js +16 -0
- package/lib/cmd/docs.js.map +1 -0
- package/lib/cmd/index.js +47 -0
- package/lib/cmd/index.js.map +1 -0
- package/lib/cmd/lint.js +50 -0
- package/lib/cmd/lint.js.map +1 -0
- package/lib/cmd/run.js +199 -0
- package/lib/cmd/run.js.map +1 -0
- package/lib/cmd/sign.js +140 -0
- package/lib/cmd/sign.js.map +1 -0
- package/lib/config.js +144 -0
- package/lib/config.js.map +1 -0
- package/{src → lib}/errors.js +26 -35
- package/lib/errors.js.map +1 -0
- package/lib/extension-runners/base.js +2 -0
- package/lib/extension-runners/base.js.map +1 -0
- package/{src → lib}/extension-runners/chromium.js +121 -178
- package/lib/extension-runners/chromium.js.map +1 -0
- package/{src → lib}/extension-runners/firefox-android.js +168 -326
- package/lib/extension-runners/firefox-android.js.map +1 -0
- package/{src → lib}/extension-runners/firefox-desktop.js +73 -114
- package/lib/extension-runners/firefox-desktop.js.map +1 -0
- package/lib/extension-runners/index.js +311 -0
- package/lib/extension-runners/index.js.map +1 -0
- package/lib/firefox/index.js +362 -0
- package/lib/firefox/index.js.map +1 -0
- package/lib/firefox/package-identifiers.js +5 -0
- package/lib/firefox/package-identifiers.js.map +1 -0
- package/{src → lib}/firefox/preferences.js +27 -70
- package/lib/firefox/preferences.js.map +1 -0
- package/{src → lib}/firefox/rdp-client.js +98 -105
- package/lib/firefox/rdp-client.js.map +1 -0
- package/{src → lib}/firefox/remote.js +55 -129
- package/lib/firefox/remote.js.map +1 -0
- package/lib/main.js +9 -0
- package/lib/main.js.map +1 -0
- package/lib/program.js +666 -0
- package/lib/program.js.map +1 -0
- package/lib/util/adb.js +322 -0
- package/lib/util/adb.js.map +1 -0
- package/lib/util/artifacts.js +52 -0
- package/lib/util/artifacts.js.map +1 -0
- package/lib/util/desktop-notifier.js +27 -0
- package/lib/util/desktop-notifier.js.map +1 -0
- package/{src → lib}/util/file-exists.js +7 -14
- package/lib/util/file-exists.js.map +1 -0
- package/{src → lib}/util/file-filter.js +31 -59
- package/lib/util/file-filter.js.map +1 -0
- package/lib/util/is-directory.js +20 -0
- package/lib/util/is-directory.js.map +1 -0
- package/lib/util/logger.js +79 -0
- package/lib/util/logger.js.map +1 -0
- package/{src → lib}/util/manifest.js +18 -50
- package/lib/util/manifest.js.map +1 -0
- package/{src → lib}/util/promisify.js +6 -9
- package/lib/util/promisify.js.map +1 -0
- package/{src → lib}/util/stdin.js +3 -7
- package/lib/util/stdin.js.map +1 -0
- package/{src → lib}/util/temp-dir.js +47 -52
- package/lib/util/temp-dir.js.map +1 -0
- package/lib/util/updates.js +16 -0
- package/lib/util/updates.js.map +1 -0
- package/lib/watcher.js +78 -0
- package/lib/watcher.js.map +1 -0
- package/package.json +51 -53
- package/CODE_OF_CONDUCT.md +0 -10
- package/bin/web-ext +0 -7
- package/dist/web-ext.js +0 -2
- package/index.mjs +0 -13
- package/src/cmd/build.js +0 -319
- package/src/cmd/docs.js +0 -33
- package/src/cmd/index.js +0 -57
- package/src/cmd/lint.js +0 -102
- package/src/cmd/run.js +0 -266
- package/src/cmd/sign.js +0 -198
- package/src/config.js +0 -187
- package/src/extension-runners/base.js +0 -40
- package/src/extension-runners/index.js +0 -381
- package/src/firefox/index.js +0 -541
- package/src/firefox/package-identifiers.js +0 -14
- package/src/main.js +0 -19
- package/src/program.js +0 -765
- package/src/util/adb.js +0 -433
- package/src/util/artifacts.js +0 -69
- package/src/util/desktop-notifier.js +0 -41
- package/src/util/is-directory.js +0 -23
- package/src/util/logger.js +0 -131
- package/src/util/updates.js +0 -21
- package/src/watcher.js +0 -115
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firefox-android.js","names":["path","readline","withTempDir","DefaultADBUtils","showDesktopNotification","defaultDesktopNotifications","MultiExtensionsReloadError","UsageError","WebExtError","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxConnector","findFreeTcpPort","createLogger","isTTY","setRawMode","log","import","meta","url","ignoredParams","profilePath","keepProfileChanges","browserConsole","preInstall","startUrl","args","DEFAULT_ADB_HOST","getIgnoredParamsWarningsMessage","optionName","FirefoxAndroidExtensionRunner","unixSocketDiscoveryRetryInterval","unixSocketDiscoveryMaxTime","constructor","params","cleanupCallbacks","Set","adbExtensionsPathBySourceDir","Map","reloadableExtensions","printIgnoredParamsWarnings","run","adbBin","adbHost","adbPort","ADBUtils","adbUtils","adbDevicesDiscoveryAndSelect","apkPackagesDiscoveryAndSelect","adbCheckRuntimePermissions","adbForceStopSelectedPackage","adbPrepareProfileDir","Promise","all","adbStartSelectedPackage","buildAndPushExtensions","adbDiscoveryAndForwardRDPUnixSocket","rdpInstallExtensions","getName","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","buildAndPushExtension","remoteFirefox","reloadAddon","error","registerCleanup","fn","add","exit","selectedAdbDevice","selectedArtifactsDir","exiting","debug","clearArtifactsDir","getDeviceProfileDir","Object","keys","forEach","ignoredParam","warn","adbDevice","devices","discoverDevices","length","devicesMsg","map","dev","join","info","foundDevices","filter","device","JSON","stringify","firefoxApk","packages","discoverInstalledFirefoxAPKs","pkgsListMsg","pkgs","pkg","selectedFirefoxApk","filteredPackages","line","pkgsList","amForceStopAPK","androidVersion","getAndroidVersionNumber","Number","isNaN","requiredPermissions","ensureRequiredAPKRuntimePermissions","customPrefs","firefoxApp","adbRemoveOldArtifacts","profile","createProfile","app","foundOldArtifacts","detectOrRemoveOldArtifacts","getOrCreateArtifactsDir","deviceProfileDir","runShellCommand","pushFile","profileDir","firefoxApkComponent","startFirefoxAPK","buildSourceDir","tmpDir","extensionPath","extFileName","basename","adbExtensionPath","adbDiscoveryTimeout","stdin","process","handleCtrlC","str","key","ctrl","name","setUserAbortDiscovery","emitKeypressEvents","on","selectedRDPSocketFile","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","removeListener","tcpPort","forwardSocketSpec","startsWith","substr","setupForward","selectedTCPPort","firefoxClient","port","client","extension","installTemporaryAddon","then","installResult","addon","id"],"sources":["../../src/extension-runners/firefox-android.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Firefox for Android instance.\n */\n\nimport path from 'path';\nimport readline from 'readline';\n\nimport {withTempDir} from '../util/temp-dir.js';\nimport DefaultADBUtils from '../util/adb.js';\nimport {\n showDesktopNotification as defaultDesktopNotifications,\n} from '../util/desktop-notifier.js';\nimport {\n MultiExtensionsReloadError,\n UsageError,\n WebExtError,\n} from '../errors.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport {\n connectWithMaxRetries as defaultFirefoxConnector,\n findFreeTcpPort,\n} from '../firefox/remote.js';\nimport {createLogger} from '../util/logger.js';\nimport {isTTY, setRawMode} from '../util/stdin.js';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport type {\n FirefoxPreferences,\n} from '../firefox/preferences';\nimport type {\n FirefoxRDPResponseAddon,\n RemoteFirefox,\n} from '../firefox/remote';\nimport type {\n ExtensionBuildResult,\n} from '../cmd/build';\n\nconst log = createLogger(import.meta.url);\n\nconst ignoredParams = {\n profilePath: '--profile-path',\n keepProfileChanges: '--keep-profile-changes',\n browserConsole: '--browser-console',\n preInstall: '--pre-install',\n startUrl: '--start-url',\n args: '--args',\n};\n\n// Default adbHost to 127.0.0.1 to prevent issues with nodejs 17\n// (because if not specified adbkit may default to ipv6 while\n// adb may still only be listening on the ipv4 address),\n// see https://github.com/mozilla/web-ext/issues/2337.\nconst DEFAULT_ADB_HOST = '127.0.0.1';\n\nconst getIgnoredParamsWarningsMessage = (optionName) => {\n return `The Firefox for Android target does not support ${optionName}`;\n};\n\nexport type FirefoxAndroidExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n\n // Firefox specific.\n customPrefs?: FirefoxPreferences,\n\n // Not supported (currently ignored with logged warning).\n preInstall?: boolean,\n browserConsole?: boolean,\n\n // Firefox android injected dependencies.\n adbBin?: string,\n adbHost?: string,\n adbPort?: string,\n adbDevice?: string,\n adbDiscoveryTimeout?: number,\n adbRemoveOldArtifacts?: boolean,\n firefoxApk?: string,\n firefoxApkComponent?: string,\n\n // Injected Dependencies.\n firefoxApp: typeof defaultFirefoxApp,\n firefoxClient: typeof defaultFirefoxConnector,\n ADBUtils?: typeof DefaultADBUtils,\n buildSourceDir: (string, string) => Promise<ExtensionBuildResult>,\n desktopNotifications: typeof defaultDesktopNotifications,\n stdin?: stream$Readable,\n|};\n\n/**\n * Implements an IExtensionRunner which manages a Firefox for Android instance.\n */\nexport class FirefoxAndroidExtensionRunner {\n // Wait 3s before the next unix socket discovery loop.\n static unixSocketDiscoveryRetryInterval: number = 3 * 1000;\n // Wait for at most 3 minutes before giving up.\n static unixSocketDiscoveryMaxTime: number = 3 * 60 * 1000;\n\n params: FirefoxAndroidExtensionRunnerParams;\n adbUtils: DefaultADBUtils;\n exiting: boolean;\n selectedAdbDevice: string;\n selectedFirefoxApk: string;\n selectedArtifactsDir: string;\n selectedRDPSocketFile: string;\n selectedTCPPort: number;\n cleanupCallbacks: Set<Function>;\n adbExtensionsPathBySourceDir: Map<string, string>;\n reloadableExtensions: Map<string, string>;\n remoteFirefox: RemoteFirefox;\n\n constructor(params: FirefoxAndroidExtensionRunnerParams) {\n this.params = params;\n this.cleanupCallbacks = new Set();\n this.adbExtensionsPathBySourceDir = new Map();\n this.reloadableExtensions = new Map();\n\n // Print warning for not currently supported options (e.g. preInstall,\n // cloned profiles, browser console).\n this.printIgnoredParamsWarnings();\n }\n\n async run(): Promise<void> {\n const {\n adbBin,\n adbHost = DEFAULT_ADB_HOST,\n adbPort,\n ADBUtils = DefaultADBUtils,\n } = this.params;\n\n this.adbUtils = new ADBUtils({\n adbBin, adbHost, adbPort,\n });\n\n await this.adbDevicesDiscoveryAndSelect();\n await this.apkPackagesDiscoveryAndSelect();\n await this.adbCheckRuntimePermissions();\n await this.adbForceStopSelectedPackage();\n\n // Create profile prefs (with enabled remote RDP server), prepare the\n // artifacts and temporary directory on the selected device, and\n // push the profile preferences to the remote profile dir.\n await this.adbPrepareProfileDir();\n\n // NOTE: running Firefox for Android on the Android Emulator can be\n // pretty slow, we can run the following 3 steps in parallel to speed up\n // it a bit.\n await Promise.all([\n // Start Firefox for Android instance if not started yet.\n // (Fennec would run in an temporary profile and so it is explicitly\n // stopped, Fenix runs on its usual profile and so it may be already\n // running).\n this.adbStartSelectedPackage(),\n\n // Build and push to devices all the extension xpis\n // and keep track of the xpi built and uploaded by extension sourceDir.\n this.buildAndPushExtensions(),\n\n // Wait for RDP unix socket file created and\n // Create an ADB forward connection on a free tcp port\n this.adbDiscoveryAndForwardRDPUnixSocket(),\n ]);\n\n // Connect to RDP socket on the local tcp server, install all the pushed extension\n // and keep track of the built and installed extension by extension sourceDir.\n await this.rdpInstallExtensions();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Firefox Android';\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const reloadErrors = new Map();\n\n for (const {sourceDir} of this.params.extensions) {\n const [res] = await this.reloadExtensionBySourceDir(sourceDir);\n if (res.reloadError instanceof Error) {\n reloadErrors.set(sourceDir, res.reloadError);\n }\n }\n\n if (reloadErrors.size > 0) {\n return [{\n runnerName,\n reloadError: new MultiExtensionsReloadError(reloadErrors),\n }];\n }\n\n return [{runnerName}];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const addonId = this.reloadableExtensions.get(extensionSourceDir);\n\n if (!addonId) {\n return [{\n sourceDir: extensionSourceDir,\n reloadError: new WebExtError(\n 'Extension not reloadable: ' +\n `no addonId has been mapped to \"${extensionSourceDir}\"`\n ),\n runnerName,\n }];\n }\n\n try {\n await this.buildAndPushExtension(extensionSourceDir);\n await this.remoteFirefox.reloadAddon(addonId);\n } catch (error) {\n return [{\n sourceDir: extensionSourceDir,\n reloadError: error,\n runnerName,\n }];\n }\n\n return [{runnerName, sourceDir: extensionSourceDir}];\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Firefox instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit(): Promise<void> {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedArtifactsDir,\n } = this;\n\n this.exiting = true;\n\n // If a Firefox for Android instance has been started,\n // we should ensure that it has been stopped when we exit.\n await this.adbForceStopSelectedPackage();\n\n if (selectedArtifactsDir) {\n log.debug('Cleaning up artifacts directory on the Android device...');\n await adbUtils.clearArtifactsDir(selectedAdbDevice);\n }\n\n // Call all the registered cleanup callbacks.\n for (const fn of this.cleanupCallbacks) {\n try {\n fn();\n } catch (error) {\n log.error(error);\n }\n }\n }\n\n // Private helper methods.\n\n getDeviceProfileDir(): string {\n return `${this.selectedArtifactsDir}/profile`;\n }\n\n printIgnoredParamsWarnings() {\n Object.keys(ignoredParams).forEach((ignoredParam) => {\n if (this.params[ignoredParam]) {\n log.warn(\n getIgnoredParamsWarningsMessage(ignoredParams[ignoredParam])\n );\n }\n });\n }\n\n async adbDevicesDiscoveryAndSelect() {\n const {adbUtils} = this;\n const {adbDevice} = this.params;\n let devices = [];\n\n log.debug('Listing android devices');\n devices = await adbUtils.discoverDevices();\n\n if (devices.length === 0) {\n throw new UsageError(\n 'No Android device found through ADB. ' +\n 'Make sure the device is connected and USB debugging is enabled.'\n );\n }\n\n if (!adbDevice) {\n const devicesMsg = devices.map((dev) => ` - ${dev}`).join('\\n');\n log.info(`\\nAndroid devices found:\\n${devicesMsg}`);\n throw new UsageError(\n 'Select an android device using --android-device=<name>');\n }\n\n const foundDevices = devices.filter((device) => {\n return device === adbDevice;\n });\n\n if (foundDevices.length === 0) {\n const devicesMsg = JSON.stringify(devices);\n throw new UsageError(\n `Android device ${adbDevice} was not found in list: ${devicesMsg}`);\n }\n\n this.selectedAdbDevice = foundDevices[0];\n log.info(`Selected ADB device: ${this.selectedAdbDevice}`);\n }\n\n async apkPackagesDiscoveryAndSelect() {\n const {\n adbUtils,\n selectedAdbDevice,\n params: {\n firefoxApk,\n },\n } = this;\n // Discovery and select a Firefox for Android version.\n const packages = await adbUtils.discoverInstalledFirefoxAPKs(\n selectedAdbDevice,\n firefoxApk\n );\n\n if (packages.length === 0) {\n throw new UsageError(\n 'No Firefox packages were found on the selected Android device');\n }\n\n const pkgsListMsg = (pkgs) => {\n return pkgs.map((pkg) => ` - ${ pkg}`).join('\\n');\n };\n\n if (!firefoxApk) {\n log.info(`\\nPackages found:\\n${pkgsListMsg(packages)}`);\n\n if (packages.length > 1) {\n throw new UsageError('Select one of the packages using --firefox-apk');\n }\n\n // If only one APK has been found, select it even if it has not been\n // specified explicitly on the comment line.\n this.selectedFirefoxApk = packages[0];\n log.info(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n return;\n }\n\n const filteredPackages = packages.filter((line) => line === firefoxApk);\n\n if (filteredPackages.length === 0) {\n const pkgsList = pkgsListMsg(filteredPackages);\n throw new UsageError(\n `Package ${firefoxApk} was not found in list: ${pkgsList}`\n );\n }\n\n this.selectedFirefoxApk = filteredPackages[0];\n log.debug(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n }\n\n async adbForceStopSelectedPackage() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n } = this;\n\n log.info(`Stopping existing instances of ${selectedFirefoxApk}...`);\n await adbUtils.amForceStopAPK(selectedAdbDevice, selectedFirefoxApk);\n }\n\n async adbCheckRuntimePermissions() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n } = this;\n\n log.debug(`Discovering Android version for ${selectedAdbDevice}...`);\n\n const androidVersion = await adbUtils.getAndroidVersionNumber(\n selectedAdbDevice\n );\n\n if (typeof androidVersion !== 'number' || Number.isNaN(androidVersion)) {\n throw new WebExtError(`Invalid Android version: ${androidVersion}`);\n }\n\n log.debug(`Detected Android version ${androidVersion}`);\n\n if (androidVersion < 23) {\n return;\n }\n\n log.debug('Checking read/write permissions needed for web-ext' +\n `on ${selectedFirefoxApk}...`);\n\n // Runtime permissions needed to Firefox to be able to access the\n // xpi file uploaded to the android device or emulator.\n const requiredPermissions = [\n 'android.permission.READ_EXTERNAL_STORAGE',\n ];\n\n await adbUtils.ensureRequiredAPKRuntimePermissions(\n selectedAdbDevice, selectedFirefoxApk, requiredPermissions\n );\n }\n\n async adbPrepareProfileDir() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: {\n customPrefs,\n firefoxApp,\n adbRemoveOldArtifacts,\n },\n } = this;\n // Create the preferences file and the Fennec temporary profile.\n log.debug(`Preparing a temporary profile for ${selectedFirefoxApk}...`);\n\n const profile = await firefoxApp.createProfile({\n app: 'fennec',\n customPrefs,\n });\n\n // Check if there are any artifacts dirs from previous runs and\n // automatically remove them if adbRemoteOldArtifacts is true.\n const foundOldArtifacts = await adbUtils.detectOrRemoveOldArtifacts(\n selectedAdbDevice, adbRemoveOldArtifacts\n );\n\n if (foundOldArtifacts) {\n if (adbRemoveOldArtifacts) {\n log.info('Old web-ext artifacts have been found and removed ' +\n `from ${selectedAdbDevice} device`);\n } else {\n log.warn(\n `Old artifacts directories have been found on ${selectedAdbDevice} ` +\n 'device. Use --adb-remove-old-artifacts to remove them automatically.'\n );\n }\n }\n\n // Choose a artifacts dir name for the assets pushed to the\n // Android device.\n this.selectedArtifactsDir = await adbUtils.getOrCreateArtifactsDir(\n selectedAdbDevice\n );\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n await adbUtils.runShellCommand(selectedAdbDevice, [\n 'mkdir', '-p', deviceProfileDir,\n ]);\n await adbUtils.pushFile(selectedAdbDevice,\n path.join(profile.profileDir, 'user.js'),\n `${deviceProfileDir}/user.js`);\n\n log.debug(`Created temporary profile at ${deviceProfileDir}.`);\n }\n\n async adbStartSelectedPackage() {\n const {\n adbUtils,\n selectedFirefoxApk,\n selectedAdbDevice,\n params: {\n firefoxApkComponent,\n },\n } = this;\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n log.info(`Starting ${selectedFirefoxApk}...`);\n\n log.debug(`Using profile ${deviceProfileDir} (ignored by Fenix)`);\n\n await adbUtils.startFirefoxAPK(\n selectedAdbDevice,\n selectedFirefoxApk,\n firefoxApkComponent,\n deviceProfileDir,\n );\n }\n\n async buildAndPushExtension(sourceDir: string) {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedArtifactsDir,\n params: {\n buildSourceDir,\n },\n } = this;\n\n await withTempDir(async (tmpDir) => {\n const {extensionPath} = await buildSourceDir(sourceDir, tmpDir.path());\n\n const extFileName = path.basename(extensionPath, '.zip');\n\n let adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n adbExtensionPath = `${selectedArtifactsDir}/${extFileName}.xpi`;\n }\n\n log.debug(`Uploading ${extFileName} on the android device`);\n\n await adbUtils.pushFile(\n selectedAdbDevice, extensionPath, adbExtensionPath\n );\n\n log.debug(`Upload completed: ${adbExtensionPath}`);\n\n this.adbExtensionsPathBySourceDir.set(sourceDir, adbExtensionPath);\n });\n }\n\n async buildAndPushExtensions() {\n for (const {sourceDir} of this.params.extensions) {\n await this.buildAndPushExtension(sourceDir);\n }\n }\n\n async adbDiscoveryAndForwardRDPUnixSocket() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: {\n adbDiscoveryTimeout,\n },\n } = this;\n\n const stdin = this.params.stdin || process.stdin;\n\n const {\n unixSocketDiscoveryRetryInterval,\n } = FirefoxAndroidExtensionRunner;\n\n let {\n unixSocketDiscoveryMaxTime,\n } = FirefoxAndroidExtensionRunner;\n\n if (typeof adbDiscoveryTimeout === 'number') {\n unixSocketDiscoveryMaxTime = adbDiscoveryTimeout;\n }\n\n const handleCtrlC = (str, key) => {\n if (key.ctrl && key.name === 'c') {\n adbUtils.setUserAbortDiscovery(true);\n }\n };\n\n // TODO: use noInput property to decide if we should\n // disable direct keypress handling.\n if (isTTY(stdin)) {\n readline.emitKeypressEvents(stdin);\n setRawMode(stdin, true);\n\n stdin.on('keypress', handleCtrlC);\n }\n\n try {\n // Got a debugger socket file to connect.\n this.selectedRDPSocketFile = (\n await adbUtils.discoverRDPUnixSocket(\n selectedAdbDevice, selectedFirefoxApk, {\n maxDiscoveryTime: unixSocketDiscoveryMaxTime,\n retryInterval: unixSocketDiscoveryRetryInterval,\n }\n )\n );\n } finally {\n if (isTTY(stdin)) {\n stdin.removeListener('keypress', handleCtrlC);\n }\n }\n\n log.debug(`RDP Socket File selected: ${this.selectedRDPSocketFile}`);\n\n const tcpPort = await findFreeTcpPort();\n\n // Log the choosen tcp port at info level (useful to the user to be able\n // to connect the Firefox DevTools to the Firefox for Android instance).\n log.info(`You can connect to this Android device on TCP port ${tcpPort}`);\n\n const forwardSocketSpec = this.selectedRDPSocketFile.startsWith('@') ?\n `localabstract:${this.selectedRDPSocketFile.substr(1)}`\n : `localfilesystem:${this.selectedRDPSocketFile}`;\n\n await adbUtils.setupForward(\n selectedAdbDevice,\n forwardSocketSpec,\n `tcp:${tcpPort}`\n );\n\n this.selectedTCPPort = tcpPort;\n }\n\n async rdpInstallExtensions() {\n const {\n selectedTCPPort,\n params: {\n extensions,\n firefoxClient,\n },\n } = this;\n\n const remoteFirefox = this.remoteFirefox = await firefoxClient({\n port: selectedTCPPort,\n });\n\n // Exit and cleanup the extension runner if the connection to the\n // remote Firefox for Android instance has been closed.\n remoteFirefox.client.on('end', () => {\n if (!this.exiting) {\n log.info('Exiting the device because Firefox for Android disconnected');\n this.exit();\n }\n });\n\n // Install all the temporary addons.\n for (const extension of extensions) {\n const {sourceDir} = extension;\n const adbExtensionPath = this.adbExtensionsPathBySourceDir.get(\n sourceDir\n );\n\n if (!adbExtensionPath) {\n throw new WebExtError(\n `ADB extension path for \"${sourceDir}\" was unexpectedly empty`\n );\n }\n\n const addonId = await (\n remoteFirefox.installTemporaryAddon(adbExtensionPath)\n .then((installResult: FirefoxRDPResponseAddon) => {\n return installResult.addon.id;\n })\n );\n\n if (!addonId) {\n throw new WebExtError(\n 'Received an empty addonId from ' +\n `remoteFirefox.installTemporaryAddon(\"${adbExtensionPath}\")`\n );\n }\n\n this.reloadableExtensions.set(extension.sourceDir, addonId);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,106 +1,64 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* This module provide an ExtensionRunner subclass that manage an extension executed
|
|
5
3
|
* in a Firefox for Desktop instance.
|
|
6
4
|
*/
|
|
7
|
-
|
|
8
5
|
// Import flow types from npm dependencies.
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
RemoteTempInstallNotSupported,
|
|
14
|
-
WebExtError,
|
|
15
|
-
} from '../errors';
|
|
16
|
-
import * as defaultFirefoxApp from '../firefox';
|
|
17
|
-
import {
|
|
18
|
-
connectWithMaxRetries as defaultFirefoxConnector,
|
|
19
|
-
} from '../firefox/remote';
|
|
20
|
-
import {createLogger} from '../util/logger';
|
|
21
|
-
// Import flow types from project files.
|
|
22
|
-
import type {
|
|
23
|
-
FirefoxRDPResponseAddon,
|
|
24
|
-
RemoteFirefox,
|
|
25
|
-
} from '../firefox/remote';
|
|
26
|
-
import type {
|
|
27
|
-
ExtensionRunnerParams,
|
|
28
|
-
ExtensionRunnerReloadResult,
|
|
29
|
-
} from './base';
|
|
30
|
-
import type {FirefoxPreferences} from '../firefox/preferences';
|
|
31
|
-
import type {FirefoxInfo} from '../firefox/index'; // eslint-disable-line import/named
|
|
32
|
-
|
|
33
|
-
type FirefoxDesktopSpecificRunnerParams = {|
|
|
34
|
-
customPrefs?: FirefoxPreferences,
|
|
35
|
-
browserConsole: boolean,
|
|
36
|
-
firefoxBinary: string,
|
|
37
|
-
preInstall: boolean,
|
|
38
|
-
|
|
39
|
-
// Firefox desktop injected dependencies.
|
|
40
|
-
firefoxApp: typeof defaultFirefoxApp,
|
|
41
|
-
firefoxClient: typeof defaultFirefoxConnector,
|
|
42
|
-
|};
|
|
43
|
-
|
|
44
|
-
export type FirefoxDesktopExtensionRunnerParams = {|
|
|
45
|
-
...ExtensionRunnerParams,
|
|
46
|
-
// Firefox desktop CLI params.
|
|
47
|
-
...FirefoxDesktopSpecificRunnerParams,
|
|
48
|
-
|};
|
|
49
|
-
|
|
50
|
-
const log = createLogger(__filename);
|
|
6
|
+
import { MultiExtensionsReloadError, RemoteTempInstallNotSupported, WebExtError } from '../errors.js';
|
|
7
|
+
import * as defaultFirefoxApp from '../firefox/index.js';
|
|
8
|
+
import { connectWithMaxRetries as defaultFirefoxConnector } from '../firefox/remote.js';
|
|
9
|
+
import { createLogger } from '../util/logger.js'; // Import flow types from project files.
|
|
51
10
|
|
|
11
|
+
const log = createLogger(import.meta.url);
|
|
52
12
|
/**
|
|
53
13
|
* Implements an IExtensionRunner which manages a Firefox Desktop instance.
|
|
54
14
|
*/
|
|
15
|
+
|
|
55
16
|
export class FirefoxDesktopExtensionRunner {
|
|
56
|
-
cleanupCallbacks: Set<Function>;
|
|
57
|
-
params: FirefoxDesktopExtensionRunnerParams;
|
|
58
|
-
profile: FirefoxProfile;
|
|
59
17
|
// Map extensions sourceDir to their related addon ids.
|
|
60
|
-
|
|
61
|
-
remoteFirefox: RemoteFirefox;
|
|
62
|
-
runningInfo: FirefoxInfo;
|
|
63
|
-
|
|
64
|
-
constructor(params: FirefoxDesktopExtensionRunnerParams) {
|
|
18
|
+
constructor(params) {
|
|
65
19
|
this.params = params;
|
|
66
|
-
|
|
67
20
|
this.reloadableExtensions = new Map();
|
|
68
21
|
this.cleanupCallbacks = new Set();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Method exported from the IExtensionRunner interface.
|
|
22
|
+
} // Method exported from the IExtensionRunner interface.
|
|
72
23
|
|
|
73
24
|
/**
|
|
74
25
|
* Returns the runner name.
|
|
75
26
|
*/
|
|
76
|
-
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
getName() {
|
|
77
30
|
return 'Firefox Desktop';
|
|
78
31
|
}
|
|
79
|
-
|
|
80
32
|
/**
|
|
81
33
|
* Setup the Firefox Profile and run a Firefox Desktop instance.
|
|
82
34
|
*/
|
|
83
|
-
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async run() {
|
|
84
38
|
// Get a firefox profile with the custom Prefs set (a new or a cloned one).
|
|
85
39
|
// Pre-install extensions as proxy if needed (and disable auto-reload if you do)
|
|
86
|
-
await this.setupProfileDir();
|
|
87
|
-
|
|
88
|
-
// (if reload is enabled):
|
|
40
|
+
await this.setupProfileDir(); // (if reload is enabled):
|
|
89
41
|
// - Connect to the firefox instance on RDP
|
|
90
42
|
// - Install any extension if needed (if not installed as proxy)
|
|
91
43
|
// - Keep track of the extension id assigned in a map with the sourceDir as a key
|
|
44
|
+
|
|
92
45
|
await this.startFirefoxInstance();
|
|
93
46
|
}
|
|
94
|
-
|
|
95
47
|
/**
|
|
96
48
|
* Reloads all the extensions, collect any reload error and resolves to
|
|
97
49
|
* an array composed by a single ExtensionRunnerReloadResult object.
|
|
98
50
|
*/
|
|
99
|
-
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
async reloadAllExtensions() {
|
|
100
54
|
const runnerName = this.getName();
|
|
101
55
|
const reloadErrors = new Map();
|
|
102
|
-
|
|
56
|
+
|
|
57
|
+
for (const {
|
|
58
|
+
sourceDir
|
|
59
|
+
} of this.params.extensions) {
|
|
103
60
|
const [res] = await this.reloadExtensionBySourceDir(sourceDir);
|
|
61
|
+
|
|
104
62
|
if (res.reloadError instanceof Error) {
|
|
105
63
|
reloadErrors.set(sourceDir, res.reloadError);
|
|
106
64
|
}
|
|
@@ -109,31 +67,29 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
109
67
|
if (reloadErrors.size > 0) {
|
|
110
68
|
return [{
|
|
111
69
|
runnerName,
|
|
112
|
-
reloadError: new MultiExtensionsReloadError(reloadErrors)
|
|
70
|
+
reloadError: new MultiExtensionsReloadError(reloadErrors)
|
|
113
71
|
}];
|
|
114
72
|
}
|
|
115
73
|
|
|
116
|
-
return [{
|
|
74
|
+
return [{
|
|
75
|
+
runnerName
|
|
76
|
+
}];
|
|
117
77
|
}
|
|
118
|
-
|
|
119
78
|
/**
|
|
120
79
|
* Reloads a single extension, collect any reload error and resolves to
|
|
121
80
|
* an array composed by a single ExtensionRunnerReloadResult object.
|
|
122
81
|
*/
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
async reloadExtensionBySourceDir(extensionSourceDir) {
|
|
126
85
|
const runnerName = this.getName();
|
|
127
86
|
const addonId = this.reloadableExtensions.get(extensionSourceDir);
|
|
128
87
|
|
|
129
88
|
if (!addonId) {
|
|
130
89
|
return [{
|
|
131
90
|
sourceDir: extensionSourceDir,
|
|
132
|
-
reloadError: new WebExtError(
|
|
133
|
-
|
|
134
|
-
`no addonId has been mapped to "${extensionSourceDir}"`
|
|
135
|
-
),
|
|
136
|
-
runnerName,
|
|
91
|
+
reloadError: new WebExtError('Extension not reloadable: ' + `no addonId has been mapped to "${extensionSourceDir}"`),
|
|
92
|
+
runnerName
|
|
137
93
|
}];
|
|
138
94
|
}
|
|
139
95
|
|
|
@@ -143,34 +99,38 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
143
99
|
return [{
|
|
144
100
|
sourceDir: extensionSourceDir,
|
|
145
101
|
reloadError: error,
|
|
146
|
-
runnerName
|
|
102
|
+
runnerName
|
|
147
103
|
}];
|
|
148
104
|
}
|
|
149
105
|
|
|
150
|
-
return [{
|
|
106
|
+
return [{
|
|
107
|
+
runnerName,
|
|
108
|
+
sourceDir: extensionSourceDir
|
|
109
|
+
}];
|
|
151
110
|
}
|
|
152
|
-
|
|
153
111
|
/**
|
|
154
112
|
* Register a callback to be called when the runner has been exited
|
|
155
113
|
* (e.g. the Firefox instance exits or the user has requested web-ext
|
|
156
114
|
* to exit).
|
|
157
115
|
*/
|
|
158
|
-
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
registerCleanup(fn) {
|
|
159
119
|
this.cleanupCallbacks.add(fn);
|
|
160
120
|
}
|
|
161
|
-
|
|
162
121
|
/**
|
|
163
122
|
* Exits the runner, by closing the managed Firefox instance.
|
|
164
123
|
*/
|
|
165
|
-
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
async exit() {
|
|
166
127
|
if (!this.runningInfo || !this.runningInfo.firefox) {
|
|
167
128
|
throw new WebExtError('No firefox instance is currently running');
|
|
168
129
|
}
|
|
169
130
|
|
|
170
131
|
this.runningInfo.firefox.kill();
|
|
171
|
-
}
|
|
132
|
+
} // Private helper methods.
|
|
172
133
|
|
|
173
|
-
// Private helper methods.
|
|
174
134
|
|
|
175
135
|
async setupProfileDir() {
|
|
176
136
|
const {
|
|
@@ -179,30 +139,36 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
179
139
|
keepProfileChanges,
|
|
180
140
|
preInstall,
|
|
181
141
|
profilePath,
|
|
182
|
-
firefoxApp
|
|
142
|
+
firefoxApp
|
|
183
143
|
} = this.params;
|
|
184
144
|
|
|
185
145
|
if (profilePath) {
|
|
186
146
|
if (keepProfileChanges) {
|
|
187
147
|
log.debug(`Using Firefox profile from ${profilePath}`);
|
|
188
|
-
this.profile = await firefoxApp.useProfile(profilePath, {
|
|
148
|
+
this.profile = await firefoxApp.useProfile(profilePath, {
|
|
149
|
+
customPrefs
|
|
150
|
+
});
|
|
189
151
|
} else {
|
|
190
152
|
log.debug(`Copying Firefox profile from ${profilePath}`);
|
|
191
|
-
this.profile = await firefoxApp.copyProfile(profilePath, {
|
|
153
|
+
this.profile = await firefoxApp.copyProfile(profilePath, {
|
|
154
|
+
customPrefs
|
|
155
|
+
});
|
|
192
156
|
}
|
|
193
157
|
} else {
|
|
194
158
|
log.debug('Creating new Firefox profile');
|
|
195
|
-
this.profile = await firefoxApp.createProfile({
|
|
196
|
-
|
|
159
|
+
this.profile = await firefoxApp.createProfile({
|
|
160
|
+
customPrefs
|
|
161
|
+
});
|
|
162
|
+
} // preInstall the extensions if needed.
|
|
163
|
+
|
|
197
164
|
|
|
198
|
-
// preInstall the extensions if needed.
|
|
199
165
|
if (preInstall) {
|
|
200
166
|
for (const extension of extensions) {
|
|
201
167
|
await firefoxApp.installExtension({
|
|
202
168
|
asProxy: true,
|
|
203
169
|
extensionPath: extension.sourceDir,
|
|
204
170
|
manifestData: extension.manifestData,
|
|
205
|
-
profile: this.profile
|
|
171
|
+
profile: this.profile
|
|
206
172
|
});
|
|
207
173
|
}
|
|
208
174
|
}
|
|
@@ -217,16 +183,17 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
217
183
|
startUrl,
|
|
218
184
|
firefoxApp,
|
|
219
185
|
firefoxClient,
|
|
220
|
-
args
|
|
186
|
+
args
|
|
221
187
|
} = this.params;
|
|
222
|
-
|
|
223
188
|
const binaryArgs = [];
|
|
224
189
|
|
|
225
190
|
if (browserConsole) {
|
|
226
191
|
binaryArgs.push('-jsconsole');
|
|
227
192
|
}
|
|
193
|
+
|
|
228
194
|
if (startUrl) {
|
|
229
195
|
const urls = Array.isArray(startUrl) ? startUrl : [startUrl];
|
|
196
|
+
|
|
230
197
|
for (const url of urls) {
|
|
231
198
|
binaryArgs.push('--url', url);
|
|
232
199
|
}
|
|
@@ -237,9 +204,9 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
237
204
|
}
|
|
238
205
|
|
|
239
206
|
this.runningInfo = await firefoxApp.run(this.profile, {
|
|
240
|
-
firefoxBinary,
|
|
207
|
+
firefoxBinary,
|
|
208
|
+
binaryArgs
|
|
241
209
|
});
|
|
242
|
-
|
|
243
210
|
this.runningInfo.firefox.on('close', () => {
|
|
244
211
|
for (const cleanupCb of this.cleanupCallbacks) {
|
|
245
212
|
try {
|
|
@@ -252,34 +219,24 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
252
219
|
|
|
253
220
|
if (!preInstall) {
|
|
254
221
|
const remoteFirefox = this.remoteFirefox = await firefoxClient({
|
|
255
|
-
port: this.runningInfo.debuggerPort
|
|
256
|
-
});
|
|
222
|
+
port: this.runningInfo.debuggerPort
|
|
223
|
+
}); // Install all the temporary addons.
|
|
257
224
|
|
|
258
|
-
// Install all the temporary addons.
|
|
259
225
|
for (const extension of extensions) {
|
|
260
226
|
try {
|
|
261
|
-
const addonId = await (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return installResult.addon.id;
|
|
265
|
-
})
|
|
266
|
-
);
|
|
227
|
+
const addonId = await remoteFirefox.installTemporaryAddon(extension.sourceDir).then(installResult => {
|
|
228
|
+
return installResult.addon.id;
|
|
229
|
+
});
|
|
267
230
|
|
|
268
231
|
if (!addonId) {
|
|
269
|
-
throw new WebExtError(
|
|
270
|
-
'Unexpected missing addonId in the installAsTemporaryAddon result'
|
|
271
|
-
);
|
|
232
|
+
throw new WebExtError('Unexpected missing addonId in the installAsTemporaryAddon result');
|
|
272
233
|
}
|
|
273
234
|
|
|
274
235
|
this.reloadableExtensions.set(extension.sourceDir, addonId);
|
|
275
236
|
} catch (error) {
|
|
276
237
|
if (error instanceof RemoteTempInstallNotSupported) {
|
|
277
|
-
log.debug(`Caught: ${error}`);
|
|
278
|
-
throw new WebExtError(
|
|
279
|
-
'Temporary add-on installation is not supported in this version' +
|
|
280
|
-
' of Firefox (you need Firefox 49 or higher). For older Firefox' +
|
|
281
|
-
' versions, use --pre-install'
|
|
282
|
-
);
|
|
238
|
+
log.debug(`Caught: ${String(error)}`);
|
|
239
|
+
throw new WebExtError('Temporary add-on installation is not supported in this version' + ' of Firefox (you need Firefox 49 or higher). For older Firefox' + ' versions, use --pre-install');
|
|
283
240
|
} else {
|
|
284
241
|
throw error;
|
|
285
242
|
}
|
|
@@ -287,4 +244,6 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
287
244
|
}
|
|
288
245
|
}
|
|
289
246
|
}
|
|
247
|
+
|
|
290
248
|
}
|
|
249
|
+
//# sourceMappingURL=firefox-desktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firefox-desktop.js","names":["MultiExtensionsReloadError","RemoteTempInstallNotSupported","WebExtError","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxConnector","createLogger","log","import","meta","url","FirefoxDesktopExtensionRunner","constructor","params","reloadableExtensions","Map","cleanupCallbacks","Set","getName","run","setupProfileDir","startFirefoxInstance","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","remoteFirefox","reloadAddon","error","registerCleanup","fn","add","exit","runningInfo","firefox","kill","customPrefs","keepProfileChanges","preInstall","profilePath","firefoxApp","debug","profile","useProfile","copyProfile","createProfile","extension","installExtension","asProxy","extensionPath","manifestData","browserConsole","firefoxBinary","startUrl","firefoxClient","args","binaryArgs","push","urls","Array","isArray","on","cleanupCb","port","debuggerPort","installTemporaryAddon","then","installResult","addon","id","String"],"sources":["../../src/extension-runners/firefox-desktop.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Firefox for Desktop instance.\n */\n\n// Import flow types from npm dependencies.\nimport type FirefoxProfile from 'firefox-profile';\n\nimport {\n MultiExtensionsReloadError,\n RemoteTempInstallNotSupported,\n WebExtError,\n} from '../errors.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport {\n connectWithMaxRetries as defaultFirefoxConnector,\n} from '../firefox/remote.js';\nimport {createLogger} from '../util/logger.js';\n// Import flow types from project files.\nimport type {\n FirefoxRDPResponseAddon,\n RemoteFirefox,\n} from '../firefox/remote';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport type {FirefoxPreferences} from '../firefox/preferences';\nimport type {FirefoxInfo} from '../firefox/index'; // eslint-disable-line import/named\n\ntype FirefoxDesktopSpecificRunnerParams = {|\n customPrefs?: FirefoxPreferences,\n browserConsole: boolean,\n firefoxBinary: string,\n preInstall: boolean,\n\n // Firefox desktop injected dependencies.\n firefoxApp: typeof defaultFirefoxApp,\n firefoxClient: typeof defaultFirefoxConnector,\n|};\n\nexport type FirefoxDesktopExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n // Firefox desktop CLI params.\n ...FirefoxDesktopSpecificRunnerParams,\n|};\n\nconst log = createLogger(import.meta.url);\n\n\n/**\n * Implements an IExtensionRunner which manages a Firefox Desktop instance.\n */\nexport class FirefoxDesktopExtensionRunner {\n cleanupCallbacks: Set<Function>;\n params: FirefoxDesktopExtensionRunnerParams;\n profile: FirefoxProfile;\n // Map extensions sourceDir to their related addon ids.\n reloadableExtensions: Map<string, string>;\n remoteFirefox: RemoteFirefox;\n runningInfo: FirefoxInfo;\n\n constructor(params: FirefoxDesktopExtensionRunnerParams) {\n this.params = params;\n\n this.reloadableExtensions = new Map();\n this.cleanupCallbacks = new Set();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Firefox Desktop';\n }\n\n /**\n * Setup the Firefox Profile and run a Firefox Desktop instance.\n */\n async run(): Promise<void> {\n // Get a firefox profile with the custom Prefs set (a new or a cloned one).\n // Pre-install extensions as proxy if needed (and disable auto-reload if you do)\n await this.setupProfileDir();\n\n // (if reload is enabled):\n // - Connect to the firefox instance on RDP\n // - Install any extension if needed (if not installed as proxy)\n // - Keep track of the extension id assigned in a map with the sourceDir as a key\n await this.startFirefoxInstance();\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const reloadErrors = new Map();\n for (const {sourceDir} of this.params.extensions) {\n const [res] = await this.reloadExtensionBySourceDir(sourceDir);\n if (res.reloadError instanceof Error) {\n reloadErrors.set(sourceDir, res.reloadError);\n }\n }\n\n if (reloadErrors.size > 0) {\n return [{\n runnerName,\n reloadError: new MultiExtensionsReloadError(reloadErrors),\n }];\n }\n\n return [{runnerName}];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const addonId = this.reloadableExtensions.get(extensionSourceDir);\n\n if (!addonId) {\n return [{\n sourceDir: extensionSourceDir,\n reloadError: new WebExtError(\n 'Extension not reloadable: ' +\n `no addonId has been mapped to \"${extensionSourceDir}\"`\n ),\n runnerName,\n }];\n }\n\n try {\n await this.remoteFirefox.reloadAddon(addonId);\n } catch (error) {\n return [{\n sourceDir: extensionSourceDir,\n reloadError: error,\n runnerName,\n }];\n }\n\n return [{runnerName, sourceDir: extensionSourceDir}];\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Firefox instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit(): Promise<void> {\n if (!this.runningInfo || !this.runningInfo.firefox) {\n throw new WebExtError('No firefox instance is currently running');\n }\n\n this.runningInfo.firefox.kill();\n }\n\n // Private helper methods.\n\n async setupProfileDir() {\n const {\n customPrefs,\n extensions,\n keepProfileChanges,\n preInstall,\n profilePath,\n firefoxApp,\n } = this.params;\n\n if (profilePath) {\n if (keepProfileChanges) {\n log.debug(`Using Firefox profile from ${profilePath}`);\n this.profile = await firefoxApp.useProfile(profilePath, {customPrefs});\n } else {\n log.debug(`Copying Firefox profile from ${profilePath}`);\n this.profile = await firefoxApp.copyProfile(profilePath, {customPrefs});\n }\n } else {\n log.debug('Creating new Firefox profile');\n this.profile = await firefoxApp.createProfile({customPrefs});\n }\n\n // preInstall the extensions if needed.\n if (preInstall) {\n for (const extension of extensions) {\n await firefoxApp.installExtension({\n asProxy: true,\n extensionPath: extension.sourceDir,\n manifestData: extension.manifestData,\n profile: this.profile,\n });\n }\n }\n }\n\n async startFirefoxInstance() {\n const {\n browserConsole,\n extensions,\n firefoxBinary,\n preInstall,\n startUrl,\n firefoxApp,\n firefoxClient,\n args,\n } = this.params;\n\n const binaryArgs = [];\n\n if (browserConsole) {\n binaryArgs.push('-jsconsole');\n }\n if (startUrl) {\n const urls = Array.isArray(startUrl) ? startUrl : [startUrl];\n for (const url of urls) {\n binaryArgs.push('--url', url);\n }\n }\n\n if (args) {\n binaryArgs.push(...args);\n }\n\n this.runningInfo = await firefoxApp.run(this.profile, {\n firefoxBinary, binaryArgs,\n });\n\n this.runningInfo.firefox.on('close', () => {\n for (const cleanupCb of this.cleanupCallbacks) {\n try {\n cleanupCb();\n } catch (error) {\n log.error(`Exception on executing cleanup callback: ${error}`);\n }\n }\n });\n\n if (!preInstall) {\n const remoteFirefox = this.remoteFirefox = await firefoxClient({\n port: this.runningInfo.debuggerPort,\n });\n\n // Install all the temporary addons.\n for (const extension of extensions) {\n try {\n const addonId = await (\n remoteFirefox.installTemporaryAddon(extension.sourceDir)\n .then((installResult: FirefoxRDPResponseAddon) => {\n return installResult.addon.id;\n })\n );\n\n if (!addonId) {\n throw new WebExtError(\n 'Unexpected missing addonId in the installAsTemporaryAddon result'\n );\n }\n\n this.reloadableExtensions.set(extension.sourceDir, addonId);\n } catch (error) {\n if (error instanceof RemoteTempInstallNotSupported) {\n log.debug(`Caught: ${String(error)}`);\n throw new WebExtError(\n 'Temporary add-on installation is not supported in this version' +\n ' of Firefox (you need Firefox 49 or higher). For older Firefox' +\n ' versions, use --pre-install'\n );\n } else {\n throw error;\n }\n }\n }\n }\n }\n}\n"],"mappings":"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"}
|