web-ext 7.2.0 → 7.3.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.
- package/README.md +2 -2
- package/lib/cmd/build.js +18 -36
- package/lib/cmd/build.js.map +1 -1
- package/lib/cmd/docs.js +1 -0
- package/lib/cmd/docs.js.map +1 -1
- package/lib/cmd/index.js +3 -5
- package/lib/cmd/index.js.map +1 -1
- package/lib/cmd/lint.js +28 -17
- package/lib/cmd/lint.js.map +1 -1
- package/lib/cmd/run.js +19 -23
- package/lib/cmd/run.js.map +1 -1
- package/lib/cmd/sign.js +80 -47
- package/lib/cmd/sign.js.map +1 -1
- package/lib/config.js +18 -29
- package/lib/config.js.map +1 -1
- package/lib/errors.js +8 -18
- package/lib/errors.js.map +1 -1
- package/lib/extension-runners/base.js +2 -0
- package/lib/extension-runners/base.js.map +1 -1
- package/lib/extension-runners/chromium.js +36 -62
- package/lib/extension-runners/chromium.js.map +1 -1
- package/lib/extension-runners/firefox-android.js +65 -102
- package/lib/extension-runners/firefox-android.js.map +1 -1
- package/lib/extension-runners/firefox-desktop.js +29 -42
- package/lib/extension-runners/firefox-desktop.js.map +1 -1
- package/lib/extension-runners/index.js +33 -46
- package/lib/extension-runners/index.js.map +1 -1
- package/lib/firefox/index.js +59 -52
- package/lib/firefox/index.js.map +1 -1
- package/lib/firefox/package-identifiers.js +2 -0
- package/lib/firefox/package-identifiers.js.map +1 -1
- package/lib/firefox/preferences.js +14 -15
- package/lib/firefox/preferences.js.map +1 -1
- package/lib/firefox/rdp-client.js +16 -64
- package/lib/firefox/rdp-client.js.map +1 -1
- package/lib/firefox/remote.js +15 -30
- package/lib/firefox/remote.js.map +1 -1
- package/lib/main.js +4 -2
- package/lib/main.js.map +1 -1
- package/lib/program.js +74 -76
- package/lib/program.js.map +1 -1
- package/lib/util/adb.js +33 -63
- package/lib/util/adb.js.map +1 -1
- package/lib/util/artifacts.js +3 -5
- package/lib/util/artifacts.js.map +1 -1
- package/lib/util/desktop-notifier.js +1 -0
- package/lib/util/desktop-notifier.js.map +1 -1
- package/lib/util/file-exists.js +1 -2
- package/lib/util/file-exists.js.map +1 -1
- package/lib/util/file-filter.js +17 -19
- package/lib/util/file-filter.js.map +1 -1
- package/lib/util/is-directory.js +2 -1
- package/lib/util/is-directory.js.map +1 -1
- package/lib/util/logger.js +7 -12
- package/lib/util/logger.js.map +1 -1
- package/lib/util/manifest.js +6 -13
- package/lib/util/manifest.js.map +1 -1
- package/lib/util/promisify.js +7 -3
- package/lib/util/promisify.js.map +1 -1
- package/lib/util/stdin.js +2 -0
- package/lib/util/stdin.js.map +1 -1
- package/lib/util/submit-addon.js +288 -0
- package/lib/util/submit-addon.js.map +1 -0
- package/lib/util/temp-dir.js +8 -18
- package/lib/util/temp-dir.js.map +1 -1
- package/lib/util/updates.js +1 -1
- package/lib/util/updates.js.map +1 -1
- package/lib/watcher.js +14 -9
- package/lib/watcher.js.map +1 -1
- package/package.json +16 -14
|
@@ -1 +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
|
+
{"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,90 +1,89 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* This module provide an ExtensionRunner subclass that manage an extension executed
|
|
3
5
|
* in a Firefox for Desktop instance.
|
|
4
6
|
*/
|
|
7
|
+
|
|
5
8
|
// Import flow types from npm dependencies.
|
|
9
|
+
|
|
6
10
|
import { MultiExtensionsReloadError, RemoteTempInstallNotSupported, WebExtError } from '../errors.js';
|
|
7
11
|
import * as defaultFirefoxApp from '../firefox/index.js';
|
|
8
12
|
import { connectWithMaxRetries as defaultFirefoxConnector } from '../firefox/remote.js';
|
|
9
|
-
import { createLogger } from '../util/logger.js';
|
|
13
|
+
import { createLogger } from '../util/logger.js';
|
|
14
|
+
// Import flow types from project files.
|
|
10
15
|
|
|
11
16
|
const log = createLogger(import.meta.url);
|
|
17
|
+
|
|
12
18
|
/**
|
|
13
19
|
* Implements an IExtensionRunner which manages a Firefox Desktop instance.
|
|
14
20
|
*/
|
|
15
|
-
|
|
16
21
|
export class FirefoxDesktopExtensionRunner {
|
|
17
22
|
// Map extensions sourceDir to their related addon ids.
|
|
23
|
+
|
|
18
24
|
constructor(params) {
|
|
19
25
|
this.params = params;
|
|
20
26
|
this.reloadableExtensions = new Map();
|
|
21
27
|
this.cleanupCallbacks = new Set();
|
|
22
|
-
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Method exported from the IExtensionRunner interface.
|
|
23
31
|
|
|
24
32
|
/**
|
|
25
33
|
* Returns the runner name.
|
|
26
34
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
35
|
getName() {
|
|
30
36
|
return 'Firefox Desktop';
|
|
31
37
|
}
|
|
38
|
+
|
|
32
39
|
/**
|
|
33
40
|
* Setup the Firefox Profile and run a Firefox Desktop instance.
|
|
34
41
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
37
42
|
async run() {
|
|
38
43
|
// Get a firefox profile with the custom Prefs set (a new or a cloned one).
|
|
39
44
|
// Pre-install extensions as proxy if needed (and disable auto-reload if you do)
|
|
40
|
-
await this.setupProfileDir();
|
|
45
|
+
await this.setupProfileDir();
|
|
46
|
+
|
|
47
|
+
// (if reload is enabled):
|
|
41
48
|
// - Connect to the firefox instance on RDP
|
|
42
49
|
// - Install any extension if needed (if not installed as proxy)
|
|
43
50
|
// - Keep track of the extension id assigned in a map with the sourceDir as a key
|
|
44
|
-
|
|
45
51
|
await this.startFirefoxInstance();
|
|
46
52
|
}
|
|
53
|
+
|
|
47
54
|
/**
|
|
48
55
|
* Reloads all the extensions, collect any reload error and resolves to
|
|
49
56
|
* an array composed by a single ExtensionRunnerReloadResult object.
|
|
50
57
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
58
|
async reloadAllExtensions() {
|
|
54
59
|
const runnerName = this.getName();
|
|
55
60
|
const reloadErrors = new Map();
|
|
56
|
-
|
|
57
61
|
for (const {
|
|
58
62
|
sourceDir
|
|
59
63
|
} of this.params.extensions) {
|
|
60
64
|
const [res] = await this.reloadExtensionBySourceDir(sourceDir);
|
|
61
|
-
|
|
62
65
|
if (res.reloadError instanceof Error) {
|
|
63
66
|
reloadErrors.set(sourceDir, res.reloadError);
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
|
-
|
|
67
69
|
if (reloadErrors.size > 0) {
|
|
68
70
|
return [{
|
|
69
71
|
runnerName,
|
|
70
72
|
reloadError: new MultiExtensionsReloadError(reloadErrors)
|
|
71
73
|
}];
|
|
72
74
|
}
|
|
73
|
-
|
|
74
75
|
return [{
|
|
75
76
|
runnerName
|
|
76
77
|
}];
|
|
77
78
|
}
|
|
79
|
+
|
|
78
80
|
/**
|
|
79
81
|
* Reloads a single extension, collect any reload error and resolves to
|
|
80
82
|
* an array composed by a single ExtensionRunnerReloadResult object.
|
|
81
83
|
*/
|
|
82
|
-
|
|
83
|
-
|
|
84
84
|
async reloadExtensionBySourceDir(extensionSourceDir) {
|
|
85
85
|
const runnerName = this.getName();
|
|
86
86
|
const addonId = this.reloadableExtensions.get(extensionSourceDir);
|
|
87
|
-
|
|
88
87
|
if (!addonId) {
|
|
89
88
|
return [{
|
|
90
89
|
sourceDir: extensionSourceDir,
|
|
@@ -92,7 +91,6 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
92
91
|
runnerName
|
|
93
92
|
}];
|
|
94
93
|
}
|
|
95
|
-
|
|
96
94
|
try {
|
|
97
95
|
await this.remoteFirefox.reloadAddon(addonId);
|
|
98
96
|
} catch (error) {
|
|
@@ -102,35 +100,32 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
102
100
|
runnerName
|
|
103
101
|
}];
|
|
104
102
|
}
|
|
105
|
-
|
|
106
103
|
return [{
|
|
107
104
|
runnerName,
|
|
108
105
|
sourceDir: extensionSourceDir
|
|
109
106
|
}];
|
|
110
107
|
}
|
|
108
|
+
|
|
111
109
|
/**
|
|
112
110
|
* Register a callback to be called when the runner has been exited
|
|
113
111
|
* (e.g. the Firefox instance exits or the user has requested web-ext
|
|
114
112
|
* to exit).
|
|
115
113
|
*/
|
|
116
|
-
|
|
117
|
-
|
|
118
114
|
registerCleanup(fn) {
|
|
119
115
|
this.cleanupCallbacks.add(fn);
|
|
120
116
|
}
|
|
117
|
+
|
|
121
118
|
/**
|
|
122
119
|
* Exits the runner, by closing the managed Firefox instance.
|
|
123
120
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
121
|
async exit() {
|
|
127
122
|
if (!this.runningInfo || !this.runningInfo.firefox) {
|
|
128
123
|
throw new WebExtError('No firefox instance is currently running');
|
|
129
124
|
}
|
|
130
|
-
|
|
131
125
|
this.runningInfo.firefox.kill();
|
|
132
|
-
}
|
|
126
|
+
}
|
|
133
127
|
|
|
128
|
+
// Private helper methods.
|
|
134
129
|
|
|
135
130
|
async setupProfileDir() {
|
|
136
131
|
const {
|
|
@@ -141,7 +136,6 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
141
136
|
profilePath,
|
|
142
137
|
firefoxApp
|
|
143
138
|
} = this.params;
|
|
144
|
-
|
|
145
139
|
if (profilePath) {
|
|
146
140
|
if (keepProfileChanges) {
|
|
147
141
|
log.debug(`Using Firefox profile from ${profilePath}`);
|
|
@@ -159,9 +153,9 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
159
153
|
this.profile = await firefoxApp.createProfile({
|
|
160
154
|
customPrefs
|
|
161
155
|
});
|
|
162
|
-
}
|
|
163
|
-
|
|
156
|
+
}
|
|
164
157
|
|
|
158
|
+
// preInstall the extensions if needed.
|
|
165
159
|
if (preInstall) {
|
|
166
160
|
for (const extension of extensions) {
|
|
167
161
|
await firefoxApp.installExtension({
|
|
@@ -173,10 +167,10 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
173
167
|
}
|
|
174
168
|
}
|
|
175
169
|
}
|
|
176
|
-
|
|
177
170
|
async startFirefoxInstance() {
|
|
178
171
|
const {
|
|
179
172
|
browserConsole,
|
|
173
|
+
devtools,
|
|
180
174
|
extensions,
|
|
181
175
|
firefoxBinary,
|
|
182
176
|
preInstall,
|
|
@@ -186,27 +180,23 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
186
180
|
args
|
|
187
181
|
} = this.params;
|
|
188
182
|
const binaryArgs = [];
|
|
189
|
-
|
|
190
183
|
if (browserConsole) {
|
|
191
184
|
binaryArgs.push('-jsconsole');
|
|
192
185
|
}
|
|
193
|
-
|
|
194
186
|
if (startUrl) {
|
|
195
187
|
const urls = Array.isArray(startUrl) ? startUrl : [startUrl];
|
|
196
|
-
|
|
197
188
|
for (const url of urls) {
|
|
198
189
|
binaryArgs.push('--url', url);
|
|
199
190
|
}
|
|
200
191
|
}
|
|
201
|
-
|
|
202
192
|
if (args) {
|
|
203
193
|
binaryArgs.push(...args);
|
|
204
194
|
}
|
|
205
|
-
|
|
206
195
|
this.runningInfo = await firefoxApp.run(this.profile, {
|
|
207
196
|
firefoxBinary,
|
|
208
197
|
binaryArgs,
|
|
209
|
-
extensions
|
|
198
|
+
extensions,
|
|
199
|
+
devtools
|
|
210
200
|
});
|
|
211
201
|
this.runningInfo.firefox.on('close', () => {
|
|
212
202
|
for (const cleanupCb of this.cleanupCallbacks) {
|
|
@@ -217,22 +207,20 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
217
207
|
}
|
|
218
208
|
}
|
|
219
209
|
});
|
|
220
|
-
|
|
221
210
|
if (!preInstall) {
|
|
222
211
|
const remoteFirefox = this.remoteFirefox = await firefoxClient({
|
|
223
212
|
port: this.runningInfo.debuggerPort
|
|
224
|
-
});
|
|
213
|
+
});
|
|
225
214
|
|
|
215
|
+
// Install all the temporary addons.
|
|
226
216
|
for (const extension of extensions) {
|
|
227
217
|
try {
|
|
228
|
-
const addonId = await remoteFirefox.installTemporaryAddon(extension.sourceDir).then(installResult => {
|
|
218
|
+
const addonId = await remoteFirefox.installTemporaryAddon(extension.sourceDir, devtools).then(installResult => {
|
|
229
219
|
return installResult.addon.id;
|
|
230
220
|
});
|
|
231
|
-
|
|
232
221
|
if (!addonId) {
|
|
233
222
|
throw new WebExtError('Unexpected missing addonId in the installAsTemporaryAddon result');
|
|
234
223
|
}
|
|
235
|
-
|
|
236
224
|
this.reloadableExtensions.set(extension.sourceDir, addonId);
|
|
237
225
|
} catch (error) {
|
|
238
226
|
if (error instanceof RemoteTempInstallNotSupported) {
|
|
@@ -245,6 +233,5 @@ export class FirefoxDesktopExtensionRunner {
|
|
|
245
233
|
}
|
|
246
234
|
}
|
|
247
235
|
}
|
|
248
|
-
|
|
249
236
|
}
|
|
250
237
|
//# sourceMappingURL=firefox-desktop.js.map
|
|
@@ -1 +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,\n binaryArgs,\n extensions,\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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"}
|
|
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","devtools","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 devtools: 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 devtools,\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,\n binaryArgs,\n extensions,\n devtools,\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, devtools)\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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"}
|