diff --git a/e2e_tests/chrome_extention.test.js b/e2e_tests/chrome_extention.test.js new file mode 100644 index 0000000..af583aa --- /dev/null +++ b/e2e_tests/chrome_extention.test.js @@ -0,0 +1,108 @@ +jest.setTimeout(60000); // in milliseconds + +const EXTENSION_INIT_WAIT_TIME = 3000; +const HEADER_TEST_URL = 'https://httpbin.org/headers'; +const PROXY_TEST_URL = 'https://flask-test-iwauxcyxjb.cn-hangzhou.fcapp.run/u673uwaq/true'; + + +let extensionId; +beforeAll(async () => { + const serviceWorkerTarget = await browser.waitForTarget( + (target) => target.type() === 'service_worker', + ); + extensionId = serviceWorkerTarget.url().split('/')[2]; + // Wait to make sure the onInstalled listener is fired to init the extension + await new Promise((resolve) => setTimeout(resolve, EXTENSION_INIT_WAIT_TIME)); +}); + + +async function turnOffExtension() { + const popupPage = await browser.newPage(); + await popupPage.goto('chrome-extension://' + extensionId + '/src/popup.html'); + const offButton = await popupPage.waitForSelector('input#input_off'); + await offButton.click(); + // Wait to make sure relevant listeners are fired to reset the extension + await new Promise((resolve) => setTimeout(resolve, EXTENSION_INIT_WAIT_TIME)); + popupPage.close(); +} + +async function turnOnExtension() { + const popupPage = await browser.newPage(); + await popupPage.goto('chrome-extension://' + extensionId + '/src/popup.html'); + const onButton = await popupPage.waitForSelector('input#input_normal'); + await onButton.click(); + // Wait to make sure relevant listeners are fired to reset the extension + await new Promise((resolve) => setTimeout(resolve, EXTENSION_INIT_WAIT_TIME)); + popupPage.close(); +} + + +async function getXhrResponse(url) { + await page.goto('http://example.com'); + return page.evaluate(function(url) { + return new Promise(function(resolve, reject) { + const req = new XMLHttpRequest(); + req.open('GET', url, /* async= */ true); + req.onload = () => { + if (req.status === 200) { + resolve(req.responseText); + } else { + reject(req); + } + }; + req.send(); + }); + }, url); // Need to pass in url as an argument here too +} + + +describe('Chrome extension should work fine by default', () => { + it('Should set headers', async () => { + await page.goto(HEADER_TEST_URL); + await expect(page.content()).resolves.toMatch(/X-Unblock-Youku-Test/i); + }); + + it('Should proxy requests', async () => { + await expect(getXhrResponse(PROXY_TEST_URL)).resolves.toMatch(/true/i); + }); +}); + + +describe('The off mode should not do anything', () => { + beforeAll(async () => { + await turnOffExtension(); + }); + // Due to order of execution, we don't need to turn on the extension before + // the next test suite's setup code turns off it again. See + // https://jestjs.io/docs/setup-teardown#order-of-execution + // afterAll(async () => { + // await turnOnExtension(); + // }); + + it('Should NOT set headers', async () => { + await page.goto(HEADER_TEST_URL); + await expect(page.content()).resolves.not.toMatch(/X-Unblock-Youku-Test/i); + }); + + it('Should NOT proxy requests', async () => { + await expect(getXhrResponse(PROXY_TEST_URL)).resolves.not.toMatch(/true/i); + }); +}); + + +describe('Turn on the Chrome extention again, and test', () => { + beforeAll(async () => { + // See the comment above + // await turnOffExtension(); + await turnOnExtension(); + }); + + it('Should set headers AGAIN', async () => { + await page.goto(HEADER_TEST_URL); + await expect(page.content()).resolves.toMatch(/X-Unblock-Youku-Test/i); + }); + + it('Should proxy requests AGAIN', async () => { + await expect(getXhrResponse(PROXY_TEST_URL)).resolves.toMatch(/true/i); + }); +}); diff --git a/e2e_tests/google.test.js b/e2e_tests/google.test.js deleted file mode 100644 index cefcbb7..0000000 --- a/e2e_tests/google.test.js +++ /dev/null @@ -1,9 +0,0 @@ -describe('Google', () => { - beforeAll(async () => { - await page.goto('https://google.com'); - }); - - it('should be titled "Google"', async () => { - await expect(page.title()).resolves.toMatch('Google'); - }); -}); diff --git a/e2e_tests/puppeteer.js b/e2e_tests/puppeteer.js deleted file mode 100644 index 7b79b82..0000000 --- a/e2e_tests/puppeteer.js +++ /dev/null @@ -1,119 +0,0 @@ -const puppeteer = require('puppeteer'); - -(async () => { - const pathToExtension = require('path').join(__dirname, '../dist'); - const browser = await puppeteer.launch({ - headless: 'chrome', // Extensions don't load if headerless=true - // headless: false, - args: [ - `--disable-extensions-except=${pathToExtension}`, - `--load-extension=${pathToExtension}`, - ], - }); - console.log('Browser version: ' + await browser.version()); - - // Wait for the extension's service worker to register listeners - const serviceWorkerTarget = await browser.waitForTarget( - (target) => target.type() === 'service_worker', - ); - const [,, extensionId] = serviceWorkerTarget.url().split('/'); - console.log('Extension ID: ' + extensionId); - - // Wait for another X seconds to make sure the listeners are fired - // TODO: Wait for a specific console.log message? - await new Promise((resolve) => setTimeout(resolve, 5000)); - - // Test HTTP header modifying - const httpPage = await browser.newPage(); - await httpPage.goto('https://httpbin.org/headers'); - const headerResult = await httpPage.content(); - console.log(headerResult.includes('X-Unblock-Youku-Test')); - - // Test the proxy server setup - const proxyResult = await httpPage.evaluate(() => { - return new Promise((resolve) => { - const req = new XMLHttpRequest(); - req.open('GET', - 'https://flask-test-iwauxcyxjb.cn-hangzhou.fcapp.run/u673uwaq/true', /* async= */ true); - req.onload = () => { - if (req.status === 200) { - resolve(req.responseText); - } else { - reject(req); - } - }; - req.send(); - }); - }); - // console.log(proxyResult); - console.log(proxyResult.includes('true')); - httpPage.close(); - - // Turn off the extenion, and test again - const popupPage = await browser.newPage(); - await popupPage.goto('chrome-extension://' + extensionId + '/src/popup.html'); - - const offButton = await popupPage.waitForSelector('input#input_off'); - await offButton.click(); - - // Wait for another X seconds to make sure the listeners are fired - // TODO: Wait for a specific console.log message? - await new Promise((resolve) => setTimeout(resolve, 5000)); - - const httpPage2 = await browser.newPage(); - await httpPage2.goto('https://httpbin.org/headers'); - const headerResult2 = await httpPage2.content(); - console.log(headerResult2.includes('X-Unblock-Youku-Test')); - - const proxyResult2 = await httpPage2.evaluate(() => { - return new Promise((resolve) => { - const req = new XMLHttpRequest(); - req.open('GET', - 'https://flask-test-iwauxcyxjb.cn-hangzhou.fcapp.run/u673uwaq/true', /* async= */ true); - req.onload = () => { - if (req.status === 200) { - resolve(req.responseText); - } else { - reject(req); - } - }; - req.send(); - }); - }); - console.log(proxyResult2.includes('true')); - httpPage2.close(); - - // Turn on the extension, and test the third time - const onButton = await popupPage.waitForSelector('input#input_normal'); - await onButton.click(); - - // Wait for another X seconds to make sure the listeners are fired - // TODO: Wait for a specific console.log message? - await new Promise((resolve) => setTimeout(resolve, 5000)); - - const httpPage3 = await browser.newPage(); - await httpPage3.goto('https://httpbin.org/headers'); - - const headerResult3 = await httpPage3.content(); - console.log(headerResult3.includes('X-Unblock-Youku-Test')); - - const proxyResult3 = await httpPage3.evaluate(() => { - return new Promise((resolve) => { - const req = new XMLHttpRequest(); - req.open('GET', - 'https://flask-test-iwauxcyxjb.cn-hangzhou.fcapp.run/u673uwaq/true', /* async= */ true); - req.onload = () => { - if (req.status === 200) { - resolve(req.responseText); - } else { - reject(req); - } - }; - req.send(); - }); - }); - console.log(proxyResult3.includes('true')); - httpPage3.close(); - - await browser.close(); -})(); diff --git a/jest-puppeteer.config.js b/jest-puppeteer.config.js new file mode 100644 index 0000000..a134e3e --- /dev/null +++ b/jest-puppeteer.config.js @@ -0,0 +1,14 @@ +const path = require('path'); + +const CRX_PATH = path.resolve(__dirname, './dist/unzipped_chrome_extension'); + +module.exports = { + launch: { + headless: 'chrome', // Extensions won't load if headerless=true + // headless: false, // Add this to debug + args: [ + `--disable-extensions-except=${CRX_PATH}`, + `--load-extension=${CRX_PATH}`, + ], + }, +}; diff --git a/jest.config.js b/jest.config.js index 053fbc7..2762fa4 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,196 +1,3 @@ -/* - * For a detailed explanation regarding each configuration property, visit: - * https://jestjs.io/docs/configuration - */ - module.exports = { - // All imported modules in your tests should be mocked automatically - // automock: false, - - // Stop running tests after `n` failures - // bail: 0, - - // The directory where Jest should store its cached dependency information - // cacheDirectory: "/private/var/folders/d8/skf_ck6x5595vzyw2xbq4dfh0000gn/T/jest_dx", - - // Automatically clear mock calls, instances, contexts and results before every test - // clearMocks: false, - - // Indicates whether the coverage information should be collected while executing the test - // collectCoverage: false, - - // An array of glob patterns indicating a set of files for which coverage information should be collected - // collectCoverageFrom: undefined, - - // The directory where Jest should output its coverage files - // coverageDirectory: undefined, - - // An array of regexp pattern strings used to skip coverage collection - // coveragePathIgnorePatterns: [ - // "/node_modules/" - // ], - - // Indicates which provider should be used to instrument code for coverage - coverageProvider: 'v8', - - // A list of reporter names that Jest uses when writing coverage reports - // coverageReporters: [ - // "json", - // "text", - // "lcov", - // "clover" - // ], - - // An object that configures minimum threshold enforcement for coverage results - // coverageThreshold: undefined, - - // A path to a custom dependency extractor - // dependencyExtractor: undefined, - - // Make calling deprecated APIs throw helpful error messages - // errorOnDeprecated: false, - - // The default configuration for fake timers - // fakeTimers: { - // "enableGlobally": false - // }, - - // Force coverage collection from ignored files using an array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: undefined, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: undefined, - - // A set of global variables that need to be available in all test environments - // globals: {}, - - // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. - // maxWorkers: "50%", - - // An array of directory names to be searched recursively up from the requiring module's location - // moduleDirectories: [ - // "node_modules" - // ], - - // An array of file extensions your modules use - // moduleFileExtensions: [ - // "js", - // "mjs", - // "cjs", - // "jsx", - // "ts", - // "tsx", - // "json", - // "node" - // ], - - // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module - // moduleNameMapper: {}, - - // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], - - // Activates notifications for test results - // notify: false, - - // An enum that specifies notification mode. Requires { notify: true } - // notifyMode: "failure-change", - - // A preset that is used as a base for Jest's configuration - // preset: undefined, preset: 'jest-puppeteer', - - // Run tests from one or more projects - // projects: undefined, - - // Use this configuration option to add custom reporters to Jest - // reporters: undefined, - - // Automatically reset mock state before every test - // resetMocks: false, - - // Reset the module registry before running each individual test - // resetModules: false, - - // A path to a custom resolver - // resolver: undefined, - - // Automatically restore mock state and implementation before every test - // restoreMocks: false, - - // The root directory that Jest should scan for tests and modules within - // rootDir: undefined, - - // A list of paths to directories that Jest should use to search for files in - // roots: [ - // "" - // ], - - // Allows you to use a custom runner instead of Jest's default test runner - // runner: "jest-runner", - - // The paths to modules that run some code to configure or set up the testing environment before each test - // setupFiles: [], - - // A list of paths to modules that run some code to configure or set up the testing framework before each test - // setupFilesAfterEnv: [], - - // The number of seconds after which a test is considered as slow and reported as such in the results. - // slowTestThreshold: 5, - - // A list of paths to snapshot serializer modules Jest should use for snapshot testing - // snapshotSerializers: [], - - // The test environment that will be used for testing - // testEnvironment: "jest-environment-node", - - // Options that will be passed to the testEnvironment - // testEnvironmentOptions: {}, - - // Adds a location field to test results - // testLocationInResults: false, - - // The glob patterns Jest uses to detect test files - // testMatch: [ - // "**/__tests__/**/*.[jt]s?(x)", - // "**/?(*.)+(spec|test).[tj]s?(x)" - // ], - - // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: [ - // "/node_modules/" - // ], - - // The regexp pattern or array of patterns that Jest uses to detect test files - // testRegex: [], - - // This option allows the use of a custom results processor - // testResultsProcessor: undefined, - - // This option allows use of a custom test runner - // testRunner: "jest-circus/runner", - - // A map from regular expressions to paths to transformers - // transform: undefined, - - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - // transformIgnorePatterns: [ - // "/node_modules/", - // "\\.pnp\\.[^\\/]+$" - // ], - - // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them - // unmockedModulePathPatterns: undefined, - - // Indicates whether each individual test should be reported during the run - // verbose: undefined, - - // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode - // watchPathIgnorePatterns: [], - - // Whether to use watchman for file crawling - // watchman: true, }; diff --git a/package-lock.json b/package-lock.json index 0c0315e..2b39dc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,8 @@ "eslint-plugin-n": "^15.2.3", "eslint-plugin-promise": "^6.0.0", "jest": "^28.1.2", - "jest-puppeteer": "^6.1.0" + "jest-puppeteer": "^6.1.0", + "puppeteer": "^15.3.0" }, "engines": { "node": "18.x", @@ -1284,7 +1285,6 @@ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@types/node": "*" } @@ -1315,7 +1315,6 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, - "peer": true, "dependencies": { "debug": "4" }, @@ -1850,8 +1849,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ci-info": { "version": "3.3.2", @@ -2007,7 +2005,6 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "dev": true, - "peer": true, "dependencies": { "node-fetch": "2.6.7" } @@ -2106,8 +2103,7 @@ "version": "0.0.1011705", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1011705.tgz", "integrity": "sha512-OKvTvu9n3swmgYshvsyVHYX0+aPzCoYUnyXUacfQMmFtBtBKewV/gT4I9jkAbpTqtTi2E4S9MXLlvzBDUlqg0Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/diff-sequences": { "version": "28.1.1", @@ -2684,7 +2680,6 @@ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -2705,7 +2700,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, - "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -2748,7 +2742,6 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, - "peer": true, "dependencies": { "pend": "~1.2.0" } @@ -3216,7 +3209,6 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, - "peer": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -4834,8 +4826,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ms": { "version": "2.1.2", @@ -4854,7 +4845,6 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dev": true, - "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -5115,8 +5105,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/picocolors": { "version": "1.0.0", @@ -5274,7 +5263,6 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -5296,15 +5284,13 @@ "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, - "peer": true + "dev": true }, "node_modules/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, - "peer": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -5325,7 +5311,6 @@ "integrity": "sha512-PYZwL0DjGeUOauSie6n9Pf+vDUod+vFnC1uHa1Uj3ex1PhRI6DOheau6oJxxj9oyEPWy8SS19KfZDwln4v4LTg==", "dev": true, "hasInstallScript": true, - "peer": true, "dependencies": { "cross-fetch": "3.1.5", "debug": "4.3.4", @@ -5857,7 +5842,6 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, - "peer": true, "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -5927,8 +5911,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/tmpl": { "version": "1.0.5", @@ -5961,8 +5944,7 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/tree-kill": { "version": "1.2.2", @@ -6044,7 +6026,6 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, - "peer": true, "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -6143,15 +6124,13 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, - "peer": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -6238,7 +6217,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", "dev": true, - "peer": true, "engines": { "node": ">=10.0.0" }, @@ -6302,7 +6280,6 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, - "peer": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -7339,7 +7316,6 @@ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", "dev": true, "optional": true, - "peer": true, "requires": { "@types/node": "*" } @@ -7362,7 +7338,6 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, - "peer": true, "requires": { "debug": "4" } @@ -7750,8 +7725,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, - "peer": true + "dev": true }, "ci-info": { "version": "3.3.2", @@ -7884,7 +7858,6 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "dev": true, - "peer": true, "requires": { "node-fetch": "2.6.7" } @@ -7957,8 +7930,7 @@ "version": "0.0.1011705", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1011705.tgz", "integrity": "sha512-OKvTvu9n3swmgYshvsyVHYX0+aPzCoYUnyXUacfQMmFtBtBKewV/gT4I9jkAbpTqtTi2E4S9MXLlvzBDUlqg0Q==", - "dev": true, - "peer": true + "dev": true }, "diff-sequences": { "version": "28.1.1", @@ -8399,7 +8371,6 @@ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, - "peer": true, "requires": { "@types/yauzl": "^2.9.1", "debug": "^4.1.1", @@ -8412,7 +8383,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, - "peer": true, "requires": { "pump": "^3.0.0" } @@ -8451,7 +8421,6 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, - "peer": true, "requires": { "pend": "~1.2.0" } @@ -8786,7 +8755,6 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, - "peer": true, "requires": { "agent-base": "6", "debug": "4" @@ -10033,8 +10001,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, - "peer": true + "dev": true }, "ms": { "version": "2.1.2", @@ -10053,7 +10020,6 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dev": true, - "peer": true, "requires": { "whatwg-url": "^5.0.0" } @@ -10237,8 +10203,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "peer": true + "dev": true }, "picocolors": { "version": "1.0.0", @@ -10354,8 +10319,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "peer": true + "dev": true }, "prompts": { "version": "2.4.2", @@ -10371,15 +10335,13 @@ "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, - "peer": true + "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, - "peer": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -10396,7 +10358,6 @@ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-15.3.0.tgz", "integrity": "sha512-PYZwL0DjGeUOauSie6n9Pf+vDUod+vFnC1uHa1Uj3ex1PhRI6DOheau6oJxxj9oyEPWy8SS19KfZDwln4v4LTg==", "dev": true, - "peer": true, "requires": { "cross-fetch": "3.1.5", "debug": "4.3.4", @@ -10796,7 +10757,6 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, - "peer": true, "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -10854,8 +10814,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "peer": true + "dev": true }, "tmpl": { "version": "1.0.5", @@ -10882,8 +10841,7 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true, - "peer": true + "dev": true }, "tree-kill": { "version": "1.2.2", @@ -10947,7 +10905,6 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, - "peer": true, "requires": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -11021,15 +10978,13 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true, - "peer": true + "dev": true }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, - "peer": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -11095,7 +11050,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", "dev": true, - "peer": true, "requires": {} }, "y18n": { @@ -11136,7 +11090,6 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, - "peer": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/package.json b/package.json index f25aaad..9f313b2 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,8 @@ "npm": "8.x" }, "scripts": { - "zip": "node tools/create_zip.js", "clean": "rm -rf dist", - "test": "jest" + "test": "npm run clean && node tools/create_zip.js && unzip -q dist/upload_to_chrome_store.zip -d dist/unzipped_chrome_extension && jest --verbose" }, "devDependencies": { "archiver": "^5.3.1", @@ -18,6 +17,7 @@ "eslint-plugin-n": "^15.2.3", "eslint-plugin-promise": "^6.0.0", "jest": "^28.1.2", - "jest-puppeteer": "^6.1.0" + "jest-puppeteer": "^6.1.0", + "puppeteer": "^15.3.0" } } diff --git a/src/modules/_header.mjs b/src/modules/_header.mjs index fd796c9..d994b71 100644 --- a/src/modules/_header.mjs +++ b/src/modules/_header.mjs @@ -53,7 +53,7 @@ export async function setHeaderModifier() { 'condition': { urlFilter: url, // Perhaps it is a bug in Chrome's declarativeNetRequest API: - // Although reousrceTypes is an optional parameter, without setting it, + // Although resourceTypes is an optional parameter, without setting it, // the rule will not be applied at all. resourceTypes: RESOURCE_TYPES, }, diff --git a/src/modules/_url_utils.mjs b/src/modules/_url_utils.mjs index 5b2dcc0..ae8f56d 100644 --- a/src/modules/_url_utils.mjs +++ b/src/modules/_url_utils.mjs @@ -3,7 +3,7 @@ */ -function _parseUrl(urlStr) { +function parseUrl(urlStr) { let protocol = null; if (urlStr.startsWith('http://')) { urlStr = urlStr.slice('http://'.length); @@ -35,10 +35,6 @@ function _parseUrl(urlStr) { portpath: urlStr.slice(sepIdx), }; } -// console.log(_parse_url('http://test.com')); -// console.log(_parse_url('http://test.com:123')); -// console.log(_parse_url('http://test.com/path')); -// console.log(_parse_url('http://test.com:123/path')); function genUrlMap(protocol, whiteUrlList, proxyUrlList) { @@ -105,7 +101,7 @@ function genUrlMap(protocol, whiteUrlList, proxyUrlList) { let i; let uobj; let hostname; let portpath; let key; let val; for (i = 0; i < ulist.length; i++) { - uobj = _parseUrl(ulist[i]); + uobj = parseUrl(ulist[i]); if (uobj === null) { console.error('Invalid URL pattern: ' + ulist[i]); continue; diff --git a/src/popup.mjs b/src/popup.mjs index d98e867..4fc4e68 100644 --- a/src/popup.mjs +++ b/src/popup.mjs @@ -52,16 +52,14 @@ Icon.clearIconText(); $('input#input_off').change(function() { console.group('Clicked on the button to change the mode to OFF...'); Settings.setNewMode(Modes.OFF).then(() => { - // Don't change the console.log message, as it will be read by puppeteer tests - console.log('[E2E] Finished changing the mode to OFF'); + console.log('Finished changing the mode to OFF'); console.groupEnd(); }); }); $('input#input_normal').change(function() { console.group('Clicked on the button to change the mode to NORMAL...'); Settings.setNewMode(Modes.NORMAL).then(() => { - // Don't change the console.log message, as it will be read by puppeteer tests - console.log('[E2E] Finished changing the mode to NORMAL'); + console.log('Finished changing the mode to NORMAL'); console.groupEnd(); }); }); diff --git a/src/service_worker.mjs b/src/service_worker.mjs index 26d0808..58303ee 100644 --- a/src/service_worker.mjs +++ b/src/service_worker.mjs @@ -10,8 +10,7 @@ import * as Settings from './modules/settings.mjs'; function initializeExtension() { console.group('To intialize the extension...'); Settings.loadCurrentSettings().then(() => { - // Don't change the console.log message, as it will be read by puppeteer tests - console.log('[E2E] Finished initializing the chrome extension'); + console.log('Finished initializing the chrome extension'); console.groupEnd(); }); } diff --git a/tools/create_zip.js b/tools/create_zip.js index 5435bef..69dc6b8 100644 --- a/tools/create_zip.js +++ b/tools/create_zip.js @@ -1,3 +1,6 @@ +// NOTE: Please don't use this file directly. Instead. use `npm run test` to +// create the zip file, which also runs tests against the code in the zip file. + const fs = require('fs'); const path = require('path'); const archiver = require('archiver');