diff --git a/.eslintrc.json b/.eslintrc.json index 5281d46..f170a39 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -30,14 +30,11 @@ "EC": true }, "root": true, - "ecmaFeatures": { - "modules": true - }, "rules": { // Possible Errors "comma-dangle": [2, "never"], "no-cond-assign": 2, - "no-console": 0, + "no-console": 1, "no-constant-condition": 2, "no-control-regex": 2, "no-debugger": 2, @@ -88,7 +85,7 @@ "no-caller": 2, "no-case-declarations": 2, "no-div-regex": 2, - "no-else-return": 1, + "no-else-return": 2, "no-empty-pattern": 2, "no-eq-null": 2, "no-eval": 2, @@ -133,7 +130,7 @@ "yoda": [2, "never", { "exceptRange": true }], // Strict Mode - "strict": [0, "global"], + "strict": [2, "global"], // Variables "init-declarations": 0, @@ -145,7 +142,7 @@ "no-undef-init": 2, "no-undef": 2, "no-undefined": 0, - "no-unused-vars": 1, + "no-unused-vars": 2, "no-use-before-define": 2, // Stylistic Issues @@ -198,7 +195,7 @@ "padded-blocks": 0, "quote-props": [2, "consistent-as-needed"], "quotes": [2, "single", "avoid-escape"], - "require-jsdoc": 2, + "require-jsdoc": 1, "semi-spacing": [2, {"before": false, "after": true}], "semi": [0, "always"], "sort-vars": 0, diff --git a/.gitignore b/.gitignore index 3dacbde..c10a8f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,13 @@ # Logs logs *.log - # Dependency directory node_modules - *.DS_Store .* !.travis.yml !.editorconfig -!.eslintrc.json +!.eslintrc.* *.xml .settings downloads diff --git a/.travis.yml b/.travis.yml index 89f3f33..03a9b8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,5 +26,6 @@ install: # http://docs.travis-ci.com/user/pull-requests/ script: + - npm run lint - npm run mocha - npm run cucumber diff --git a/cucumber.sh b/cucumber.sh new file mode 100644 index 0000000..9f2df05 --- /dev/null +++ b/cucumber.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +#Run server in background +node_modules/http-server/bin/http-server ./test/demo-app -p 9000 > /dev/null & +server=$! +#Run tests +./node_modules/.bin/wdio test/wdio.conf.js +#Kill server after run +kill -9 ${server} diff --git a/index.js b/index.js index 327fc4e..0df09c9 100644 --- a/index.js +++ b/index.js @@ -1,13 +1,13 @@ 'use strict' -const fs = require('fs'); -const files = fs.readdirSync('./src/steps'); +const fs = require('fs') +const files = fs.readdirSync('./src/steps') files.forEach((f) => { const path = `./src/steps/${f}` - const fileSteps = require(path); + const fileSteps = require(path) if (typeof fileSteps === 'function') { - fileSteps.apply(this); + fileSteps.apply(this) } -}); +}) diff --git a/package.json b/package.json index 2106752..0f4257e 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "scripts": { "lint": "./node_modules/eslint/bin/eslint.js -c .eslintrc.json src/ test/", "mocha": "./node_modules/.bin/mocha test/mocha/*.spec.js", - "cucumber": "./node_modules/.bin/wdio test/wdio.conf.js", + "cucumber": ". ./cucumber.sh", "test": "npm run lint && npm run mocha && npm run cucumber" }, "repository": { @@ -39,6 +39,7 @@ "devDependencies": { "chai": "^4.1.2", "eslint": "^4.11.0", + "http-server": "^0.10.0", "mocha": "^4.0.1", "wdio-cucumber-framework": "^1.0.2", "wdio-selenium-standalone-service": "0.0.9", diff --git a/src/helpers/objects.processor.js b/src/helpers/objects.processor.js index bf6a627..d4a64a0 100644 --- a/src/helpers/objects.processor.js +++ b/src/helpers/objects.processor.js @@ -1,6 +1,5 @@ -'use strict' - /* eslint no-param-reassign: 0*/ +/* eslint no-undef: 0 */ const { _r } = require('./utils') @@ -8,11 +7,11 @@ const dynamicId = '$dynamicId$' const regDynamicId = '\\$dynamicId\\$' // Can come from applysteps ?? -const pageObject = '("[^"]+"\."[^"]+")' -const pageObjectsParts = '^"([^"]+)"\."([^"]+)"$' +const pageObject = '([a-zA-Z0-9_-]+ from [a-zA-Z0-9_-]+ page)' +const pageObjectsParts = '^([a-zA-Z0-9_-]+) from ([a-zA-Z0-9_-]+) page$' -const dictionaryObject = '("[^"]+"\."[^"]+"|"[^"]*")' -const dictionaryObjectsParts = '^(?:"([^"]+)"\."([^"]+)"|"([^"]*)")$' +const dictionaryObject = '([a-zA-Z0-9_-]+ from [a-zA-Z0-9_-]+ dictionary|"[^"]*")' +const dictionaryObjectsParts = '^(?:([a-zA-Z0-9_-]+) from ([a-zA-Z0-9_-]+) dictionary|"([^"]*)")$' // Todo do we need this in csp-qa function injectInto(locator, injection) { @@ -34,64 +33,61 @@ function injectInto(locator, injection) { const body = locator.replace(/\[[0-9]+\]$/, '') return injectInto(body, injection) + nums - } else { - // Locator ends with brackets, which contain some properties - return locator.substring(0, locator.length - 1) + ' and ' + injection } - } else { - // Locator contains no brackets - return locator + '[' + injection + return locator.substring(0, locator.length - 1) + ' and ' + injection } + return locator + '[' + injection } -function parsePageObject(str) { +function pageObjectGetter(str) { const match = _r(pageObjectsParts).exec(str) if (!match) { throw new Error(`Was unable to find Page Object for "${str}"`) } if (match[1]) { - const page = match[1] - const object = match[2] + const page = match[2] + const object = match[1] - if (!this.pages[page]) { + if (!pages[page]) { throw new Error(`"${page}" page is missing`) } - if (!this.pages[page][object]) { + if (!pages[page][object]) { throw new Error(`"${object}" page object is missing for the "${page}" page`) } - return this.pages[page][object] + return pages[page][object] } throw new Error(`Unknown Page Object type for "${str}"`) } function getPageObject(str) { - const value = parsePageObject.call(this, str) - const idValue = value.replace(_r(regDynamicId, 'g'), this.id) + const pageObjectGetterFunc = objectsProcessor.pageObjectGetter || pageObjectGetter + const value = pageObjectGetterFunc(str) + const idValue = value.replace(_r(regDynamicId, 'g'), id.getId()) const injection = 'not(ancestor-or-self::*[contains(@style,"visibility: hidden;") ' + - 'or contains(@style,"display: none;") or contains(@class,"x-hide-offsets")])'; + 'or contains(@style,"display: none") or contains(@class,"x-hide-offsets")])' const injectedvalue = injectInto(idValue, injection) return injectedvalue } -function parseDictionaryObject(str) { +function dicionaryGetter(str) { const match = _r(dictionaryObjectsParts).exec(str) if (!match) { throw new Error(`Was unable to find Dictionary Object type for "${str}"`) } if (match[1]) { - const dictionary = match[1] - const object = match[2] + const dictionary = match[2] + const object = match[1] - if (!this.pages[dictionary]) { + if (!pages[dictionary]) { throw new Error(`"${dictionary}" page is missing`) } - if (!this.pages[dictionary][object]) { + if (!pages[dictionary][object]) { throw new Error(`"${object}" page object is missing for the "${dictionary}" page`) } - return this.pages[dictionary][object] + return pages[dictionary][object] } if (match[3] !== undefined) { return match[3] @@ -100,8 +96,9 @@ function parseDictionaryObject(str) { } function getDictionaryObject(str) { - const value = parseDictionaryObject.call(this, str) - const idValue = value.replace(_r(regDynamicId, 'g'), this.id) + const dicionaryGetterFunc = objectsProcessor.dicionaryGetter || dicionaryGetter + const value = dicionaryGetterFunc(str) + const idValue = value.replace(_r(regDynamicId, 'g'), id.getId()) return idValue } diff --git a/src/helpers/utils.js b/src/helpers/utils.js index 4dd33de..b7894e8 100644 --- a/src/helpers/utils.js +++ b/src/helpers/utils.js @@ -1,5 +1,3 @@ -'use strict' - const escapeRegExp = function (str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\$&') } diff --git a/src/steps/given.js b/src/steps/given.js index dbe0b50..2884dcc 100644 --- a/src/steps/given.js +++ b/src/steps/given.js @@ -1,8 +1,7 @@ /* eslint no-undef: 0 */ +/* eslint new-cap: 0 */ -'use strict' - -const { defineSupportCode } = require('cucumber'); +const { defineSupportCode } = require('cucumber') const { dictionaryObject, getDictionaryObject } = require('../helpers/objects.processor') const { _r } = require('../helpers/utils') @@ -16,8 +15,8 @@ module.exports = function () { */ const url = getDictionaryObject.call(this, urlDictionary) - browser.url(url); - }); + browser.url(url) + }) - }); + }) } diff --git a/src/steps/then.js b/src/steps/then.js index e69de29..618a4f0 100644 --- a/src/steps/then.js +++ b/src/steps/then.js @@ -0,0 +1,22 @@ +/* eslint no-undef: 0 */ +/* eslint new-cap: 0 */ + +const { defineSupportCode } = require('cucumber') +const { pageObject, getPageObject } = require('../helpers/objects.processor') +const { _r } = require('../helpers/utils') + +module.exports = function () { + defineSupportCode(({ Then }) => { + + Then(_r(`^${pageObject} should be present$`), (object) => { + /** + * The element should be present + * @type {PageObject} + */ + const locator = getPageObject(object) + + browser.$(locator).waitForExist() + }) + + }) +} diff --git a/test/demo-app/index.html b/test/demo-app/index.html new file mode 100644 index 0000000..bf120b1 --- /dev/null +++ b/test/demo-app/index.html @@ -0,0 +1,11 @@ + + + + DEMO APP FOR THE WDIO-STEPS + + + + + + + diff --git a/test/demo-app/scripts/script.js b/test/demo-app/scripts/script.js new file mode 100644 index 0000000..e69de29 diff --git a/test/demo-app/styles/style.css b/test/demo-app/styles/style.css new file mode 100644 index 0000000..e69de29 diff --git a/test/features/page_objects/main.js b/test/features/page_objects/main.js new file mode 100644 index 0000000..035b6ec --- /dev/null +++ b/test/features/page_objects/main.js @@ -0,0 +1,5 @@ +let e = {} + +e.txtHeader = '//*[@id="header"]' + +module.exports = e diff --git a/test/features/url.validation.feature b/test/features/url.validation.feature index 495da42..93254e4 100644 --- a/test/features/url.validation.feature +++ b/test/features/url.validation.feature @@ -6,5 +6,6 @@ Feature: URL As a developer I want to open URL and check that is a certain value - Scenario: The URL should be https://github.com/ - Given I open "https://github.com/" + Scenario: Check I write method + Given I open "http://localhost:9000" + Then txtHeader from main page should be present diff --git a/test/mocha/objects.processor.spec.js b/test/mocha/objects.processor.spec.js index 2b5bf70..3ff8d81 100644 --- a/test/mocha/objects.processor.spec.js +++ b/test/mocha/objects.processor.spec.js @@ -1,5 +1,3 @@ -'use strict'; - const { expect } = require('chai') const { @@ -14,18 +12,21 @@ const { _r } = require('../../src/helpers/utils') const realId = 12345 -const World = { - id: realId, - pages: { - page: { - object: `//div[@id='${dynamicId}']` - }, - dictionary: { - object: `dictionaryObject${dynamicId}` - } +global.pages = { + main: { + object: `//div[@id='${dynamicId}']` + }, + book: { + word: `dictionaryObject${dynamicId}` } } +global.id = { + getId: () => realId +} + +global.objectsProcessor = { } + describe('injectInto', () => { const data = [ { locator: '//a', injection: '@class="b"]', result: '//a[@class="b"]' }, @@ -36,18 +37,18 @@ describe('injectInto', () => { data.forEach((d) => { it(`should get "${d.result}" string from "${d.locator}" and "${d.injection}" injection`, () => { - expect(injectInto(d.locator, d.injection)).to.be.equals(d.result); - }); - }); -}); + expect(injectInto(d.locator, d.injection)).to.be.equals(d.result) + }) + }) +}) describe('getPageObject', () => { const data = [ { - step: 'When I click "page"."object"', + step: 'When I click object from main page', regExp: _r(`When I click ${pageObject}`), result: `//div[@id='${realId}' and not(ancestor-or-self::*[contains(@style,"visibility: hidden;") ` + - 'or contains(@style,"display: none;") or contains(@class,"x-hide-offsets")])]' + 'or contains(@style,"display: none") or contains(@class,"x-hide-offsets")])]' } ] @@ -59,18 +60,18 @@ describe('getPageObject', () => { expect(match).to.be.an('array') const strPageObject = match[1] - const pageObjectVal = getPageObject.call(World, strPageObject) + const pageObjectVal = getPageObject(strPageObject) expect(pageObjectVal).to.be.equals(result) next() - }); - }); -}); + }) + }) +}) describe('getDictionaryObject', () => { const data = [ { - step: 'When I write "dictionary"."object"', + step: 'When I write word from book dictionary', regExp: _r(`When I write ${dictionaryObject}`), result: `dictionaryObject${realId}` }, @@ -89,10 +90,10 @@ describe('getDictionaryObject', () => { expect(match).to.be.an('array') const strDictionaryObject = match[1] - const dictionaryObjectVal = getDictionaryObject.call(World, strDictionaryObject) + const dictionaryObjectVal = getDictionaryObject(strDictionaryObject) expect(dictionaryObjectVal).to.be.equals(result) next() - }); - }); -}); + }) + }) +}) diff --git a/test/wdio.conf.js b/test/wdio.conf.js index bc2ec45..338bf23 100644 --- a/test/wdio.conf.js +++ b/test/wdio.conf.js @@ -188,6 +188,19 @@ exports.config = { global.expect = chai.expect; global.assert = chai.assert; global.should = chai.should(); + + global.pages = { + main: require('./features/page_objects/main') + } + + global.id = { + value: '', + regenerate: () => this.value === (new Date()).getTime(), + getId: () => this.value + } + + global.objectsProcessor = { } + }, /** * Runs before a WebdriverIO command gets executed. diff --git a/yarn.lock b/yarn.lock index efa8517..0bbadcc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -127,6 +127,10 @@ assertion-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + async@^2.0.0, async@^2.1.4: version "2.6.0" resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" @@ -364,6 +368,10 @@ core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +corser@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87" + crc32-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" @@ -476,7 +484,7 @@ debug@3.1.0, debug@^3.0.1: dependencies: ms "2.0.0" -debug@^2.6.3: +debug@^2.2.0, debug@^2.6.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -519,14 +527,10 @@ delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" -diff@3.3.1: +diff@3.3.1, diff@^3.0.0: version "3.3.1" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" -diff@^3.0.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" - doctrine@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" @@ -547,6 +551,15 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" +ecstatic@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-2.2.1.tgz#b5087fad439dd9dd49d31e18131454817fe87769" + dependencies: + he "^1.1.1" + mime "^1.2.11" + minimist "^1.1.0" + url-join "^2.0.2" + ejs@~2.5.6: version "2.5.7" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" @@ -670,6 +683,10 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +eventemitter3@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -896,7 +913,7 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" -he@1.1.1: +he@1.1.1, he@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -908,6 +925,26 @@ hoek@4.x.x: version "4.2.0" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" +http-proxy@^1.8.1: + version "1.16.2" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" + dependencies: + eventemitter3 "1.x.x" + requires-port "1.x.x" + +http-server@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.10.0.tgz#b2a446b16a9db87ed3c622ba9beb1b085b1234a7" + dependencies: + colors "1.0.3" + corser "~2.0.0" + ecstatic "^2.0.0" + http-proxy "^1.8.1" + opener "~1.4.0" + optimist "0.6.x" + portfinder "^1.0.13" + union "~0.4.3" + http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -1131,6 +1168,10 @@ mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: dependencies: mime-db "~1.30.0" +mime@^1.2.11: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" @@ -1145,11 +1186,11 @@ minimist@0.0.8, minimist@~0.0.1: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.2.0: +minimist@^1.1.0, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -mkdirp@0.5.1, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -1236,7 +1277,11 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -optimist@~0.6.1: +opener@~1.4.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + +optimist@0.6.x, optimist@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" dependencies: @@ -1306,6 +1351,14 @@ pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" +portfinder@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -1338,6 +1391,10 @@ q@~1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" +qs@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" + qs@~6.3.0: version "6.3.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" @@ -1437,6 +1494,10 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" +requires-port@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" @@ -1649,7 +1710,7 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -supports-color@4.4.0: +supports-color@4.4.0, supports-color@^4.0.0: version "4.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" dependencies: @@ -1659,12 +1720,6 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^4.0.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" - dependencies: - has-flag "^2.0.0" - supports-color@~5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.0.0.tgz#1db26229f6ae02f9acdb5410907c36ce2e362b13" @@ -1755,6 +1810,12 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +union@~0.4.3: + version "0.4.6" + resolved "https://registry.yarnpkg.com/union/-/union-0.4.6.tgz#198fbdaeba254e788b0efcb630bc11f24a2959e0" + dependencies: + qs "~2.3.3" + upper-case-first@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115" @@ -1773,6 +1834,10 @@ urix@^0.1.0, urix@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" +url-join@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.2.tgz#c072756967ad24b8b59e5741551caac78f50b8b7" + url@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"