| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * This file is part of Adblock Plus <https://adblockplus.org/>, |    2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
|    3  * Copyright (C) 2006-present eyeo GmbH |    3  * Copyright (C) 2006-present eyeo GmbH | 
|    4  * |    4  * | 
|    5  * Adblock Plus is free software: you can redistribute it and/or modify |    5  * Adblock Plus is free software: you can redistribute it and/or modify | 
|    6  * it under the terms of the GNU General Public License version 3 as |    6  * it under the terms of the GNU General Public License version 3 as | 
|    7  * published by the Free Software Foundation. |    7  * published by the Free Software Foundation. | 
|    8  * |    8  * | 
|    9  * Adblock Plus is distributed in the hope that it will be useful, |    9  * Adblock Plus is distributed in the hope that it will be useful, | 
|   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of |   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|   12  * GNU General Public License for more details. |   12  * GNU General Public License for more details. | 
|   13  * |   13  * | 
|   14  * You should have received a copy of the GNU General Public License |   14  * You should have received a copy of the GNU General Public License | 
|   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. |   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
|   16  */ |   16  */ | 
|   17  |   17  | 
|   18 /* eslint-env node */ |   18 /* eslint-env node */ | 
|   19  |   19  | 
|   20 "use strict"; |   20 "use strict"; | 
|   21  |   21  | 
|   22 const fs = require("fs"); |   22 const assert = require("assert"); | 
|   23 const path = require("path"); |   23 const path = require("path"); | 
|   24  |   24  | 
|   25 const MemoryFS = require("memory-fs"); |   25 const MemoryFS = require("memory-fs"); | 
|   26 const nodeunit = require("nodeunit"); |  | 
|   27 const webpack = require("webpack"); |   26 const webpack = require("webpack"); | 
|   28  |   27  | 
|   29 const chromiumRemoteProcess = require("./test/runners/chromium_remote_process"); |   28 const chromiumRemoteProcess = require("./runners/chromium_remote_process"); | 
|   30 const chromiumProcess = require("./test/runners/chromium_process"); |   29 const chromiumProcess = require("./runners/chromium_process"); | 
|   31 const edgeProcess = require("./test/runners/edge_process"); |   30 const edgeProcess = require("./runners/edge_process"); | 
|   32 const firefoxProcess = require("./test/runners/firefox_process"); |   31 const firefoxProcess = require("./runners/firefox_process"); | 
|   33  |   32  | 
|   34 let unitFiles = []; |   33 // Path are to be from the top-level directory | 
|   35 let browserFiles = []; |   34 let browserFiles = ["./test/browser/elemHideEmulation.js", "./test/browser/snipp
     ets.js"]; | 
|   36  |   35  | 
|   37 let runnerDefinitions = { |   36 let runnerDefinitions = { | 
|   38   // Chromium with chrome-remote-interface |   37   // Chromium with chrome-remote-interface | 
|   39   chromium_remote: chromiumRemoteProcess, |   38   chromium_remote: chromiumRemoteProcess, | 
|   40   // Chromium with WebDriver (requires Chromium >= 63.0.3239) |   39   // Chromium with WebDriver (requires Chromium >= 63.0.3239) | 
|   41   chromium: chromiumProcess, |   40   chromium: chromiumProcess, | 
|   42   edge: edgeProcess, |   41   edge: edgeProcess, | 
|   43   firefox: firefoxProcess |   42   firefox: firefoxProcess | 
|   44 }; |   43 }; | 
|   45  |   44  | 
|   46 function configureRunners() |   45 function configureRunners() | 
|   47 { |   46 { | 
|   48   let runners = "BROWSER_TEST_RUNNERS" in process.env ? |   47   let runners = "BROWSER_TEST_RUNNERS" in process.env ? | 
|   49       process.env.BROWSER_TEST_RUNNERS.split(",") : []; |   48       process.env.BROWSER_TEST_RUNNERS.split(",") : []; | 
|   50  |   49  | 
|   51   if (runners.length == 0) |   50   if (runners.length == 0) | 
|   52   { |   51   { | 
|   53     // We default to not using the Chromium remote interface on Windows, |   52     // We default to not using the Chromium remote interface on Windows, | 
|   54     // as it fails. |   53     // as it fails. | 
|   55     if (process.platform == "win32") |   54     if (process.platform == "win32") | 
|   56       return ["chromium", "edge", "firefox"]; |   55       return ["chromium", "edge", "firefox"]; | 
|   57     return ["chromium_remote", "firefox"]; |   56     return ["chromium_remote", "firefox"]; | 
|   58   } |   57   } | 
|   59  |   58  | 
|   60   return runners.filter(runner => runnerDefinitions.hasOwnProperty(runner)); |   59   return runners.filter(runner => runnerDefinitions.hasOwnProperty(runner)); | 
|   61 } |   60 } | 
|   62  |   61  | 
|   63 let runnerProcesses = configureRunners(); |   62 let runnerProcesses = configureRunners(); | 
|   64  |   63  | 
|   65 function addTestPaths(testPaths, recurse) |  | 
|   66 { |  | 
|   67   for (let testPath of testPaths) |  | 
|   68   { |  | 
|   69     let stat = fs.statSync(testPath); |  | 
|   70     if (stat.isDirectory()) |  | 
|   71     { |  | 
|   72       if (recurse) |  | 
|   73       { |  | 
|   74         addTestPaths(fs.readdirSync(testPath).map( |  | 
|   75           file => path.join(testPath, file))); |  | 
|   76       } |  | 
|   77       continue; |  | 
|   78     } |  | 
|   79     if (path.basename(testPath).startsWith("_")) |  | 
|   80       continue; |  | 
|   81     if (path.extname(testPath) == ".js") |  | 
|   82     { |  | 
|   83       if (testPath.split(path.sep).includes("browser")) |  | 
|   84         browserFiles.push(testPath); |  | 
|   85       else |  | 
|   86         unitFiles.push(testPath); |  | 
|   87     } |  | 
|   88   } |  | 
|   89 } |  | 
|   90  |  | 
|   91 function webpackInMemory(bundleFilename, options) |   64 function webpackInMemory(bundleFilename, options) | 
|   92 { |   65 { | 
|   93   return new Promise((resolve, reject) => |   66   return new Promise((resolve, reject) => | 
|   94   { |   67   { | 
|   95     // Based on this example |   68     // Based on this example | 
|   96     // https://webpack.js.org/api/node/#custom-file-systems |   69     // https://webpack.js.org/api/node/#custom-file-systems | 
|   97     let memoryFS = new MemoryFS(); |   70     let memoryFS = new MemoryFS(); | 
|   98  |   71  | 
|   99     options.output = {filename: bundleFilename, path: "/"}; |   72     options.output = {filename: bundleFilename, path: "/"}; | 
|  100     options.devtool = "cheap-eval-source-map"; |   73     options.devtool = "cheap-eval-source-map"; | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  117       else |   90       else | 
|  118       { |   91       { | 
|  119         let bundle = memoryFS.readFileSync("/" + bundleFilename, "utf-8"); |   92         let bundle = memoryFS.readFileSync("/" + bundleFilename, "utf-8"); | 
|  120         memoryFS.unlinkSync("/" + bundleFilename); |   93         memoryFS.unlinkSync("/" + bundleFilename); | 
|  121         resolve(bundle); |   94         resolve(bundle); | 
|  122       } |   95       } | 
|  123     }); |   96     }); | 
|  124   }); |   97   }); | 
|  125 } |   98 } | 
|  126  |   99  | 
|  127 function runBrowserTests(processes) |  100 describe("Browser tests", function() | 
|  128 { |  101 { | 
|  129   if (!browserFiles.length) |  102   assert.ok(browserFiles.length); | 
|  130     return Promise.resolve(); |  | 
|  131  |  103  | 
|  132   let nodeunitPath = path.join(__dirname, "node_modules", "nodeunit", |  104   this.timeout(0); | 
|  133                                "examples", "browser", "nodeunit.js"); |  105  | 
|  134   let bundleFilename = "bundle.js"; |  106   let bundleFilename = "bundle.js"; | 
|  135  |  107  | 
|  136   return webpackInMemory(bundleFilename, { |  108   let bundle; | 
|  137     entry: path.join(__dirname, "test", "browser", "_bootstrap.js"), |  109   let mochaPath = path.join(__dirname, "..", "node_modules", "mocha", | 
|  138     module: { |  110                            "mocha.js"); | 
|  139       rules: [{ |  111   before(async() => | 
|  140         resource: nodeunitPath, |  112   { | 
|  141         // I would have rather used exports-loader here, to avoid treating |  113     bundle = await webpackInMemory(bundleFilename, { | 
|  142         // nodeunit as a global. Unfortunately the nodeunit browser example |  114       entry: path.join(__dirname, "browser", "_bootstrap.js"), | 
|  143         // script is quite slopily put together, if exports isn't falsey it |  115       module: { | 
|  144         // breaks! As a workaround we need to use script-loader, which means |  116         rules: [{ | 
|  145         // that exports is falsey for that script as a side-effect. |  117           // we use the browser version of mocha | 
|  146         use: ["script-loader"] |  118           resource: mochaPath, | 
|  147       }] |  119           use: ["script-loader"] | 
|  148     }, |  120         }] | 
|  149     resolve: { |  | 
|  150       alias: { |  | 
|  151         nodeunit$: nodeunitPath |  | 
|  152       }, |  121       }, | 
|  153       modules: [path.resolve(__dirname, "lib")] |  122       resolve: { | 
|  154     } |  123         alias: { | 
|  155   }).then(bundle => |  124           mocha$: mochaPath | 
|  156     Promise.all( |  125         }, | 
|  157       processes.map(currentProcess => |  126         modules: [path.resolve(__dirname, "..", "lib")] | 
|  158         runnerDefinitions[currentProcess]( |  127       } | 
|  159           bundle, bundleFilename, |  128     }); | 
|  160           browserFiles.map( |  129   }); | 
|  161             file => path.relative(path.join(__dirname, "test", "browser"), |  | 
|  162                                   file).replace(/\.js$/, "") |  | 
|  163           ) |  | 
|  164         ) |  | 
|  165         // We need to convert rejected promise to a resolved one |  | 
|  166         // or the test will not let close the webdriver. |  | 
|  167         .catch(e => e) |  | 
|  168     )).then(results => |  | 
|  169     { |  | 
|  170       let errors = results.filter(e => typeof e != "undefined"); |  | 
|  171       if (errors.length) |  | 
|  172         throw `Browser unit test failed: ${errors.join(", ")}`; |  | 
|  173     }) |  | 
|  174   ); |  | 
|  175 } |  | 
|  176  |  130  | 
|  177 if (process.argv.length > 2) |  131   it("Runner prerequisites", () => | 
|  178   addTestPaths(process.argv.slice(2), true); |  132   { | 
|  179 else |  133     assert.ok(bundle); | 
|  180 { |  134     assert.notEqual(runnerProcesses.length, 0, "No runners was found"); | 
|  181   addTestPaths( |  135   }); | 
|  182     [path.join(__dirname, "test"), path.join(__dirname, "test", "browser")], |  | 
|  183     true |  | 
|  184   ); |  | 
|  185 } |  | 
|  186  |  136  | 
|  187 runBrowserTests(runnerProcesses).then(() => |  137   runnerProcesses.map(currentProcess => | 
|  188 { |  138   { | 
|  189   if (unitFiles.length) |  139     it(currentProcess, () => | 
|  190     nodeunit.reporters.default.run(unitFiles); |  140        runnerDefinitions[currentProcess]( | 
|  191 }).catch(error => |  141          bundle, bundleFilename, | 
|  192 { |  142          browserFiles.map( | 
|  193   console.error(error); |  143            file => path.relative(path.join(__dirname, "browser"), | 
|  194   process.exit(1); |  144                                  file).replace(/\.js$/, "") | 
 |  145          ) | 
 |  146        ) | 
 |  147       ); | 
 |  148   }); | 
|  195 }); |  149 }); | 
| OLD | NEW |