diff --git a/gulpfile.js b/gulpfile.js index 2ea323a05fe69..eb6ac14b64981 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -415,21 +415,6 @@ function createTestSource(testsName, bot) { console.log("### Running " + testsName + " tests"); var PDF_TEST = process.env.PDF_TEST || "test_manifest.json"; - var PDF_BROWSERS = - process.env.PDF_BROWSERS || - "resources/browser_manifests/browser_manifest.json"; - - if (!checkFile("test/" + PDF_BROWSERS)) { - console.log( - "Browser manifest file test/" + PDF_BROWSERS + " does not exist." - ); - console.log( - "Copy and adjust the example in test/resources/browser_manifests." - ); - this.emit("error", new Error("Missing manifest file")); - return null; - } - var args = ["test.js"]; switch (testsName) { case "browser": @@ -448,10 +433,12 @@ function createTestSource(testsName, bot) { this.emit("error", new Error("Unknown name: " + testsName)); return null; } - args.push("--browserManifestFile=" + PDF_BROWSERS); if (bot) { args.push("--strictVerify"); } + if (process.argv.includes("--noChrome")) { + args.push("--noChrome"); + } var testProcess = startNode(args, { cwd: TEST_DIR, stdio: "inherit" }); testProcess.on("close", function (code) { @@ -466,26 +453,14 @@ function makeRef(done, bot) { console.log(); console.log("### Creating reference images"); - var PDF_BROWSERS = - process.env.PDF_BROWSERS || - "resources/browser_manifests/browser_manifest.json"; - - if (!checkFile("test/" + PDF_BROWSERS)) { - console.log( - "Browser manifest file test/" + PDF_BROWSERS + " does not exist." - ); - console.log( - "Copy and adjust the example in test/resources/browser_manifests." - ); - done(new Error("Missing manifest file")); - return; - } - var args = ["test.js", "--masterMode"]; if (bot) { args.push("--noPrompts", "--strictVerify"); } - args.push("--browserManifestFile=" + PDF_BROWSERS); + if (process.argv.includes("--noChrome")) { + args.push("--noChrome"); + } + var testProcess = startNode(args, { cwd: TEST_DIR, stdio: "inherit" }); testProcess.on("close", function (code) { done(); diff --git a/package-lock.json b/package-lock.json index 423270a7ef57b..17431b972afdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1172,6 +1172,29 @@ "@types/babel-types": "*" } }, + "@types/mime-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz", + "integrity": "sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=", + "dev": true + }, + "@types/node": { + "version": "13.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.0.tgz", + "integrity": "sha512-WE4IOAC6r/yBZss1oQGM5zs2D7RuKR6Q+w+X2SouPofnWn+LbCqClRyhO3ZE7Ix8nmFgo/oVuuE01cJT2XB13A==", + "dev": true, + "optional": true + }, + "@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -1394,6 +1417,12 @@ "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "dev": true + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -2086,6 +2115,46 @@ "integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==", "dev": true }, + "bl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", + "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "bluebird": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", @@ -2893,6 +2962,58 @@ "sha.js": "^2.4.8" } }, + "cross-env": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz", + "integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", + "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -4156,6 +4277,54 @@ } } }, + "extract-zip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.0.tgz", + "integrity": "sha512-i42GQ498yibjdvIhivUsRslx608whtGoFIhF26Z7O4MYncBxp8CwalOs1lnHy21A9sIohWO2+uiE4SRtC9JXDg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, "fancy-log": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", @@ -4198,6 +4367,15 @@ "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==", "dev": true }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "fecha": { "version": "2.3.3", "resolved": "http://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", @@ -4405,6 +4583,12 @@ "readable-stream": "^2.0.0" } }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "fs-minipass": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", @@ -5579,6 +5763,33 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "dev": true, + "requires": { + "agent-base": "5", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -6828,6 +7039,21 @@ "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", "dev": true }, + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "dev": true, + "requires": { + "mime-db": "1.43.0" + } + }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -6953,6 +7179,12 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "mkdirp-classic": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz", + "integrity": "sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g==", + "dev": true + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -11156,6 +11388,12 @@ "sha.js": "^2.4.8" } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -11493,6 +11731,12 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -11708,6 +11952,66 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "puppeteer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-3.0.0.tgz", + "integrity": "sha512-ArmIS8w+XhL4KGP05kxMousA9SFxmeirMkNNcVe5LjK4iGCbZ8qKnG4byuXMru7Ty7a9QwiMUIf80X+zmJuf2A==", + "dev": true, + "requires": { + "@types/mime-types": "^2.1.0", + "debug": "^4.1.0", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "mime": "^2.0.3", + "mime-types": "^2.1.25", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -12934,6 +13238,56 @@ } } }, + "tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "tar-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "terser": { "version": "4.6.11", "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.11.tgz", @@ -13235,6 +13589,28 @@ "dev": true, "optional": true }, + "unbzip2-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.1.tgz", + "integrity": "sha512-sgDYfSDPMsA4Hr2/w7vOlrJBlwzmyakk1+hW8ObLvxSp0LA36LcL2XItGvOT3OSblohSdevMuT8FQjLsqyy4sA==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + }, + "dependencies": { + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + } + } + }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -14580,6 +14956,12 @@ } } }, + "ws": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==", + "dev": true + }, "xmlcreate": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", @@ -14757,6 +15139,16 @@ } } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yazl": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.4.3.tgz", diff --git a/package.json b/package.json index d871527fd3244..c5b6986b1749a 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "babel-loader": "^8.1.0", "canvas": "^2.6.1", "core-js": "^3.6.5", + "cross-env": "^7.0.2", "escodegen": "^1.14.1", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", @@ -38,6 +39,7 @@ "postcss-calc": "^7.0.2", "postcss-css-variables": "^0.14.0", "prettier": "^2.0.4", + "puppeteer": "^3.0.0", "rimraf": "^2.7.1", "streamqueue": "^1.1.2", "systemjs": "^0.21.6", @@ -55,6 +57,7 @@ "yargs": "^11.1.1" }, "scripts": { + "postinstall": "node -e \"require('child_process').execSync('cross-env PUPPETEER_PRODUCT=firefox node node_modules/puppeteer/install.js');\"", "test": "gulp npm-test" }, "repository": { diff --git a/test/driver.js b/test/driver.js index f86db197d1314..53729a785690f 100644 --- a/test/driver.js +++ b/test/driver.js @@ -300,7 +300,6 @@ var Driver = (function DriverClosure() { var parameters = this._getQueryStringParameters(); this.browser = parameters.browser; this.manifestFile = parameters.manifestFile; - this.appPath = parameters.path; this.delay = parameters.delay | 0 || 0; this.inFlightRequests = 0; this.testFilter = parameters.testFilter @@ -340,13 +339,7 @@ var Driver = (function DriverClosure() { ); }; this._info("User agent: " + navigator.userAgent); - this._log( - 'Harness thinks this browser is "' + - this.browser + - '" with path "' + - this.appPath + - '"\n' - ); + this._log(`Harness thinks this browser is ${this.browser}\n`); this._log('Fetching manifest "' + this.manifestFile + '"... '); var r = new XMLHttpRequest(); @@ -679,7 +672,7 @@ var Driver = (function DriverClosure() { // Send the quit request var r = new XMLHttpRequest(); - r.open("POST", "/tellMeToQuit?path=" + escape(this.appPath), false); + r.open("POST", `/tellMeToQuit?browser=${escape(this.browser)}`, false); r.onreadystatechange = function (e) { if (r.readyState === 4) { window.close(); diff --git a/test/font/jasmine-boot.js b/test/font/jasmine-boot.js index 6b20acef9bc6f..d8249cff5964d 100644 --- a/test/font/jasmine-boot.js +++ b/test/font/jasmine-boot.js @@ -119,10 +119,7 @@ function initializePDFJS(callback) { env.addReporter(htmlReporter); if (queryString.getParam("browser")) { - var testReporter = new TestReporter( - queryString.getParam("browser"), - queryString.getParam("path") - ); + var testReporter = new TestReporter(queryString.getParam("browser")); env.addReporter(testReporter); } diff --git a/test/resources/browser_manifests/.gitignore b/test/resources/browser_manifests/.gitignore deleted file mode 100644 index 9d39a490fd2a2..0000000000000 --- a/test/resources/browser_manifests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -browser_manifest.json diff --git a/test/resources/browser_manifests/browser_manifest.json.example b/test/resources/browser_manifests/browser_manifest.json.example deleted file mode 100644 index 6482a03e88477..0000000000000 --- a/test/resources/browser_manifests/browser_manifest.json.example +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "name": "Firefox", - "path": "/path/to/firefox/executable" - }, - { - "name": "Chrome", - "path": "/path/to/chrome/executable" - } -] diff --git a/test/resources/firefox/user.js b/test/resources/firefox/user.js deleted file mode 100644 index e34616b2ac6e1..0000000000000 --- a/test/resources/firefox/user.js +++ /dev/null @@ -1,2 +0,0 @@ -// Disable the default browser test. -user_pref('browser.shell.checkDefaultBrowser', false); diff --git a/test/test.js b/test/test.js index 79d1470526d8c..25cecb5df56f0 100644 --- a/test/test.js +++ b/test/test.js @@ -18,10 +18,10 @@ "use strict"; var WebServer = require("./webserver.js").WebServer; -var WebBrowser = require("./webbrowser.js").WebBrowser; var path = require("path"); var fs = require("fs"); var os = require("os"); +var puppeteer = require("puppeteer"); var url = require("url"); var testUtils = require("./testutils.js"); @@ -43,19 +43,11 @@ function parseOptions() { "fontTest", "noPrompts", "noDownload", + "noChrome", "downloadOnly", "strictVerify", ]) - .string([ - "manifestFile", - "browser", - "browserManifestFile", - "port", - "statsFile", - "statsDelay", - "testfilter", - ]) - .alias("browser", "b") + .string(["manifestFile", "port", "statsFile", "statsDelay", "testfilter"]) .alias("help", "h") .alias("masterMode", "m") .alias("testfilter", "t") @@ -70,12 +62,6 @@ function parseOptions() { "A path to JSON file in the form of test_manifest.json" ) .default("manifestFile", "test_manifest.json") - .describe("browser", "The path to a single browser ") - .describe( - "browserManifestFile", - "A path to JSON file in the form of " + - "those found in resources/browser_manifests/" - ) .describe( "reftest", "Automatically start reftest showing comparison " + @@ -84,14 +70,15 @@ function parseOptions() { .describe("testfilter", "Run specific reftest(s).") .default("testfilter", []) .example( - "$0 --b=firefox -t=issue5567 -t=issue5909", - "Run the reftest identified by issue5567 and issue5909 in Firefox." + "$0 -t=issue5567 -t=issue5909", + "Run the reftest identified by issue5567 and issue5909." ) .describe("port", "The port the HTTP server should listen on.") .default("port", 0) .describe("unitTest", "Run the unit tests.") .describe("fontTest", "Run the font tests.") .describe("noDownload", "Skips test PDFs downloading.") + .describe("noChrome", "Skip Chrome when running tests.") .describe("downloadOnly", "Download test PDFs without running the tests.") .describe("strictVerify", "Error if verifying the manifest files fails.") .describe("statsFile", "The file where to store stats.") @@ -119,12 +106,6 @@ function parseOptions() { return !argv.masterMode || argv.manifestFile === "test_manifest.json"; }, "when --masterMode is specified --manifestFile shall be equal " + "test_manifest.json") - ) - .check( - describeCheck(function (argv) { - return !argv.browser || !argv.browserManifestFile; - }, "--browser and --browserManifestFile must not be specified at the " + - "same time.") ); var result = yargs.argv; if (result.help) { @@ -184,16 +165,14 @@ function updateRefImages() { function examineRefImages() { startServer(); - var startUrl = - "http://" + - server.host + - ":" + - server.port + - "/test/resources/reftest-analyzer.html#web=/test/eq.log"; - var config = Object.assign({}, sessions[0].config); - config.headless = false; - var browser = WebBrowser.create(config); - browser.start(startUrl); + + const startUrl = `http://${host}:${server.port}/test/resources/reftest-analyzer.html#web=/test/eq.log`; + startBrowser("firefox", startUrl).then(function (browser) { + browser.on("disconnected", function () { + stopServer(); + process.exit(0); + }); + }); } function startRefTest(masterMode, showRefImages) { @@ -274,7 +253,8 @@ function startRefTest(masterMode, showRefImages) { server.hooks.POST.push(refTestPostHandler); onAllSessionsClosed = finalize; - startBrowsers("/test/test_slave.html", function (session) { + const startUrl = `http://${host}:${server.port}/test/test_slave.html`; + startBrowsers(startUrl, function (session) { session.masterMode = masterMode; session.taskResults = {}; session.tasks = {}; @@ -617,11 +597,7 @@ function refTestPostHandler(req, res) { var session; if (pathname === "/tellMeToQuit") { - // finding by path - var browserPath = parsedUrl.query.path; - session = sessions.filter(function (curSession) { - return curSession.config.path === browserPath; - })[0]; + session = getSession(parsedUrl.query.browser); monitorBrowserTimeout(session, null); closeSession(session.name); return; @@ -712,7 +688,9 @@ function startUnitTest(testUrl, name) { var runtime = (Date.now() - startTime) / 1000; console.log(name + " tests runtime was " + runtime.toFixed(1) + " seconds"); }; - startBrowsers(testUrl, function (session) { + + const startUrl = `http://${host}:${server.port}${testUrl}`; + startBrowsers(startUrl, function (session) { session.numRuns = 0; session.numErrors = 0; }); @@ -784,52 +762,84 @@ function unitTestPostHandler(req, res) { return true; } -function startBrowsers(testUrl, initSessionCallback) { - var browsers; - if (options.browserManifestFile) { - browsers = JSON.parse(fs.readFileSync(options.browserManifestFile)); - } else if (options.browser) { - var browserPath = options.browser; - var name = path.basename(browserPath, path.extname(browserPath)); - browsers = [{ name: name, path: browserPath }]; - } else { - console.error("Specify either browser or browserManifestFile."); - process.exit(1); +async function startBrowser(browserName, startUrl) { + const revisions = require("puppeteer/package.json").puppeteer; + const wantedRevision = + browserName === "chrome" + ? revisions.chrome_revision + : revisions.firefox_revision; + + // Remove other revisions than the one we want to use. Updating Puppeteer can + // cause a new revision to be used, and not removing older revisions causes + // the disk to fill up. + const browserFetcher = puppeteer.createBrowserFetcher({ + product: browserName, + }); + const localRevisions = await browserFetcher.localRevisions(); + if (localRevisions.length > 1) { + for (const localRevision of localRevisions) { + if (localRevision !== wantedRevision) { + console.log(`Removing old ${browserName} revision ${localRevision}...`); + await browserFetcher.remove(localRevision); + } + } } + + const browser = await puppeteer.launch({ + product: browserName, + headless: false, + defaultViewport: null, + // Firefox must complete its execution before starting, mainly on Windows. + // Refer to https://github.com/puppeteer/puppeteer/issues/5376 and + // https://phabricator.services.mozilla.com/D6702. + args: browserName === "firefox" ? ["--wait-for-browser"] : [], + }); + const pages = await browser.pages(); + const page = pages[0]; + await page.goto(startUrl, { timeout: 0 }); + return browser; +} + +function startBrowsers(rootUrl, initSessionCallback) { + const browserNames = options.noChrome ? ["firefox"] : ["firefox", "chrome"]; + sessions = []; - browsers.forEach(function (b) { - var browser = WebBrowser.create(b); - var startUrl = - getServerBaseAddress() + - testUrl + - "?browser=" + - encodeURIComponent(b.name) + - "&manifestFile=" + - encodeURIComponent("/test/" + options.manifestFile) + - "&testFilter=" + - JSON.stringify(options.testfilter) + - "&path=" + - encodeURIComponent(b.path) + - "&delay=" + - options.statsDelay + - "&masterMode=" + - options.masterMode; - browser.start(startUrl); - var session = { - name: b.name, - config: b, - browser: browser, + for (const browserName of browserNames) { + // The session must be pushed first and augmented with the browser once + // it's initialized. The reason for this is that browser initialization + // takes more time when the browser is not found locally yet and we don't + // want `onAllSessionsClosed` to trigger if one of the browsers is done + // and the other one is still initializing, since that would mean that + // once the browser is initialized the server would have stopped already. + // Pushing the session first ensures that `onAllSessionsClosed` will + // only trigger once all browsers are initialized and done. + const session = { + name: browserName, + browser: undefined, closed: false, }; - if (initSessionCallback) { - initSessionCallback(session); - } sessions.push(session); - }); -} -function getServerBaseAddress() { - return "http://" + host + ":" + server.port; + const queryParameters = + `?browser=${encodeURIComponent(browserName)}` + + `&manifestFile=${encodeURIComponent("/test/" + options.manifestFile)}` + + `&testFilter=${JSON.stringify(options.testfilter)}` + + `&delay=${options.statsDelay}` + + `&masterMode=${options.masterMode}`; + const startUrl = rootUrl + queryParameters; + + startBrowser(browserName, startUrl) + .then(function (browser) { + session.browser = browser; + if (initSessionCallback) { + initSessionCallback(session); + } + }) + .catch(function (ex) { + console.log(`Error while starting ${browserName}: ${ex}`); + closeSession(browserName); + }); + } } function startServer() { @@ -851,22 +861,24 @@ function getSession(browser) { })[0]; } -function closeSession(browser) { - var i = 0; - while (i < sessions.length && sessions[i].name !== browser) { - i++; - } - if (i < sessions.length) { - var session = sessions[i]; - session.browser.stop(function () { - session.closed = true; - var allClosed = sessions.every(function (s) { - return s.closed; - }); - if (allClosed && onAllSessionsClosed) { - onAllSessionsClosed(); +async function closeSession(browser) { + for (const session of sessions) { + if (session.name !== browser) { + continue; + } + if (session.browser !== undefined) { + for (const page of await session.browser.pages()) { + await page.close(); } + await session.browser.close(); + } + session.closed = true; + const allClosed = sessions.every(function (s) { + return s.closed; }); + if (allClosed && onAllSessionsClosed) { + onAllSessionsClosed(); + } } } @@ -900,8 +912,6 @@ function main() { if (options.downloadOnly) { ensurePDFsDownloaded(function () {}); - } else if (!options.browser && !options.browserManifestFile) { - startServer(); } else if (options.unitTest) { // Allows linked PDF files in unit-tests as well. ensurePDFsDownloaded(function () { diff --git a/test/unit/jasmine-boot.js b/test/unit/jasmine-boot.js index c414ba1fbfb09..01ab57afca951 100644 --- a/test/unit/jasmine-boot.js +++ b/test/unit/jasmine-boot.js @@ -175,10 +175,7 @@ function initializePDFJS(callback) { env.addReporter(htmlReporter); if (queryString.getParam("browser")) { - var testReporter = new TestReporter( - queryString.getParam("browser"), - queryString.getParam("path") - ); + var testReporter = new TestReporter(queryString.getParam("browser")); env.addReporter(testReporter); } diff --git a/test/unit/testreporter.js b/test/unit/testreporter.js index 0733a307d7c33..c74825ae241e5 100644 --- a/test/unit/testreporter.js +++ b/test/unit/testreporter.js @@ -1,7 +1,7 @@ "use strict"; // eslint-disable-next-line no-unused-vars -var TestReporter = function (browser, appPath) { +var TestReporter = function (browser) { function send(action, json, cb) { var r = new XMLHttpRequest(); // (The POST URI is ignored atm.) @@ -39,7 +39,7 @@ var TestReporter = function (browser, appPath) { } function sendQuitRequest() { - send("/tellMeToQuit?path=" + escape(appPath), {}); + send(`/tellMeToQuit?browser=${escape(browser)}`, {}); } this.now = function () { diff --git a/test/webbrowser.js b/test/webbrowser.js deleted file mode 100644 index 97de33619e4b1..0000000000000 --- a/test/webbrowser.js +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2014 Mozilla Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* eslint-disable object-shorthand */ - -"use strict"; - -var os = require("os"); -var fs = require("fs"); -var path = require("path"); -var spawn = require("child_process").spawn; -var testUtils = require("./testutils.js"); -var crypto = require("crypto"); - -var tempDirPrefix = "pdfjs_"; - -function WebBrowser(name, execPath, headless) { - this.name = name; - this.path = execPath; - this.headless = headless; - this.tmpDir = null; - this.profileDir = null; - this.process = null; - this.requestedExit = false; - this.finished = false; - this.callback = null; - // Used to identify processes whose pid is lost. This string is directly used - // as a command-line argument, so it only consists of letters. - this.uniqStringId = "webbrowser" + crypto.randomBytes(32).toString("hex"); -} -WebBrowser.prototype = { - start: function (url) { - this.tmpDir = path.join(os.tmpdir(), tempDirPrefix + this.name); - if (!fs.existsSync(this.tmpDir)) { - fs.mkdirSync(this.tmpDir); - } - this.startProcess(url); - }, - getProfileDir: function () { - if (!this.profileDir) { - var profileDir = path.join(this.tmpDir, "profile"); - if (fs.existsSync(profileDir)) { - testUtils.removeDirSync(profileDir); - } - fs.mkdirSync(profileDir); - this.profileDir = profileDir; - this.setupProfileDir(profileDir); - } - return this.profileDir; - }, - buildArguments: function (url) { - return [url]; - }, - setupProfileDir: function (dir) {}, - startProcess: function (url) { - console.assert(!this.process, "startProcess may be called only once"); - - var args = this.buildArguments(url); - args = args.concat("--" + this.uniqStringId); - - this.process = spawn(this.path, args, { - stdio: [process.stdin, process.stdout, process.stderr], - }); - - this.process.on( - "exit", - function (code, signal) { - this.process = null; - var exitInfo = - code !== null - ? " with status " + code - : " in response to signal " + signal; - if (this.requestedExit) { - this.log("Browser process exited" + exitInfo); - } else { - // This was observed on Windows bots with Firefox. Apparently the - // Firefox Maintenance Service restarts Firefox shortly after starting - // up. When this happens, we no longer know the pid of the process. - this.log("Browser process unexpectedly exited" + exitInfo); - } - }.bind(this) - ); - }, - cleanup: function () { - console.assert( - this.requestedExit, - "cleanup should only be called after an explicit stop() request" - ); - - try { - testUtils.removeDirSync(this.tmpDir); - } catch (e) { - if (e.code !== "ENOENT") { - this.log("Failed to remove profile directory: " + e); - if (!this.cleanupFailStart) { - this.cleanupFailStart = Date.now(); - } else if (Date.now() - this.cleanupFailStart > 10000) { - throw new Error("Failed to remove profile dir within 10 seconds"); - } - this.log("Retrying in a second..."); - setTimeout(this.cleanup.bind(this), 1000); - return; - } - // This should not happen, but we just warn instead of failing loudly - // because the post-condition of cleanup is that the profile directory is - // gone. If the directory does not exists, then this post-condition is - // satisfied. - this.log("Cannot remove non-existent directory: " + e); - } - this.finished = true; - this.log("Clean-up finished. Going to call callback..."); - this.callback(); - }, - stop: function (callback) { - console.assert(this.tmpDir, ".start() must be called before stop()"); - // Require the callback to ensure that callers do not make any assumptions - // on the state of this browser instance until the callback is called. - console.assert(typeof callback === "function", "callback is required"); - console.assert(!this.requestedExit, ".stop() may be called only once"); - - this.requestedExit = true; - if (this.finished) { - this.log("Browser already stopped, invoking callback..."); - callback(); - } else if (this.process) { - this.log("Going to wait until the browser process has exited."); - this.callback = callback; - this.process.once("exit", this.cleanup.bind(this)); - this.process.kill("SIGTERM"); - } else { - this.log("Process already exited, checking if the process restarted..."); - this.callback = callback; - this.killProcessUnknownPid(this.cleanup.bind(this)); - } - }, - killProcessUnknownPid: function (callback) { - this.log("pid unknown, killing processes matching " + this.uniqStringId); - - var cmdKillAll, cmdCheckAllKilled, isAllKilled; - - if (process.platform === "win32") { - var wmicPrefix = [ - "process", - "where", - "\"not Name = 'cmd.exe' " + - "and not Name like '%wmic%' " + - "and CommandLine like '%" + - this.uniqStringId + - "%'\"", - ]; - cmdKillAll = { - file: "wmic", - args: wmicPrefix.concat(["call", "terminate"]), - }; - cmdCheckAllKilled = { - file: "wmic", - args: wmicPrefix.concat(["get", "CommandLine"]), - }; - isAllKilled = function (exitCode, stdout) { - return !stdout.includes(this.uniqStringId); - }.bind(this); - } else { - cmdKillAll = { file: "pkill", args: ["-f", this.uniqStringId] }; - cmdCheckAllKilled = { file: "pgrep", args: ["-f", this.uniqStringId] }; - isAllKilled = function (pgrepStatus) { - return pgrepStatus === 1; // "No process matched.", per man pgrep. - }; - } - function execAsyncNoStdin(cmd, onExit) { - var proc = spawn(cmd.file, cmd.args, { - shell: true, - stdio: "pipe", - }); - // Close stdin, otherwise wmic won't run. - proc.stdin.end(); - var stdout = ""; - proc.stdout.on("data", data => { - stdout += data; - }); - proc.on("close", code => { - onExit(code, stdout); - }); - } - var killDateStart = Date.now(); - // Note: First process' output it shown, the later outputs are suppressed. - execAsyncNoStdin( - cmdKillAll, - function checkAlive(firstExitCode, firstStdout) { - execAsyncNoStdin( - cmdCheckAllKilled, - function (exitCode, stdout) { - if (isAllKilled(exitCode, stdout)) { - callback(); - } else if (Date.now() - killDateStart > 10000) { - // Should finish termination within 10 (generous) seconds. - if (firstStdout) { - this.log("Output of first command:\n" + firstStdout); - } - if (stdout) { - this.log("Output of last command:\n" + stdout); - } - throw new Error("Failed to kill process of " + this.name); - } else { - setTimeout(checkAlive.bind(this), 500); - } - }.bind(this) - ); - }.bind(this) - ); - }, - log: function (msg) { - console.log("[" + this.name + "] " + msg); - }, -}; - -var firefoxResourceDir = path.join(__dirname, "resources", "firefox"); - -function FirefoxBrowser(name, execPath, headless) { - if (os.platform() === "darwin") { - var m = /([^.\/]+)\.app(\/?)$/.exec(execPath); - if (m) { - execPath += (m[2] ? "" : "/") + "Contents/MacOS/firefox"; - } - } - WebBrowser.call(this, name, execPath, headless); -} -FirefoxBrowser.prototype = Object.create(WebBrowser.prototype); -FirefoxBrowser.prototype.buildArguments = function (url) { - var profileDir = this.getProfileDir(); - var args = []; - if (os.platform() === "darwin") { - args.push("-foreground"); - } - if (this.headless) { - args.push("--headless"); - } - args.push("-no-remote", "-profile", profileDir, url); - return args; -}; -FirefoxBrowser.prototype.setupProfileDir = function (dir) { - testUtils.copySubtreeSync(firefoxResourceDir, dir); -}; - -function ChromiumBrowser(name, execPath, headless) { - if (os.platform() === "darwin") { - var m = /([^.\/]+)\.app(\/?)$/.exec(execPath); - if (m) { - execPath += (m[2] ? "" : "/") + "Contents/MacOS/" + m[1]; - } - } - WebBrowser.call(this, name, execPath, headless); -} -ChromiumBrowser.prototype = Object.create(WebBrowser.prototype); -ChromiumBrowser.prototype.buildArguments = function (url) { - var profileDir = this.getProfileDir(); - var crashDumpsDir = path.join(this.tmpDir, "crash_dumps"); - var args = [ - "--user-data-dir=" + profileDir, - "--no-first-run", - "--disable-sync", - "--no-default-browser-check", - "--disable-device-discovery-notifications", - "--disable-translate", - "--disable-background-timer-throttling", - "--disable-renderer-backgrounding", - ]; - if (this.headless) { - args.push( - "--headless", - "--crash-dumps-dir=" + crashDumpsDir, - "--disable-gpu", - "--remote-debugging-port=9222" - ); - } - args.push(url); - return args; -}; - -WebBrowser.create = function (desc) { - var name = desc.name; - var execPath = fs.realpathSync(desc.path); - if (!execPath) { - throw new Error("Browser executable not found: " + desc.path); - } - - if (/firefox/i.test(name)) { - return new FirefoxBrowser(name, execPath, desc.headless); - } - if (/(chrome|chromium|opera)/i.test(name)) { - return new ChromiumBrowser(name, execPath, desc.headless); - } - return new WebBrowser(name, execPath, desc.headless); -}; - -exports.WebBrowser = WebBrowser;