{"version":3,"sources":["jsdelivr-header.js","/npm/@wikimedia/karma-firefox-launcher@2.1.3/index.js"],"names":[],"mappings":"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","file":"/npm/@wikimedia/karma-firefox-launcher@2.1.3/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@wikimedia/karma-firefox-launcher@2.1.3/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","'use strict'\n\nconst fs = require('fs')\nconst path = require('path')\nlet isWsl = require('is-wsl')\nconst which = require('which')\nconst { execSync } = require('child_process')\nconst { StringDecoder } = require('string_decoder')\n\nconst PREFS = [\n  'user_pref(\"browser.shell.checkDefaultBrowser\", false);',\n  'user_pref(\"browser.bookmarks.restore_default_bookmarks\", false);',\n  'user_pref(\"dom.disable_open_during_load\", false);',\n  'user_pref(\"dom.max_script_run_time\", 0);',\n  'user_pref(\"dom.min_background_timeout_value\", 10);',\n  'user_pref(\"extensions.autoDisableScopes\", 0);',\n  'user_pref(\"browser.tabs.remote.autostart\", false);',\n  'user_pref(\"browser.tabs.remote.autostart.2\", false);',\n  'user_pref(\"extensions.enabledScopes\", 15);'\n].join('\\n')\n\n// NOTE: add 'config.browsers' to get which browsers are started\nconst $INJECT_LIST = ['baseBrowserDecorator', 'args', 'logger', 'emitter']\n\n// Check if Firefox is installed on the WSL side and use that if it's available\nif (isWsl && which.sync('firefox', { nothrow: true })) {\n  isWsl = false\n}\n\n/**\n * Takes a string from Windows' tasklist.exe with the following arguments:\n * `/FO CSV /NH /SVC` and returns an array of PIDs.\n * @param {string} tasklist Expected to be in the form of:\n * `'\"firefox.exe\",\"14972\",\"Console\",\"1\",\"5.084 K\"\\r\\n\"firefox.exe\",\"12204\",\"Console\",\"1\",\"221.656 K\"'`\n * @returns {string[]} Array of String PIDs. Can be empty.\n */\nconst extractPids = tasklist => tasklist\n  .split(',')\n  .filter(x => /^\"\\d{3,10}\"$/.test(x))\n  .map(pid => pid.replace(/\"/g, ''))\n\n/**\n  * Curried function version of safeExecSync with reference to logger\n  * in a closure.\n  * @param {function} log An instance of logger.create\n  * @returns {{(command:string):string}} A closure with reference to logger\n  */\nconst createSafeExecSync = log => command => {\n  let output = ''\n  try {\n    output = String(execSync(command))\n  } catch (err) {\n    // Something went wrong but we can usually continue.\n    // For Windows kill.exe, one common error is trying to kill a PID\n    // that no longer exist, which is fine.\n    log.debug(String(err))\n  }\n  return output\n}\n\n// Get all possible Program Files folders even on other drives\n// inspect the user's path to find other drives that may contain Program Files folders\nconst getAllPrefixes = function () {\n  const drives = []\n  const paden = process.env.Path.split(';')\n  const re = /^[A-Z]:\\\\/i\n  let pad\n  for (let p = 0; p < paden.length; p++) {\n    pad = paden[p]\n    if (re.test(pad) && drives.indexOf(pad[0]) === -1) {\n      drives.push(pad[0])\n    }\n  }\n\n  const result = []\n  const prefixes = [process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']]\n  let prefix\n  for (let i = 0; i < prefixes.length; i++) {\n    if (typeof prefixes[i] !== 'undefined') {\n      for (let d = 0; d < drives.length; d += 1) {\n        prefix = drives[d] + prefixes[i].slice(1)\n        if (result.indexOf(prefix) === -1) {\n          result.push(prefix)\n        }\n      }\n    }\n  }\n  return result\n}\n\n// Return location of firefox.exe file for a given Firefox directory\n// (available: \"Mozilla Firefox\", \"Aurora\", \"Nightly\").\nconst getFirefoxExe = function (firefoxDirName) {\n  if (process.platform !== 'win32' && process.platform !== 'win64') {\n    return null\n  }\n\n  const firefoxDirNames = Array.prototype.slice.call(arguments)\n\n  for (const prefix of getAllPrefixes()) {\n    for (const dir of firefoxDirNames) {\n      const candidate = path.join(prefix, dir, 'firefox.exe')\n      if (fs.existsSync(candidate)) {\n        return candidate\n      }\n    }\n  }\n\n  return path.join('C:\\\\Program Files', firefoxDirNames[0], 'firefox.exe')\n}\n\nconst getAllPrefixesWsl = function () {\n  const drives = []\n  // Some folks configure their wsl.conf to mount Windows drives without the\n  // /mnt prefix (e.g. see https://nickjanetakis.com/blog/setting-up-docker-for-windows-and-wsl-to-work-flawlessly)\n  //\n  // In fact, they could configure this to be any number of things. So we\n  // take each path, convert it to a Windows path, check if it looks like\n  // it starts with a drive and then record that.\n  const re = /^([A-Z]):\\\\/i\n  for (const pathElem of process.env.PATH.split(':')) {\n    if (fs.existsSync(pathElem)) {\n      const windowsPath = execSync('wslpath -w \"' + pathElem + '\"').toString()\n      const matches = windowsPath.match(re)\n      if (matches !== null && drives.indexOf(matches[1]) === -1) {\n        drives.push(matches[1])\n      }\n    }\n  }\n\n  const result = []\n  // We don't have the PROGRAMFILES or PROGRAMFILES(X86) environment variables\n  // in WSL so we just hard code them.\n  const prefixes = ['Program Files', 'Program Files (x86)']\n  for (const prefix of prefixes) {\n    for (const drive of drives) {\n      // We only have the drive, and only wslpath knows exactly what they map to\n      // in Linux, so we convert it back here.\n      const wslPath =\n        execSync('wslpath \"' + drive + ':\\\\' + prefix + '\"').toString().trim()\n      result.push(wslPath)\n    }\n  }\n\n  return result\n}\n\nconst getFirefoxExeWsl = function (firefoxDirName) {\n  if (!isWsl) {\n    return null\n  }\n\n  const firefoxDirNames = Array.prototype.slice.call(arguments)\n\n  for (const prefix of getAllPrefixesWsl()) {\n    for (const dir of firefoxDirNames) {\n      const candidate = path.join(prefix, dir, 'firefox.exe')\n      if (fs.existsSync(candidate)) {\n        return candidate\n      }\n    }\n  }\n\n  return path.join('/mnt/c/Program Files/', firefoxDirNames[0], 'firefox.exe')\n}\n\nconst getFirefoxWithFallbackOnOSX = function () {\n  if (process.platform !== 'darwin') {\n    return null\n  }\n\n  const firefoxDirNames = Array.prototype.slice.call(arguments)\n  const prefix = '/Applications/'\n  const suffix = '.app/Contents/MacOS/firefox'\n\n  let bin\n  let homeBin\n  for (let i = 0; i < firefoxDirNames.length; i++) {\n    bin = prefix + firefoxDirNames[i] + suffix\n\n    if ('HOME' in process.env) {\n      homeBin = path.join(process.env.HOME, bin)\n\n      if (fs.existsSync(homeBin)) {\n        return homeBin\n      }\n    }\n\n    if (fs.existsSync(bin)) {\n      return bin\n    }\n  }\n}\n\nconst makeHeadlessVersion = function (Browser) {\n  const HeadlessBrowser = function () {\n    Browser.apply(this, arguments)\n    const execCommand = this._execCommand\n    this._execCommand = function (command, args) {\n      // --start-debugger-server ws:6000 can also be used, since remote debugging protocol also speaks WebSockets\n      // https://hacks.mozilla.org/2017/12/using-headless-mode-in-firefox/\n      execCommand.call(this, command, args.concat(['-headless', '--start-debugger-server 6000']))\n    }\n  }\n\n  HeadlessBrowser.prototype = Object.create(Browser.prototype, {\n    name: { value: Browser.prototype.name + 'Headless' }\n  })\n  HeadlessBrowser.$inject = Browser.$inject\n  return HeadlessBrowser\n}\n\n// https://developer.mozilla.org/en-US/docs/Command_Line_Options\nconst FirefoxBrowser = function (baseBrowserDecorator, args, logger, emitter) {\n  baseBrowserDecorator(this)\n\n  const log = logger.create(this.name + 'Launcher')\n  const safeExecSync = createSafeExecSync(log)\n  let browserProcessPid\n  let browserProcessPidWsl = []\n\n  this._getPrefs = function (prefs) {\n    if (typeof prefs !== 'object') {\n      return PREFS\n    }\n    let result = PREFS\n    for (const key in prefs) {\n      result += 'user_pref(\"' + key + '\", ' + JSON.stringify(prefs[key]) + ');\\n'\n    }\n    return result\n  }\n\n  this._start = function (url) {\n    const self = this\n    const command = args.command || this._getCommand()\n    const profilePath = args.profile || self._tempDir\n    const flags = args.flags || []\n    let extensionsDir\n\n    if (Array.isArray(args.extensions)) {\n      extensionsDir = path.resolve(profilePath, 'extensions')\n      fs.mkdirSync(extensionsDir)\n      args.extensions.forEach(function (ext) {\n        const extBuffer = fs.readFileSync(ext)\n        const copyDestination = path.resolve(extensionsDir, path.basename(ext))\n        fs.writeFileSync(copyDestination, extBuffer)\n      })\n    }\n\n    fs.writeFileSync(path.join(profilePath, 'prefs.js'), this._getPrefs(args.prefs))\n    const translatedProfilePath =\n      isWsl ? execSync('wslpath -w ' + profilePath).toString().trim() : profilePath\n\n    if (isWsl) {\n      log.warn('WSL environment detected: Please do not open Firefox while running tests as it will be killed after the test!')\n      log.warn('WSL environment detected: See https://github.com/karma-runner/karma-firefox-launcher/issues/101#issuecomment-891850143')\n\n      browserProcessPidWsl = extractPids(safeExecSync('tasklist.exe /FI \"IMAGENAME eq firefox.exe\" /FO CSV /NH /SVC'))\n      log.debug('Recorded PIDs not to kill:', browserProcessPidWsl)\n    }\n\n    // If we are using the launcher process, make it print the child process ID\n    // to stderr so we can capture it. Does not work in WSL.\n    //\n    // https://wiki.mozilla.org/Platform/Integration/InjectEject/Launcher_Process/\n    process.env.MOZ_DEBUG_BROWSER_PAUSE = 0\n    browserProcessPid = undefined\n    self._execCommand(\n      command,\n      [url, '-profile', translatedProfilePath, '-no-remote', '-wait-for-browser'].concat(flags)\n    )\n\n    self._process.stderr.on('data', errBuff => {\n      let errString\n      if (typeof errBuff === 'string') {\n        errString = errBuff\n      } else {\n        const decoder = new StringDecoder('utf8')\n        errString = decoder.write(errBuff)\n      }\n      const matches = errString.match(/BROWSERBROWSERBROWSERBROWSER\\s+debug me @ (\\d+)/)\n      if (matches) {\n        browserProcessPid = parseInt(matches[1], 10)\n      }\n    })\n  }\n\n  if (isWsl) {\n    // exit: will run for each browser when all tests has finished\n    emitter.on('exit', (done) => {\n      const tasklist = extractPids(safeExecSync('tasklist.exe /FI \"IMAGENAME eq firefox.exe\" /FO CSV /NH /SVC'))\n        .filter(pid => browserProcessPidWsl.indexOf(pid) === -1)\n\n      // if this is not the first time 'exit' is called then tasklist is probably empty\n      if (tasklist.length > 0) {\n        log.debug('Killing the following PIDs:', tasklist)\n        const killResult = safeExecSync('taskkill.exe /F ' + tasklist.map(pid => `/PID ${pid}`).join(' ') + ' 2>&1')\n        log.debug(killResult)\n      }\n\n      return process.nextTick(done)\n    })\n  }\n\n  this.on('kill', function (done) {\n    // If we have a separate browser process PID, try killing it.\n    if (browserProcessPid) {\n      try {\n        process.kill(browserProcessPid)\n      } catch (e) {\n        // Ignore failure -- the browser process might have already been\n        // terminated.\n      }\n    }\n\n    return process.nextTick(done)\n  })\n}\n\nFirefoxBrowser.prototype = {\n  name: 'Firefox',\n\n  DEFAULT_CMD: {\n    linux: isWsl ? getFirefoxExeWsl('Mozilla Firefox') : 'firefox',\n    freebsd: 'firefox',\n    darwin: getFirefoxWithFallbackOnOSX('Firefox'),\n    win32: getFirefoxExe('Mozilla Firefox')\n  },\n  ENV_CMD: 'FIREFOX_BIN'\n}\n\nFirefoxBrowser.$inject = $INJECT_LIST\n\nconst FirefoxHeadlessBrowser = makeHeadlessVersion(FirefoxBrowser)\n\nconst FirefoxDeveloperBrowser = function () {\n  FirefoxBrowser.apply(this, arguments)\n}\n\nFirefoxDeveloperBrowser.prototype = {\n  name: 'FirefoxDeveloper',\n  DEFAULT_CMD: {\n    linux: isWsl ? getFirefoxExeWsl('Firefox Developer Edition') : 'firefox',\n    darwin: getFirefoxWithFallbackOnOSX('Firefox Developer Edition', 'FirefoxDeveloperEdition', 'FirefoxAurora'),\n    win32: getFirefoxExe('Firefox Developer Edition')\n  },\n  ENV_CMD: 'FIREFOX_DEVELOPER_BIN'\n}\n\nFirefoxDeveloperBrowser.$inject = $INJECT_LIST\n\nconst FirefoxDeveloperHeadlessBrowser = makeHeadlessVersion(FirefoxDeveloperBrowser)\n\nconst FirefoxAuroraBrowser = function () {\n  FirefoxBrowser.apply(this, arguments)\n}\n\nFirefoxAuroraBrowser.prototype = {\n  name: 'FirefoxAurora',\n  DEFAULT_CMD: {\n    linux: isWsl ? getFirefoxExeWsl('Aurora') : 'firefox',\n    darwin: getFirefoxWithFallbackOnOSX('FirefoxAurora'),\n    win32: getFirefoxExe('Aurora')\n  },\n  ENV_CMD: 'FIREFOX_AURORA_BIN'\n}\n\nFirefoxAuroraBrowser.$inject = $INJECT_LIST\n\nconst FirefoxAuroraHeadlessBrowser = makeHeadlessVersion(FirefoxAuroraBrowser)\n\nconst FirefoxNightlyBrowser = function () {\n  FirefoxBrowser.apply(this, arguments)\n}\n\nFirefoxNightlyBrowser.prototype = {\n  name: 'FirefoxNightly',\n\n  DEFAULT_CMD: {\n    linux: isWsl ? getFirefoxExeWsl('Nightly', 'Firefox Nightly') : 'firefox',\n    darwin: getFirefoxWithFallbackOnOSX('FirefoxNightly', 'Firefox Nightly'),\n    win32: getFirefoxExe('Nightly', 'Firefox Nightly')\n  },\n  ENV_CMD: 'FIREFOX_NIGHTLY_BIN'\n}\n\nFirefoxNightlyBrowser.$inject = $INJECT_LIST\n\nconst FirefoxNightlyHeadlessBrowser = makeHeadlessVersion(FirefoxNightlyBrowser)\n\n// PUBLISH DI MODULE\nmodule.exports = {\n  'launcher:Firefox': ['type', FirefoxBrowser],\n  'launcher:FirefoxHeadless': ['type', FirefoxHeadlessBrowser],\n  'launcher:FirefoxDeveloper': ['type', FirefoxDeveloperBrowser],\n  'launcher:FirefoxDeveloperHeadless': ['type', FirefoxDeveloperHeadlessBrowser],\n  'launcher:FirefoxAurora': ['type', FirefoxAuroraBrowser],\n  'launcher:FirefoxAuroraHeadless': ['type', FirefoxAuroraHeadlessBrowser],\n  'launcher:FirefoxNightly': ['type', FirefoxNightlyBrowser],\n  'launcher:FirefoxNightlyHeadless': ['type', FirefoxNightlyHeadlessBrowser]\n}\n"]}