diff --git a/CHANGELOG.md b/CHANGELOG.md index 276c5588..9a46451d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +0.9.1 / 2018-07-04 +================== + + * Webworker module and assertions + * Bug with request mocks remove and override fixed + * Logo link fixed in readme + 0.9.0 / 2018-06-24 ================== diff --git a/README.md b/README.md index 2437c2e4..7ef4c571 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Wendigo - + _by @angrykoala_ @@ -44,6 +44,7 @@ await browser.assert.text("#my-modal", "Button Clicked"); * [Console](#console) * [LocalStorage](#localstorage) * [Requests](#requests) + * [Webworkers](#webworkers) * [Errors](#errors) * [Examples](#examples) * [Development](#development) @@ -631,6 +632,17 @@ await browser.assert.console({ }); ``` +**webworker(options, msg?)** +Assert that at least one webworker is running, the following options can be passes: +* `url`: Matches only the webworkers with given url +* `count`: Matches exactly the given number of webworkers running. + +```js +await browser.assert.webworker({url: "foo.js"}); // At least one webworker with given url running +await browser.assert.webworker(); // at least one webworker running +await browser.assert.webworker({count: 0}); // No webworkers running +``` + ### Negative assertions Most of the browser assertions have a negative version that can be used with `browser.assert.not`. Most of the "not" assertions are simply the inverse of the positive version. @@ -1129,6 +1141,18 @@ await browser.assert.request.method("POST").url("localhost:8000/api"); > Negative assertions are not supported for requests +## Webworkers +The webworkers module allows to retrieve all the webworkers in the current page: + +**all()** +Returns all the webworkers currently executing in the page. Each webworker will have the following properties: + +* _url_: Returns the webworker file url +* _worker_: Returns the [Puppeteer's Worker instance](https://pptr.dev/#?product=Puppeteer&version=v1.5.0&show=api-class-worker) + + + + ## Errors Wendigo errors can be accessed through `Wendigo.Errors`. These Errors will be thrown by Wendigo browser: diff --git a/lib/browser_core.js b/lib/browser_core.js index 783dfde8..2be15b69 100644 --- a/lib/browser_core.js +++ b/lib/browser_core.js @@ -3,7 +3,7 @@ const path = require('path'); const ErrorFactory = require('./errors/error_factory'); const config = require('../config'); -const DomElement = require('./dom_element'); +const DomElement = require('./models/dom_element'); const injectionScriptsPath = config.injectionScripts.path; const injectionScripts = config.injectionScripts.files; diff --git a/lib/mixins/browser_actions.js b/lib/mixins/browser_actions.js index 3ea89a23..3fdccae3 100644 --- a/lib/mixins/browser_actions.js +++ b/lib/mixins/browser_actions.js @@ -2,7 +2,7 @@ "use strict"; const ErrorFactory = require('../errors/error_factory'); -const DomElement = require('../dom_element'); +const DomElement = require('../models/dom_element'); const utils = require('../utils'); module.exports = function BrowserActionsMixin(s) { diff --git a/lib/mixins/browser_queries.js b/lib/mixins/browser_queries.js index 4d14cf52..17d0e89c 100644 --- a/lib/mixins/browser_queries.js +++ b/lib/mixins/browser_queries.js @@ -1,6 +1,6 @@ "use strict"; -const DomElement = require('../dom_element'); +const DomElement = require('../models/dom_element'); const ErrorFactory = require('../errors/error_factory'); module.exports = function BrowserQueriesMixin(s) { diff --git a/lib/dom_element.js b/lib/models/dom_element.js similarity index 100% rename from lib/dom_element.js rename to lib/models/dom_element.js diff --git a/lib/models/request_mock.js b/lib/models/request_mock.js new file mode 100644 index 00000000..e6cbbf2c --- /dev/null +++ b/lib/models/request_mock.js @@ -0,0 +1,95 @@ +"use strict"; + +const EventEmitter = require('events'); +const URL = require('url').URL; + +const ErrorFactory = require('../errors/error_factory'); +const utils = require('../utils'); + + +module.exports = class RequestMock { + constructor(url, options) { + this._setURL(url); + this._response = { + status: options.status, + headers: options.headers, + contentType: options.contentType, + body: this._processBody(options.body) + }; + this.delay = options.delay || 0; + this.method = options.method; + if(options.queryString || typeof options.queryString === "string") this.queryString = utils.parseQueryString(options.queryString); + this._auto = options.auto !== false; + this._timesCalled = 0; + this._events = new EventEmitter(); + } + + get called() { + return this._timesCalled > 0; + } + + get timesCalled() { + return this._timesCalled; + } + + get response() { + return this._response; + } + + get assert() { + return { + called: this._assertCalled.bind(this) + }; + } + + get immediate() { + return this.delay === 0; + } + + get auto() { + return this._auto; + } + + onTrigger(cb) { + this._events.once("respond", cb); + } + + trigger() { + if(this.auto) throw ErrorFactory.generateFatalError(`Cannot trigger auto request mock.`); + this._events.emit("respond"); + } + + increaseCalled() { + this._timesCalled++; + } + + _assertCalled(times, msg) { + if(typeof times === 'number') { + if(times !== this._timesCalled) { + if(!msg) msg = `Mock of ${this.url} not called ${times} times.`; + throw ErrorFactory.generateAssertionError(msg, this._timesCalled, times); + } + } else if(!this.called) { + if(!msg) msg = `Mock of ${this.url} not called.`; + throw ErrorFactory.generateAssertionError(msg); + } + } + + _processBody(rawBody) { + if(typeof rawBody === "object") { + return JSON.stringify(rawBody); + } else return rawBody; + } + + _setURL(url) { + if(url instanceof RegExp) { + this.url = url; + } else { + url = new URL(url); + this.url = `${url.origin}${url.pathname}`; + if(url.search) { + this.queryString = utils.parseQueryString(url); + } + } + } +}; diff --git a/lib/models/webworker.js b/lib/models/webworker.js new file mode 100644 index 00000000..67663885 --- /dev/null +++ b/lib/models/webworker.js @@ -0,0 +1,11 @@ +"use strict"; + +module.exports = class WebWoker { + constructor(ww) { + this.worker = ww; + } + + get url() { + return this.worker.url(); + } +}; diff --git a/lib/modules/assertions/browser_assertions.js b/lib/modules/assertions/browser_assertions.js index 1b77321d..9be5ea36 100644 --- a/lib/modules/assertions/browser_assertions.js +++ b/lib/modules/assertions/browser_assertions.js @@ -356,6 +356,31 @@ module.exports = class BrowserAssertions extends BrowserModule { } /* eslint-enable complexity */ + /* eslint-disable complexity */ + webworker(options, msg) { + if(!options) options = {}; + let workers = this._browser.webworkers.all(); + let urlMsg = ""; + if(options.url) { + urlMsg = ` with url "${options.url}"`; + workers = workers.filter((w) => { + return w.url === options.url; + }); + } + if(options.count !== undefined) { + if(workers.length !== options.count) { + if(!msg) msg = `Expected ${options.count} webworkers running${urlMsg}, ${workers.length} found.`; + return assertUtils.rejectAssertion(msg); + } + } else { + if(workers.length === 0) { + if(!msg) msg = `Expected at least 1 webworker running${urlMsg}, 0 found.`; + return assertUtils.rejectAssertion(msg); + } + } + } + /* eslint-enable complexity */ + }; /* eslint-enable max-lines */ diff --git a/lib/modules/browser_webworkers.js b/lib/modules/browser_webworkers.js new file mode 100644 index 00000000..77981e2f --- /dev/null +++ b/lib/modules/browser_webworkers.js @@ -0,0 +1,17 @@ +"use strict"; + +const BrowserModule = require('./browser_module'); +const WebWorker = require('../models/webworker'); + +module.exports = class BrowserWebWorkers extends BrowserModule { + constructor(browser) { + super(browser); + } + + all() { + return this._browser.page.workers().map((ww) => { + return new WebWorker(ww); + }); + } + +}; diff --git a/lib/request_mocker.js b/lib/request_mocker.js index 40cb53fc..c6f8cec2 100644 --- a/lib/request_mocker.js +++ b/lib/request_mocker.js @@ -1,108 +1,8 @@ "use strict"; -const EventEmitter = require('events'); const URL = require('url').URL; -const querystring = require('querystring'); - -const ErrorFactory = require('./errors/error_factory'); const utils = require('./utils'); - - -function parseQueryString(qs) { - if(typeof qs === 'string') { - return querystring.parse(qs); - } else if(qs instanceof URL) { - qs = qs.searchParams.toString(); - return querystring.parse(qs); - } else return qs; -} - -class RequestMock { - constructor(url, options) { - this._setURL(url); - this._response = { - status: options.status, - headers: options.headers, - contentType: options.contentType, - body: this._processBody(options.body) - }; - this.delay = options.delay || 0; - this.method = options.method; - if(options.queryString || typeof options.queryString === "string") this.queryString = parseQueryString(options.queryString); - this._auto = options.auto !== false; - this._timesCalled = 0; - this._events = new EventEmitter(); - } - - get called() { - return this._timesCalled > 0; - } - - get timesCalled() { - return this._timesCalled; - } - - get response() { - return this._response; - } - - get assert() { - return { - called: this._assertCalled.bind(this) - }; - } - - get immediate() { - return this.delay === 0; - } - - get auto() { - return this._auto; - } - - onTrigger(cb) { - this._events.once("respond", cb); - } - - trigger() { - if(this.auto) throw ErrorFactory.generateFatalError(`Cannot trigger auto request mock.`); - this._events.emit("respond"); - } - - increaseCalled() { - this._timesCalled++; - } - - _assertCalled(times, msg) { - if(typeof times === 'number') { - if(times !== this._timesCalled) { - if(!msg) msg = `Mock of ${this.url} not called ${times} times.`; - throw ErrorFactory.generateAssertionError(msg, this._timesCalled, times); - } - } else if(!this.called) { - if(!msg) msg = `Mock of ${this.url} not called.`; - throw ErrorFactory.generateAssertionError(msg); - } - } - - _processBody(rawBody) { - if(typeof rawBody === "object") { - return JSON.stringify(rawBody); - } else return rawBody; - } - - _setURL(url) { - if(url instanceof RegExp) { - this.url = url; - } else { - url = new URL(url); - this.url = `${url.origin}${url.pathname}`; - if(url.search) { - this.queryString = parseQueryString(url); - } - } - } -} +const RequestMock = require('./models/request_mock'); module.exports = class RequestMocker { @@ -115,7 +15,7 @@ module.exports = class RequestMocker { const method = request.method(); const mock = this._getMock(`${url.origin}${url.pathname}`, { method: method, - queryString: url.search ? parseQueryString(url) : undefined + queryString: url.search ? utils.parseQueryString(url) : undefined }); if(mock) { // TODO: move this to request ? mock.increaseCalled(); @@ -131,9 +31,9 @@ module.exports = class RequestMocker { return mock; } - removeMock(url, options) { + removeMock(url, options = {}) { this._mockedRequests = this._mockedRequests.filter((m) => { - return !this._matchMock(m, url, options); + return !(this._matchUrl(url, m.url) && this._matchOptions(m, options)); }); } @@ -161,12 +61,19 @@ module.exports = class RequestMocker { } _matchMock(mock, url, options) { - if(!utils.matchText(url, mock.url)) return false; - if(mock.method && options.method !== mock.method) return false; - if(mock.queryString && !utils.compareObjects(options.queryString, mock.queryString)) return false; + return this._matchUrl(url, mock.url) && this._matchOptions(options, mock); + } + + _matchOptions(options, expected) { + if(expected.method && options.method !== expected.method) return false; + if(expected.queryString && !utils.compareObjects(options.queryString, expected.queryString)) return false; return true; } + _matchUrl(url, expected) { + return utils.matchText(url, expected); + } + // Priority is: Method > URL > QueryString _hasHigherPriority(m1, m2) { const existsPriority = this._checkElementPriority(m1, m2); diff --git a/lib/utils.js b/lib/utils.js index 7c6d622b..e2a2a609 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,4 +1,7 @@ "use strict"; +const querystring = require('querystring'); +const URL = require('url').URL; + module.exports = { isNumber(n) { @@ -47,5 +50,14 @@ module.exports = { if(obj1[k] !== obj2[k]) return false; } return true; + }, + parseQueryString(qs) { + if(typeof qs === 'string') { + return querystring.parse(qs); + } else if(qs instanceof URL) { + qs = qs.searchParams.toString(); + return querystring.parse(qs); + } else return qs; } + }; diff --git a/lib/wendigo.js b/lib/wendigo.js index 0557351e..a67bd470 100644 --- a/lib/wendigo.js +++ b/lib/wendigo.js @@ -18,7 +18,8 @@ const components = { "cookies": require('./modules/browser_cookies'), "localStorage": require('./modules/browser_local_storage'), "requests": require('./modules/browser_requests'), - "console": require('./modules/browser_console') + "console": require('./modules/browser_console'), + "webworkers": require('./modules/browser_webworkers') }; const assertComponents = { diff --git a/logo/light.png b/logo/light.png new file mode 100644 index 00000000..4cc7d4de Binary files /dev/null and b/logo/light.png differ diff --git a/package-lock.json b/package-lock.json index cc1e8914..8f0b502b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "wendigo", - "version": "0.9.0", + "version": "0.9.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10,7 +10,7 @@ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "dev": true, "requires": { - "mime-types": "~2.1.18", + "mime-types": "2.1.18", "negotiator": "0.6.1" } }, @@ -26,7 +26,7 @@ "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", "dev": true, "requires": { - "acorn": "^5.0.3" + "acorn": "5.7.1" } }, "agent-base": { @@ -34,19 +34,19 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", "requires": { - "es6-promisify": "^5.0.0" + "es6-promisify": "5.0.0" } }, "ajv": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.1.tgz", - "integrity": "sha512-pgZos1vgOHDiC7gKNbZW8eKvCnNXARv2oqrGQT7Hzbq5Azp7aZG6DJzADnkuSq7RH6qkXp4J/m68yPX/2uBHyQ==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz", + "integrity": "sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.1" + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" } }, "ajv-keywords": { @@ -79,7 +79,7 @@ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "sprintf-js": "1.0.3" } }, "array-flatten": { @@ -94,7 +94,7 @@ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "^1.0.1" + "array-uniq": "1.0.3" } }, "array-uniq": { @@ -120,9 +120,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" }, "dependencies": { "chalk": { @@ -131,11 +131,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" } }, "strip-ansi": { @@ -144,7 +144,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } } } @@ -161,15 +161,15 @@ "dev": true, "requires": { "bytes": "3.0.0", - "content-type": "~1.0.4", + "content-type": "1.0.4", "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", + "depd": "1.1.2", + "http-errors": "1.6.3", "iconv-lite": "0.4.19", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "6.5.1", "raw-body": "2.3.2", - "type-is": "~1.6.15" + "type-is": "1.6.16" }, "dependencies": { "debug": { @@ -194,7 +194,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -221,7 +221,7 @@ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { - "callsites": "^0.2.0" + "callsites": "0.2.0" } }, "callsites": { @@ -236,9 +236,9 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" }, "dependencies": { "ansi-styles": { @@ -247,7 +247,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "1.9.2" } }, "supports-color": { @@ -256,7 +256,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -279,7 +279,7 @@ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "restore-cursor": "2.0.0" } }, "cli-width": { @@ -324,10 +324,10 @@ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "buffer-from": "1.1.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" } }, "content-disposition": { @@ -365,11 +365,11 @@ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "nice-try": "1.0.4", + "path-key": "2.0.1", + "semver": "5.5.0", + "shebang-command": "1.2.0", + "which": "1.3.1" } }, "debug": { @@ -397,8 +397,8 @@ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "dev": true, "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" + "foreach": "2.0.5", + "object-keys": "1.0.12" } }, "del": { @@ -407,13 +407,13 @@ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true, "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.1", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" } }, "depd": { @@ -440,7 +440,7 @@ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "^2.0.2" + "esutils": "2.0.2" } }, "ee-first": { @@ -461,11 +461,11 @@ "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", "dev": true, "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.3", + "is-callable": "1.1.4", + "is-regex": "1.0.4" } }, "es-to-primitive": { @@ -474,9 +474,9 @@ "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", "dev": true, "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" + "is-callable": "1.1.4", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" } }, "es6-promise": { @@ -489,7 +489,7 @@ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "requires": { - "es6-promise": "^4.0.3" + "es6-promise": "4.2.4" } }, "escape-html": { @@ -505,49 +505,49 @@ "dev": true }, "eslint": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.0.0.tgz", - "integrity": "sha512-MA0YWJLeK7BPEBxJCINvKnQdKpeTwbac3Xonh0PPFjWYZkowZf+Xl30lJWJ/BWOqFQdAdPcyOh0aBqlbH6ojAg==", - "dev": true, - "requires": { - "ajv": "^6.5.0", - "babel-code-frame": "^6.26.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^4.0.0", - "eslint-visitor-keys": "^1.0.0", - "espree": "^4.0.0", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.5.0", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^5.2.0", - "is-resolvable": "^1.1.0", - "js-yaml": "^3.11.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.5", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.1.0", - "require-uncached": "^1.0.3", - "semver": "^5.5.0", - "string.prototype.matchall": "^2.0.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^4.0.3", - "text-table": "^0.2.0" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.0.1.tgz", + "integrity": "sha512-D5nG2rErquLUstgUaxJlWB5+gu+U/3VDY0fk/Iuq8y9CUFy/7Y6oF4N2cR1tV8knzQvciIbfqfohd359xTLIKQ==", + "dev": true, + "requires": { + "ajv": "6.5.2", + "babel-code-frame": "6.26.0", + "chalk": "2.4.1", + "cross-spawn": "6.0.5", + "debug": "3.1.0", + "doctrine": "2.1.0", + "eslint-scope": "4.0.0", + "eslint-visitor-keys": "1.0.0", + "espree": "4.0.0", + "esquery": "1.0.1", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "11.7.0", + "ignore": "3.3.10", + "imurmurhash": "0.1.4", + "inquirer": "5.2.0", + "is-resolvable": "1.1.0", + "js-yaml": "3.12.0", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.10", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "regexpp": "1.1.0", + "require-uncached": "1.0.3", + "semver": "5.5.0", + "string.prototype.matchall": "2.0.0", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.3", + "text-table": "0.2.0" } }, "eslint-scope": { @@ -556,8 +556,8 @@ "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "esrecurse": "4.2.1", + "estraverse": "4.2.0" } }, "eslint-visitor-keys": { @@ -572,8 +572,8 @@ "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", "dev": true, "requires": { - "acorn": "^5.6.0", - "acorn-jsx": "^4.1.1" + "acorn": "5.7.1", + "acorn-jsx": "4.1.1" } }, "esprima": { @@ -588,7 +588,7 @@ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "4.2.0" } }, "esrecurse": { @@ -597,7 +597,7 @@ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "4.2.0" } }, "estraverse": { @@ -624,36 +624,36 @@ "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", "dev": true, "requires": { - "accepts": "~1.3.5", + "accepts": "1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.2", "content-disposition": "0.5.2", - "content-type": "~1.0.4", + "content-type": "1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.3", + "proxy-addr": "2.0.3", "qs": "6.5.1", - "range-parser": "~1.2.0", + "range-parser": "1.2.0", "safe-buffer": "5.1.1", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", + "statuses": "1.4.0", + "type-is": "1.6.16", "utils-merge": "1.0.1", - "vary": "~1.1.2" + "vary": "1.1.2" }, "dependencies": { "debug": { @@ -679,9 +679,9 @@ "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" + "chardet": "0.4.2", + "iconv-lite": "0.4.23", + "tmp": "0.0.33" } }, "extract-zip": { @@ -728,7 +728,7 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "requires": { - "pend": "~1.2.0" + "pend": "1.2.0" } }, "figures": { @@ -737,7 +737,7 @@ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "escape-string-regexp": "1.0.5" } }, "file-entry-cache": { @@ -746,8 +746,8 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "1.3.0", + "object-assign": "4.1.1" } }, "finalhandler": { @@ -757,12 +757,12 @@ "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", - "unpipe": "~1.0.0" + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.4.0", + "unpipe": "1.0.0" }, "dependencies": { "debug": { @@ -782,10 +782,10 @@ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" } }, "foreach": { @@ -828,12 +828,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "globals": { @@ -848,12 +848,12 @@ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "graceful-fs": { @@ -874,7 +874,7 @@ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { - "function-bind": "^1.1.1" + "function-bind": "1.1.1" } }, "has-ansi": { @@ -883,7 +883,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "has-flag": { @@ -910,10 +910,10 @@ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { - "depd": "~1.1.2", + "depd": "1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "statuses": "1.4.0" } }, "https-proxy-agent": { @@ -921,8 +921,8 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" + "agent-base": "4.2.0", + "debug": "3.1.0" } }, "iconv-lite": { @@ -931,7 +931,7 @@ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": "2.1.2" } }, "ignore": { @@ -951,8 +951,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -966,19 +966,19 @@ "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", "dev": true, "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.1.0", - "figures": "^2.0.0", - "lodash": "^4.3.0", + "ansi-escapes": "3.1.0", + "chalk": "2.4.1", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.2.0", + "figures": "2.0.0", + "lodash": "4.17.10", "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^5.5.2", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" + "run-async": "2.3.0", + "rxjs": "5.5.11", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" } }, "ipaddr.js": { @@ -988,9 +988,9 @@ "dev": true }, "is-callable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", "dev": true }, "is-date-object": { @@ -1017,7 +1017,7 @@ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { - "is-path-inside": "^1.0.0" + "is-path-inside": "1.0.1" } }, "is-path-inside": { @@ -1026,7 +1026,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "^1.0.1" + "path-is-inside": "1.0.2" } }, "is-promise": { @@ -1041,7 +1041,7 @@ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "dev": true, "requires": { - "has": "^1.0.1" + "has": "1.0.3" } }, "is-resolvable": { @@ -1079,8 +1079,8 @@ "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "1.0.10", + "esprima": "4.0.0" } }, "json-schema-traverse": { @@ -1101,8 +1101,8 @@ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "1.1.2", + "type-check": "0.3.2" } }, "lodash": { @@ -1146,7 +1146,7 @@ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "~1.33.0" + "mime-db": "1.33.0" } }, "mimic-fn": { @@ -1160,7 +1160,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -1206,7 +1206,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -1266,7 +1266,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "onetime": { @@ -1275,7 +1275,7 @@ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "mimic-fn": "1.2.0" } }, "optionator": { @@ -1284,12 +1284,12 @@ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" } }, "os-tmpdir": { @@ -1350,7 +1350,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "^2.0.0" + "pinkie": "2.0.4" } }, "pluralize": { @@ -1381,7 +1381,7 @@ "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", "dev": true, "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.1.2", "ipaddr.js": "1.6.0" } }, @@ -1401,14 +1401,14 @@ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.5.0.tgz", "integrity": "sha512-eELwFtFxL+uhmg4jPZOZXzSrPEYy4CaYQNbcchBbfxY+KjMpnv6XGf/aYWaQG49OTpfi2/DMziXtDM8XuJgoUA==", "requires": { - "debug": "^3.1.0", - "extract-zip": "^1.6.6", - "https-proxy-agent": "^2.2.1", - "mime": "^2.0.3", - "progress": "^2.0.0", - "proxy-from-env": "^1.0.0", - "rimraf": "^2.6.1", - "ws": "^5.1.1" + "debug": "3.1.0", + "extract-zip": "1.6.7", + "https-proxy-agent": "2.2.1", + "mime": "2.3.1", + "progress": "2.0.0", + "proxy-from-env": "1.0.0", + "rimraf": "2.6.2", + "ws": "5.2.1" } }, "qs": { @@ -1450,7 +1450,7 @@ "depd": "1.1.1", "inherits": "2.0.3", "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" + "statuses": "1.4.0" } }, "iconv-lite": { @@ -1472,13 +1472,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "regexp.prototype.flags": { @@ -1487,7 +1487,7 @@ "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", "dev": true, "requires": { - "define-properties": "^1.1.2" + "define-properties": "1.1.2" } }, "regexpp": { @@ -1502,8 +1502,8 @@ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" + "caller-path": "0.1.0", + "resolve-from": "1.0.1" } }, "resolve-from": { @@ -1518,8 +1518,8 @@ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + "onetime": "2.0.1", + "signal-exit": "3.0.2" } }, "rimraf": { @@ -1527,7 +1527,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "run-async": { @@ -1536,7 +1536,7 @@ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "dev": true, "requires": { - "is-promise": "^2.1.0" + "is-promise": "2.1.0" } }, "rxjs": { @@ -1572,18 +1572,18 @@ "dev": true, "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", + "http-errors": "1.6.3", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.4.0" }, "dependencies": { "debug": { @@ -1609,9 +1609,9 @@ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "dev": true, "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", "send": "0.16.2" } }, @@ -1627,7 +1627,7 @@ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "1.0.0" } }, "shebang-regex": { @@ -1648,7 +1648,7 @@ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0" + "is-fullwidth-code-point": "2.0.0" } }, "sprintf-js": { @@ -1669,8 +1669,8 @@ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" } }, "string.prototype.matchall": { @@ -1679,11 +1679,11 @@ "integrity": "sha512-WoZ+B2ypng1dp4iFLF2kmZlwwlE19gmjgKuhL1FJfDgCREWb3ye3SDVHSzLH6bxfnvYmkCxbzkmWcQZHA4P//Q==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.10.0", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "regexp.prototype.flags": "^1.2.0" + "define-properties": "1.1.2", + "es-abstract": "1.12.0", + "function-bind": "1.1.1", + "has-symbols": "1.0.0", + "regexp.prototype.flags": "1.2.0" } }, "string_decoder": { @@ -1691,7 +1691,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.2" } }, "strip-ansi": { @@ -1700,7 +1700,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "3.0.0" }, "dependencies": { "ansi-regex": { @@ -1735,12 +1735,12 @@ "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { - "ajv": "^6.0.1", - "ajv-keywords": "^3.0.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", + "ajv": "6.5.2", + "ajv-keywords": "3.2.0", + "chalk": "2.4.1", + "lodash": "4.17.10", "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "string-width": "2.1.1" } }, "text-table": { @@ -1761,7 +1761,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "os-tmpdir": "1.0.2" } }, "type-check": { @@ -1770,7 +1770,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "1.1.2" } }, "type-is": { @@ -1780,7 +1780,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.18" + "mime-types": "2.1.18" } }, "typedarray": { @@ -1800,7 +1800,7 @@ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { - "punycode": "^2.1.0" + "punycode": "2.1.1" } }, "util-deprecate": { @@ -1826,7 +1826,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "^2.0.0" + "isexe": "2.0.0" } }, "wordwrap": { @@ -1846,15 +1846,15 @@ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "^0.5.1" + "mkdirp": "0.5.1" } }, "ws": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.0.tgz", - "integrity": "sha512-c18dMeW+PEQdDFzkhDsnBAlS4Z8KGStBQQUcQ5mf7Nf689jyGk0594L+i9RaQuf4gog6SvWLJorz2NfSaqxZ7w==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.1.tgz", + "integrity": "sha512-2NkHdPKjDBj3CHdnAGNpmlliryKqF+n9MYXX7/wsVC4yqYocKreKNjydPDvT3wShAZnndlM0RytEfTALCDvz7A==", "requires": { - "async-limiter": "~1.0.0" + "async-limiter": "1.0.0" } }, "yauzl": { @@ -1862,7 +1862,7 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", "requires": { - "fd-slicer": "~1.0.1" + "fd-slicer": "1.0.1" } } } diff --git a/package.json b/package.json index 1ff79eae..294b4a4f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wendigo", - "version": "0.9.0", + "version": "0.9.1", "description": "A proper monster for front-end automated testing", "engines": { "node": ">=8.0.0" @@ -12,7 +12,7 @@ ], "main": "lib/wendigo.js", "scripts": { - "test": "mocha tests --recursive --exit --retries 2", + "test": "mocha ./tests/**/*.test.js ./tests/hooks.js --exit --retries 2", "lint": "eslint lib/ tests/ --ext .js" }, "repository": { @@ -40,7 +40,7 @@ "puppeteer": "^1.5.0" }, "devDependencies": { - "eslint": "^5.0.0", + "eslint": "^5.0.1", "express": "^4.16.3", "mocha": "^5.2.0" } diff --git a/tests/assertions/assert_webworkers.test.js b/tests/assertions/assert_webworkers.test.js new file mode 100644 index 00000000..1f6e6036 --- /dev/null +++ b/tests/assertions/assert_webworkers.test.js @@ -0,0 +1,82 @@ +"use strict"; + +const Wendigo = require('../../lib/wendigo'); +const configUrls = require('../config.json').urls; +const utils = require('../test_utils'); + +describe("Assert Webworkers", function() { + this.timeout(5000); + let browser; + + before(async () => { + browser = await Wendigo.createBrowser(); + }); + + beforeEach(async () => { + await browser.open(configUrls.webworker); + }); + + after(async () => { + await browser.close(); + }); + + it("Assert Webworker", async () => { + await browser.assert.webworker({ + count: 0 + }); + await browser.clickText("Start Worker"); + await browser.wait(); + await browser.assert.webworker(); + await browser.assert.webworker({ + count: 1 + }); + }); + + it("Assert Webworkers Throws", async () => { + await utils.assertThrowsAssertionAsync(async () => { + await browser.assert.webworker(); + }, `Expected at least 1 webworker running, 0 found.`); + }); + + it("Assert Webworkers Count Throws", async () => { + await browser.clickText("Start Worker"); + await browser.wait(); + await utils.assertThrowsAssertionAsync(async () => { + await browser.assert.webworker({ + count: 2 + }); + }, `Expected 2 webworkers running, 1 found.`); + }); + + it("Assert Webworker Throws Custom Message", async () => { + await utils.assertThrowsAssertionAsync(async () => { + await browser.assert.webworker(null, "ww fails"); + }, `ww fails`); + }); + + it("Assert Webworker Url", async () => { + await browser.clickText("Start Worker"); + await browser.wait(); + await browser.assert.webworker({ + count: 1, + url: "http://localhost:3456/worker.js" + }); + }); + + it("Assert Webworker Url Throws", async () => { + await utils.assertThrowsAssertionAsync(async () => { + await browser.assert.webworker({ + count: 1, + url: "http://localhost:3456/worker.js" + }); + }, `Expected 1 webworkers running with url "http://localhost:3456/worker.js", 0 found.`); + }); + it("Assert Webworker Url Throws Custom Message", async () => { + await utils.assertThrowsAssertionAsync(async () => { + await browser.assert.webworker({ + count: 1, + url: "http://localhost:3456/worker.js" + }, "ww fails"); + }, `ww fails`); + }); +}); diff --git a/tests/browser/query.test.js b/tests/browser/query.test.js index 18317912..70482db8 100644 --- a/tests/browser/query.test.js +++ b/tests/browser/query.test.js @@ -2,7 +2,7 @@ const Wendigo = require('../../lib/wendigo'); const assert = require('assert'); -const DomElement = require('../../lib/dom_element'); +const DomElement = require('../../lib/models/dom_element'); const configUrls = require('../config.json').urls; const utils = require('../test_utils'); diff --git a/tests/browser_components/browser_webworker.test.js b/tests/browser_components/browser_webworker.test.js new file mode 100644 index 00000000..ce834236 --- /dev/null +++ b/tests/browser_components/browser_webworker.test.js @@ -0,0 +1,49 @@ +"use strict"; + +const assert = require('assert'); +const Wendigo = require('../../lib/wendigo'); +const configUrls = require('../config.json').urls; + +describe("Webworkers", function() { + this.timeout(5000); + let browser; + + before(async () => { + browser = await Wendigo.createBrowser(); + }); + + beforeEach(async () => { + await browser.open(configUrls.webworker); + }); + + after(async () => { + await browser.close(); + }); + + it("Get All Webworkers", async () => { + let workers = browser.webworkers.all(); + assert.strictEqual(workers.length, 0); + await browser.clickText("Start Worker"); + await browser.wait(); + workers = browser.webworkers.all(); + assert.strictEqual(workers.length, 1); + }); + + it("Stop Webworkers", async () => { + let workers = browser.webworkers.all(); + assert.strictEqual(workers.length, 0); + await browser.clickText("Start Worker"); + await browser.wait(); + await browser.clickText("Stop Worker"); + await browser.wait(); + workers = browser.webworkers.all(); + assert.strictEqual(workers.length, 0); + }); + + it("Webworker Url", async () => { + await browser.clickText("Start Worker"); + await browser.wait(); + const workers = browser.webworkers.all(); + assert.strictEqual(workers[0].url, "http://localhost:3456/worker.js"); + }); +}); diff --git a/tests/browser_components/request_mocker.test.js b/tests/browser_components/request_mocker.test.js index c4ab5f35..d673bc9c 100644 --- a/tests/browser_components/request_mocker.test.js +++ b/tests/browser_components/request_mocker.test.js @@ -91,6 +91,7 @@ describe("Requests Mocker", function() { }; await browser.requests.mock(configUrls.api, mockResponse2); await browser.requests.mock(configUrls.api, mockResponse); // Overrides + assert.strictEqual(browser.requests._requestMocker._mockedRequests.length, 1); await browser.clickText("click me"); await browser.wait(100); await browser.assert.text("#result", "MOCK"); @@ -121,6 +122,15 @@ describe("Requests Mocker", function() { await browser.assert.text("#result", "DUMMY"); }); + it("Remove Mock Without Exact Match", async () => { + const response = Object.assign({}, mockResponse, {method: "GET"}); + await browser.requests.mock(configUrls.api, response); + await browser.requests.removeMock(configUrls.api); + await browser.clickText("click me"); + await browser.wait(100); + await browser.assert.text("#result", "DUMMY"); + }); + it("Remove Inexisting Mock", async () => { const response = Object.assign({}, mockResponse, {method: "GET"}); await browser.requests.mock(configUrls.api, response); diff --git a/tests/config.json b/tests/config.json index 401f1a22..909faccb 100644 --- a/tests/config.json +++ b/tests/config.json @@ -14,6 +14,7 @@ "userAgent": "http://localhost:3456/user_agent.html", "console": "http://localhost:3456/console.html", "scroll": "http://localhost:3456/scroll.html", + "webworker": "http://localhost:3456/webworker.html", "redirect": "http://localhost:3456/redirect", "api": "http://localhost:3456/api" } diff --git a/tests/dummy_server/static/webworker.html b/tests/dummy_server/static/webworker.html new file mode 100644 index 00000000..e661455d --- /dev/null +++ b/tests/dummy_server/static/webworker.html @@ -0,0 +1,28 @@ + + +
+ +Count numbers:
+ + + + + + + diff --git a/tests/dummy_server/static/worker.js b/tests/dummy_server/static/worker.js new file mode 100644 index 00000000..f2a828be --- /dev/null +++ b/tests/dummy_server/static/worker.js @@ -0,0 +1,11 @@ +"use strict"; + +let i = 0; + +function timedCount() { + i = i + 1; + postMessage(i); + setTimeout("timedCount()", 500); +} + +timedCount();