diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index 6b50c7ddc..d54a04878 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -1,19 +1,6 @@ /* eslint no-invalid-this: "off" */ -// import Nightmare from 'nightmare'; -import Nightmare from 'puppeteer'; -import {URL} from 'url'; -import config from './config.js'; - -let currentUser; - let actions = { - clickIfExists: async function(selector) { - let exists = await this.exists(selector); - if (exists) await this.click(selector); - return exists; - }, - parsedUrl: async function() { return new URL(await this.url()); }, @@ -27,59 +14,33 @@ let actions = { changeLanguageToEnglish: async function() { let langSelector = '.user-popover vn-autocomplete[ng-model="$ctrl.lang"]'; - let lang = await this.waitToClick('#user') - .wait(langSelector) - .waitToGetProperty(`${langSelector} input`, 'value'); + await this.waitToClick('#user'); + await this.wait(langSelector); + let lang = await this.waitToGetProperty(`${langSelector} input`, 'value'); if (lang !== 'English') await this.autocompleteSearch(langSelector, 'English'); + + await this.waitFor(250); // tryed {visible: true}, page 'mutation' and waitForSelector unsuccessfully... + await this.mouse.down(); + await this.waitForSelector(langSelector, {hidden: true}); }, - // doLogin: async function(userName, password) { - // if (password == null) password = 'nightmare'; - // await this.wait(`vn-login [name=user]`) - // .clearInput(`vn-login [name=user]`) - // .write(`vn-login [name=user]`, userName) - // .write(`vn-login [name=password]`, password) - // .click(`vn-login button[type=submit]`); - // }, - - doLogin: async function(userName, password) { - if (password == null) password = 'nightmare'; - return await this.waitFor(`vn-login [name=user]`) - .clearInput(`vn-login [name=user]`) - .write(`vn-login [name=user]`, userName) - .write(`vn-login [name=password]`, password) - .click(`vn-login button[type=submit]`); + doLogin: async function(userName, password = 'nightmare') { + await this.wait(`vn-login [name=user]`); + await this.clearInput(`vn-login [name=user]`); + await this.write(`vn-login [name=user]`, userName); + await this.clearInput(`vn-login [name=password]`); + await this.write(`vn-login [name=password]`, password); + await this.click('vn-login button[type=submit]'); }, login: async function(userName) { - if (currentUser !== userName) { - let accountClicked = await this.clickIfExists('#user'); - - if (accountClicked) { - let buttonSelector = '.vn-dialog.shown button[response=accept]'; - await this.waitToClick('#logout') - .wait(buttonSelector => { - return document.querySelector(buttonSelector) != null - || location.hash == '#!/login'; - }, buttonSelector); - await this.clickIfExists(buttonSelector); - } - - try { - await this.waitForURL('#!/login'); - } catch (e) { - await this.goto(`${config.url}/#!/login`); - } - - await this.doLogin(userName, null) - .waitForURL('#!/') - .changeLanguageToEnglish(); - - currentUser = userName; - } else - await this.waitToClick('a[ui-sref=home]'); + await this.doLogin(userName); + await this.wait(() => { + return document.location.hash === '#!/'; + }, {}); + await this.changeLanguageToEnglish(); }, waitForLogin: async function(userName) { @@ -91,13 +52,14 @@ let actions = { return m[0] + '-' + m[1]; }).toLowerCase(); - await this.waitToClick(`vn-home a[ui-sref="${moduleName}.index"]`) - .waitForURL(snakeName); + let selector = `vn-home a[ui-sref="${moduleName}.index"]`; + await this.waitToClick(selector); + await this.waitForURL(snakeName); }, loginAndModule: async function(userName, moduleName) { - await this.login(userName) - .selectModule(moduleName); + await this.login(userName); + await this.selectModule(moduleName); }, datePicker: async function(selector, changeMonth, day) { @@ -106,371 +68,360 @@ let actions = { date.setDate(day ? day : 16); date = date.toISOString().substr(0, 10); - await this.wait(selector) - .evaluate((selector, date) => { - let input = document.querySelector(selector).$ctrl.input; - input.value = date; - input.dispatchEvent(new Event('change')); - }, selector, date); + await this.wait(selector); + await this.evaluate((selector, date) => { + let input = document.querySelector(selector).$ctrl.input; + input.value = date; + input.dispatchEvent(new Event('change')); + }, selector, date); }, pickTime: async function(selector, time) { - await this.wait(selector) - .evaluate((selector, time) => { - let input = document.querySelector(selector).$ctrl.input; - input.value = time; - input.dispatchEvent(new Event('change')); - }, selector, time); + await this.wait(selector); + await this.evaluate((selector, time) => { + let input = document.querySelector(selector).$ctrl.input; + input.value = time; + input.dispatchEvent(new Event('change')); + }, selector, time); }, - clearTextarea: function(selector) { - return this.wait(selector) - .evaluate(inputSelector => { - return document.querySelector(inputSelector).value = ''; - }, selector); + clearTextarea: async function(selector) { + await this.wait(selector); + await this.input.evaluate(inputSelector => { + return document.querySelector(inputSelector).value = ''; + }, selector); }, - clearInput: function(selector) { - return this.wait(selector) - .evaluate(selector => { - let $ctrl = document.querySelector(selector).closest('.vn-field').$ctrl; - $ctrl.field = null; - $ctrl.$.$apply(); - $ctrl.input.dispatchEvent(new Event('change')); - }, selector); + clearInput: async function(selector) { + await this.wait(selector); + return await this.evaluate(selector => { + let $ctrl = document.querySelector(selector).closest('.vn-field').$ctrl; + $ctrl.field = null; + $ctrl.$.$apply(); + $ctrl.input.dispatchEvent(new Event('change')); + }, selector); }, - getProperty: function(selector, property) { - return this.evaluate((selector, property) => { + getProperty: async function(selector, property) { + return await this.evaluate((selector, property) => { return document.querySelector(selector)[property].replace(/\s+/g, ' ').trim(); }, selector, property); }, - waitPropertyLength: function(selector, property, minLength) { - return this.wait((selector, property, minLength) => { + waitPropertyLength: async function(selector, property, minLength) { + await this.wait((selector, property, minLength) => { const element = document.querySelector(selector); return element && element[property] != null && element[property] !== '' && element[property].length >= minLength; - }, selector, property, minLength) - .getProperty(selector, property); + }, {}, selector, property, minLength); + return await this.getProperty(selector, property); }, - waitPropertyValue: function(selector, property, status) { - return this.wait(selector) - .wait((selector, property, status) => { - const element = document.querySelector(selector); - return element[property] === status; - }, selector, property, status); + waitPropertyValue: async function(selector, property, status) { + await this.wait(selector); + return await this.wait((selector, property, status) => { + const element = document.querySelector(selector); + return element[property] === status; + }, {}, selector, property, status); }, - waitToGetProperty: function(selector, property) { - return this.wait((selector, property) => { + waitToGetProperty: async function(selector, property) { + await this.wait((selector, property) => { const element = document.querySelector(selector); return element && element[property] != null && element[property] !== ''; - }, selector, property) - .getProperty(selector, property); + }, {}, selector, property); + return await this.getProperty(selector, property); }, - write: function(selector, text) { - return this.wait(selector) - .type(selector, text); + write: async function(selector, text) { + await this.wait(selector); + await this.type(selector, text); }, - waitToClick: function(selector) { - return this.wait(selector) - .click(selector); + waitToClick: async function(selector) { + await this.wait(selector); + await this.click(selector); }, - focusElement: function(selector) { - return this.wait(selector) - .evaluate(selector => { - let element = document.querySelector(selector); - element.focus(); - }, selector); + focusElement: async function(selector) { + await this.wait(selector); + return await this.evaluate(selector => { + let element = document.querySelector(selector); + element.focus(); + }, selector); }, - isVisible: function(selector) { - return this.wait(selector) - .evaluate(elementSelector => { - let selectorMatches = document.querySelectorAll(elementSelector); - let element = selectorMatches[0]; + isVisible: async function(selector) { + await this.wait(selector); + return await this.evaluate(elementSelector => { + let selectorMatches = document.querySelectorAll(elementSelector); + let element = selectorMatches[0]; - if (selectorMatches.length > 1) - throw new Error(`Multiple matches of ${elementSelector} found`); + if (selectorMatches.length > 1) + throw new Error(`Multiple matches of ${elementSelector} found`); - let isVisible = false; - if (element) { - let eventHandler = event => { - event.preventDefault(); - isVisible = true; - }; - element.addEventListener('mouseover', eventHandler); - let rect = element.getBoundingClientRect(); - let x = rect.left + rect.width / 2; - let y = rect.top + rect.height / 2; - let elementInCenter = document.elementFromPoint(x, y); - let elementInTopLeft = document.elementFromPoint(rect.left, rect.top); - let elementInBottomRight = document.elementFromPoint(rect.right, rect.bottom); + let isVisible = false; + if (element) { + let eventHandler = event => { + event.preventDefault(); + isVisible = true; + }; + element.addEventListener('mouseover', eventHandler); + let rect = element.getBoundingClientRect(); + let x = rect.left + rect.width / 2; + let y = rect.top + rect.height / 2; + let elementInCenter = document.elementFromPoint(x, y); + let elementInTopLeft = document.elementFromPoint(rect.left, rect.top); + let elementInBottomRight = document.elementFromPoint(rect.right, rect.bottom); - let e = new MouseEvent('mouseover', { - view: window, - bubbles: true, - cancelable: true, - }); + let e = new MouseEvent('mouseover', { + view: window, + bubbles: true, + cancelable: true, + }); - if (elementInCenter) - elementInCenter.dispatchEvent(e); + if (elementInCenter) + elementInCenter.dispatchEvent(e); - if (elementInTopLeft) - elementInTopLeft.dispatchEvent(e); + if (elementInTopLeft) + elementInTopLeft.dispatchEvent(e); - if (elementInBottomRight) - elementInBottomRight.dispatchEvent(e); + if (elementInBottomRight) + elementInBottomRight.dispatchEvent(e); - element.removeEventListener('mouseover', eventHandler); - } - return isVisible; - }, selector); + element.removeEventListener('mouseover', eventHandler); + } + return isVisible; + }, selector); }, - waitImgLoad: function(selector) { - return this.wait(selector) - .wait(selector => { - const imageReady = document.querySelector(selector).complete; - return imageReady; - }, selector); + waitImgLoad: async function(selector) { + await this.wait(selector); + return await this.wait(selector => { + const imageReady = document.querySelector(selector).complete; + return imageReady; + }, selector); }, - clickIfVisible: function(selector) { - return this.wait(selector) - .isVisible(selector) - .then(visible => { - if (visible) - return this.click(selector); + clickIfVisible: async function(selector) { + await this.wait(selector); + let isVisible = await this.isVisible(selector); - throw new Error(`invisible selector: ${selector}`); - }); + if (isVisible) + return await this.click(selector); + + throw new Error(`invisible selector: ${selector}`); }, - countElement: function(selector) { - return this.evaluate(selector => { + countElement: async function(selector) { + return await this.evaluate(selector => { return document.querySelectorAll(selector).length; }, selector); }, - waitForNumberOfElements: function(selector, count) { - return this.wait((selector, count) => { + waitForNumberOfElements: async function(selector, count) { + return await this.wait((selector, count) => { return document.querySelectorAll(selector).length === count; - }, selector, count); + }, {}, selector, count); }, - waitForClassNotPresent: function(selector, className) { - return this.wait(selector) - .wait((selector, className) => { - if (!document.querySelector(selector).classList.contains(className)) - return true; - }, selector, className); + waitForClassNotPresent: async function(selector, className) { + await this.wait(selector); + return await this.wait((selector, className) => { + if (!document.querySelector(selector).classList.contains(className)) + return true; + }, {}, selector, className); }, - waitForClassPresent: function(selector, className) { - return this.wait(selector) - .wait((elementSelector, targetClass) => { - if (document.querySelector(elementSelector).classList.contains(targetClass)) - return true; - }, selector, className); + waitForClassPresent: async function(selector, className) { + await this.wait(selector); + return await this.wait((elementSelector, targetClass) => { + if (document.querySelector(elementSelector).classList.contains(targetClass)) + return true; + }, {}, selector, className); }, - waitForTextInElement: function(selector, text) { - return this.wait(selector) - .wait((selector, text) => { - return document.querySelector(selector).innerText.toLowerCase().includes(text.toLowerCase()); - }, selector, text); + waitForTextInElement: async function(selector, text) { + await this.wait(selector); + return await this.wait((selector, text) => { + return document.querySelector(selector).innerText.toLowerCase().includes(text.toLowerCase()); + }, {}, selector, text); }, - waitForTextInInput: function(selector, text) { - return this.wait(selector) - .wait((selector, text) => { - return document.querySelector(selector).value.toLowerCase().includes(text.toLowerCase()); - }, selector, text); + waitForTextInInput: async function(selector, text) { + await this.wait(selector); + return await this.wait((selector, text) => { + return document.querySelector(selector).value.toLowerCase().includes(text.toLowerCase()); + }, {}, selector, text); }, - waitForInnerText: function(selector) { - return this.wait(selector) - .wait(selector => { - const innerText = document.querySelector(selector).innerText; - return innerText != null && innerText != ''; - }, selector) - .evaluate(selector => { - return document.querySelector(selector).innerText; - }, selector); + waitForInnerText: async function(selector) { + await this.wait(selector); + await this.wait(selector => { + const innerText = document.querySelector(selector).innerText; + return innerText != null && innerText != ''; + }, selector); + return await this.evaluate(selector => { + return document.querySelector(selector).innerText; + }, selector); }, - waitForEmptyInnerText: function(selector) { - return this.wait(selector => { + waitForEmptyInnerText: async function(selector) { + return await this.wait(selector => { return document.querySelector(selector).innerText == ''; }, selector); }, - waitForURL: function(hashURL) { - return this.wait(hash => { - return document.location.hash.includes(hash); - }, hashURL); + waitForURL: async function(hashURL) { + await this.wait(expectedHash => { + return document.location.hash.includes(expectedHash); + }, {}, hashURL); }, - waitForShapes: function(selector) { - return this.wait(selector) - .evaluate(selector => { - const shapes = document.querySelectorAll(selector); - const shapesList = []; + waitForShapes: async function(selector) { + await this.wait(selector); + return await this.evaluate(selector => { + const shapes = document.querySelectorAll(selector); + const shapesList = []; - for (const shape of shapes) - shapesList.push(shape.innerText); + for (const shape of shapes) + shapesList.push(shape.innerText); - - return shapesList; - }, selector); - }, - waitForSnackbar: function() { - return this.wait(500) - .waitForShapes('vn-snackbar .shape .text'); + return shapesList; + }, selector); }, - waitForLastShape: function(selector) { - return this.wait(selector) - .evaluate(selector => { - const shape = document.querySelector(selector); - - return shape.innerText; - }, selector); + waitForSnackbar: async function() { + await this.wait(500); + return await this.waitForShapes('vn-snackbar .shape .text'); }, - waitForLastSnackbar: function() { - return this.wait(500) - .waitForSpinnerLoad() - .waitForLastShape('vn-snackbar .shape .text'); + waitForLastShape: async function(selector) { + await this.wait(selector); + return await this.evaluate(selector => { + const shape = document.querySelector(selector); + + return shape.innerText; + }, selector); }, - accessToSearchResult: function(searchValue) { - return this.clearInput('vn-searchbar input') - .write('vn-searchbar input', searchValue) - .click('vn-searchbar vn-icon[icon="search"]') - .wait(100) - .waitForNumberOfElements('.search-result', 1) - .evaluate(() => { - return document.querySelector('ui-view vn-card vn-table') != null; - }) - .then(result => { - if (result) - return this.waitToClick('ui-view vn-card vn-td'); - - return this.waitToClick('ui-view vn-card a'); - }); + waitForLastSnackbar: async function() { + await this.wait(500); + await this.waitForSpinnerLoad(); + return await this.waitForLastShape('vn-snackbar .shape .text'); }, - accessToSection: function(sectionRoute) { - return this.wait(`vn-left-menu`) - .evaluate(sectionRoute => { - return document.querySelector(`vn-left-menu li li > a[ui-sref="${sectionRoute}"]`) != null; - }, sectionRoute) - .then(nested => { - if (nested) { - this.waitToClick('vn-left-menu vn-item-section > vn-icon[icon=keyboard_arrow_down]') - .wait('vn-left-menu .expanded'); - } + accessToSearchResult: async function(searchValue) { + await this.clearInput('vn-searchbar input'); + await this.write('vn-searchbar input', searchValue); + await this.click('vn-searchbar vn-icon[icon="search"]'); + await this.waitForNumberOfElements('.search-result', 1); + let result = await this.evaluate(() => { + return document.querySelector('ui-view vn-card vn-table') != null; + }); + if (result) + return await this.waitToClick('ui-view vn-card vn-td'); - return this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`) - .waitForSpinnerLoad(); - }); + return await this.waitToClick('ui-view vn-card a'); }, - autocompleteSearch: function(autocompleteSelector, searchValue) { - return this.waitToClick(`${autocompleteSelector} input`) - .write(`.vn-drop-down.shown input`, searchValue) - .waitToClick(`.vn-drop-down.shown li.active`) - .wait((autocompleteSelector, searchValue) => { - return document.querySelector(`${autocompleteSelector} input`).value - .toLowerCase() - .includes(searchValue.toLowerCase()); - }, autocompleteSelector, searchValue); + accessToSection: async function(sectionRoute) { + await this.wait(`vn-left-menu`); + letnested = await this.evaluate(sectionRoute => { + return document.querySelector(`vn-left-menu li li > a[ui-sref="${sectionRoute}"]`) != null; + }, sectionRoute); + + if (nested) { + await this.waitToClick('vn-left-menu vn-item-section > vn-icon[icon=keyboard_arrow_down]'); + await this.wait('vn-left-menu .expanded'); + } + + await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); + await this.waitForSpinnerLoad(); }, - reloadSection: function(sectionRoute) { - return this.waitToClick('vn-icon[icon="desktop_windows"]') - .wait('vn-card.summary') - .waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); + autocompleteSearch: async function(autocompleteSelector, searchValue) { + await this.waitToClick(`${autocompleteSelector} input`); + await this.write(`.vn-drop-down.shown input`, searchValue); + await this.waitToClick(`.vn-drop-down.shown li.active`); + await this.wait((autocompleteSelector, searchValue) => { + return document.querySelector(`${autocompleteSelector} input`).value + .toLowerCase() + .includes(searchValue.toLowerCase()); + }, {}, autocompleteSelector, searchValue); + await this.wait(() => { + return !document.querySelector('.vn-drop-down'); + }, {}); }, - forceReloadSection: function(sectionRoute) { - return this.waitToClick('vn-icon[icon="desktop_windows"]') - .waitToClick('button[response="accept"]') - .wait('vn-card.summary') - .waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); + reloadSection: async function(sectionRoute) { + await this.waitToClick('vn-icon[icon="desktop_windows"]'); + await this.wait('vn-card.summary'); + await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); }, - checkboxState: function(selector) { - return this.wait(selector) - .evaluate(selector => { - let checkbox = document.querySelector(selector); - switch (checkbox.$ctrl.field) { - case null: - return 'intermediate'; - case true: - return 'checked'; - default: - return 'unchecked'; - } - }, selector); + forceReloadSection: async function(sectionRoute) { + await this.waitToClick('vn-icon[icon="desktop_windows"]'); + await this.waitToClick('button[response="accept"]'); + await this.wait('vn-card.summary'); + await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); }, - isDisabled: function(selector) { - return this.wait(selector) - .evaluate(selector => { - let element = document.querySelector(selector); - return element.$ctrl.disabled; - }, selector); + checkboxState: async function(selector) { + await this.wait(selector); + return await this.evaluate(selector => { + let checkbox = document.querySelector(selector); + switch (checkbox.$ctrl.field) { + case null: + return 'intermediate'; + case true: + return 'checked'; + default: + return 'unchecked'; + } + }, selector); }, - waitForStylePresent: function(selector, property, value) { - return this.wait((selector, property, value) => { + isDisabled: async function(selector) { + await this.wait(selector); + return await this.evaluate(selector => { + let element = document.querySelector(selector); + return element.$ctrl.disabled; + }, selector); + }, + + waitForStylePresent: async function(selector, property, value) { + return await this.wait((selector, property, value) => { const element = document.querySelector(selector); return element.style[property] == value; - }, selector, property, value); + }, {}, selector, property, value); }, - waitForSpinnerLoad: function() { - return this.waitUntilNotPresent('vn-topbar vn-spinner'); + waitForSpinnerLoad: async function() { + await this.waitUntilNotPresent('vn-topbar vn-spinner'); }, - waitForWatcherData: function(selector) { - return this.wait(selector) - .wait(selector => { - const watcher = document.querySelector(selector); - let orgData = watcher.$ctrl.orgData; - return !angular.equals({}, orgData) && orgData != null; - }, selector) - .waitForSpinnerLoad(); + waitForWatcherData: async function(selector) { + await this.wait(selector); + await this.wait(selector => { + const watcher = document.querySelector(selector); + let orgData = watcher.$ctrl.orgData; + return !angular.equals({}, orgData) && orgData != null; + }, selector); + await this.waitForSpinnerLoad(); } }; -// for (let name in actions) { -// Nightmare.action(name, function(...args) { -// let fnArgs = args.slice(0, args.length - 1); -// let done = args[args.length - 1]; +export function extendPage(page) { + for (let name in actions) { + page[name] = async(...args) => { + return await actions[name].call(page, ...args); + }; + } -// actions[name].apply(this, fnArgs) -// .then(res => done(null, res)) -// .catch(err => { -// let stringArgs = fnArgs -// .map(i => typeof i == 'function' ? 'Function' : i) -// .join(', '); + page.wait = page.waitFor; -// let orgMessage = err.message.startsWith('.wait()') -// ? '.wait() timed out' -// : err.message; - -// done(new Error(`.${name}(${stringArgs}) failed: ${orgMessage}`)); -// }); -// }); -// } + return page; +} export default actions; diff --git a/e2e/helpers/nightmare.js b/e2e/helpers/nightmare.js deleted file mode 100644 index 01630e03c..000000000 --- a/e2e/helpers/nightmare.js +++ /dev/null @@ -1,27 +0,0 @@ -const Nightmare = require('nightmare'); - -let nightmare; - -module.exports = function createNightmare(width = 1280, height = 800) { - if (nightmare) - return nightmare; - - nightmare = new Nightmare({ - show: process.env.E2E_SHOW, - typeInterval: 10, - x: 0, - y: 0, - waitTimeout: 2000, - // openDevTools: {mode: 'detach'} - }).viewport(width, height); - - nightmare.on('console', (type, message, ...args) => { - if (type === 'error') { - console[type](message, ...args); - throw new Error(message); - } else - console[type](message, ...args); - }); - - return browser; -}; diff --git a/e2e/helpers/puppeteer.js b/e2e/helpers/puppeteer.js index 017b533d0..0841d368f 100644 --- a/e2e/helpers/puppeteer.js +++ b/e2e/helpers/puppeteer.js @@ -1,15 +1,35 @@ -const puppeteer = require('puppeteer'); +import Puppeteer from 'puppeteer'; +import {extendPage} from './extensions'; +import {url as defaultURL} from './config'; -(async() => { - const browser = await puppeteer.launch({ - headless: false, - slowMo: 0, // slow down by ms - // devtools: true, - }); +let browser; + +export function getBrowser() { + return browser || {close: () => {}}; +} + +async function openPage(url = defaultURL) { + if (!browser) { + browser = await Puppeteer.launch({ + defaultViewport: null, + headless: false, + slowMo: 0, // slow down by ms + // devtools: true, + }); + } const page = await browser.newPage(); - await page.goto('https://wowhead.com'); - await page.screenshot({path: 'example.png'}); + await page._client.send('Network.clearBrowserCookies'); + await page.goto(url); - await browser.close(); -})(); + page.on('console', msg => { + let type = msg.type(); + if (type === 'error') + console[type](msg.text()); + }); + + const extendedPage = extendPage(page); + return extendedPage; +} + +export default openPage; diff --git a/e2e/paths/01-login/01_login.spec.js b/e2e/paths/01-login/01_login.spec.js index 245dcf58e..2dbc06d83 100644 --- a/e2e/paths/01-login/01_login.spec.js +++ b/e2e/paths/01-login/01_login.spec.js @@ -1,65 +1,42 @@ -// import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; -// describe('Login path', () => { -// const nightmare = createNightmare(); - -// it('should receive an error when the username is incorrect', async() => { -// const result = await nightmare -// .doLogin('badUser', null) -// .waitForLastSnackbar(); - -// changes for puppeteer - -import createNightmare from '../../helpers/nightmare'; -import Puppeteer from 'puppeteer'; -import actions from '../../helpers/extensions'; -import {objectTypeAnnotation} from '@babel/types'; - -describe('Login path', () => { - let browser; - let nightmare; - beforeEach(async() => { - browser = await Puppeteer.launch({ - headless: false, - slowMo: 0, // slow down by ms - // devtools: true, - }); - nightmare = await browser.newPage(); - Object.keys(actions).forEach(key => { - nightmare.__proto__[key] = actions[key].bind(nightmare); - }); - nightmare.__proto__.wait = nightmare.waitFor; +fdescribe('Login path', async() => { + let page; + beforeAll(async() => { + page = await openPage(); }); - fit('should receive an error when the username is incorrect', async() => { - const result = await nightmare - .doLogin('badUser', null); - // .waitForLastSnackbar(); + afterAll(async() => { + page.close(); + }); + + it('should receive an error when the username is incorrect', async() => { + await page.doLogin('badUser', ''); + const result = await page.waitForLastSnackbar(); expect(result.length).toBeGreaterThan(0); }); it('should receive an error when the username is blank', async() => { - const result = await nightmare - .doLogin('', null) - .waitForLastSnackbar(); + await page.doLogin('', ''); + const result = await page.waitForLastSnackbar(); expect(result.length).toBeGreaterThan(0); }); it('should receive an error when the password is incorrect', async() => { - const result = await nightmare - .doLogin('employee', 'badPassword') - .waitForLastSnackbar(); + await page.doLogin('employee', 'badPassword'); + const result = await page.waitForLastSnackbar(); expect(result.length).toBeGreaterThan(0); }); it('should log in', async() => { - const url = await nightmare - .doLogin('employee', null) - .wait('#user') - .parsedUrl(); + await page.doLogin('employee', 'nightmare'); + await page.wait(2000); + await page.waitToClick('vn-login button[type=submit]'); + await page.wait('#user'); + let url = await page.parsedUrl(); expect(url.hash).toEqual('#!/'); }); diff --git a/e2e/paths/02-client-module/01_create_client.spec.js b/e2e/paths/02-client-module/01_create_client.spec.js index f2fe30464..63dfacad6 100644 --- a/e2e/paths/02-client-module/01_create_client.spec.js +++ b/e2e/paths/02-client-module/01_create_client.spec.js @@ -1,90 +1,87 @@ import selectors from '../../helpers/selectors'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; -describe('Client create path', () => { - const nightmare = createNightmare(); +fdescribe('Client create path', async() => { + let page; + beforeAll(async() => { + page = await openPage(); + await page.loginAndModule('employee', 'client'); + }); - beforeAll(() => { - nightmare - .loginAndModule('employee', 'client'); + afterAll(async() => { + page.close(); }); it(`should search for the user Carol Danvers to confirm it isn't created yet`, async() => { - const result = await nightmare - .write(selectors.clientsIndex.searchClientInput, 'Carol Danvers') - .waitToClick(selectors.clientsIndex.searchButton) - .waitForNumberOfElements(selectors.clientsIndex.searchResult, 0) - .countElement(selectors.clientsIndex.searchResult); + await page.write(selectors.clientsIndex.searchClientInput, 'Carol Danvers'); + await page.waitToClick(selectors.clientsIndex.searchButton); + await page.waitForNumberOfElements(selectors.clientsIndex.searchResult, 0); + const result = await page.countElement(selectors.clientsIndex.searchResult); expect(result).toEqual(0); }); it('should now access to the create client view by clicking the create-client floating button', async() => { - const url = await nightmare - .waitToClick(selectors.clientsIndex.createClientButton) - .wait(selectors.createClientView.createButton) - .parsedUrl(); + await page.waitToClick(selectors.clientsIndex.createClientButton); + await page.wait(selectors.createClientView.createButton); + const url = await page.parsedUrl(); expect(url.hash).toEqual('#!/client/create'); }); it('should receive an error when clicking the create button having all the form fields empty', async() => { - const result = await nightmare - .waitToClick(selectors.createClientView.createButton) - .waitForLastSnackbar(); + await page.waitToClick(selectors.createClientView.createButton); + const result = await page.waitForLastSnackbar(); expect(result).toEqual('Some fields are invalid'); }); it('should receive an error when clicking the create button having name and Business name fields empty', async() => { - const result = await nightmare - .write(selectors.createClientView.taxNumber, '74451390E') - .write(selectors.createClientView.userName, 'CaptainMarvel') - .write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es') - .autocompleteSearch(selectors.createClientView.salesPersonAutocomplete, 'replenisher') - .waitToClick(selectors.createClientView.createButton) - .waitForLastSnackbar(); + await page.write(selectors.createClientView.taxNumber, '74451390E'); + await page.write(selectors.createClientView.userName, 'CaptainMarvel'); + await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); + await page.autocompleteSearch(selectors.createClientView.salesPersonAutocomplete, 'replenisher'); + await page.waitToClick(selectors.createClientView.createButton); + const result = await page.waitForLastSnackbar(); expect(result).toEqual('Some fields are invalid'); }); it(`should attempt to create a new user with all it's data but wrong email`, async() => { - const result = await nightmare - .write(selectors.createClientView.name, 'Carol Danvers') - .write(selectors.createClientView.socialName, 'AVG tax') - .write(selectors.createClientView.street, 'Many places') - .autocompleteSearch(selectors.createClientView.country, 'España') - .autocompleteSearch(selectors.createClientView.province, 'Province one') - .write(selectors.createClientView.city, 'Valencia') - .write(selectors.createClientView.postcode, '46000') - .clearInput(selectors.createClientView.email) - .write(selectors.createClientView.email, 'incorrect email format') - .waitToClick(selectors.createClientView.createButton) - .waitForLastSnackbar(); + await page.write(selectors.createClientView.name, 'Carol Danvers'); + await page.write(selectors.createClientView.socialName, 'AVG tax'); + await page.write(selectors.createClientView.street, 'Many places'); + await page.autocompleteSearch(selectors.createClientView.country, 'España'); + await page.autocompleteSearch(selectors.createClientView.province, 'Province one'); + await page.write(selectors.createClientView.city, 'Valencia'); + await page.write(selectors.createClientView.postcode, '46000'); + await page.clearInput(selectors.createClientView.email); + await page.write(selectors.createClientView.email, 'incorrect email format'); + await page.waitToClick(selectors.createClientView.createButton); + const result = await page.waitForLastSnackbar(); expect(result).toEqual('Some fields are invalid'); }); it(`should attempt to create a new user with all it's data but wrong postal code`, async() => { - const result = await nightmare - .clearInput(selectors.createClientView.email) - .write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es') - .clearInput(selectors.createClientView.postcode) - .write(selectors.createClientView.postcode, '479999') - .waitToClick(selectors.createClientView.createButton) - .waitForLastSnackbar(); + await page.clearInput(selectors.createClientView.email); + await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); + await page.clearInput(selectors.createClientView.postcode); + await page.write(selectors.createClientView.postcode, '479999'); + await page.waitToClick(selectors.createClientView.createButton); + const result = await page.waitForLastSnackbar(); expect(result).toEqual(`The postcode doesn't exists. Ensure you put the correct format`); }); it(`should check for autocompleted city, province and country`, async() => { - const clientCity = await nightmare + const clientCity = await page .waitToGetProperty(`${selectors.createClientView.city}`, 'value'); - const clientProvince = await nightmare + const clientProvince = await page .waitToGetProperty(`${selectors.createClientView.province} input`, 'value'); - const clientCountry = await nightmare + const clientCountry = await page .waitToGetProperty(`${selectors.createClientView.country} input`, 'value'); expect(clientCity).toEqual('Valencia'); @@ -93,32 +90,29 @@ describe('Client create path', () => { }); it(`should create a new user with all correct data`, async() => { - const result = await nightmare - .clearInput(selectors.createClientView.postcode) - .write(selectors.createClientView.postcode, '46000') - .waitToClick(selectors.createClientView.createButton) - .waitForLastSnackbar(); + await page.clearInput(selectors.createClientView.postcode); + await page.write(selectors.createClientView.postcode, '46000'); + await page.waitToClick(selectors.createClientView.createButton); + const result = await page.waitForLastSnackbar(); expect(result).toEqual('Data saved!'); }); it('should click on the Clients button of the top bar menu', async() => { - const url = await nightmare - .waitToClick(selectors.globalItems.applicationsMenuButton) - .wait(selectors.globalItems.applicationsMenuVisible) - .waitToClick(selectors.globalItems.clientsButton) - .wait(selectors.clientsIndex.createClientButton) - .parsedUrl(); + await page.waitToClick(selectors.globalItems.applicationsMenuButton); + await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitToClick(selectors.globalItems.clientsButton); + await page.wait(selectors.clientsIndex.createClientButton); + const url = await page.parsedUrl(); expect(url.hash).toEqual('#!/client/index'); }); it(`should search for the user Carol Danvers to confirm it exists`, async() => { - const result = await nightmare - .write(selectors.clientsIndex.searchClientInput, 'Carol Danvers') - .waitToClick(selectors.clientsIndex.searchButton) - .waitForNumberOfElements(selectors.clientsIndex.searchResult, 1) - .countElement(selectors.clientsIndex.searchResult); + await page.write(selectors.clientsIndex.searchClientInput, 'Carol Danvers'); + await page.waitToClick(selectors.clientsIndex.searchButton); + await page.waitForNumberOfElements(selectors.clientsIndex.searchResult, 1); + const result = await page.countElement(selectors.clientsIndex.searchResult); expect(result).toEqual(1); }); diff --git a/e2e/paths/02-client-module/02_edit_basic_data.spec.js b/e2e/paths/02-client-module/02_edit_basic_data.spec.js index 988ad82c8..2cea50d35 100644 --- a/e2e/paths/02-client-module/02_edit_basic_data.spec.js +++ b/e2e/paths/02-client-module/02_edit_basic_data.spec.js @@ -1,175 +1,172 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client Edit basicData path', () => { - const nightmare = createNightmare(); - describe('as employee', () => { - beforeAll(() => { - nightmare - .loginAndModule('employee', 'client') - .accessToSearchResult('Bruce Wayne') - .accessToSection('client.card.basicData'); - }); - - it('should not be able to change the salesPerson', async() => { - const result = await nightmare - .wait(selectors.clientBasicData.nameInput) - .evaluate(selector => { - return document.querySelector(selector).disabled; - }, `${selectors.clientBasicData.salesPersonAutocomplete} input`); - - expect(result).toBeTruthy(); - }); - - it('should edit the client basic data but leave salesPerson untainted', async() => { - const result = await nightmare - .clearInput(selectors.clientBasicData.nameInput) - .write(selectors.clientBasicData.nameInput, 'Ptonomy Wallace') - .clearInput(selectors.clientBasicData.contactInput) - .write(selectors.clientBasicData.contactInput, 'David Haller') - .clearInput(selectors.clientBasicData.phoneInput) - .write(selectors.clientBasicData.phoneInput, '987654321') - .clearInput(selectors.clientBasicData.mobileInput) - .write(selectors.clientBasicData.mobileInput, '123456789') - .clearInput(selectors.clientBasicData.emailInput) - .write(selectors.clientBasicData.emailInput, 'PWallace@verdnatura.es') - .autocompleteSearch(selectors.clientBasicData.channelAutocomplete, 'Rumors on the streets') - .waitToClick(selectors.clientBasicData.saveButton) - .waitForLastSnackbar(); - - expect(result).toEqual('Data saved!'); - }); - - it('should confirm the name have been edited', async() => { - const result = await nightmare - .reloadSection('client.card.basicData') - .waitToGetProperty(selectors.clientBasicData.nameInput, 'value'); - - expect(result).toEqual('Ptonomy Wallace'); - }); - - it('should confirm the contact name have been edited', async() => { - const result = await nightmare - .waitToGetProperty(selectors.clientBasicData.contactInput, 'value'); - - expect(result).toEqual('David Haller'); - }); - - it('should confirm the landline phone number have been added', async() => { - const result = await nightmare - .waitToGetProperty(selectors.clientBasicData.phoneInput, 'value'); - - expect(result).toEqual('987654321'); - }); - - it('should confirm the mobile phone number have been added', async() => { - const result = await nightmare - .waitToGetProperty(selectors.clientBasicData.mobileInput, 'value'); - - expect(result).toEqual('123456789'); - }); - - it('should confirm the email have been edited', async() => { - const result = await nightmare - .waitToGetProperty(selectors.clientBasicData.emailInput, 'value'); - - expect(result).toEqual('PWallace@verdnatura.es'); - }); - - it('should confirm the channel have been selected', async() => { - const result = await nightmare - .waitToGetProperty(`${selectors.clientBasicData.channelAutocomplete} input`, 'value'); - - expect(result).toEqual('Rumors on the streets'); - }); + let page; + beforeAll(async() => { + page = await openPage(); + await page.loginAndModule('employee', 'client'); + // await page.accessToSearchResult('Bruce Wayne'); + // await page.accessToSection('client.card.basicData'); }); - describe('as salesAssistant', () => { - beforeAll(() => { - nightmare - .loginAndModule('salesASsistant', 'client') - .accessToSearchResult('Ptonomy Wallace') - .accessToSection('client.card.basicData'); - }); - - it('should be able to change the salesPerson', async() => { - const result = await nightmare - .wait(selectors.clientBasicData.nameInput) - .evaluate(selector => { - return document.querySelector(selector).disabled; - }, `${selectors.clientBasicData.salesPersonAutocomplete} input`); - - expect(result).toBeFalsy(); - }); - - it('should edit the client basic data including salesPerson', async() => { - const result = await nightmare - .clearInput(selectors.clientBasicData.nameInput) - .write(selectors.clientBasicData.nameInput, 'Ororo Munroe') - .clearInput(selectors.clientBasicData.contactInput) - .write(selectors.clientBasicData.contactInput, 'Black Panther') - .clearInput(selectors.clientBasicData.phoneInput) - .write(selectors.clientBasicData.phoneInput, '123456789') - .clearInput(selectors.clientBasicData.mobileInput) - .write(selectors.clientBasicData.mobileInput, '987654321') - .clearInput(selectors.clientBasicData.emailInput) - .write(selectors.clientBasicData.emailInput, 'Storm@verdnatura.es') - .autocompleteSearch(selectors.clientBasicData.salesPersonAutocomplete, 'replenisherNick') - .autocompleteSearch(selectors.clientBasicData.channelAutocomplete, 'Metropolis newspaper') - .waitToClick(selectors.clientBasicData.saveButton) - .waitForLastSnackbar(); - - expect(result).toEqual('Data saved!'); - }); - - it('should now confirm the name have been edited', async() => { - const result = await nightmare - .reloadSection('client.card.basicData') - .waitToGetProperty(selectors.clientBasicData.nameInput, 'value'); - - expect(result).toEqual('Ororo Munroe'); - }); - - it('should now confirm the contact name have been edited', async() => { - const result = await nightmare - .waitToGetProperty(selectors.clientBasicData.contactInput, 'value'); - - expect(result).toEqual('Black Panther'); - }); - - it('should now confirm the landline phone number have been added', async() => { - const result = await nightmare - .waitToGetProperty(selectors.clientBasicData.phoneInput, 'value'); - - expect(result).toEqual('123456789'); - }); - - it('should now confirm the mobile phone number have been added', async() => { - const result = await nightmare - .waitToGetProperty(selectors.clientBasicData.mobileInput, 'value'); - - expect(result).toEqual('987654321'); - }); - - it('should now confirm the email have been edited', async() => { - const result = await nightmare - .waitToGetProperty(selectors.clientBasicData.emailInput, 'value'); - - expect(result).toEqual('Storm@verdnatura.es'); - }); - - it('should confirm the sales person have been selected', async() => { - const result = await nightmare - .waitToGetProperty(`${selectors.clientBasicData.salesPersonAutocomplete} input`, 'value'); - - expect(result).toEqual('replenisherNick'); - }); - - it('should now confirm the channel have been selected', async() => { - const result = await nightmare - .waitToGetProperty(`${selectors.clientBasicData.channelAutocomplete} input`, 'value'); - - expect(result).toEqual('Metropolis newspaper'); - }); + afterAll(async() => { + page.close(); }); + + // describe('as employee', () => { + it('should not be able to change the salesPerson', async() => { + // await page.wait(selectors.clientBasicData.nameInput); + // const result = await page.evaluate(selector => { + // return document.querySelector(selector).disabled; + // }, `${selectors.clientBasicData.salesPersonAutocomplete} input`); + + expect(result).toBeTruthy(); + }); + + // it('should edit the client basic data but leave salesPerson untainted', async() => { + // await page.clearInput(selectors.clientBasicData.nameInput); + // await page.write(selectors.clientBasicData.nameInput, 'Ptonomy Wallace'); + // await page.clearInput(selectors.clientBasicData.contactInput); + // await page.write(selectors.clientBasicData.contactInput, 'David Haller'); + // await page.clearInput(selectors.clientBasicData.phoneInput); + // await page.write(selectors.clientBasicData.phoneInput, '987654321'); + // await page.clearInput(selectors.clientBasicData.mobileInput); + // await page.write(selectors.clientBasicData.mobileInput, '123456789'); + // await page.clearInput(selectors.clientBasicData.emailInput); + // await page.write(selectors.clientBasicData.emailInput, 'PWallace@verdnatura.es'); + // await page.autocompleteSearch(selectors.clientBasicData.channelAutocomplete, 'Rumors on the streets'); + // await page.waitToClick(selectors.clientBasicData.saveButton); + // const result = await page.waitForLastSnackbar(); + + // expect(result).toEqual('Data saved!'); + // }); + + // it('should confirm the name have been edited', async() => { + // await page.reloadSection('client.card.basicData'); + // const result = await page.waitToGetProperty(selectors.clientBasicData.nameInput, 'value'); + + // expect(result).toEqual('Ptonomy Wallace'); + // }); + + // it('should confirm the contact name have been edited', async() => { + // const result = await page + // .waitToGetProperty(selectors.clientBasicData.contactInput, 'value'); + + // expect(result).toEqual('David Haller'); + // }); + + // it('should confirm the landline phone number have been added', async() => { + // const result = await page + // .waitToGetProperty(selectors.clientBasicData.phoneInput, 'value'); + + // expect(result).toEqual('987654321'); + // }); + + // it('should confirm the mobile phone number have been added', async() => { + // const result = await page + // .waitToGetProperty(selectors.clientBasicData.mobileInput, 'value'); + + // expect(result).toEqual('123456789'); + // }); + + // it('should confirm the email have been edited', async() => { + // const result = await page + // .waitToGetProperty(selectors.clientBasicData.emailInput, 'value'); + + // expect(result).toEqual('PWallace@verdnatura.es'); + // }); + + // it('should confirm the channel have been selected', async() => { + // const result = await page + // .waitToGetProperty(`${selectors.clientBasicData.channelAutocomplete} input`, 'value'); + + // expect(result).toEqual('Rumors on the streets'); + // }); + // }); + + // describe('as salesAssistant', () => { + // beforeAll(async() => { + // await page.loginAndModule('salesASsistant', 'client'); + // await page.accessToSearchResult('Ptonomy Wallace'); + // await page.accessToSection('client.card.basicData'); + // }); + + // it('should be able to change the salesPerson', async() => { + // await page.wait(selectors.clientBasicData.nameInput); + // const result = await page.evaluate(selector => { + // return document.querySelector(selector).disabled; + // }, `${selectors.clientBasicData.salesPersonAutocomplete} input`); + + // expect(result).toBeFalsy(); + // }); + + // it('should edit the client basic data including salesPerson', async() => { + // await page.clearInput(selectors.clientBasicData.nameInput); + // await page.write(selectors.clientBasicData.nameInput, 'Ororo Munroe'); + // await page.clearInput(selectors.clientBasicData.contactInput); + // await page.write(selectors.clientBasicData.contactInput, 'Black Panther'); + // await page.clearInput(selectors.clientBasicData.phoneInput); + // await page.write(selectors.clientBasicData.phoneInput, '123456789'); + // await page.clearInput(selectors.clientBasicData.mobileInput); + // await page.write(selectors.clientBasicData.mobileInput, '987654321'); + // await page.clearInput(selectors.clientBasicData.emailInput); + // await page.write(selectors.clientBasicData.emailInput, 'Storm@verdnatura.es'); + // await page.autocompleteSearch(selectors.clientBasicData.salesPersonAutocomplete, 'replenisherNick'); + // await page.autocompleteSearch(selectors.clientBasicData.channelAutocomplete, 'Metropolis newspaper'); + // await page.waitToClick(selectors.clientBasicData.saveButton); + // const result = await page.waitForLastSnackbar(); + + // expect(result).toEqual('Data saved!'); + // }); + + // it('should now confirm the name have been edited', async() => { + // await page.reloadSection('client.card.basicData'); + // const result = await page.waitToGetProperty(selectors.clientBasicData.nameInput, 'value'); + + // expect(result).toEqual('Ororo Munroe'); + // }); + + // it('should now confirm the contact name have been edited', async() => { + // const result = await page + // .waitToGetProperty(selectors.clientBasicData.contactInput, 'value'); + + // expect(result).toEqual('Black Panther'); + // }); + + // it('should now confirm the landline phone number have been added', async() => { + // const result = await page + // .waitToGetProperty(selectors.clientBasicData.phoneInput, 'value'); + + // expect(result).toEqual('123456789'); + // }); + + // it('should now confirm the mobile phone number have been added', async() => { + // const result = await page + // .waitToGetProperty(selectors.clientBasicData.mobileInput, 'value'); + + // expect(result).toEqual('987654321'); + // }); + + // it('should now confirm the email have been edited', async() => { + // const result = await page + // .waitToGetProperty(selectors.clientBasicData.emailInput, 'value'); + + // expect(result).toEqual('Storm@verdnatura.es'); + // }); + + // it('should confirm the sales person have been selected', async() => { + // const result = await page + // .waitToGetProperty(`${selectors.clientBasicData.salesPersonAutocomplete} input`, 'value'); + + // expect(result).toEqual('replenisherNick'); + // }); + + // it('should now confirm the channel have been selected', async() => { + // const result = await page + // .waitToGetProperty(`${selectors.clientBasicData.channelAutocomplete} input`, 'value'); + + // expect(result).toEqual('Metropolis newspaper'); + // }); + // }); }); diff --git a/e2e/paths/02-client-module/03_edit_fiscal_data.spec.js b/e2e/paths/02-client-module/03_edit_fiscal_data.spec.js index 9d41ed223..8514e1efa 100644 --- a/e2e/paths/02-client-module/03_edit_fiscal_data.spec.js +++ b/e2e/paths/02-client-module/03_edit_fiscal_data.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client Edit fiscalData path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/04_edit_billing_data.spec.js b/e2e/paths/02-client-module/04_edit_billing_data.spec.js index ffea943f1..66a5ba2fe 100644 --- a/e2e/paths/02-client-module/04_edit_billing_data.spec.js +++ b/e2e/paths/02-client-module/04_edit_billing_data.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client Edit billing data path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/05_add_address.spec.js b/e2e/paths/02-client-module/05_add_address.spec.js index 4502a9be1..1391041e5 100644 --- a/e2e/paths/02-client-module/05_add_address.spec.js +++ b/e2e/paths/02-client-module/05_add_address.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client Add address path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/06_add_address_notes.spec.js b/e2e/paths/02-client-module/06_add_address_notes.spec.js index a37fef529..afd2d3fd4 100644 --- a/e2e/paths/02-client-module/06_add_address_notes.spec.js +++ b/e2e/paths/02-client-module/06_add_address_notes.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client add address notes path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/07_edit_web_access.spec.js b/e2e/paths/02-client-module/07_edit_web_access.spec.js index 999b1c123..d5071913a 100644 --- a/e2e/paths/02-client-module/07_edit_web_access.spec.js +++ b/e2e/paths/02-client-module/07_edit_web_access.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client Edit web access path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/08_add_notes.spec.js b/e2e/paths/02-client-module/08_add_notes.spec.js index 1528dd79b..9872da0e6 100644 --- a/e2e/paths/02-client-module/08_add_notes.spec.js +++ b/e2e/paths/02-client-module/08_add_notes.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client Add notes path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/09_add_credit.spec.js b/e2e/paths/02-client-module/09_add_credit.spec.js index 60ff2d347..b55970b82 100644 --- a/e2e/paths/02-client-module/09_add_credit.spec.js +++ b/e2e/paths/02-client-module/09_add_credit.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client Add credit path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/10_add_greuge.spec.js b/e2e/paths/02-client-module/10_add_greuge.spec.js index 46fdf65e3..d8b4a0ca0 100644 --- a/e2e/paths/02-client-module/10_add_greuge.spec.js +++ b/e2e/paths/02-client-module/10_add_greuge.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client Add greuge path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/11_mandate.spec.js b/e2e/paths/02-client-module/11_mandate.spec.js index 4048ae8a2..cfee7d195 100644 --- a/e2e/paths/02-client-module/11_mandate.spec.js +++ b/e2e/paths/02-client-module/11_mandate.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client mandate path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/12_lock_of_verified_data.spec.js b/e2e/paths/02-client-module/12_lock_of_verified_data.spec.js index 398185ba5..67ec0d243 100644 --- a/e2e/paths/02-client-module/12_lock_of_verified_data.spec.js +++ b/e2e/paths/02-client-module/12_lock_of_verified_data.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client lock verified data path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/13_log.spec.js b/e2e/paths/02-client-module/13_log.spec.js index 60ab6e7bc..eddfd85c2 100644 --- a/e2e/paths/02-client-module/13_log.spec.js +++ b/e2e/paths/02-client-module/13_log.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client log path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/14_balance.spec.js b/e2e/paths/02-client-module/14_balance.spec.js index 56e1336c8..09713c171 100644 --- a/e2e/paths/02-client-module/14_balance.spec.js +++ b/e2e/paths/02-client-module/14_balance.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client balance path', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/15_user_config.spec.js b/e2e/paths/02-client-module/15_user_config.spec.js index d47e4a447..dcf771890 100644 --- a/e2e/paths/02-client-module/15_user_config.spec.js +++ b/e2e/paths/02-client-module/15_user_config.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('User config', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/16_web_payment.spec.js b/e2e/paths/02-client-module/16_web_payment.spec.js index 3e9a26b75..890885f02 100644 --- a/e2e/paths/02-client-module/16_web_payment.spec.js +++ b/e2e/paths/02-client-module/16_web_payment.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client web Payment', () => { const nightmare = createNightmare(); diff --git a/e2e/paths/02-client-module/17_dms.spec.js b/e2e/paths/02-client-module/17_dms.spec.js index 236401cf4..2eb27b65d 100644 --- a/e2e/paths/02-client-module/17_dms.spec.js +++ b/e2e/paths/02-client-module/17_dms.spec.js @@ -1,5 +1,5 @@ import selectors from '../../helpers/selectors.js'; -import createNightmare from '../../helpers/nightmare'; +import openPage from '../../helpers/puppeteer'; describe('Client DMS', () => { const nightmare = createNightmare(); diff --git a/gulpfile.js b/gulpfile.js index 0519da531..2b77eb008 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -190,19 +190,14 @@ e2eOnly.description = `Runs the e2e tests only`; function e2eSingleRun() { require('@babel/register')({presets: ['@babel/preset-env']}); require('@babel/polyfill'); + let getBrowser = require('./e2e/helpers/puppeteer').getBrowser; const jasmine = require('gulp-jasmine'); const SpecReporter = require('jasmine-spec-reporter').SpecReporter; - const createNightmare = require('./e2e/helpers/nightmare'); - - if (argv.show || argv.s) - process.env.E2E_SHOW = true; - process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = true; - const specFiles = [ `${__dirname}/e2e/paths/01*/*[sS]pec.js`, - // `${__dirname}/e2e/paths/02*/*[sS]pec.js`, + `${__dirname}/e2e/paths/02*/*[sS]pec.js`, // `${__dirname}/e2e/paths/03*/*[sS]pec.js`, // `${__dirname}/e2e/paths/04*/*[sS]pec.js`, // `${__dirname}/e2e/paths/05*/*[sS]pec.js`, @@ -228,11 +223,9 @@ function e2eSingleRun() { }) ] }) - // .on('jasmineDone', async function() { - // const nightmare = await createNightmare(); - // nightmare.end(() => {}); - // await browser.close(); - // }) + .on('jasmineDone', async function() { + await getBrowser().close(); + }) ); } e2eSingleRun.description = `Runs the e2e tests just once`; @@ -263,7 +256,7 @@ e2e = gulp.series(docker, async function isBackendReady() { log(`Backend ready after ${attempts} attempt(s)`); return attempts; -}, e2eOnly); +}, e2eSingleRun); e2e.description = `Restarts database and runs the e2e tests`; function smokesOnly() { @@ -611,5 +604,6 @@ module.exports = { docker, dockerStart, dockerWait, - backendStatus + backendStatus, + e2eSingleRun }; diff --git a/package-lock.json b/package-lock.json index c51e1b9f3..a08515094 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2250,7 +2250,7 @@ }, "util": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { @@ -3044,7 +3044,7 @@ "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { "cache-base": "^1.0.1", @@ -3580,7 +3580,7 @@ "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { "collection-visit": "^1.0.0", @@ -3786,7 +3786,7 @@ "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -5069,7 +5069,7 @@ "dependencies": { "fs-extra": { "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "dev": true, "requires": { @@ -6003,7 +6003,7 @@ }, "file-loader": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "resolved": "http://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", "dev": true, "requires": { @@ -7202,7 +7202,7 @@ "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha1-bXcPDrUjrHgWTXK15xqIdyZcw+o=", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "requires": { "global-prefix": "^1.0.1", @@ -7919,7 +7919,7 @@ "dependencies": { "es6-promise": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", "dev": true }, @@ -8987,7 +8987,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "^3.0.1" @@ -9363,7 +9363,7 @@ "jasmine-spec-reporter": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", - "integrity": "sha1-HWMq7ANBZwrTJPkrqEtLMrNeniI=", + "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==", "dev": true, "requires": { "colors": "1.1.2" @@ -11434,7 +11434,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "minstache": { @@ -11978,7 +11978,7 @@ }, "jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true }, @@ -12642,7 +12642,7 @@ "dependencies": { "minimist": { "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", "dev": true }, @@ -13247,7 +13247,7 @@ }, "pretty-bytes": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", + "resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", "dev": true, "requires": { @@ -13356,7 +13356,7 @@ }, "through2": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", + "resolved": "http://registry.npmjs.org/through2/-/through2-0.2.3.tgz", "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", "dev": true, "requires": { @@ -13406,6 +13406,12 @@ "ipaddr.js": "1.9.0" } }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -13477,6 +13483,89 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, + "puppeteer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-2.0.0.tgz", + "integrity": "sha512-t3MmTWzQxPRP71teU6l0jX47PHXlc4Z52sQv4LJQSZLq1ttkKS2yGM3gaI57uQwZkNaoGd0+HPPMELZkcyhlqA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^3.0.0", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "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" + } + }, + "https-proxy-agent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", + "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -13803,7 +13892,7 @@ "dependencies": { "jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } @@ -14203,7 +14292,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -14336,7 +14425,7 @@ "dependencies": { "source-map": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { @@ -14771,7 +14860,7 @@ "snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { "define-property": "^1.0.0", @@ -14822,7 +14911,7 @@ "snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { "kind-of": "^3.2.0" @@ -15103,7 +15192,7 @@ "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { "extend-shallow": "^3.0.0" @@ -17316,7 +17405,7 @@ }, "globby": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { @@ -17329,7 +17418,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -17678,6 +17767,15 @@ "signal-exit": "^3.0.2" } }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, "x-xss-protection": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz",