pax_global_header00006660000000000000000000000064146640347670014533gustar00rootroot0000000000000052 comment=39824a4714300bc07edab618789c06dab7f6e280 testtool/000077500000000000000000000000001466403476700127545ustar00rootroot00000000000000testtool/.gitignore000066400000000000000000000000251466403476700147410ustar00rootroot00000000000000node_modules .tern-* testtool/.npmignore000066400000000000000000000000161466403476700147500ustar00rootroot00000000000000/node_modules testtool/README.md000066400000000000000000000015211466403476700142320ustar00rootroot00000000000000# @marijn/testtool Utility for running collections of Mocha test files that contain both Node-based and browser-based tests. ## API * **`gatherTests`**`(dirs: string[]) → {tests: string[], browserTests: string[]}`\ Find `test/test-*.js` and `test/webtest-*.js` in the given directories. * **`runTests`**`(input: {tests: string[], browserTests: string[], browsers: string[], grep?: string}) → Promise`\ Run the given set of tests, optionally filtering by name with `grep`, or configuring which browsers to run the web tests on. ## Community This is open source software released under an [MIT license](https://github.com/marijnh/testtool/blob/master/LICENSE). Development happens on [GitHub](https://github.com/marijnh/testtool/). Use the [bug tracker](https://github.com/marijnh/testtool/issues) to report problems. testtool/bin/000077500000000000000000000000001466403476700135245ustar00rootroot00000000000000testtool/bin/testtool.js000077500000000000000000000022641466403476700157460ustar00rootroot00000000000000#!/usr/bin/env node const {resolve} = require("path") const {gatherTests, runTests, createTestServer} = require("..") function help(exit = 1) { console.log("Usage: testtool [--server] [--chrome] [--firefox] [--grep pattern] [... dirs]") process.exit(exit) } let dirs = [], browsers = [], grep = null, server = false for (let i = 2, arg; (arg = process.argv[i]) != null; i++) { if (arg == "--chrome") browsers.push("chrome") else if (arg == "--firefox") browsers.push("firefox") else if (arg == "--help") exit(0) else if (arg == "--grep") grep = process.argv[++i] else if (arg == "--server") server = true else if (arg[0] == "-") help() else dirs.push(resolve(arg)) } if (!dirs.length) dirs.push(".") if (!browsers.length) browsers.push("chrome") let {tests, browserTests} = gatherTests(dirs) if (!tests.length && !browserTests.length) { console.log("No tests") process.exit(0) } if (server) { let srv = createTestServer({files: browserTests, root: dirs.length == 1 ? dirs[0] : path.dirname(dirs[0])}) console.log(`Test server running on port ${srv.address().port}`) } else { runTests({tests, browserTests, grep, browsers}).then(failed => process.exit(failed ? 1 : 0)) } testtool/package.json000066400000000000000000000011251466403476700152410ustar00rootroot00000000000000{ "name": "@marijn/testtool", "version": "0.1.3", "description": "Helper package to run Mocha tests", "author": { "name": "Marijn Haverbeke", "email": "marijnh@gmail.com", "url": "http://marijnhaverbeke.nl" }, "main": "./src/testtool.js", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/marijnh/testtool.git" }, "bin": { "testtool": "bin/testtool.js" }, "dependencies": { "mocha": "^10.0.0", "ist": "^1.1.7", "esmoduleserve": "^0.2.0", "selenium-webdriver": "^4.10.0", "serve-static": "^1.14.1" } } testtool/src/000077500000000000000000000000001466403476700135435ustar00rootroot00000000000000testtool/src/testtool.js000066400000000000000000000122141466403476700157560ustar00rootroot00000000000000const Mocha = require("mocha") const path = require("path"), fs = require("fs"), url = require("url") /// Find `test/test-*.js` and `test/webtest-*.js` in the given /// directories. exports.gatherTests = function(dirs) { let tests = [], browserTests = [] for (let dir of dirs) { let testDir = path.join(dir, "test"), files try { files = fs.readdirSync(testDir) } catch { continue } for (let f of files) { let m = /^(web)?test-.*\.js$/.exec(f) if (m) (m[1] ? browserTests : tests).push(path.join(testDir, f)) } } return {tests, browserTests} } class PlainError extends Error { get name() { return "" } } /// Run the given set of tests, optionally filtering by name with /// `grep`, or configuring which browsers to run the web tests on. exports.runTests = async function({tests = [], browserTests = [], browsers = ["chrome"], grep = null}) { let mocha = new Mocha if (grep) mocha.grep(new RegExp(grep)) for (let file of tests) mocha.addFile(file) await mocha.loadFilesAsync() if (browserTests.length && browsers.length) { let server = exports.createTestServer({ files: browserTests, root: path.dirname(path.dirname(path.dirname(browserTests[0]))), selenium: true }) for (let browser of browsers) { let result = await exports.runBrowserTests({files: browserTests, grep, browser, server, grep}) let suite = Mocha.Suite.create(mocha.suite, `Browser tests (${browser})`) let top = {suite, sub: Object.create(null)} for (let test of result) { if (test.pending) continue let scope = top for (let sub of test.scope) scope = scope.sub[sub] || (scope.sub[sub] = { suite: Mocha.Suite.create(scope.suite, sub), sub: Object.create(null) }) scope.suite.addTest(new Mocha.Test(test.name, () => { if (test.fail) throw new PlainError(test.fail) })) } } server.close() } return new Promise(r => mocha.run(r)) } exports.runBrowserTests = async function({files, browser = "chrome", server, grep}) { const {Builder, By, until} = require("selenium-webdriver") const webdriver = require("selenium-webdriver/" + browser) let builder = new Builder().forBrowser(browser).setChromeOptions(new webdriver.Options().addArguments('--headless=new')) let driver = await builder.build() try { let port = server.address().port await driver.get(`http://localhost:${port}/${grep ? `?grep=${encodeURIComponent(grep)}` : ''}`) let resultNode = await driver.wait(until.elementLocated(By.css("pre.test-result")), 20000) return JSON.parse(await resultNode.getAttribute("textContent")) } finally { driver.quit() } } exports.createTestServer = function(options) { let {files, root, port = undefined, selenium = false} = options let moduleserver = new (require("esmoduleserve/moduleserver"))({root: root, maxDepth: 2}) let serveStatic = require("serve-static")(root) return require("http").createServer((req, resp) => { let {pathname} = url.parse(req.url), m if (pathname == "/") { resp.writeHead(200, {"content-type": "text/html; charset=utf-8"}) resp.end(exports.testHTML(files.map(f => path.relative(root, f)), options)) } else if (m = /^.*\/mocha(\.\w+)$/.exec(pathname)) { let base = require.resolve("mocha/mocha") let content = fs.readFileSync(base.replace(/\.\w+$/, m[1]), "utf8") resp.writeHead(200, {"content-type": (m == ".js" ? "application/javascript" : "text/css") + "; charset=utf-8"}) resp.end(content) } else if (moduleserver.handleRequest(req, resp)) { // Handled } else { serveStatic(req, resp, err => { resp.statusCode = 404 resp.end('Not found') }) } }).listen(port) } exports.testHTML = function(testFiles, options = {}) { if (typeof options == "boolean") options = {selenium: options} // Old calling style let {selenium = false, mochaPath = "", html = `browser tests

browser tests

`} = options return ` ${html}
${testFiles.map(f => ` `).join("")}` }