diff --git a/.eslintrc.json b/.eslintrc.json index fdfe09a..a8b4ddb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,6 @@ { "parserOptions": { - "ecmaVersion": 6, + "ecmaVersion": 2017, "sourceType": "module" }, "env": { diff --git a/.gitignore b/.gitignore index 2643cda..fa517f2 100644 --- a/.gitignore +++ b/.gitignore @@ -8,10 +8,10 @@ node_modules !.travis.yml !.editorconfig !.eslintrc.* +!.vscode *.xml .settings downloads *~ .idea -.vscode errorShots/ diff --git a/.travis.yml b/.travis.yml index 03a9b8d..9fbf245 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ dist: trusty # http://docs.travis-ci.com/user/languages/javascript-with-nodejs/ language: node_js node_js: - - "6" + - "7" # http://docs.travis-ci.com/user/gui-and-headless-browsers before_install: diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c8d5f55 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,23 @@ +{ + "cucumberautocomplete.steps": [ + "src/steps/*.js" + ], + "cucumberautocomplete.syncfeatures": "test/features/*feature", + "cucumberautocomplete.strictGherkinCompletion": true, + "cucumberautocomplete.smartSnippets": true, + "cucumberautocomplete.stepsInvariants": true, + "cucumberautocomplete.customParameters": [ + { + "parameter":"(_r(", + "value":"(" + }, + { + "parameter":"${dictionaryObject}", + "value":"([a-zA-Z0-9_-]+ from [a-zA-Z0-9_-]+ dictionary|\"[^\"]*\")" + }, + { + "parameter":"${pageObject}", + "value":"([a-zA-Z0-9_-]+ from [a-zA-Z0-9_-]+ page)" + } + ], +} \ No newline at end of file diff --git a/package.json b/package.json index 16f97d3..cb8cf8a 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "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", + "wdio-cucumber-framework": "^1.1.0", + "wdio-selenium-standalone-service": "0.0.10", "wdio-spec-reporter": "^0.1.2", - "webdriverio": "^4.9.8" + "webdriverio": "^4.12.0" } } diff --git a/src/commands/index.js b/src/commands/index.js new file mode 100644 index 0000000..5972fc5 --- /dev/null +++ b/src/commands/index.js @@ -0,0 +1,5 @@ +const waitForPageToLoad = require('./wait.for.page.to.load'); + +module.exports = function applyCommands () { + browser.addCommand('waitForPageToLoad', waitForPageToLoad); +}; diff --git a/src/commands/wait.for.page.to.load.js b/src/commands/wait.for.page.to.load.js new file mode 100644 index 0000000..104b3c8 --- /dev/null +++ b/src/commands/wait.for.page.to.load.js @@ -0,0 +1,9 @@ +/* global stepsConfig */ + +module.exports = function waitForPageToLoad () { + /** + * Wait for page to get fully loaded + * @param {callback} callback - A callback to run + */ + return browser.waitUntil(stepsConfig.finishedLoadingConditions); +}; diff --git a/src/helpers/objects.processor.js b/src/helpers/objects.processor.js index 1f38768..4c64ccd 100644 --- a/src/helpers/objects.processor.js +++ b/src/helpers/objects.processor.js @@ -1,5 +1,6 @@ /* eslint no-param-reassign: 0 */ /* eslint no-undef: 0 */ +/* global stepsConfig */ const { _r } = require('./utils'); @@ -16,17 +17,17 @@ const dictionaryObjectsParts = '^(?:([a-zA-Z0-9_-]+) from ([a-zA-Z0-9_-]+) dicti // Todo do we need this in csp-qa function injectInto (locator, injection) { const lastInjectionSymbol = injection.slice(-1); - const lastLocatorSumbol = locator.slice(-1); + const lastLocatorSymbol = locator.slice(-1); if (lastInjectionSymbol !== ']') { // Add ']' to the end of injection only if missing (for backward compatibility) injection += ']'; } - if (lastLocatorSumbol === ')') { + if (lastLocatorSymbol === ')') { // If our locator ends with round brackets return injectInto(locator.replace(/\)$/, ''), injection) + ')'; } - if (lastLocatorSumbol === ']') { + if (lastLocatorSymbol === ']') { if (locator.match(/\[[0-9]+\]$/)) { // Locator ends with brackets, which contains some xpath num const nums = locator.match(/\[[0-9]+\]$/)[0]; @@ -49,21 +50,21 @@ function pageObjectGetter (str) { const page = match[2]; const object = match[1]; - if (!pages[page]) { + if (!stepsConfig.pages[page]) { throw new Error(`"${page}" page is missing`); } - if (!pages[page][object]) { + if (!stepsConfig.pages[page][object]) { throw new Error(`"${object}" page object is missing for the "${page}" page`); } - return pages[page][object]; + return stepsConfig.pages[page][object]; } throw new Error(`Unknown Page Object type for "${str}"`); } function getPageObject (str) { - const pageObjectGetterFunc = objectsProcessor.pageObjectGetter || pageObjectGetter; + const pageObjectGetterFunc = stepsConfig.objectsProcessor.pageObjectGetter || pageObjectGetter; const value = pageObjectGetterFunc(str); - const idValue = value.replace(_r(regDynamicId, 'g'), id.getId()); + const idValue = value.replace(_r(regDynamicId, 'g'), stepsConfig.id.idValue); const injection = `not(ancestor-or-self::*[contains(@style,"visibility: hidden;") or contains(@style,"display: none") or contains(@class,"x-hide-offsets")])`; const injectedValue = injectInto(idValue, injection); @@ -81,13 +82,13 @@ function dictionaryGetter (str) { const dictionary = match[2]; const object = match[1]; - if (!pages[dictionary]) { + if (!stepsConfig.pages[dictionary]) { throw new Error(`"${dictionary}" page is missing`); } - if (!pages[dictionary][object]) { + if (!stepsConfig.pages[dictionary][object]) { throw new Error(`"${object}" page object is missing for the "${dictionary}" page`); } - return pages[dictionary][object]; + return stepsConfig.pages[dictionary][object]; } if (match[3] !== undefined) { return match[3]; @@ -96,9 +97,9 @@ function dictionaryGetter (str) { } function getDictionaryObject (str) { - const dictionaryGetterFunc = objectsProcessor.dictionaryGetter || dictionaryGetter; + const dictionaryGetterFunc = stepsConfig.objectsProcessor.dictionaryGetter || dictionaryGetter; const value = dictionaryGetterFunc(str); - const idValue = value.replace(_r(regDynamicId, 'g'), id.getId()); + const idValue = value.replace(_r(regDynamicId, 'g'), stepsConfig.id.idValue); return idValue; } diff --git a/src/steps.conf.generator.js b/src/steps.conf.generator.js new file mode 100644 index 0000000..0053cac --- /dev/null +++ b/src/steps.conf.generator.js @@ -0,0 +1,45 @@ +const defaultFinishedLoadingConditions = (loaderSelectors) => { + // Check if jQuery is present on the page and if any XMLHttpRequests (AJAX) are in progress + if (typeof $ !== 'undefined' && $.active) { + return false; + } + + // Check if any loaders are still present on the page + return browser.executeAsync((selectors, done) => { + done(!selectors.some((selector) => { + return document.querySelector(selector); + })); + }, loaderSelectors).value; + +}; + +const defaultIdGenerator = () => (new Date()).getTime(); + +module.exports = function ({ + loaderSelectors = [], // [] - array of xpath selectors, that will be used by finishedLoadingConditions. + finishedLoadingConditions = defaultFinishedLoadingConditions, // <(loaderSelectors) => >. + pages = {}, // <{[key: string]: {[key: string]: }}> - object, that contains "key" -> "Page object" pairs. + defaultIdValue = '', // Default value of steps config Id. + idGenerator = defaultIdGenerator, // <() => > - function, that will return new generated id. + objectsProcessor = {} // objectsProcessor childs could be previded here - see objects.processor.js for more details. +}) { + const Id = class { + constructor () { + this.value = defaultIdValue || idGenerator.call(this); + } + get idValue () { + return this.value; + } + regenerate () { + this.value = idGenerator.call(this); + } + }; + + return { + loaderSelectors, + finishedLoadingConditions: finishedLoadingConditions.bind(this, loaderSelectors), + pages, + id: new Id(), + objectsProcessor + }; +}; diff --git a/src/steps/given.js b/src/steps/given.js index 36bbf7c..4db8a9a 100644 --- a/src/steps/given.js +++ b/src/steps/given.js @@ -7,14 +7,18 @@ const { _r } = require('../helpers/utils'); module.exports = function () { defineSupportCode(({ Given }) => { - Given(_r(`^I open ${dictionaryObject}$`), (urlDictionary) => { + Given(_r(`^I open ${dictionaryObject}$`), async function async (urlDictionary) { /** * The URL to navigate to * @type {String} or {DictionaryObject} */ const url = getDictionaryObject.call(this, urlDictionary); - browser.url(url); + try { + return await browser.url(url); + } catch (err) { + throw new Error(err); + } }); }); diff --git a/src/steps/then.js b/src/steps/then.js index b8bedbb..133b421 100644 --- a/src/steps/then.js +++ b/src/steps/then.js @@ -7,24 +7,32 @@ const { _r } = require('../helpers/utils'); module.exports = function () { defineSupportCode(({ Then }) => { - Then(_r(`^${pageObject} should be present$`), (element) => { + Then(_r(`^${pageObject} should be present$`), async function async (element) { /** * The element should be present * @param {pageObject} element - String or "page"."object" to select the element */ const locator = getPageObject(element); - browser.$(locator).waitForExist(); + try { + return await browser.waitForExist(locator); + } catch (err) { + throw new Error(err); + } }); - Then(_r(`^${pageObject} should not be present$`), (element) => { + Then(_r(`^${pageObject} should not be present$`), async function async (element) { /** * The element should not be present * @param {pageObject} element - String or "page"."object" to select the element */ const locator = getPageObject(element); - browser.$(locator).waitForExist(null, true); + try { + return await browser.waitForExist(locator, null, true); + } catch (err) { + throw new Error(err); + } }); }); diff --git a/src/steps/when.js b/src/steps/when.js index 6801464..db21e61 100644 --- a/src/steps/when.js +++ b/src/steps/when.js @@ -1,14 +1,47 @@ /* eslint new-cap: 0 */ const { defineSupportCode } = require('cucumber'); -const { dictionaryObject, getDictionaryObject } = require('../helpers/objects.processor'); +const { pageObject, getPageObject, dictionaryObject, getDictionaryObject } = require('../helpers/objects.processor'); const { _r, getInteger } = require('../helpers/utils'); - module.exports = function () { defineSupportCode(({ When }) => { - When(_r(`I wait ${dictionaryObject} ms$`), (timeObject) => { + When(_r(`I click ${pageObject}$`), async function async (element) { + /** + * Click on the element + * @param {pageObject} element - String or "page"."object" to select the element + */ + const locator = getPageObject(element); + + try { + await browser.waitForExist(locator); + await browser.waitForPageToLoad(); + await browser.moveToObject(locator); + return await browser.click(locator); + } catch (err) { + throw new Error(err); + } + }); + + When(_r(`I doubleclick ${pageObject}$`), async function async (element) { + /** + * Double-click on the element + * @param {pageObject} element - String or "page"."object" to select the element + */ + const locator = getPageObject(element); + + try { + await browser.waitForExist(locator); + await browser.waitForPageToLoad(); + await browser.moveToObject(locator); + return await browser.doubleClick(locator); + } catch (err) { + throw new Error(err); + } + }); + + When(_r(`I wait ${dictionaryObject} ms$`), async function async (timeObject) { /** * Wait for specified amount of milliseconds * @param {String} timeObject - String with specified amount of milliseconds @@ -16,21 +49,33 @@ module.exports = function () { const timeValue = getDictionaryObject.call(this, timeObject); const time = getInteger(timeValue); - browser.pause(time); + try { + return await browser.pause(time); + } catch (err) { + throw new Error(err); + } }); - When(_r('I close current tab$'), () => { + When(_r('I close current tab$'), async function async () { /** * Close current tab */ - browser.close(); + try { + return await browser.close(); + } catch (err) { + throw new Error(err); + } }); - When(_r('I open new window$'), () => { + When(_r('I open new window$'), async function async () { /** * Open default empty ('about:blank') tab */ - browser.newWindow('about:blank'); + try { + return await browser.newWindow('about:blank'); + } catch (err) { + throw new Error(err); + } }); }); diff --git a/test/demo-app/images/loader1.gif b/test/demo-app/images/loader1.gif new file mode 100644 index 0000000..cc70a7a Binary files /dev/null and b/test/demo-app/images/loader1.gif differ diff --git a/test/demo-app/images/loader2.gif b/test/demo-app/images/loader2.gif new file mode 100644 index 0000000..d84f653 Binary files /dev/null and b/test/demo-app/images/loader2.gif differ diff --git a/test/demo-app/new-page.html b/test/demo-app/new-page.html index 9004b9d..15a9f01 100644 --- a/test/demo-app/new-page.html +++ b/test/demo-app/new-page.html @@ -3,9 +3,45 @@ NEW PAGE FOR THE WDIO-STEPS + + +
New page header
-
New page
+
New page
+
+ + +
+
Double-click before
+
+ Click to get text +
diff --git a/test/demo-app/scripts/loaders.js b/test/demo-app/scripts/loaders.js new file mode 100644 index 0000000..bff4bbc --- /dev/null +++ b/test/demo-app/scripts/loaders.js @@ -0,0 +1,22 @@ +function launchLoader (timeout, idValue) { + + const blockLoader = document.createElement('div'); + + blockLoader.setAttribute('id', idValue); + document.body.insertBefore(blockLoader, document.body.firstChild); + + setTimeout(function () { + document.getElementById(idValue).remove(); + }, timeout); + +} + +document.addEventListener('DOMContentLoaded', () => { + + const timeout1 = 5000; + const timeout2 = 8000; + + launchLoader(timeout1, 'loader1'); + launchLoader(timeout2, 'loader2'); + +}); diff --git a/test/demo-app/styles/loaders.css b/test/demo-app/styles/loaders.css new file mode 100644 index 0000000..2069d91 --- /dev/null +++ b/test/demo-app/styles/loaders.css @@ -0,0 +1,15 @@ +#loader1 { + width: 100%; + height: 100%; + position: fixed; + z-index: 9999; + background: url("../images/loader1.gif") no-repeat center center rgba(0,0,0,0.2) +} + +#loader2 { + width: 100%; + height: 100%; + position: fixed; + z-index: 9998; + background: url("../images/loader2.gif") no-repeat center center rgba(0,0,0,0.1) +} diff --git a/test/features/click.feature b/test/features/click.feature new file mode 100644 index 0000000..6d17db6 --- /dev/null +++ b/test/features/click.feature @@ -0,0 +1,25 @@ +@Fast +@Click + +Feature: Click + In order to check steps with clicking on the elements + As a developer + I want to check that clicking works properly + + Scenario: I click step should click on the element + Given I open "http://localhost:9000/new-page.html" + And checkboxTestUnchecked from main page should be present + When I click checkboxTestUnchecked from main page + Then checkboxTestChecked from main page should be present + + Scenario: I doubleclick step should double-click on the element + Given I open "http://localhost:9000/new-page.html" + And blockTextBefore from main page should be present + When I doubleclick blockTextBefore from main page + Then blockTextBefore from main page should not be present + And blockTextAfter from main page should be present + + Scenario: waitForPageToLoad should wait for all loaders to finish + Given I open "http://localhost:9000/new-page.html" + When I click buttonLaunch from main page + Then I click buttonWasClicked from main page diff --git a/test/features/dictionary_objects/values.js b/test/features/dictionary_objects/values.js index c03390b..cb2529b 100644 --- a/test/features/dictionary_objects/values.js +++ b/test/features/dictionary_objects/values.js @@ -1,4 +1,4 @@ -let e = {}; +const e = {}; e.txtTimeout = '500'; diff --git a/test/features/page_objects/main.js b/test/features/page_objects/main.js index c95e845..d5ce8a4 100644 --- a/test/features/page_objects/main.js +++ b/test/features/page_objects/main.js @@ -1,8 +1,14 @@ -let e = {}; +const e = {}; e.txtHeader = '//*[@id="header"]'; e.txtNewHeader = '//*[@id="new-header"]'; e.divTimeout = '//*[@id="div_timeout"]'; e.div = '//div'; +e.checkboxTestUnchecked = '//*[@id="cbx-test" and not(@checked="checked")]'; +e.checkboxTestChecked = '//*[@id="cbx-test" and @checked="checked"]'; +e.blockTextBefore = '//*[@id="block-text" and contains(text(), "Double-click before")]'; +e.blockTextAfter = '//*[@id="block-text" and contains(text(), "after double-click")]'; +e.buttonLaunch = '//*[@id="button-launch"]'; +e.buttonWasClicked = '//*[@id="button-launch" and contains(text(), "Button was clicked")]'; module.exports = e; diff --git a/test/features/show.hide.timeout.feature b/test/features/show.hide.timeout.feature index 7078e1f..05baa6e 100644 --- a/test/features/show.hide.timeout.feature +++ b/test/features/show.hide.timeout.feature @@ -5,7 +5,12 @@ Feature: Present / Not present As a developer I want to check that certain value is present and not present after time - Scenario: Check I write method + Scenario: Check that certain element is present and the other is not present on the page + Given I open "http://localhost:9000" + Then divTimeout from main page should be present + And checkboxTestUnchecked from main page should not be present + + Scenario: I wait step should wait for specified amount of milliseconds Given I open "http://localhost:9000" Then txtHeader from main page should be present Then divTimeout from main page should be present @@ -14,4 +19,4 @@ Feature: Present / Not present Then txtHeader from main page should be present Then I wait txtTimeout from values dictionary ms Then divTimeout from main page should not be present - Then txtHeader from main page should be present \ No newline at end of file + Then txtHeader from main page should be present diff --git a/test/features/url.validation.feature b/test/features/url.manipulations.feature similarity index 61% rename from test/features/url.validation.feature rename to test/features/url.manipulations.feature index 93254e4..04400fa 100644 --- a/test/features/url.validation.feature +++ b/test/features/url.manipulations.feature @@ -4,8 +4,8 @@ Feature: URL In order to check steps with URL As a developer - I want to open URL and check that is a certain value + I want to perform different operations with URLs - Scenario: Check I write method + Scenario: I open step should open the specified page Given I open "http://localhost:9000" Then txtHeader from main page should be present diff --git a/test/features/window.tab.manipulation.feature b/test/features/window.tab.manipulations.feature similarity index 99% rename from test/features/window.tab.manipulation.feature rename to test/features/window.tab.manipulations.feature index feff72d..e475231 100644 --- a/test/features/window.tab.manipulation.feature +++ b/test/features/window.tab.manipulations.feature @@ -19,4 +19,3 @@ Feature: Window/tab When I open new window When I close current tab 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 33f6e0a..87e1e33 100644 --- a/test/mocha/objects.processor.spec.js +++ b/test/mocha/objects.processor.spec.js @@ -9,10 +9,12 @@ const { dynamicId } = require('../../src/helpers/objects.processor'); const { _r } = require('../../src/helpers/utils'); +const stepsConfigGenerator = require('../../src/steps.conf.generator'); const realId = 12345; -global.pages = { +// Makes stepsConfig visible globally to use stepsConfig.pages, stepsConfig.id, stepsConfig.loaderSelectors +const pages = { main: { object: `//div[@id='${dynamicId}']` }, @@ -20,12 +22,9 @@ global.pages = { word: `dictionaryObject${dynamicId}` } }; +const idGenerator = () => realId; -global.id = { - getId: () => realId -}; - -global.objectsProcessor = {}; +global.stepsConfig = stepsConfigGenerator({ pages, idGenerator }); describe('injectInto', () => { const data = [ diff --git a/test/steps.conf.js b/test/steps.conf.js new file mode 100644 index 0000000..b6c5875 --- /dev/null +++ b/test/steps.conf.js @@ -0,0 +1,18 @@ +// Array of selectors for loaders that appear when page is loaded or XHR/AJAX requests are done +const loaderSelectors = [ + 'div:not([style*="display: none"])[class*="test-loader"]', + 'div:not([style*="visibility: hidden"])[class*="test-loader"]', + '[id*="loader1"]', + '[id*="loader2"]' +]; + +// Object that contains pathes to all page objects used for tests +const pages = { + main: require('./features/page_objects/main'), + values: require('./features/dictionary_objects/values') +}; + +module.exports = { + loaderSelectors, + pages +}; diff --git a/test/wdio.conf.js b/test/wdio.conf.js index c296d25..ed39236 100644 --- a/test/wdio.conf.js +++ b/test/wdio.conf.js @@ -192,18 +192,16 @@ exports.config = { global.assert = chai.assert; global.should = chai.should(); - global.pages = { - main: require('./features/page_objects/main'), - values: require('./features/dictionary_objects/values') - }; + // Makes stepsConfig visible globally to use stepsConfig vars + const stepsConfigGenerator = require('../src/steps.conf.generator'); + const stepsConfigPresets = require('./steps.conf'); - global.id = { - value: '', - regenerate: () => this.value === (new Date()).getTime(), - getId: () => this.value - }; + global.stepsConfig = stepsConfigGenerator(stepsConfigPresets); - global.objectsProcessor = {}; + // Adds browser.waitForPageToLoad() command to wait for page to get fully loaded + const applyStepsCommands = require('../src/commands'); + + applyStepsCommands(); } /** diff --git a/yarn.lock b/yarn.lock index 0bbadcc..f71d814 100644 --- a/yarn.lock +++ b/yarn.lock @@ -391,6 +391,16 @@ cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -478,13 +488,13 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -debug@3.1.0, debug@^3.0.1: +debug@3.1.0, debug@^3.0.0, debug@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: ms "2.0.0" -debug@^2.2.0, debug@^2.6.3: +debug@^2.2.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -1011,6 +1021,10 @@ inquirer@^3.0.6, inquirer@~3.3.0: strip-ansi "^4.0.0" through "^2.3.6" +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -1019,6 +1033,12 @@ is-generator@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3" +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + is-my-json-valid@^2.12.4: version "2.16.1" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" @@ -1235,6 +1255,10 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +nice-try@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" + normalize-path@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -1317,6 +1341,10 @@ path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" @@ -1367,11 +1395,7 @@ process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" -progress@1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" - -progress@^2.0.0: +progress@2.0.0, progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" @@ -1549,18 +1573,18 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" -selenium-standalone@^6.5.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/selenium-standalone/-/selenium-standalone-6.11.0.tgz#eb21ff65f3b2ece75061b35d4f9e7572ac0280c2" +selenium-standalone@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/selenium-standalone/-/selenium-standalone-6.13.0.tgz#d61d2994e196b2ff61a19de498c6711375f5a51b" dependencies: async "^2.1.4" commander "^2.9.0" - cross-spawn "^5.1.0" - debug "^2.6.3" + cross-spawn "^6.0.0" + debug "^3.0.0" lodash "^4.17.4" minimist "^1.2.0" mkdirp "^0.5.1" - progress "1.1.8" + progress "2.0.0" request "2.79.0" tar-stream "1.5.2" urijs "^1.18.4" @@ -1571,6 +1595,10 @@ semver@^5.3.0: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" +semver@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -1857,10 +1885,6 @@ uuid@^3.0.0, uuid@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" -validator@~9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/validator/-/validator-9.1.1.tgz#3bdd1065cbd28f9d96ac806dee01030d32fd97ef" - verror@1.10.0, verror@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -1869,12 +1893,14 @@ verror@1.10.0, verror@^1.9.0: core-util-is "1.0.2" extsprintf "^1.2.0" -wdio-cucumber-framework@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wdio-cucumber-framework/-/wdio-cucumber-framework-1.0.2.tgz#96cad58a0dde6af132dfe645a52c1f9dd849b19a" +wdio-cucumber-framework@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wdio-cucumber-framework/-/wdio-cucumber-framework-1.1.0.tgz#b817cc15fb91a60ff537db55354a024b004cd9d4" dependencies: babel-runtime "~6.25.0" cucumber "~2.3.1" + glob "^7.1.2" + is-glob "^4.0.0" mockery "~2.1.0" wdio-sync "0.7.0" @@ -1882,12 +1908,12 @@ wdio-dot-reporter@~0.0.8: version "0.0.9" resolved "https://registry.yarnpkg.com/wdio-dot-reporter/-/wdio-dot-reporter-0.0.9.tgz#929b2adafd49d6b0534fda068e87319b47e38fe5" -wdio-selenium-standalone-service@0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/wdio-selenium-standalone-service/-/wdio-selenium-standalone-service-0.0.9.tgz#c80d4ff489744d5a0b91d5189764916d4c0c8564" +wdio-selenium-standalone-service@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/wdio-selenium-standalone-service/-/wdio-selenium-standalone-service-0.0.10.tgz#cdb64d9a53fa3ea0ed3cf0ebf4fd3bdca93dcf05" dependencies: fs-extra "^0.30.0" - selenium-standalone "^6.5.0" + selenium-standalone "^6.13.0" wdio-spec-reporter@^0.1.2: version "0.1.2" @@ -1904,9 +1930,9 @@ wdio-sync@0.7.0: fibers "~2.0.0" object.assign "^4.0.3" -webdriverio@^4.9.8: - version "4.9.9" - resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-4.9.9.tgz#695de325166528e162d5b6d29a7f2c18aafdd3aa" +webdriverio@^4.12.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-4.12.0.tgz#e340def272183c8168a4dd0b382322f9d7bee10d" dependencies: archiver "~2.1.0" babel-runtime "^6.26.0" @@ -1927,7 +1953,6 @@ webdriverio@^4.9.8: safe-buffer "~5.1.1" supports-color "~5.0.0" url "~0.11.0" - validator "~9.1.1" wdio-dot-reporter "~0.0.8" wgxpath "~1.0.0"