web-ext 6.7.0 → 7.1.0

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.
Files changed (94) hide show
  1. package/README.md +17 -8
  2. package/bin/web-ext.js +13 -0
  3. package/index.js +12 -0
  4. package/lib/cmd/build.js +226 -0
  5. package/lib/cmd/build.js.map +1 -0
  6. package/lib/cmd/docs.js +16 -0
  7. package/lib/cmd/docs.js.map +1 -0
  8. package/lib/cmd/index.js +47 -0
  9. package/lib/cmd/index.js.map +1 -0
  10. package/lib/cmd/lint.js +50 -0
  11. package/lib/cmd/lint.js.map +1 -0
  12. package/lib/cmd/run.js +199 -0
  13. package/lib/cmd/run.js.map +1 -0
  14. package/lib/cmd/sign.js +140 -0
  15. package/lib/cmd/sign.js.map +1 -0
  16. package/lib/config.js +144 -0
  17. package/lib/config.js.map +1 -0
  18. package/{src → lib}/errors.js +26 -35
  19. package/lib/errors.js.map +1 -0
  20. package/lib/extension-runners/base.js +2 -0
  21. package/lib/extension-runners/base.js.map +1 -0
  22. package/{src → lib}/extension-runners/chromium.js +121 -178
  23. package/lib/extension-runners/chromium.js.map +1 -0
  24. package/{src → lib}/extension-runners/firefox-android.js +168 -326
  25. package/lib/extension-runners/firefox-android.js.map +1 -0
  26. package/{src → lib}/extension-runners/firefox-desktop.js +73 -114
  27. package/lib/extension-runners/firefox-desktop.js.map +1 -0
  28. package/lib/extension-runners/index.js +311 -0
  29. package/lib/extension-runners/index.js.map +1 -0
  30. package/lib/firefox/index.js +362 -0
  31. package/lib/firefox/index.js.map +1 -0
  32. package/lib/firefox/package-identifiers.js +5 -0
  33. package/lib/firefox/package-identifiers.js.map +1 -0
  34. package/{src → lib}/firefox/preferences.js +27 -70
  35. package/lib/firefox/preferences.js.map +1 -0
  36. package/{src → lib}/firefox/rdp-client.js +98 -105
  37. package/lib/firefox/rdp-client.js.map +1 -0
  38. package/{src → lib}/firefox/remote.js +55 -129
  39. package/lib/firefox/remote.js.map +1 -0
  40. package/lib/main.js +9 -0
  41. package/lib/main.js.map +1 -0
  42. package/lib/program.js +663 -0
  43. package/lib/program.js.map +1 -0
  44. package/lib/util/adb.js +322 -0
  45. package/lib/util/adb.js.map +1 -0
  46. package/lib/util/artifacts.js +52 -0
  47. package/lib/util/artifacts.js.map +1 -0
  48. package/lib/util/desktop-notifier.js +27 -0
  49. package/lib/util/desktop-notifier.js.map +1 -0
  50. package/{src → lib}/util/file-exists.js +7 -14
  51. package/lib/util/file-exists.js.map +1 -0
  52. package/{src → lib}/util/file-filter.js +31 -59
  53. package/lib/util/file-filter.js.map +1 -0
  54. package/lib/util/is-directory.js +20 -0
  55. package/lib/util/is-directory.js.map +1 -0
  56. package/lib/util/logger.js +79 -0
  57. package/lib/util/logger.js.map +1 -0
  58. package/{src → lib}/util/manifest.js +18 -50
  59. package/lib/util/manifest.js.map +1 -0
  60. package/{src → lib}/util/promisify.js +6 -9
  61. package/lib/util/promisify.js.map +1 -0
  62. package/{src → lib}/util/stdin.js +3 -7
  63. package/lib/util/stdin.js.map +1 -0
  64. package/{src → lib}/util/temp-dir.js +47 -52
  65. package/lib/util/temp-dir.js.map +1 -0
  66. package/lib/util/updates.js +16 -0
  67. package/lib/util/updates.js.map +1 -0
  68. package/lib/watcher.js +78 -0
  69. package/lib/watcher.js.map +1 -0
  70. package/package.json +50 -52
  71. package/CODE_OF_CONDUCT.md +0 -10
  72. package/bin/web-ext +0 -7
  73. package/dist/web-ext.js +0 -2
  74. package/index.mjs +0 -13
  75. package/src/cmd/build.js +0 -319
  76. package/src/cmd/docs.js +0 -33
  77. package/src/cmd/index.js +0 -57
  78. package/src/cmd/lint.js +0 -102
  79. package/src/cmd/run.js +0 -266
  80. package/src/cmd/sign.js +0 -198
  81. package/src/config.js +0 -187
  82. package/src/extension-runners/base.js +0 -40
  83. package/src/extension-runners/index.js +0 -381
  84. package/src/firefox/index.js +0 -541
  85. package/src/firefox/package-identifiers.js +0 -14
  86. package/src/main.js +0 -19
  87. package/src/program.js +0 -765
  88. package/src/util/adb.js +0 -433
  89. package/src/util/artifacts.js +0 -69
  90. package/src/util/desktop-notifier.js +0 -41
  91. package/src/util/is-directory.js +0 -23
  92. package/src/util/logger.js +0 -131
  93. package/src/util/updates.js +0 -21
  94. package/src/watcher.js +0 -114
@@ -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 type FirefoxProfile from 'firefox-profile';
10
-
11
- import {
12
- MultiExtensionsReloadError,
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
- reloadableExtensions: Map<string, string>;
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
- getName(): string {
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
- async run(): Promise<void> {
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
- async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {
51
+
52
+
53
+ async reloadAllExtensions() {
100
54
  const runnerName = this.getName();
101
55
  const reloadErrors = new Map();
102
- for (const {sourceDir} of this.params.extensions) {
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 [{runnerName}];
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
- async reloadExtensionBySourceDir(
124
- extensionSourceDir: string
125
- ): Promise<Array<ExtensionRunnerReloadResult>> {
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
- 'Extension not reloadable: ' +
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 [{runnerName, sourceDir: extensionSourceDir}];
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
- registerCleanup(fn: Function): void {
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
- async exit(): Promise<void> {
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, {customPrefs});
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, {customPrefs});
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({customPrefs});
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, binaryArgs,
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
- remoteFirefox.installTemporaryAddon(extension.sourceDir)
263
- .then((installResult: FirefoxRDPResponseAddon) => {
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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"}