diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/bin/hot-perf b/bin/hot-perf index 60c011a..dfb485d 100755 --- a/bin/hot-perf +++ b/bin/hot-perf @@ -1,3 +1,3 @@ #!/usr/bin/env node -require('../lib/cli.js'); +require('../lib/cli.js'); \ No newline at end of file diff --git a/lib/cli.js b/lib/cli.js index 981a6f3..7c16956 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,46 +1,74 @@ -const program = require('caporal'); -const semver = require('semver'); -const config = require('./config'); -const { version: packageVersion, engines } = require('./../package'); +const program = require("caporal"); +const semver = require("semver"); +const config = require("./config"); +const { version: packageVersion, engines } = require("./../package"); const appToServeMap = new Map([ - ['tr', 'test-runner'], - ['bv', 'benchmark-viewer'], + ["tr", "test-runner"], + ["bv", "benchmark-viewer"], ]); const hotVersionRegExp = /^(\d{1,3}\.\d{1,3}\.\d{1,3}|latest)$/; function parseArgs() { program .version(packageVersion) - .description('JavaScript performance tests for Handsontable') - .command('local-server', 'Run a local server ("test-runner", "tr" or "benchmark-viewer", "bv").') - .alias('ls') - .argument('', 'Type of the application to serve ("test-runner" or "benchmark-viewer")', /^(test\-runner|tr|benchmark\-viewer|bv)$/, 'test-runner') - .option('--hot-version ', 'The Handsontable which will be used for running a benchmark.', hotVersionRegExp) - .option('--hot-server ', 'The server which will be used to serve Handsontable assets from.') + .description("JavaScript performance tests for Handsontable") + .command( + "local-server", + 'Run a local server ("test-runner", "tr" or "benchmark-viewer", "bv").', + ) + .alias("ls") + .argument( + "", + 'Type of the application to serve ("test-runner" or "benchmark-viewer")', + /^(test\-runner|tr|benchmark\-viewer|bv)$/, + "test-runner", + ) + .option( + "--hot-version ", + "The Handsontable which will be used for running a benchmark.", + hotVersionRegExp, + ) + .option( + "--hot-server ", + "The server which will be used to serve Handsontable assets from.", + ) .action((args, options) => { - require('./commands/local-server')( + require("./commands/local-server")( appToServeMap.get(args.appToServe) ?? args.appToServe, parseInt(config.SERVER_PORT, 10) + 1, - options + options, ); }) - .command('run', 'Run a benchmark.') - .alias('r') - .option('--hot-version ', 'The Handsontable which will be used for running a benchmark.', hotVersionRegExp) - .option('--hot-server ', 'The server which will be used to serve Handsontable assets from.') - .option('--test-name ', 'The name under which the test will be saved.') - .option('--cpu-throttle-rate ', 'The CPU throttle rate.') + .command("run", "Run a benchmark.") + .alias("r") + .option( + "--hot-version ", + "The Handsontable which will be used for running a benchmark.", + hotVersionRegExp, + ) + .option( + "--hot-server ", + "The server which will be used to serve Handsontable assets from.", + ) + .option( + "--test-name ", + "The name under which the test will be saved.", + ) + .option("--cpu-throttle-rate ", "The CPU throttle rate.") .action(async (args, options) => { - await require('./commands/local-server')('test-runner', config.SERVER_PORT, options); + await require("./commands/local-server")( + "test-runner", + config.SERVER_PORT, + options, + ); - const statsGenerator = require('./commands/protractor')(options); + const statsGenerator = require("./commands/protractor")(options); - await require('./storage').saveByReplace(statsGenerator); + await require("./storage").saveByReplace(statsGenerator); process.exit(0); - }) - ; + }); program.parse(process.argv); } @@ -48,14 +76,16 @@ function parseArgs() { (function main() { try { if (!semver.satisfies(process.versions.node, engines.node)) { - throw Error(`The project requires Node.js${engines.node} for running. You've currently installed version ${process.versions.node}.`); + throw Error( + `The project requires Node.js${engines.node} for running. You've currently installed version ${process.versions.node}.`, + ); } parseArgs(); } catch (ex) { /* eslint-disable no-console */ console.log(ex.message); - console.log(''); + console.log(""); process.exit(2); } -}()); +})(); diff --git a/lib/commands/local-server/index.js b/lib/commands/local-server/index.js index a9a79aa..a7736c6 100644 --- a/lib/commands/local-server/index.js +++ b/lib/commands/local-server/index.js @@ -1,45 +1,49 @@ -const Hapi = require('@hapi/hapi'); -const path = require('path'); -const config = require('./../../config'); -const { loadAll } = require('./../../storage'); +const Hapi = require("@hapi/hapi"); +const path = require("path"); +const config = require("./../../config"); +const { loadAll } = require("./../../storage"); -module.exports = async function(appName, customPort = config.SERVER_PORT, { hotVersion = 'latest', hotServer, testName } = {}) { +module.exports = async function ( + appName, + customPort = config.SERVER_PORT, + { hotVersion = "latest", hotServer, testName } = {}, +) { const server = Hapi.server({ port: customPort, host: config.SERVER_HOST, routes: { files: { - relativeTo: __dirname + path.sep + 'public', - } + relativeTo: __dirname + path.sep + "public", + }, }, }); - await server.register(require('@hapi/vision')); - await server.register(require('@hapi/inert')); + await server.register(require("@hapi/vision")); + await server.register(require("@hapi/inert")); server.views({ engines: { - html: require('handlebars'), + html: require("handlebars"), }, relativeTo: __dirname, - path: 'templates', + path: "templates", }); server.route({ - method: 'GET', - path: '/{param*}', + method: "GET", + path: "/{param*}", handler: { directory: { - path: '.', + path: ".", redirectToSlash: true, index: true, - } - } + }, + }, }); server.route({ - method: 'GET', - path: '/', + method: "GET", + path: "/", handler: async function (request, h) { const stats = await loadAll(); @@ -48,16 +52,16 @@ module.exports = async function(appName, customPort = config.SERVER_PORT, { hotV stats: JSON.stringify(Array.from(stats.entries())), urls: getHotUrl({ hotVersion, hotServer }), }); - } + }, }); await server.start(); console.log(`Server running at: ${server.info.uri}`); -} +}; function getHotUrl({ hotVersion, hotServer } = {}) { - const urls = { script: '', style: '' }; + const urls = { script: "", style: "" }; if (hotServer) { urls.script = `${hotServer}/dist/handsontable.full.js`; diff --git a/lib/commands/local-server/public/js/bar-item.js b/lib/commands/local-server/public/js/bar-item.js index ced6260..b7657dd 100644 --- a/lib/commands/local-server/public/js/bar-item.js +++ b/lib/commands/local-server/public/js/bar-item.js @@ -1,4 +1,4 @@ -(function(w, d) { +(function (w, d) { var colorIndex = -1; /** @@ -18,8 +18,8 @@ BarItem.prototype = Object.create(Observer.prototype, { constructor: { value: BarItem, - configurable: true - } + configurable: true, + }, }); /** @@ -27,7 +27,7 @@ * * @returns {HTMLElement} */ - BarItem.prototype.renderDOM = function() { + BarItem.prototype.renderDOM = function () { if (this.template) { return this.template; } @@ -38,47 +38,53 @@ var btnClean; var form; - this.template = t = d.importNode(d.querySelector('#bar').content, true); - form = t.querySelector('form'); - selHotVersion = t.querySelector('select[name=hot-version]'); - selTest = t.querySelector('select[name=test]'); - btnClean = t.querySelector('.btn-clean'); + this.template = t = d.importNode(d.querySelector("#bar").content, true); + form = t.querySelector("form"); + selHotVersion = t.querySelector("select[name=hot-version]"); + selTest = t.querySelector("select[name=test]"); + btnClean = t.querySelector(".btn-clean"); var hotVersions = Array.from(this.barManager.getStatsMap().keys()); - hotVersions = hotVersions.map(function(version) { - return version.replace(/_/g, '.'); - }).sort(function(a, b) { - if (a === b) { - return 0; - } + hotVersions = hotVersions + .map(function (version) { + return version.replace(/_/g, "."); + }) + .sort(function (a, b) { + if (a === b) { + return 0; + } - if (!SemVer.valid(a) || !SemVer.valid(b)) { - return 1; - } + if (!SemVer.valid(a) || !SemVer.valid(b)) { + return 1; + } - return SemVer.lt(a, b) ? 1 : -1; - }) + return SemVer.lt(a, b) ? 1 : -1; + }); selHotVersion.appendChild(this._buildOptionsList(hotVersions)); - selHotVersion.addEventListener('change', function() { - selTest.textContent = ''; - selTest.appendChild(_this._buildOptionsList(_this.barManager.getStatsMap(selHotVersion.value))); + selHotVersion.addEventListener("change", function () { + selTest.textContent = ""; + selTest.appendChild( + _this._buildOptionsList( + _this.barManager.getStatsMap(selHotVersion.value), + ), + ); }); - selTest.addEventListener('change', function() { + selTest.addEventListener("change", function () { _this.selectedHotVersion = selHotVersion.value; _this.selectedTest = selTest.value; - _this.emit('change', _this); + _this.emit("change", _this); }); - btnClean.addEventListener('click', function() { - selHotVersion.value = ''; - selTest.value = ''; + btnClean.addEventListener("click", function () { + selHotVersion.value = ""; + selTest.value = ""; _this.clearChartData(); - _this.emit('reset', _this); + _this.emit("reset", _this); }); return this.template; @@ -90,9 +96,9 @@ * @param {Object} data * @returns {Object} */ - BarItem.prototype.parseChartData = function(data) { - Object.keys(data.metrics).forEach(function(metric) { - var samples = data.samples.map(function(sample) { + BarItem.prototype.parseChartData = function (data) { + Object.keys(data.metrics).forEach(function (metric) { + var samples = data.samples.map(function (sample) { return sample.values[metric]; }); @@ -111,58 +117,55 @@ /** * @returns {Object} */ - BarItem.prototype.hasChartData = function() { + BarItem.prototype.hasChartData = function () { return this.chartData.id ? true : false; }; /** * @returns {Object} */ - BarItem.prototype.getChartData = function() { + BarItem.prototype.getChartData = function () { return this.chartData; }; /** * */ - BarItem.prototype.clearChartData = function() { + BarItem.prototype.clearChartData = function () { this.chartData = {}; }; /** * @returns {Function} */ - BarItem.prototype.getFillColor = function() { - var color = function(alpha) { + BarItem.prototype.getFillColor = function () { + var color = function (alpha) { // yellow #F9CC01 - return 'rgba(249, 204, 1, ' + alpha + ')'; + return "rgba(249, 204, 1, " + alpha + ")"; }; if (colorIndex === 0) { - color = function(alpha) { + color = function (alpha) { // red #F36247 - return 'rgba(243, 98, 71, ' + alpha + ')'; - } - } - else if (colorIndex === 1) { - color = function(alpha) { + return "rgba(243, 98, 71, " + alpha + ")"; + }; + } else if (colorIndex === 1) { + color = function (alpha) { // blue - return 'rgba(27, 149, 200, ' + alpha + ')'; - } - } - else if (colorIndex === 2) { - color = function(alpha) { + return "rgba(27, 149, 200, " + alpha + ")"; + }; + } else if (colorIndex === 2) { + color = function (alpha) { // purple #A35DBD - return 'rgba(163, 93, 189, ' + alpha + ')'; - } - } - else if (colorIndex === 3) { - color = function(alpha) { + return "rgba(163, 93, 189, " + alpha + ")"; + }; + } else if (colorIndex === 3) { + color = function (alpha) { // green #00B972 - return 'rgba(0, 185, 114, ' + alpha + ')'; - } + return "rgba(0, 185, 114, " + alpha + ")"; + }; } - colorIndex ++; + colorIndex++; return color; }; @@ -174,21 +177,22 @@ * @returns {DocumentFragment} * @private */ - BarItem.prototype._buildOptionsList = function(list) { - var node = d.createDocumentFragment(), option; + BarItem.prototype._buildOptionsList = function (list) { + var node = d.createDocumentFragment(), + option; - option = d.createElement('option'); - option.value = ''; - option.textContent = '...'; + option = d.createElement("option"); + option.value = ""; + option.textContent = "..."; node.appendChild(option); var listOptions = [].concat(list); - listOptions.forEach(function(item) { - var option = d.createElement('option'); + listOptions.forEach(function (item) { + var option = d.createElement("option"); - if (typeof item === 'string') { + if (typeof item === "string") { option.value = item; option.textContent = item; } else { @@ -203,5 +207,4 @@ }; w.BarItem = BarItem; - -}(window, document)); +})(window, document); diff --git a/lib/commands/local-server/public/js/bar-manager.js b/lib/commands/local-server/public/js/bar-manager.js index a10adcc..a10efcd 100644 --- a/lib/commands/local-server/public/js/bar-manager.js +++ b/lib/commands/local-server/public/js/bar-manager.js @@ -1,20 +1,20 @@ -(function(w, d) { +(function (w, d) { /** * @constructor */ function BarManager(statsMap, sampleSize) { - this.barsContainer = d.querySelector('.bars'); + this.barsContainer = d.querySelector(".bars"); this.bars = []; this.charts = []; this.statsMap = statsMap; this.sampleSize = sampleSize || 100; - this.registerChart('scriptTime'); - this.registerChart('renderTime'); - this.registerChart('pureScriptTime'); - this.registerChart('gcTime'); - this.registerChart('gcAmount'); - this.registerChart('majorGcTime'); + this.registerChart("scriptTime"); + this.registerChart("renderTime"); + this.registerChart("pureScriptTime"); + this.registerChart("gcTime"); + this.registerChart("gcAmount"); + this.registerChart("majorGcTime"); this._createDefaultBars(); this.renderDOM(); @@ -26,9 +26,9 @@ * @param {String} [hotVersion] Optionally narrow data to test for specify Handsontable version * @returns {Object} */ - BarManager.prototype.getStatsMap = function(hotVersion) { + BarManager.prototype.getStatsMap = function (hotVersion) { if (hotVersion) { - return this.statsMap.get(hotVersion.replace(/\./g, '_')); + return this.statsMap.get(hotVersion.replace(/\./g, "_")); } return this.statsMap; @@ -37,7 +37,7 @@ /** * @param {String} metric */ - BarManager.prototype.registerChart = function(metric) { + BarManager.prototype.registerChart = function (metric) { this.charts.push(new ChartItem(metric, this.sampleSize)); }; @@ -45,10 +45,10 @@ * @param {String} metric * @returns ChartItem */ - BarManager.prototype.getChart = function(metricName) { + BarManager.prototype.getChart = function (metricName) { var result; - this.charts.forEach(function(chart) { + this.charts.forEach(function (chart) { if (chart.metric === metricName) { result = chart; } @@ -60,8 +60,8 @@ /** * Render UI to DOM */ - BarManager.prototype.renderDOM = function() { - this.bars.forEach(function(bar) { + BarManager.prototype.renderDOM = function () { + this.bars.forEach(function (bar) { this.barsContainer.appendChild(bar.renderDOM()); }, this); }; @@ -69,16 +69,16 @@ /** * Render charts */ - BarManager.prototype.renderCharts = function() { + BarManager.prototype.renderCharts = function () { var chartData = {}; - this.bars.forEach(function(bar) { + this.bars.forEach(function (bar) { if (!bar.hasChartData()) { return; } var barData = bar.getChartData(); - Object.keys(ChartItem.METRICS).forEach(function(metricType) { + Object.keys(ChartItem.METRICS).forEach(function (metricType) { var data = barData[metricType]; if (!chartData[metricType]) { @@ -90,7 +90,7 @@ }); }); - Object.keys(ChartItem.METRICS).forEach(function(metricType) { + Object.keys(ChartItem.METRICS).forEach(function (metricType) { var chart = this.getChart(metricType); if (!chart) { @@ -103,12 +103,14 @@ /** * @param {BarItem} bar */ - BarManager.prototype.onBarChanged = function(bar) { + BarManager.prototype.onBarChanged = function (bar) { var _this = this; - var chartData = this.getStatsMap(bar.selectedHotVersion).filter(function(sample) { - return sample.id === bar.selectedTest; - })[0]; + var chartData = this.getStatsMap(bar.selectedHotVersion).filter( + function (sample) { + return sample.id === bar.selectedTest; + }, + )[0]; bar.parseChartData(chartData); this.renderCharts(); @@ -117,7 +119,7 @@ /** * @param {BarItem} bar */ - BarManager.prototype.onBarReset = function(bar) { + BarManager.prototype.onBarReset = function (bar) { this.renderCharts(); }; @@ -125,19 +127,18 @@ * Create bar empty slots * @private */ - BarManager.prototype._createDefaultBars = function() { + BarManager.prototype._createDefaultBars = function () { this.bars.push(new BarItem(this)); this.bars.push(new BarItem(this)); this.bars.push(new BarItem(this)); this.bars.push(new BarItem(this)); this.bars.push(new BarItem(this)); - this.bars.forEach(function(bar) { - bar.on('change', this.onBarChanged.bind(this)); - bar.on('reset', this.onBarReset.bind(this)); + this.bars.forEach(function (bar) { + bar.on("change", this.onBarChanged.bind(this)); + bar.on("reset", this.onBarReset.bind(this)); }, this); }; w.BarManager = BarManager; - -}(window, document)); +})(window, document); diff --git a/lib/commands/local-server/public/js/chart-item.js b/lib/commands/local-server/public/js/chart-item.js index afe50ae..3e59ca6 100644 --- a/lib/commands/local-server/public/js/chart-item.js +++ b/lib/commands/local-server/public/js/chart-item.js @@ -1,23 +1,29 @@ -(function(w, d) { - +(function (w, d) { var METRICS = { - scriptTime: 'Script execution time in ms, including garbage collection and render (lower is better). ' + - 'To keep 60FPS execution time should not exceed 16.6ms.', - pureScriptTime: 'Script execution time in ms, without garbage collection nor render (lower is better).', - renderTime: 'Render time in and outside of script in ms (lower is better).', - gcTime: 'Garbage collection time in and outside of script in ms (lower is better).', - gcAmount: 'Garbage collection amount in kilobytes (lower is better).', - majorGcTime: 'Time of major garbage collections in ms (lower is better).' + scriptTime: + "Script execution time in ms, including garbage collection and render (lower is better). " + + "To keep 60FPS execution time should not exceed 16.6ms.", + pureScriptTime: + "Script execution time in ms, without garbage collection nor render (lower is better).", + renderTime: "Render time in and outside of script in ms (lower is better).", + gcTime: + "Garbage collection time in and outside of script in ms (lower is better).", + gcAmount: "Garbage collection amount in kilobytes (lower is better).", + majorGcTime: "Time of major garbage collections in ms (lower is better).", }; function parseTooltipMetrics(metric, value) { - var fps = ''; - - if (metric === 'scriptTime' || metric === 'pureScriptTime' || metric === 'renderTime') { - fps = ' (' + ((1000 / parseFloat(value, 10)) >> 0) + 'FPS)';; + var fps = ""; + + if ( + metric === "scriptTime" || + metric === "pureScriptTime" || + metric === "renderTime" + ) { + fps = " (" + ((1000 / parseFloat(value, 10)) >> 0) + "FPS)"; } - return parseFloat(value, 10).toFixed(2) + 'ms' + fps; + return parseFloat(value, 10).toFixed(2) + "ms" + fps; } /** @@ -32,33 +38,33 @@ barDatasetSpacing: 0, barStrokeWidth: 1, barShowStroke: false, - customTooltips: function(tooltip) { + customTooltips: function (tooltip) { if (!tooltip) { return; } if (tooltip.labels) { tooltip.title = metric; - tooltip.labels.forEach(function(value, index) { + tooltip.labels.forEach(function (value, index) { tooltip.labels[index] = parseTooltipMetrics(metric, value); }); - } - else { + } else { tooltip.text = parseTooltipMetrics(metric, tooltip.text); } tooltip.custom = null; tooltip.draw(); - } + }, }; this.chart = null; this.metric = metric; - this.container = d.querySelector('.charts'); - this.template = d.importNode(d.querySelector('#chart').content, true); - this.ctx = this.template.querySelector('canvas').getContext('2d'); + this.container = d.querySelector(".charts"); + this.template = d.importNode(d.querySelector("#chart").content, true); + this.ctx = this.template.querySelector("canvas").getContext("2d"); - this.template.querySelector('.header').textContent = metric; - this.template.querySelector('.description').textContent = ' - ' + METRICS[metric]; + this.template.querySelector(".header").textContent = metric; + this.template.querySelector(".description").textContent = + " - " + METRICS[metric]; - this.legendEl = this.template.querySelector('.legend'); + this.legendEl = this.template.querySelector(".legend"); this.container.appendChild(this.template); this.createEmptyCharts(); } @@ -66,8 +72,8 @@ ChartItem.prototype = Object.create(Observer.prototype, { constructor: { value: Chart, - configurable: true - } + configurable: true, + }, }); ChartItem.METRICS = METRICS; @@ -77,25 +83,27 @@ * * @param {Object|Array|null} data */ - ChartItem.prototype.render = function(data) { - data = data ? Array.isArray(data) ? data : [data] : null; + ChartItem.prototype.render = function (data) { + data = data ? (Array.isArray(data) ? data : [data]) : null; if (this.chart) { this.chart.destroy(); } - this.legendEl.textContent = ''; + this.legendEl.textContent = ""; if (data) { - this.chart = new Chart(this.ctx).Bar({ - labels: this._generateFixedArray(), - datasets: data - }, this.chartOptions); - - data.forEach(function(d) { + this.chart = new Chart(this.ctx).Bar( + { + labels: this._generateFixedArray(), + datasets: data, + }, + this.chartOptions, + ); + + data.forEach(function (d) { this.legendEl.appendChild(this._buildLegendTemplate(d.strokeColor, d)); }, this); - } - else { + } else { this.createEmptyCharts(); } }; @@ -103,12 +111,14 @@ /** * Create empty charts */ - ChartItem.prototype.createEmptyCharts = function() { + ChartItem.prototype.createEmptyCharts = function () { var data = { labels: this._generateFixedArray(), - datasets: [{ - data: this._generateFixedArray() - }] + datasets: [ + { + data: this._generateFixedArray(), + }, + ], }; this.chart = new Chart(this.ctx).Bar(data, this.chartOptions); @@ -122,11 +132,12 @@ * @returns {Node} * @private */ - ChartItem.prototype._buildLegendTemplate = function(color, data) { - var template = d.importNode(d.querySelector('#legend').content, true); + ChartItem.prototype._buildLegendTemplate = function (color, data) { + var template = d.importNode(d.querySelector("#legend").content, true); - template.querySelector('.color').style.backgroundColor = color; - template.querySelector('.description').textContent = data.selectedHotVersion + ', ' + data.selectedTest; + template.querySelector(".color").style.backgroundColor = color; + template.querySelector(".description").textContent = + data.selectedHotVersion + ", " + data.selectedTest; return template; }; @@ -137,10 +148,9 @@ * @returns {Array} * @private */ - ChartItem.prototype._generateFixedArray = function() { - return new Array(this.sampleSize).join(',').split(','); + ChartItem.prototype._generateFixedArray = function () { + return new Array(this.sampleSize).join(",").split(","); }; w.ChartItem = ChartItem; - -}(window, document)); +})(window, document); diff --git a/lib/commands/local-server/public/js/observer.js b/lib/commands/local-server/public/js/observer.js index 469e9dd..c414bf6 100644 --- a/lib/commands/local-server/public/js/observer.js +++ b/lib/commands/local-server/public/js/observer.js @@ -1,4 +1,4 @@ -(function(w, d) { +(function (w, d) { /** * Simple implementation event observer pattern */ @@ -6,7 +6,7 @@ this.listeners = {}; } - Observer.prototype.emit = function(name, args) { + Observer.prototype.emit = function (name, args) { if (!this.listeners[name]) { return this; } @@ -14,13 +14,13 @@ var itemsLength = this.listeners[name].length; var i = 0; - while(i < itemsLength) { + while (i < itemsLength) { items[i].apply(this, Array.isArray(args) ? args : [args]); - i ++; + i++; } }; - Observer.prototype.on = function(name, callback) { + Observer.prototype.on = function (name, callback) { if (!this.listeners[name]) { this.listeners[name] = []; } @@ -32,5 +32,4 @@ }; w.Observer = Observer; - -}(window, document)); +})(window, document); diff --git a/lib/commands/local-server/public/js/test-runner.js b/lib/commands/local-server/public/js/test-runner.js index cdfda60..7223721 100644 --- a/lib/commands/local-server/public/js/test-runner.js +++ b/lib/commands/local-server/public/js/test-runner.js @@ -1,4 +1,3 @@ - /** * Parse Handsontable settings from query string * @@ -11,8 +10,11 @@ function getHotSettings() { if (!settings.hasOwnProperty(i)) { continue; } - if (i === 'data') { - settings[i] = Handsontable.helper.createSpreadsheetData(settings[i].split(',')[0], settings[i].split(',')[1]); + if (i === "data") { + settings[i] = Handsontable.helper.createSpreadsheetData( + settings[i].split(",")[0], + settings[i].split(",")[1], + ); } else { settings[i] = parseSetting(settings[i]); } @@ -31,13 +33,17 @@ function getHotSettings() { * @returns {Object} */ function parseQueryString(queryString) { - var params = {}, queries, temp, i, l; + var params = {}, + queries, + temp, + i, + l; - queries = queryString.split('&'); + queries = queryString.split("&"); l = queries.length; - for (i = 0; i < l; i ++) { - temp = queries[i].split('='); + for (i = 0; i < l; i++) { + temp = queries[i].split("="); params[temp[0]] = temp[1]; } diff --git a/lib/commands/protractor/index.js b/lib/commands/protractor/index.js index ba4d152..0fa3bf7 100644 --- a/lib/commands/protractor/index.js +++ b/lib/commands/protractor/index.js @@ -1,14 +1,22 @@ -const { fork } = require('child_process'); +const { fork } = require("child_process"); -module.exports = function ({ hotVersion = 'latest', cpuThrottleRate = 0, hotServer, testName } = {}) { - console.log('Running protractor...'); +module.exports = function ({ + hotVersion = "latest", + cpuThrottleRate = 0, + hotServer, + testName, +} = {}) { + console.log("Running protractor..."); const env = process.env; - env.HOT_VERSION = testName ? testName : (hotServer ? 'develop' : hotVersion); + env.HOT_VERSION = testName ? testName : hotServer ? "develop" : hotVersion; env.CPU_THROTTLE_RATE = cpuThrottleRate; - - const childProcess = fork('./node_modules/.bin/protractor', ['protractor.conf.js'], { env }); + const childProcess = fork( + "./node_modules/.bin/protractor", + ["protractor.conf.js"], + { env }, + ); let isDone = false; let promiseResolver = null; @@ -16,11 +24,11 @@ module.exports = function ({ hotVersion = 'latest', cpuThrottleRate = 0, hotServ promiseResolver = resolve; }); - childProcess.on('exit', function(code) { + childProcess.on("exit", function (code) { promiseResolver(null); isDone = true; }); - childProcess.on('message', function(sampleResults) { + childProcess.on("message", function (sampleResults) { const samples = JSON.parse(sampleResults); promiseResolver(samples); @@ -37,5 +45,5 @@ module.exports = function ({ hotVersion = 'latest', cpuThrottleRate = 0, hotServ yield pendingPromise; } - } -} + }; +}; diff --git a/lib/config.js b/lib/config.js index c7ad7fd..7291d75 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,7 +1,7 @@ module.exports = { SAMPLE_SIZE: 100, - SERVER_HOST: 'localhost', - SERVER_PORT: '8082', - DB_URL: 'mongodb://root:root@localhost:27017', - DB_NAME: 'performance_lab', + SERVER_HOST: "localhost", + SERVER_PORT: "8082", + DB_URL: "mongodb://root:root@localhost:27017", + DB_NAME: "performance_lab", }; diff --git a/lib/storage/index.js b/lib/storage/index.js index 648090e..727018f 100644 --- a/lib/storage/index.js +++ b/lib/storage/index.js @@ -1,7 +1,13 @@ -const { connect, close, insertMany, findAll, dropIfExists } = require('./mongo'); -const axios = require('axios'); +const { + connect, + close, + insertMany, + findAll, + dropIfExists, +} = require("./mongo"); +const axios = require("axios"); -module.exports.saveByReplace = async function(statsGenerator) { +module.exports.saveByReplace = async function (statsGenerator) { const stats = statsGenerator(); const collections = new Map(); let hotVersion; @@ -17,14 +23,16 @@ module.exports.saveByReplace = async function(statsGenerator) { hotVersion = description.hotVersion; // Convert "latest" tag to specific semver value - if (hotVersion === 'latest') { - const response = await axios.get('https://api.cdnjs.com/libraries/handsontable?fields=version'); + if (hotVersion === "latest") { + const response = await axios.get( + "https://api.cdnjs.com/libraries/handsontable?fields=version", + ); const data = response.data; hotVersion = data.version; } - hotVersion = hotVersion.replace(/\./g, '_'); + hotVersion = hotVersion.replace(/\./g, "_"); if (!collections.has(hotVersion)) { collections.set(hotVersion, []); @@ -45,12 +53,12 @@ module.exports.saveByReplace = async function(statsGenerator) { } await close(); -} +}; -module.exports.loadAll = async function() { +module.exports.loadAll = async function () { await connect(); const results = await findAll(); await close(); return results; -} +}; diff --git a/lib/storage/mongo.js b/lib/storage/mongo.js index 0c92cef..db70726 100644 --- a/lib/storage/mongo.js +++ b/lib/storage/mongo.js @@ -1,5 +1,5 @@ -const MongoClient = require('mongodb').MongoClient; -const config = require('./../config'); +const MongoClient = require("mongodb").MongoClient; +const config = require("./../config"); const dbName = config.DB_NAME; @@ -63,7 +63,10 @@ async function dropIfExists(collectionName) { } async function isCollectionExists(collectionName) { - const collections = await currentConnection.db(dbName).listCollections().toArray(); + const collections = await currentConnection + .db(dbName) + .listCollections() + .toArray(); return collections.some((collection) => collection.name === collectionName); } @@ -75,4 +78,4 @@ module.exports = { insertMany, close, connect, -} +}; diff --git a/package-lock.json b/package-lock.json index 260e841..6d5fccc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,57 +1,61 @@ { "name": "performance-lab", - "version": "2.3.0", + "version": "2.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "performance-lab", - "version": "2.3.0", + "version": "2.4.0", "hasInstallScript": true, "license": "MIT", "bin": { "performance-lab": "bin/hot-perf" }, "devDependencies": { - "@angular/benchpress": "^0.2.1", + "@angular/benchpress": "^0.3.0", "@hapi/hapi": "^19.2.0", "@hapi/inert": "^6.0.1", "@hapi/vision": "^6.0.0", "axios": "^0.19.2", "caporal": "^1.4.0", + "chromedriver": "^117.0.3", "fs-extra": "^9.0.1", "handlebars": "^4.7.6", "mongodb": "^3.6.0", + "prettier": "3.0.3", "protractor": "^7.0.0", - "rxjs": "^6.6.2", - "semver": "^7.3.2", - "webdriver-manager": "^12.1.8" + "rxjs": "^7.8.1", + "semver": "^7.3.2" }, "engines": { "node": ">=11" } }, "node_modules/@angular/benchpress": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@angular/benchpress/-/benchpress-0.2.1.tgz", - "integrity": "sha512-ojHCP96ZunHBZpt08USSEdLJsuXnEEdJtfzl+9oTdMXbooKkzSVO7N6bVdjefbGRNAleAuSAo3gVrdPqumLznA==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@angular/benchpress/-/benchpress-0.3.0.tgz", + "integrity": "sha512-ApxoY5lTj1S0QFLdq5ZdTfdkIds1m3tma9EJOZpNVHRU9eCj2D/5+VFb5tlWsv9NHQ2S0XXkJjauFOAdfzT8uw==", "dev": true, "dependencies": { - "@angular/core": "^10.0.0-0 || ^11.0.0", + "@angular/core": "^13.0.0 || ^14.0.0-0", "reflect-metadata": "^0.1.13" } }, "node_modules/@angular/core": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-10.0.8.tgz", - "integrity": "sha512-52M1krR/TRZsV9WKPd+r7IPVT8c5Nh+Im1z3/ZY7rG0HmxXsV7YzuTuKV7oyHbWPg0WPJAwyH0+qxBK3kpvc8w==", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.3.0.tgz", + "integrity": "sha512-wYiwItc0Uyn4FWZ/OAx/Ubp2/WrD3EgUJ476y1XI7yATGPF8n9Ld5iCXT08HOvc4eBcYlDfh90kTXR6/MfhzdQ==", "dev": true, "dependencies": { - "tslib": "^2.0.0" + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "rxjs": "^6.5.3", - "zone.js": "~0.10.3" + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.11.4 || ~0.12.0" } }, "node_modules/@hapi/accept": { @@ -423,12 +427,25 @@ "@hapi/hoek": "9.x.x" } }, + "node_modules/@testim/chrome-version": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz", + "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", + "dev": true + }, "node_modules/@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "node_modules/@types/node": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", + "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==", + "dev": true, + "optional": true + }, "node_modules/@types/q": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", @@ -441,13 +458,23 @@ "integrity": "sha512-tGomyEuzSC1H28y2zlW6XPCaDaXFaD6soTdb4GNdmte2qfHtrKqhy0ZFs4r/1hpazCfEZqeTSRLvSasmEx89uw==", "dev": true }, + "node_modules/@types/yauzl": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.1.tgz", + "integrity": "sha512-CHzgNU3qYBnp/O4S3yv2tXPlvMTq0YWSTVg2/JYLqWZGHwwgJGAwd00poay/11asPq8wLFwHzubyInqHIFmmiw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", "dev": true, "engines": { - "node": ">=0.3.0" + "node": ">=6.0" } }, "node_modules/agent-base": { @@ -616,9 +643,9 @@ } }, "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "node_modules/bcrypt-pbkdf": { @@ -689,6 +716,15 @@ "node": ">=0.6.19" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -767,6 +803,121 @@ "node": ">=0.10.0" } }, + "node_modules/chromedriver": { + "version": "117.0.3", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-117.0.3.tgz", + "integrity": "sha512-c2rk2eGK5zZFBJMdviUlAJfQEBuPNIKfal4+rTFVYAmrWbMPYAqPozB+rIkc1lDP/Ryw44lPiqKglrI01ILhTQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@testim/chrome-version": "^1.1.3", + "axios": "^1.4.0", + "compare-versions": "^6.0.0", + "extract-zip": "^2.0.1", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^1.1.0", + "tcp-port-used": "^1.0.1" + }, + "bin": { + "chromedriver": "bin/chromedriver" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chromedriver/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/chromedriver/node_modules/axios": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/chromedriver/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/chromedriver/node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/chromedriver/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chromedriver/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chromedriver/node_modules/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 + }, "node_modules/cli-cursor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", @@ -910,10 +1061,16 @@ "node": ">= 0.8" } }, + "node_modules/compare-versions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "node_modules/concat-stream": { @@ -976,6 +1133,12 @@ "node": ">=0.10.0" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "node_modules/del": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", @@ -1034,6 +1197,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -1093,6 +1265,49 @@ "tmp": "^0.0.29" } }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/extract-zip/node_modules/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 + }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -1129,6 +1344,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -1233,6 +1457,21 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1243,15 +1482,15 @@ } }, "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -1485,6 +1724,15 @@ "node": ">=0.10.0" } }, + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -1533,6 +1781,26 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "node_modules/is2": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz", + "integrity": "sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "ip-regex": "^4.1.0", + "is-url": "^1.2.4" + }, + "engines": { + "node": ">=v0.10.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -1747,9 +2015,9 @@ } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -1953,6 +2221,12 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -1989,6 +2263,21 @@ "node": ">=0.10.0" } }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/prettyjson": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.1.tgz", @@ -2039,12 +2328,28 @@ "node": ">=10.13.x" } }, + "node_modules/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 + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "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, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -2210,23 +2515,14 @@ "dev": true }, "node_modules/rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" + "tslib": "^2.1.0" } }, - "node_modules/rxjs/node_modules/tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", - "dev": true - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2477,6 +2773,39 @@ "ms": "2.0.0" } }, + "node_modules/tcp-port-used": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz", + "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==", + "dev": true, + "dependencies": { + "debug": "4.3.1", + "is2": "^2.0.6" + } + }, + "node_modules/tcp-port-used/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/tcp-port-used/node_modules/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 + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -2509,9 +2838,9 @@ } }, "node_modules/tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, "node_modules/tunnel-agent": { @@ -2613,12 +2942,12 @@ } }, "node_modules/webdriver-manager": { - "version": "12.1.8", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.8.tgz", - "integrity": "sha512-qJR36SXG2VwKugPcdwhaqcLQOD7r8P2Xiv9sfNbfZrKBnX243iAkOueX1yAmeNgIKhJ3YAT/F2gq6IiEZzahsg==", + "version": "12.1.9", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.9.tgz", + "integrity": "sha512-Yl113uKm8z4m/KMUVWHq1Sjtla2uxEBtx2Ue3AmIlnlPAKloDn/Lvmy6pqWCUersVISpdMeVpAaGbNnvMuT2LQ==", "dev": true, "dependencies": { - "adm-zip": "^0.4.9", + "adm-zip": "^0.5.2", "chalk": "^1.1.1", "del": "^2.2.0", "glob": "^7.0.3", @@ -2877,32 +3206,45 @@ "node": ">=8" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/zone.js": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", - "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.12.0.tgz", + "integrity": "sha512-XtC+I5dXU14HrzidAKBNMqneIVUykLEAA1x+v4KVrd6AUPWlwYORF8KgsVqvgdHiKZ4BkxxjvYi/ksEixTPR0Q==", "dev": true, - "peer": true + "peer": true, + "dependencies": { + "tslib": "^2.3.0" + } } }, "dependencies": { "@angular/benchpress": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@angular/benchpress/-/benchpress-0.2.1.tgz", - "integrity": "sha512-ojHCP96ZunHBZpt08USSEdLJsuXnEEdJtfzl+9oTdMXbooKkzSVO7N6bVdjefbGRNAleAuSAo3gVrdPqumLznA==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@angular/benchpress/-/benchpress-0.3.0.tgz", + "integrity": "sha512-ApxoY5lTj1S0QFLdq5ZdTfdkIds1m3tma9EJOZpNVHRU9eCj2D/5+VFb5tlWsv9NHQ2S0XXkJjauFOAdfzT8uw==", "dev": true, "requires": { - "@angular/core": "^10.0.0-0 || ^11.0.0", + "@angular/core": "^13.0.0 || ^14.0.0-0", "reflect-metadata": "^0.1.13" } }, "@angular/core": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-10.0.8.tgz", - "integrity": "sha512-52M1krR/TRZsV9WKPd+r7IPVT8c5Nh+Im1z3/ZY7rG0HmxXsV7YzuTuKV7oyHbWPg0WPJAwyH0+qxBK3kpvc8w==", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.3.0.tgz", + "integrity": "sha512-wYiwItc0Uyn4FWZ/OAx/Ubp2/WrD3EgUJ476y1XI7yATGPF8n9Ld5iCXT08HOvc4eBcYlDfh90kTXR6/MfhzdQ==", "dev": true, "requires": { - "tslib": "^2.0.0" + "tslib": "^2.3.0" } }, "@hapi/accept": { @@ -3259,12 +3601,25 @@ "@hapi/hoek": "9.x.x" } }, + "@testim/chrome-version": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz", + "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", + "dev": true + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/node": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", + "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==", + "dev": true, + "optional": true + }, "@types/q": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", @@ -3277,10 +3632,20 @@ "integrity": "sha512-tGomyEuzSC1H28y2zlW6XPCaDaXFaD6soTdb4GNdmte2qfHtrKqhy0ZFs4r/1hpazCfEZqeTSRLvSasmEx89uw==", "dev": true }, + "@types/yauzl": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.1.tgz", + "integrity": "sha512-CHzgNU3qYBnp/O4S3yv2tXPlvMTq0YWSTVg2/JYLqWZGHwwgJGAwd00poay/11asPq8wLFwHzubyInqHIFmmiw==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", "dev": true }, "agent-base": { @@ -3414,9 +3779,9 @@ } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "bcrypt-pbkdf": { @@ -3478,6 +3843,12 @@ "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q==", "dev": true }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -3543,6 +3914,85 @@ } } }, + "chromedriver": { + "version": "117.0.3", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-117.0.3.tgz", + "integrity": "sha512-c2rk2eGK5zZFBJMdviUlAJfQEBuPNIKfal4+rTFVYAmrWbMPYAqPozB+rIkc1lDP/Ryw44lPiqKglrI01ILhTQ==", + "dev": true, + "requires": { + "@testim/chrome-version": "^1.1.3", + "axios": "^1.4.0", + "compare-versions": "^6.0.0", + "extract-zip": "^2.0.1", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^1.1.0", + "tcp-port-used": "^1.0.1" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "axios": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "dev": true, + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "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 + } + } + }, "cli-cursor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", @@ -3656,10 +4106,16 @@ "delayed-stream": "~1.0.0" } }, + "compare-versions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "concat-stream": { @@ -3710,6 +4166,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "del": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", @@ -3759,6 +4221,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -3809,6 +4280,35 @@ "tmp": "^0.0.29" } }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "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.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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 + } + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -3839,6 +4339,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -3922,6 +4431,15 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3932,15 +4450,15 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -4125,6 +4643,12 @@ } } }, + "ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -4161,6 +4685,23 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "is2": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz", + "integrity": "sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "ip-regex": "^4.1.0", + "is-url": "^1.2.4" + } + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -4355,9 +4896,9 @@ } }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -4514,6 +5055,12 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -4541,6 +5088,12 @@ "pinkie": "^2.0.0" } }, + "prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true + }, "prettyjson": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.1.tgz", @@ -4580,12 +5133,28 @@ "yargs": "^15.3.1" } }, + "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 + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "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" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -4721,20 +5290,12 @@ "dev": true }, "rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "requires": { - "tslib": "^1.9.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", - "dev": true - } + "tslib": "^2.1.0" } }, "safe-buffer": { @@ -4942,6 +5503,33 @@ } } }, + "tcp-port-used": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz", + "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==", + "dev": true, + "requires": { + "debug": "4.3.1", + "is2": "^2.0.6" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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 + } + } + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -4968,9 +5556,9 @@ } }, "tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, "tunnel-agent": { @@ -5050,12 +5638,12 @@ } }, "webdriver-manager": { - "version": "12.1.8", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.8.tgz", - "integrity": "sha512-qJR36SXG2VwKugPcdwhaqcLQOD7r8P2Xiv9sfNbfZrKBnX243iAkOueX1yAmeNgIKhJ3YAT/F2gq6IiEZzahsg==", + "version": "12.1.9", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.9.tgz", + "integrity": "sha512-Yl113uKm8z4m/KMUVWHq1Sjtla2uxEBtx2Ue3AmIlnlPAKloDn/Lvmy6pqWCUersVISpdMeVpAaGbNnvMuT2LQ==", "dev": true, "requires": { - "adm-zip": "^0.4.9", + "adm-zip": "^0.5.2", "chalk": "^1.1.1", "del": "^2.2.0", "glob": "^7.0.3", @@ -5262,12 +5850,25 @@ "decamelize": "^1.2.0" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "zone.js": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", - "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.12.0.tgz", + "integrity": "sha512-XtC+I5dXU14HrzidAKBNMqneIVUykLEAA1x+v4KVrd6AUPWlwYORF8KgsVqvgdHiKZ4BkxxjvYi/ksEixTPR0Q==", "dev": true, - "peer": true + "peer": true, + "requires": { + "tslib": "^2.3.0" + } } } } diff --git a/package.json b/package.json index c1118be..8c3ab76 100644 --- a/package.json +++ b/package.json @@ -6,24 +6,25 @@ "bin": "./bin/hot-perf", "private": true, "devDependencies": { - "@angular/benchpress": "^0.2.1", + "@angular/benchpress": "^0.3.0", "@hapi/hapi": "^19.2.0", "@hapi/inert": "^6.0.1", "@hapi/vision": "^6.0.0", "axios": "^0.19.2", "caporal": "^1.4.0", + "chromedriver": "^117.0.3", "fs-extra": "^9.0.1", "handlebars": "^4.7.6", "mongodb": "^3.6.0", + "prettier": "3.0.3", "protractor": "^7.0.0", - "rxjs": "^6.6.2", - "semver": "^7.3.2", - "webdriver-manager": "^12.1.8" + "rxjs": "^7.8.1", + "semver": "^7.3.2" }, "scripts": { "start": "./bin/hot-perf run", "serve": "./bin/hot-perf local-server benchmark-viewer", - "postinstall": "webdriver-manager update && webdriver-manager update --versions.chrome 105.0.5195.52 && chmod +x bin/hot-perf" + "postinstall": "chmod +x bin/hot-perf" }, "repository": { "type": "git", diff --git a/protractor.conf.js b/protractor.conf.js index 8477560..7d21d37 100644 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -1,18 +1,23 @@ -const path = require('path'); +const path = require("path"); const USE_HEADLESS_MODE = false; const CPU_THROTTLE_RATE = process.env.CPU_THROTTLE_RATE; exports.config = { directConnect: true, - chromeDriver: path.resolve('./node_modules/webdriver-manager/selenium/chromedriver_105.0.5195.52'), - + chromeDriver: path.resolve("./node_modules/chromedriver/bin/chromedriver"), + // SELENIUM_PROMISE_MANAGER: false, capabilities: { - browserName: 'chrome', + browserName: "chrome", chromeOptions: { - 'args': ['--js-flags=--expose-gc', '--window-size=1300,1000', ...(USE_HEADLESS_MODE ? ['--headless', '--disable-gpu'] : []) ], - 'perfLoggingPrefs': { - 'traceCategories': 'v8,blink.console,devtools.timeline,devtools.timeline.frame,blink.user_timing' + args: [ + "--js-flags=--expose-gc", + "--window-size=1300,1000", + ...(USE_HEADLESS_MODE ? ["--headless", "--disable-gpu"] : []), + ], + perfLoggingPrefs: { + traceCategories: + "v8,blink.console,devtools.timeline,devtools.timeline.frame,blink.user_timing", }, // 'mobileEmulation': { // 'deviceMetrics': { @@ -23,24 +28,24 @@ exports.config = { // } }, loggingPrefs: { - performance: 'ALL', - browser: 'ALL', - driver: 'ALL', + performance: "ALL", + browser: "ALL", + driver: "ALL", }, }, - specs: ['test/config.js', 'test/spec/**/*.spec.js'], + specs: ["test/spec/**/*.spec.js"], // specs: ['test/config.js', 'test/spec/arrow-keys-navigation.spec.js', 'test/spec/editing.spec.js'], // specs: ['test/config.js', 'test/spec/arrow-keys-navigation.spec.js'], // specs: ['test/config.js', 'test/spec/editing.spec.js'], // specs: ['test/config.js', 'test/spec/altering.spec.js'], // specs: ['test/config.js', 'test/spec/view-scrolling.spec.js'], - framework: 'jasmine2', + framework: "jasmine2", - onPrepare: function() { + onPrepare: function () { patchProtractorWait(browser); - beforeEach(function() { + beforeEach(function () { patchProtractorWait(browser); }); }, @@ -50,8 +55,9 @@ exports.config = { jasmineNodeOpts: { showColors: true, - defaultTimeoutInterval: 1200000 - } + // 5 minute timeout + defaultTimeoutInterval: 300000, + }, }; function patchProtractorWait(browser) { @@ -59,8 +65,8 @@ function patchProtractorWait(browser) { browser.ignoreSynchronization = true; if (CPU_THROTTLE_RATE) { - browser.driver.sendChromiumCommand('Emulation.setCPUThrottlingRate', { - rate: parseInt(CPU_THROTTLE_RATE, 10) + browser.driver.sendChromiumCommand("Emulation.setCPUThrottlingRate", { + rate: parseInt(CPU_THROTTLE_RATE, 10), }); } diff --git a/test/config.js b/test/config.js index d913ac1..a249a49 100644 --- a/test/config.js +++ b/test/config.js @@ -1,7 +1,7 @@ const origIt = global.it; -global.it = function(name, cb) { - origIt.call(this, name, function(done) { +global.it = function (name, cb) { + origIt.call(this, name, function (done) { cb().then(done, done.fail); }); -} +}; diff --git a/test/runner.js b/test/runner.js index 569cf58..437dfc4 100644 --- a/test/runner.js +++ b/test/runner.js @@ -1,51 +1,57 @@ -const config = require('./../lib/config'); -const benchpress = require('@angular/benchpress'); -const fs = require('fs-extra'); -const path = require('path'); +const config = require("./../lib/config"); const HOT_VERSION = process.env.HOT_VERSION; exports.SAMPLE_SIZE = config.SAMPLE_SIZE; -const bindings = [ - benchpress.SeleniumWebDriverAdapter.PROTRACTOR_PROVIDERS, - // { provide: benchpress.Options.FORCE_GC, useValue: true }, - { provide: benchpress.RegressionSlopeValidator.SAMPLE_SIZE, useValue: config.SAMPLE_SIZE }, - benchpress.JsonFileReporter.PROVIDERS, - benchpress.MultiReporter.provideWith([ - benchpress.ConsoleReporter, - benchpress.JsonFileReporter - ]), -]; - -benchpress.Options.DEFAULT_PROVIDERS.push({ - provide: benchpress.Options.WRITE_FILE, - useValue: (filename, content) => void process.send(content), -}); - -const runner = new benchpress.Runner(bindings); - -exports.runSample = async function(config) { - config.providers = [{ - provide: benchpress.Options.SAMPLE_DESCRIPTION, - useValue: { hotVersion: HOT_VERSION } - }]; +exports.runSample = async function (benchpressConfig) { + const benchpress = await import("@angular/benchpress"); + + const bindings = [ + benchpress.SeleniumWebDriverAdapter.PROTRACTOR_PROVIDERS, + // { provide: benchpress.Options.FORCE_GC, useValue: true }, + { + provide: benchpress.RegressionSlopeValidator.SAMPLE_SIZE, + useValue: benchpressConfig.SAMPLE_SIZE ?? config.SAMPLE_SIZE, + }, + benchpress.JsonFileReporter.PROVIDERS, + benchpress.MultiReporter.provideWith([ + benchpress.ConsoleReporter, + benchpress.JsonFileReporter, + ]), + ]; + + benchpress.Options.DEFAULT_PROVIDERS.push({ + provide: benchpress.Options.WRITE_FILE, + useValue: (filename, content) => void process.send(content), + }); + + const runner = new benchpress.Runner(bindings); + + benchpressConfig.providers = [ + { + provide: benchpress.Options.SAMPLE_DESCRIPTION, + useValue: { hotVersion: HOT_VERSION }, + }, + ]; return new Promise((resolve) => { - setTimeout(() => resolve(runner.sample(config)), 50); + setTimeout(() => resolve(runner.sample(benchpressConfig)), 50); }); -} +}; -exports.openPage = async function(hotSettings) { +exports.openPage = async function (hotSettings) { const urlParams = []; hotSettings = hotSettings || {}; Object.keys(hotSettings).forEach((paramName) => { - urlParams.push(paramName + '=' + hotSettings[paramName]); + urlParams.push(paramName + "=" + hotSettings[paramName]); }); - const url = `http://${config.SERVER_HOST}:${config.SERVER_PORT}?${urlParams.join('&')}`; + const url = `http://${config.SERVER_HOST}:${ + config.SERVER_PORT + }?${urlParams.join("&")}`; return new Promise((resolve) => { browser.get(encodeURI(url)); @@ -53,4 +59,4 @@ exports.openPage = async function(hotSettings) { // setTimeout(() => resolve(url), 500); resolve(url); }); -} +}; diff --git a/test/spec/altering.spec.js b/test/spec/altering.spec.js index c7adf20..fd8e7f5 100644 --- a/test/spec/altering.spec.js +++ b/test/spec/altering.spec.js @@ -1,39 +1,41 @@ -const { runSample, openPage } = require('./../runner'); -const { waitUntilHotIsInitialized, sleep } = require('./../utils'); +const { runSample, openPage } = require("./../runner"); +const { waitUntilHotIsInitialized, sleep } = require("./../utils"); -describe('altering a table', () => { - it('started creating row', async () => { +describe("altering a table", () => { + it("started creating row", async () => { await openPage(); await waitUntilHotIsInitialized(); await runSample({ - id: 'altering.creating-row-top', + id: "altering.creating-row-top", execute: () => { - browser.executeScript(`hot.alter('insert_row', 1, 5)`); + browser.executeScript(`hot.alter('insert_row_above', 1, 5)`); }, }); }); - it('started creating column', async () => { + it("started creating column", async () => { await openPage(); await waitUntilHotIsInitialized(); await runSample({ - id: 'altering.creating-column-top', + id: "altering.creating-column-top", execute: () => { - browser.executeScript(`hot.alter('insert_col', 1, 5)`); + browser.executeScript(`hot.alter('insert_col_start', 1, 5)`); }, }); }); - it('started loading new data', async () => { + it("started loading new data", async () => { await openPage(); await waitUntilHotIsInitialized(); await runSample({ - id: 'altering.loading-data', + id: "altering.loading-data", execute: () => { - browser.executeScript(`hot.loadData(Handsontable.helper.createSpreadsheetData(400, 100))`); + browser.executeScript( + `hot.loadData(Handsontable.helper.createSpreadsheetData(400, 100))`, + ); }, }); }); diff --git a/test/spec/arrow-keys-navigation.spec.js b/test/spec/arrow-keys-navigation.spec.js index e9170ad..8df1845 100644 --- a/test/spec/arrow-keys-navigation.spec.js +++ b/test/spec/arrow-keys-navigation.spec.js @@ -1,25 +1,23 @@ -const { runSample, openPage, SAMPLE_SIZE } = require('./../runner'); -const { waitUntilHotIsInitialized, sleep } = require('./../utils'); +const { runSample, openPage, SAMPLE_SIZE } = require("./../runner"); +const { waitUntilHotIsInitialized, sleep } = require("./../utils"); -describe('navigating by arrow key', () => { - describe('arrow down', () => { - it('started from the most top-left position', async () => { +describe("navigating by arrow key", () => { + describe("arrow down", () => { + it("started from the most top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); - browser.executeScript('hot.selectCell(25, 0)'); + browser.executeScript("hot.selectCell(25, 0)"); await runSample({ - id: 'arrow-down.most-top-left', + id: "arrow-down.most-top-left", execute: () => { - browser.actions() - .sendKeys(protractor.Key.ARROW_DOWN) - .perform(); + browser.actions().sendKeys(protractor.Key.ARROW_DOWN).perform(); }, }); }); - it('started from the middle position', async () => { + it("started from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -28,18 +26,16 @@ describe('navigating by arrow key', () => { `); await runSample({ - id: 'arrow-down.middle', + id: "arrow-down.middle", execute: () => { - browser.actions() - .sendKeys(protractor.Key.ARROW_DOWN) - .perform(); + browser.actions().sendKeys(protractor.Key.ARROW_DOWN).perform(); }, }); }); }); - describe('arrow up', () => { - it('started from the most bottom-right position', async () => { + describe("arrow up", () => { + it("started from the most bottom-right position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -52,18 +48,16 @@ describe('navigating by arrow key', () => { `); await runSample({ - id: 'arrow-up.most-bottom-right', + id: "arrow-up.most-bottom-right", execute: () => { - browser.actions() - .sendKeys(protractor.Key.ARROW_UP) - .perform(); + browser.actions().sendKeys(protractor.Key.ARROW_UP).perform(); }, }); }); }); - describe('arrow right', () => { - it('started from the most top-left position', async () => { + describe("arrow right", () => { + it("started from the most top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -72,16 +66,14 @@ describe('navigating by arrow key', () => { `); await runSample({ - id: 'arrow-right.most-top-left', + id: "arrow-right.most-top-left", execute: () => { - browser.actions() - .sendKeys(protractor.Key.ARROW_RIGHT) - .perform(); + browser.actions().sendKeys(protractor.Key.ARROW_RIGHT).perform(); }, }); }); - it('started from the middle position', async () => { + it("started from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -90,18 +82,16 @@ describe('navigating by arrow key', () => { `); await runSample({ - id: 'arrow-right.middle', + id: "arrow-right.middle", execute: () => { - browser.actions() - .sendKeys(protractor.Key.ARROW_RIGHT) - .perform(); + browser.actions().sendKeys(protractor.Key.ARROW_RIGHT).perform(); }, }); }); }); - describe('arrow left', () => { - it('started from the most bottom-right position', async () => { + describe("arrow left", () => { + it("started from the most bottom-right position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -114,18 +104,16 @@ describe('navigating by arrow key', () => { `); await runSample({ - id: 'arrow-left.most-bottom-right', + id: "arrow-left.most-bottom-right", execute: () => { - browser.actions() - .sendKeys(protractor.Key.ARROW_LEFT) - .perform(); + browser.actions().sendKeys(protractor.Key.ARROW_LEFT).perform(); }, }); }); }); - describe('arrow down and arrow up', () => { - it('started from the middle position and back to the initial position', async () => { + describe("arrow down and arrow up", () => { + it("started from the middle position and back to the initial position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -137,50 +125,40 @@ describe('navigating by arrow key', () => { let currentSampleSize = 0; await runSample({ - id: 'arrow-down-up.middle', + id: "arrow-down-up.middle", execute: () => { if (currentSampleSize > sampleSize / 2) { - browser.actions() - .sendKeys(protractor.Key.ARROW_UP) - .perform(); - browser.actions() - .sendKeys(protractor.Key.ARROW_UP) - .perform(); + browser.actions().sendKeys(protractor.Key.ARROW_UP).perform(); + browser.actions().sendKeys(protractor.Key.ARROW_UP).perform(); } else { - browser.actions() - .sendKeys(protractor.Key.ARROW_DOWN) - .perform(); - browser.actions() - .sendKeys(protractor.Key.ARROW_DOWN) - .perform(); + browser.actions().sendKeys(protractor.Key.ARROW_DOWN).perform(); + browser.actions().sendKeys(protractor.Key.ARROW_DOWN).perform(); } - currentSampleSize ++; + currentSampleSize++; }, }); }); }); - describe('page down', () => { - it('started from the most top-left position', async () => { + describe("page down", () => { + it("started from the most top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); - browser.executeScript('hot.selectCell(0, 0)'); + browser.executeScript("hot.selectCell(0, 0)"); await runSample({ - id: 'page-down.most-top-left', + id: "page-down.most-top-left", execute: () => { - browser.actions() - .sendKeys(protractor.Key.PAGE_DOWN) - .perform(); + browser.actions().sendKeys(protractor.Key.PAGE_DOWN).perform(); }, }); }); }); - describe('page down and page up', () => { - it('started from the middle position and back to the initial position', async () => { + describe("page down and page up", () => { + it("started from the middle position and back to the initial position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -190,19 +168,15 @@ describe('navigating by arrow key', () => { let currentSampleSize = 0; await runSample({ - id: 'page-down-up.most-top-left', + id: "page-down-up.most-top-left", execute: () => { if (currentSampleSize > sampleSize / 2) { - browser.actions() - .sendKeys(protractor.Key.PAGE_UP) - .perform(); + browser.actions().sendKeys(protractor.Key.PAGE_UP).perform(); } else { - browser.actions() - .sendKeys(protractor.Key.PAGE_DOWN) - .perform(); + browser.actions().sendKeys(protractor.Key.PAGE_DOWN).perform(); } - currentSampleSize ++; + currentSampleSize++; }, }); }); diff --git a/test/spec/editing.spec.js b/test/spec/editing.spec.js index 5d546e7..2fa9860 100644 --- a/test/spec/editing.spec.js +++ b/test/spec/editing.spec.js @@ -1,8 +1,8 @@ -const { runSample, openPage } = require('./../runner'); -const { waitUntilHotIsInitialized, sleep } = require('./../utils'); +const { runSample, openPage } = require("./../runner"); +const { waitUntilHotIsInitialized, sleep } = require("./../utils"); -describe('editing a cell', () => { - it('started from the most top-left position', async () => { +describe("editing a cell", () => { + it("started from the most top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -12,16 +12,14 @@ describe('editing a cell', () => { `); await runSample({ - id: 'editing-cell.most-top-left', + id: "editing-cell.most-top-left", execute: () => { - browser.actions() - .sendKeys(protractor.Key.ENTER) - .perform(); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); }, }); }); - it('started from the middle position', async () => { + it("started from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -34,16 +32,14 @@ describe('editing a cell', () => { `); await runSample({ - id: 'editing-cell.middle', + id: "editing-cell.middle", execute: () => { - browser.actions() - .sendKeys(protractor.Key.ENTER) - .perform(); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); }, }); }); - it('started from the bottom-right position', async () => { + it("started from the bottom-right position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -56,9 +52,10 @@ describe('editing a cell', () => { `); await runSample({ - id: 'editing-cell.bottom-right', + id: "editing-cell.bottom-right", execute: () => { - browser.actions() + browser + .actions() .sendKeys(protractor.Key.ENTER) .sendKeys(protractor.Key.SHIFT) .perform(); diff --git a/test/spec/view-scrolling.spec.js b/test/spec/view-scrolling.spec.js index cd339a1..df4e513 100644 --- a/test/spec/view-scrolling.spec.js +++ b/test/spec/view-scrolling.spec.js @@ -1,31 +1,33 @@ -const { runSample, openPage } = require('./../runner'); -const { waitUntilHotIsInitialized, sleep } = require('./../utils'); +const { runSample, openPage } = require("./../runner"); +const { waitUntilHotIsInitialized, sleep } = require("./../utils"); const SCROLL_STEP = 50; -const wtHolderInjection = (overlay = 'master', scrollType) => ` +const wtHolderInjection = (overlay = "master", scrollType) => ` window.wtHolder = document.querySelector('.ht_${overlay} .wtHolder'); window.step = document.querySelector('.ht_master .wtHolder').${scrollType}; `; -describe('navigating by scroll', () => { - describe('master table', () => { - it('scroll down starting from the most top-left position', async () => { +describe("navigating by scroll", () => { + describe("master table", () => { + it("scroll down starting from the most top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); browser.executeScript(` - ${wtHolderInjection('master', 'scrollTop')} + ${wtHolderInjection("master", "scrollTop")} `); await runSample({ - id: 'scroll-down.master.most-top-left', + id: "scroll-down.master.most-top-left", execute: () => { - browser.executeScript(`wtHolder.scrollTop = (step = step + ${SCROLL_STEP});`); + browser.executeScript( + `wtHolder.scrollTop = (step = step + ${SCROLL_STEP});`, + ); }, }); }); - xit('scroll down starting from the middle position', async () => { + xit("scroll down starting from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -34,34 +36,38 @@ describe('navigating by scroll', () => { var __cols = parseInt(hot.countCols() / 2, 10); hot.selectCell(__rows, __cols); - ${wtHolderInjection('master', 'scrollTop')} + ${wtHolderInjection("master", "scrollTop")} `); await runSample({ - id: 'scroll-down.master.middle', + id: "scroll-down.master.middle", execute: () => { - browser.executeScript(`wtHolder.scrollTop = (step = step + ${SCROLL_STEP});`); + browser.executeScript( + `wtHolder.scrollTop = (step = step + ${SCROLL_STEP});`, + ); }, }); }); - it('scroll right starting from the top-left position', async () => { + it("scroll right starting from the top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); browser.executeScript(` - ${wtHolderInjection('master', 'scrollLeft')} + ${wtHolderInjection("master", "scrollLeft")} `); await runSample({ - id: 'scroll-right.master.top-left', + id: "scroll-right.master.top-left", execute: () => { - browser.executeScript(`wtHolder.scrollLeft = (step = step + ${SCROLL_STEP});`); + browser.executeScript( + `wtHolder.scrollLeft = (step = step + ${SCROLL_STEP});`, + ); }, }); }); - xit('scroll right starting from the middle position', async () => { + xit("scroll right starting from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -70,37 +76,43 @@ describe('navigating by scroll', () => { var __cols = parseInt(hot.countCols() / 2, 10); hot.selectCell(__rows, __cols); - ${wtHolderInjection('master', 'scrollLeft')} + ${wtHolderInjection("master", "scrollLeft")} `); await runSample({ - id: 'scroll-right.master.middle', + id: "scroll-right.master.middle", execute: () => { - browser.executeScript(`wtHolder.scrollLeft = (step = step + ${SCROLL_STEP});`); + browser.executeScript( + `wtHolder.scrollLeft = (step = step + ${SCROLL_STEP});`, + ); }, }); }); }); - xdescribe('top overlay', () => { - it('scroll down starting from the most top-left position', async () => { + xdescribe("top overlay", () => { + it("scroll down starting from the most top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); browser.executeScript(` hot.selectCell(20, 20); - ${wtHolderInjection('clone_top', 'scrollTop')} + ${wtHolderInjection("clone_top", "scrollTop")} `); await runSample({ - id: 'scroll-down.top-overlay.most-top-left', + id: "scroll-down.top-overlay.most-top-left", execute: () => { - browser.executeScript(`wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaY': ${SCROLL_STEP / 2.5}, 'deltaMode': 0}));`); + browser.executeScript( + `wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaY': ${ + SCROLL_STEP / 2.5 + }, 'deltaMode': 0}));`, + ); }, }); }); - it('scroll down starting from the middle position', async () => { + it("scroll down starting from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -109,35 +121,43 @@ describe('navigating by scroll', () => { var __cols = parseInt(hot.countCols() / 2, 10); hot.selectCell(__rows, __cols); - ${wtHolderInjection('clone_top', 'scrollTop')} + ${wtHolderInjection("clone_top", "scrollTop")} `); await runSample({ - id: 'scroll-down.top-overlay.middle', + id: "scroll-down.top-overlay.middle", execute: () => { - browser.executeScript(`wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaY': ${SCROLL_STEP / 2.5}, 'deltaMode': 0}));`); + browser.executeScript( + `wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaY': ${ + SCROLL_STEP / 2.5 + }, 'deltaMode': 0}));`, + ); }, }); }); - it('scroll right starting from the top-left position', async () => { + it("scroll right starting from the top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); browser.executeScript(` hot.selectCell(20, 20); - ${wtHolderInjection('clone_top', 'scrollLeft')} + ${wtHolderInjection("clone_top", "scrollLeft")} `); await runSample({ - id: 'scroll-right.top-overlay.top-left', + id: "scroll-right.top-overlay.top-left", execute: () => { - browser.executeScript(`wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaX': ${SCROLL_STEP / 2.5}, 'deltaMode': 0}));`); + browser.executeScript( + `wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaX': ${ + SCROLL_STEP / 2.5 + }, 'deltaMode': 0}));`, + ); }, }); }); - it('scroll right starting from the middle position', async () => { + it("scroll right starting from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -146,37 +166,45 @@ describe('navigating by scroll', () => { var __cols = parseInt(hot.countCols() / 2, 10); hot.selectCell(__rows, __cols); - ${wtHolderInjection('clone_top', 'scrollLeft')} + ${wtHolderInjection("clone_top", "scrollLeft")} `); await runSample({ - id: 'scroll-right.top-overlay.top-left', + id: "scroll-right.top-overlay.top-left", execute: () => { - browser.executeScript(`wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaX': ${SCROLL_STEP / 2.5}, 'deltaMode': 0}));`); + browser.executeScript( + `wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaX': ${ + SCROLL_STEP / 2.5 + }, 'deltaMode': 0}));`, + ); }, }); }); }); - xdescribe('left overlay', () => { - it('scroll down starting from the most top-left position', async () => { + xdescribe("left overlay", () => { + it("scroll down starting from the most top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); browser.executeScript(` hot.selectCell(20, 20); - ${wtHolderInjection('clone_left', 'scrollTop')} + ${wtHolderInjection("clone_left", "scrollTop")} `); await runSample({ - id: 'scroll-down.left-overlay.most-top-left', + id: "scroll-down.left-overlay.most-top-left", execute: () => { - browser.executeScript(`wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaY': ${SCROLL_STEP / 2.5}, 'deltaMode': 0}));`); + browser.executeScript( + `wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaY': ${ + SCROLL_STEP / 2.5 + }, 'deltaMode': 0}));`, + ); }, }); }); - it('scroll down starting from the middle position', async () => { + it("scroll down starting from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -185,35 +213,43 @@ describe('navigating by scroll', () => { var __cols = parseInt(hot.countCols() / 2, 10); hot.selectCell(__rows, __cols); - ${wtHolderInjection('clone_left', 'scrollTop')} + ${wtHolderInjection("clone_left", "scrollTop")} `); await runSample({ - id: 'scroll-down.left-overlay.most-top-left', + id: "scroll-down.left-overlay.most-top-left", execute: () => { - browser.executeScript(`wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaY': ${SCROLL_STEP / 2.5}, 'deltaMode': 0}));`); + browser.executeScript( + `wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaY': ${ + SCROLL_STEP / 2.5 + }, 'deltaMode': 0}));`, + ); }, }); }); - it('scroll right starting from the top-left position', async () => { + it("scroll right starting from the top-left position", async () => { await openPage(); await waitUntilHotIsInitialized(); browser.executeScript(` hot.selectCell(20, 20); - ${wtHolderInjection('clone_left', 'scrollLeft')} + ${wtHolderInjection("clone_left", "scrollLeft")} `); await runSample({ - id: 'scroll-right.left-overlay.most-top-left', + id: "scroll-right.left-overlay.most-top-left", execute: () => { - browser.executeScript(`wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaX': ${SCROLL_STEP / 2.5}, 'deltaMode': 0}));`); + browser.executeScript( + `wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaX': ${ + SCROLL_STEP / 2.5 + }, 'deltaMode': 0}));`, + ); }, }); }); - it('scroll right starting from the middle position', async () => { + it("scroll right starting from the middle position", async () => { await openPage(); await waitUntilHotIsInitialized(); @@ -222,13 +258,17 @@ describe('navigating by scroll', () => { var __cols = parseInt(hot.countCols() / 2, 10); hot.selectCell(__rows, __cols); - ${wtHolderInjection('clone_left', 'scrollLeft')} + ${wtHolderInjection("clone_left", "scrollLeft")} `); await runSample({ - id: 'scroll-right.left-overlay.middle', + id: "scroll-right.left-overlay.middle", execute: () => { - browser.executeScript(`wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaX': ${SCROLL_STEP / 2.5}, 'deltaMode': 0}));`); + browser.executeScript( + `wtHolder.dispatchEvent(new WheelEvent('wheel', {'deltaX': ${ + SCROLL_STEP / 2.5 + }, 'deltaMode': 0}));`, + ); }, }); }); diff --git a/test/utils.js b/test/utils.js index 4f753d6..212afdd 100644 --- a/test/utils.js +++ b/test/utils.js @@ -1,13 +1,13 @@ -module.exports.waitUntilHotIsInitialized = async function() { +module.exports.waitUntilHotIsInitialized = async function () { return await browser.controlFlow().wait(async () => { const title = await browser.driver.getTitle(); - return title === 'ready'; + return title === "ready"; }, 5000); -} +}; -module.exports.sleep = async function(delay = 1000) { +module.exports.sleep = async function (delay = 1000) { return new Promise((r) => { - setTimeout(() => r(), delay) - }) -} + setTimeout(() => r(), delay); + }); +};