test: add visual regression testing with playwright
2
.gitignore
vendored
|
|
@ -28,6 +28,8 @@ yarn-error.log
|
||||||
/.tmp/
|
/.tmp/
|
||||||
/coverage/
|
/coverage/
|
||||||
/storybook-static/
|
/storybook-static/
|
||||||
|
/screenshots/.current/
|
||||||
|
/screenshots/.diff/
|
||||||
|
|
||||||
## temp files
|
## temp files
|
||||||
local.log
|
local.log
|
||||||
|
|
|
||||||
11
package.json
|
|
@ -30,7 +30,9 @@
|
||||||
"test:browser:all": "wtr \"packages/**/*/test/**/*.test.js\" --playwright --browsers webkit chromium firefox --coverage",
|
"test:browser:all": "wtr \"packages/**/*/test/**/*.test.js\" --playwright --browsers webkit chromium firefox --coverage",
|
||||||
"test:browser:watch": "wtr \"packages/**/*/test/**/*.test.js\" --watch",
|
"test:browser:watch": "wtr \"packages/**/*/test/**/*.test.js\" --watch",
|
||||||
"test:browserstack": "wtr --config ./web-test-runner-browserstack.config.js \"packages/form-core/test/**/*.test.js\"",
|
"test:browserstack": "wtr --config ./web-test-runner-browserstack.config.js \"packages/form-core/test/**/*.test.js\"",
|
||||||
"test:node": "node scripts/workspaces-scripts.mjs run test:node"
|
"test:node": "node scripts/workspaces-scripts.mjs run test:node",
|
||||||
|
"test:screenshots": "rimraf screenshots/.diff/ && rimraf screenshots/.current/ && mocha --require scripts/screenshots/bootstrap.js --exit --timeout 10000 \"packages/**/test/*.screenshots-test.js\"",
|
||||||
|
"test:screenshots:update": "cross-env UPDATE_SCREENSHOTS=true npm run test:screenshots"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.9.2",
|
"@changesets/cli": "^2.9.2",
|
||||||
|
|
@ -55,14 +57,21 @@
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"concurrently": "^5.2.0",
|
"concurrently": "^5.2.0",
|
||||||
|
"cross-env": "^7.0.2",
|
||||||
"eclint": "^2.8.1",
|
"eclint": "^2.8.1",
|
||||||
|
"es-dev-server": "^1.57.1",
|
||||||
|
"es6-promisify": "^6.1.1",
|
||||||
"eslint": "^6.1.0",
|
"eslint": "^6.1.0",
|
||||||
"eslint-config-prettier": "^6.11.0",
|
"eslint-config-prettier": "^6.11.0",
|
||||||
"husky": "^1.0.0",
|
"husky": "^1.0.0",
|
||||||
"lint-staged": "^10.0.0",
|
"lint-staged": "^10.0.0",
|
||||||
|
"looks-same": "^7.2.3",
|
||||||
"markdownlint-cli": "^0.17.0",
|
"markdownlint-cli": "^0.17.0",
|
||||||
|
"minimist": "^1.2.5",
|
||||||
|
"mkdirp-promise": "^5.0.1",
|
||||||
"mocha": "^7.1.1",
|
"mocha": "^7.1.1",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
|
"playwright": "^1.2.1",
|
||||||
"prettier": "^2.0.5",
|
"prettier": "^2.0.5",
|
||||||
"prettier-package-json": "^2.1.3",
|
"prettier-package-json": "^2.1.3",
|
||||||
"rimraf": "^2.6.3",
|
"rimraf": "^2.6.3",
|
||||||
|
|
|
||||||
60
packages/button/test/demos.screenshots-test.js
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* globals capture getStoryPage */
|
||||||
|
|
||||||
|
const selector = 'lion-button';
|
||||||
|
|
||||||
|
describe('buttons-button', () => {
|
||||||
|
it('main', async () => {
|
||||||
|
const id = 'buttons-button--main';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('main-hovered', async () => {
|
||||||
|
const id = 'buttons-button--main';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.hover(selector);
|
||||||
|
await capture({ selector, id: `${id}-hovered`, page });
|
||||||
|
});
|
||||||
|
it('main-focused', async () => {
|
||||||
|
const id = 'buttons-button--main';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.focus(selector);
|
||||||
|
await capture({ selector, id: `${id}-focused`, page });
|
||||||
|
});
|
||||||
|
it('handler', async () => {
|
||||||
|
const id = 'buttons-button--handler';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('icon-button', async () => {
|
||||||
|
const id = 'buttons-button--icon-button';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('icon-only', async () => {
|
||||||
|
const id = 'buttons-button--icon-only';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('icon-only-hovered', async () => {
|
||||||
|
const id = 'buttons-button--icon-only';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.hover(selector);
|
||||||
|
await capture({ selector, id: `${id}-hovered`, page });
|
||||||
|
});
|
||||||
|
it('icon-only-focused', async () => {
|
||||||
|
const id = 'buttons-button--icon-only';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.focus(selector);
|
||||||
|
await capture({ selector, id: `${id}-focused`, page });
|
||||||
|
});
|
||||||
|
it('disabled', async () => {
|
||||||
|
const id = 'buttons-button--disabled';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('within-form', async () => {
|
||||||
|
const id = 'buttons-button--within-form';
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"commander": "^2.20.0",
|
"commander": "^2.20.0",
|
||||||
"deepmerge": "^4.0.0",
|
"deepmerge": "^4.0.0",
|
||||||
"es-dev-server": "^1.18.1",
|
"es-dev-server": "^1.57.1",
|
||||||
"es-module-lexer": "^0.3.6",
|
"es-module-lexer": "^0.3.6",
|
||||||
"glob": "^7.1.6",
|
"glob": "^7.1.6",
|
||||||
"htm": "^3.0.3",
|
"htm": "^3.0.3",
|
||||||
|
|
|
||||||
131
packages/select-rich/test/demos.screenshots-test.js
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
/* globals capture getStoryPage */
|
||||||
|
|
||||||
|
const selector = 'lion-select-rich';
|
||||||
|
|
||||||
|
describe('forms-select-rich', () => {
|
||||||
|
it('main', async () => {
|
||||||
|
const id = `forms-select-rich--main`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('main-opened', async () => {
|
||||||
|
const id = `forms-select-rich--main`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const el = document.querySelector('lion-select-rich');
|
||||||
|
el.opened = true;
|
||||||
|
});
|
||||||
|
await capture({
|
||||||
|
selector,
|
||||||
|
id: `${id}-opened`,
|
||||||
|
page,
|
||||||
|
endClipSelector: 'lion-options',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('options-with-html', async () => {
|
||||||
|
const id = `forms-select-rich--options-with-html`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('options-with-html-opened', async () => {
|
||||||
|
const id = `forms-select-rich--options-with-html`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const el = document.querySelector('lion-select-rich');
|
||||||
|
el.opened = true;
|
||||||
|
});
|
||||||
|
await capture({
|
||||||
|
selector,
|
||||||
|
id: `${id}-opened`,
|
||||||
|
page,
|
||||||
|
endClipSelector: 'lion-options',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('many-options-with-scrolling-opened', async () => {
|
||||||
|
const id = `forms-select-rich--many-options-with-scrolling`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const el = document.querySelector('lion-select-rich');
|
||||||
|
el.opened = true;
|
||||||
|
});
|
||||||
|
await capture({
|
||||||
|
selector,
|
||||||
|
id: `${id}-opened`,
|
||||||
|
page,
|
||||||
|
endClipSelector: 'lion-options',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('read-only-prefilled', async () => {
|
||||||
|
const id = `forms-select-rich--read-only-prefilled`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('disabled-select', async () => {
|
||||||
|
const id = `forms-select-rich--disabled-select`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('disabled-option-opened', async () => {
|
||||||
|
const id = `forms-select-rich--disabled-option`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const el = document.querySelector('lion-select-rich');
|
||||||
|
el.opened = true;
|
||||||
|
});
|
||||||
|
await capture({
|
||||||
|
selector,
|
||||||
|
id: `${id}-opened`,
|
||||||
|
page,
|
||||||
|
endClipSelector: 'lion-options',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('validation', async () => {
|
||||||
|
const id = `forms-select-rich--validation`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const el = document.querySelector('lion-select-rich');
|
||||||
|
el.updateComplete.then(() => {
|
||||||
|
el.touched = true;
|
||||||
|
el.dirty = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('render-options', async () => {
|
||||||
|
const id = `forms-select-rich--render-options`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('interaction-mode-mac', async () => {
|
||||||
|
const id = `forms-select-rich--interaction-mode`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.click('lion-select-rich');
|
||||||
|
await page.keyboard.press('ArrowDown');
|
||||||
|
await capture({
|
||||||
|
selector,
|
||||||
|
id: `${id}-mac`,
|
||||||
|
page,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('interaction-mode-windows-linux', async () => {
|
||||||
|
const id = `forms-select-rich--interaction-mode`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await page.click('lion-select-rich:last-of-type');
|
||||||
|
await page.keyboard.press('ArrowDown');
|
||||||
|
await capture({
|
||||||
|
selector: 'lion-select-rich:last-of-type',
|
||||||
|
id: `${id}-windows-linux`,
|
||||||
|
page,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('no-default-selection', async () => {
|
||||||
|
const id = `forms-select-rich--no-default-selection`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
it('single-option', async () => {
|
||||||
|
const id = `forms-select-rich--single-option`;
|
||||||
|
const page = await getStoryPage(id);
|
||||||
|
await capture({ selector, id, page });
|
||||||
|
});
|
||||||
|
});
|
||||||
BIN
screenshots/buttons/button/disabled.png
Normal file
|
After Width: | Height: | Size: 898 B |
BIN
screenshots/buttons/button/handler.png
Normal file
|
After Width: | Height: | Size: 2 KiB |
BIN
screenshots/buttons/button/icon-button.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
screenshots/buttons/button/icon-only-focused.png
Normal file
|
After Width: | Height: | Size: 771 B |
BIN
screenshots/buttons/button/icon-only-hovered.png
Normal file
|
After Width: | Height: | Size: 829 B |
BIN
screenshots/buttons/button/icon-only.png
Normal file
|
After Width: | Height: | Size: 739 B |
BIN
screenshots/buttons/button/main-focused.png
Normal file
|
After Width: | Height: | Size: 820 B |
BIN
screenshots/buttons/button/main-hovered.png
Normal file
|
After Width: | Height: | Size: 843 B |
BIN
screenshots/buttons/button/main.png
Normal file
|
After Width: | Height: | Size: 783 B |
BIN
screenshots/buttons/button/within-form.png
Normal file
|
After Width: | Height: | Size: 817 B |
BIN
screenshots/forms/select-rich/disabled-option-opened.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
screenshots/forms/select-rich/disabled-select.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
screenshots/forms/select-rich/interaction-mode-mac.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
screenshots/forms/select-rich/interaction-mode-windows-linux.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
screenshots/forms/select-rich/main-opened.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
screenshots/forms/select-rich/main.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
BIN
screenshots/forms/select-rich/no-default-selection.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
screenshots/forms/select-rich/options-with-html-opened.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
screenshots/forms/select-rich/options-with-html.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
screenshots/forms/select-rich/read-only-prefilled.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
screenshots/forms/select-rich/render-options.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
screenshots/forms/select-rich/single-option.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
screenshots/forms/select-rich/validation.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
5
scripts/screenshots/bootstrap.js
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
const { createCapture, getPage, getStoryPage } = require('./index.js');
|
||||||
|
|
||||||
|
global.capture = createCapture();
|
||||||
|
global.getPage = getPage;
|
||||||
|
global.getStoryPage = getStoryPage;
|
||||||
282
scripts/screenshots/index.js
Normal file
|
|
@ -0,0 +1,282 @@
|
||||||
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
|
const { chromium } = require('playwright');
|
||||||
|
const looksSame = require('looks-same');
|
||||||
|
const { join } = require('path');
|
||||||
|
const mkdirp = require('mkdirp-promise');
|
||||||
|
const fs = require('fs');
|
||||||
|
const { promisify } = require('es6-promisify');
|
||||||
|
const minimist = require('minimist');
|
||||||
|
const { mdjsTransformer } = require('@mdjs/core');
|
||||||
|
const { createConfig, startServer } = require('es-dev-server');
|
||||||
|
const nodePath = require('path');
|
||||||
|
|
||||||
|
const access = promisify(fs.access);
|
||||||
|
const compareScreenshots = promisify(looksSame);
|
||||||
|
const createScreenshotsDiff = promisify(looksSame.createDiff);
|
||||||
|
const args = minimist(process.argv);
|
||||||
|
|
||||||
|
const DIFF_FOLDER_PREFIX = '.diff';
|
||||||
|
const CURRENT_FOLDER_PREFIX = '.current';
|
||||||
|
const ROOT = 'screenshots';
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
function log(line) {
|
||||||
|
// console.info(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} root
|
||||||
|
* @param {string} id
|
||||||
|
* @param {string} selector
|
||||||
|
* @return {{file: string, folder: string, path: string}}
|
||||||
|
*/
|
||||||
|
async function buildPath({ root, id, selector }) {
|
||||||
|
log(`Building path for ${id} - ${selector}`);
|
||||||
|
|
||||||
|
const [, category, component, file] = /(\w*)-(.*)--(.*)$/g.exec(id);
|
||||||
|
|
||||||
|
const extension = '.png';
|
||||||
|
|
||||||
|
const paths = {
|
||||||
|
file,
|
||||||
|
folder: join(root, category, component),
|
||||||
|
path: join(root, category, component, file + extension),
|
||||||
|
};
|
||||||
|
|
||||||
|
log(`Path is ${paths.path}`);
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PATHS = {
|
||||||
|
root: ROOT,
|
||||||
|
diffRoot: join(ROOT, DIFF_FOLDER_PREFIX),
|
||||||
|
currentRoot: join(ROOT, CURRENT_FOLDER_PREFIX),
|
||||||
|
};
|
||||||
|
|
||||||
|
async function start() {
|
||||||
|
const config = createConfig({
|
||||||
|
nodeResolve: true,
|
||||||
|
preserveSymlinks: true,
|
||||||
|
rootDir: nodePath.join(__dirname, '../../storybook-static/'),
|
||||||
|
responseTransformers: [mdjsTransformer],
|
||||||
|
});
|
||||||
|
console.log('⚠️ Screenshots tests are made with builded storybook');
|
||||||
|
try {
|
||||||
|
return await startServer(config);
|
||||||
|
} catch (e) {
|
||||||
|
return start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const serverPromise = start();
|
||||||
|
|
||||||
|
const browserPromise = chromium.launch({
|
||||||
|
ignoreDefaultArgs: ['--hide-scrollbars'],
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('beforeExit', () => {
|
||||||
|
browserPromise.then(browser => browser.close());
|
||||||
|
serverPromise.then(server => server.close());
|
||||||
|
});
|
||||||
|
|
||||||
|
async function getPage(path) {
|
||||||
|
const browser = await browserPromise;
|
||||||
|
const server = await serverPromise;
|
||||||
|
const url = `http://127.0.0.1:${server.server.address().port}${path}`;
|
||||||
|
log(`Creating a page for ${url}`);
|
||||||
|
const page = await browser.newPage();
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
page.on('console', msg => {
|
||||||
|
if (msg._type !== 'debug') {
|
||||||
|
if (msg._type === 'warning') {
|
||||||
|
console.warn(`PAGE console.warn:`, msg._text);
|
||||||
|
} else {
|
||||||
|
console[msg._type](`PAGE console.${msg._type}:`, msg._text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.goto(url);
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
log(`Page has been created`);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getStoryPage(id) {
|
||||||
|
return getPage(`/iframe.html?id=${id}&viewMode=story`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getClip({ page, selector, endClipSelector }) {
|
||||||
|
log(`Getting clip for ${selector}`);
|
||||||
|
|
||||||
|
const clip = await page.evaluate(
|
||||||
|
([sel, endSel]) => {
|
||||||
|
const el = document.querySelector(sel);
|
||||||
|
|
||||||
|
if (!el) {
|
||||||
|
throw new Error(`An el matching selector \`${sel}\` wasn't found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const range = document.createRange();
|
||||||
|
|
||||||
|
range.setStartBefore(el);
|
||||||
|
range.setEndAfter(endSel ? document.querySelector(endSel) : el);
|
||||||
|
|
||||||
|
const rect = range.getBoundingClientRect();
|
||||||
|
const margin = 8;
|
||||||
|
|
||||||
|
const x = rect.left - margin < 0 ? 0 : rect.left - margin;
|
||||||
|
const y = rect.top - margin < 0 ? 0 : rect.top - margin;
|
||||||
|
|
||||||
|
return {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width: rect.width + (rect.left - x) * 2,
|
||||||
|
height: rect.height + (rect.top - y) * 2,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[selector, endClipSelector],
|
||||||
|
);
|
||||||
|
|
||||||
|
log(`Clip has been retrieved: ${JSON.stringify(clip)}`);
|
||||||
|
|
||||||
|
return clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getScreenshot({ root, id, selector, page, clip }) {
|
||||||
|
log(`Making a screenshot`);
|
||||||
|
|
||||||
|
const { path, folder } = await buildPath({ root, id, selector });
|
||||||
|
|
||||||
|
mkdirp(folder);
|
||||||
|
|
||||||
|
// Remove caret from screenshots to avoid caret diff
|
||||||
|
await page.evaluate(() => {
|
||||||
|
document.body.style.caretColor = 'transparent';
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.screenshot({ path, clip });
|
||||||
|
|
||||||
|
log(`Screenshot was saved in ${path}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
path,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getReference({ root, id, selector }) {
|
||||||
|
log(`Searching for the reference`);
|
||||||
|
|
||||||
|
const { path } = await buildPath({ root, id, selector });
|
||||||
|
|
||||||
|
try {
|
||||||
|
await access(path);
|
||||||
|
|
||||||
|
log(`Reference is in ${path}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
path,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
log(`Reference was not found`);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const screenshotsCompareOptions = {
|
||||||
|
highlightColor: '#ff00ff',
|
||||||
|
tolerance: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
async function invalidateScreenshots({ diffRoot: root, id, selector, reference, current }) {
|
||||||
|
const { path, folder } = await buildPath({ root, id, selector });
|
||||||
|
|
||||||
|
mkdirp(folder);
|
||||||
|
|
||||||
|
await createScreenshotsDiff({
|
||||||
|
...screenshotsCompareOptions,
|
||||||
|
reference: reference.path,
|
||||||
|
current: current.path,
|
||||||
|
diff: path,
|
||||||
|
});
|
||||||
|
|
||||||
|
log(`Screenshot is invalid. Diff saved in ${path}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
path,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function validateScreenshot(suite) {
|
||||||
|
const { current, reference } = suite;
|
||||||
|
log(`Validating screenshot`);
|
||||||
|
|
||||||
|
if (!reference.path) {
|
||||||
|
throw new Error('No reference screenshot was found.');
|
||||||
|
}
|
||||||
|
const { equal } = await compareScreenshots(
|
||||||
|
current.path,
|
||||||
|
reference.path,
|
||||||
|
screenshotsCompareOptions,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!equal) {
|
||||||
|
const { path } = await invalidateScreenshots(suite);
|
||||||
|
throw new Error(`Screenshots mismatch. Diff saved in ${path}`);
|
||||||
|
} else {
|
||||||
|
log(`Screenshot is valid`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateScreenshots = args['update-screenshots'] || process.env.UPDATE_SCREENSHOTS;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const avaConfig = JSON.parse(args._[2]);
|
||||||
|
updateScreenshots = avaConfig.updateScreenshots;
|
||||||
|
} catch (e) {
|
||||||
|
log('Could not parse config');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {capture}
|
||||||
|
*/
|
||||||
|
function createCapture() {
|
||||||
|
return async function capture({ url = '', selector = 'body', endClipSelector, page, id }) {
|
||||||
|
const suite = {
|
||||||
|
...PATHS,
|
||||||
|
url,
|
||||||
|
id,
|
||||||
|
selector,
|
||||||
|
page,
|
||||||
|
endClipSelector,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!suite.page) {
|
||||||
|
suite.page = await getPage(url);
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
suite.clip = await getClip(suite);
|
||||||
|
|
||||||
|
if (updateScreenshots) {
|
||||||
|
await getScreenshot(suite);
|
||||||
|
} else {
|
||||||
|
suite.current = await getScreenshot({ ...suite, root: suite.currentRoot });
|
||||||
|
suite.reference = await getReference(suite);
|
||||||
|
|
||||||
|
if (suite.reference) {
|
||||||
|
await validateScreenshot(suite);
|
||||||
|
} else {
|
||||||
|
throw new Error('No reference screenshot was found.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.createCapture = createCapture;
|
||||||
|
exports.getPage = getPage;
|
||||||
|
exports.getStoryPage = getStoryPage;
|
||||||
178
yarn.lock
|
|
@ -1651,9 +1651,9 @@
|
||||||
integrity sha512-1HpblP5edeENi0SKms7B+PKYdxHMBIQpaf0nAgTVsZeYgM9OJ3r9nrK/0MOUBZODAOZ1quvO3wlpuljq2hZPWA==
|
integrity sha512-1HpblP5edeENi0SKms7B+PKYdxHMBIQpaf0nAgTVsZeYgM9OJ3r9nrK/0MOUBZODAOZ1quvO3wlpuljq2hZPWA==
|
||||||
|
|
||||||
"@open-wc/demoing-storybook@^2.0.2":
|
"@open-wc/demoing-storybook@^2.0.2":
|
||||||
version "2.3.13"
|
version "2.3.14"
|
||||||
resolved "https://registry.yarnpkg.com/@open-wc/demoing-storybook/-/demoing-storybook-2.3.13.tgz#d258c3d09c4fb4fd3f587d72cf40428792c72066"
|
resolved "https://registry.yarnpkg.com/@open-wc/demoing-storybook/-/demoing-storybook-2.3.14.tgz#a99c4f1709bacd14a69bbd3669d4ea1ad4e22920"
|
||||||
integrity sha512-zQ8HJs4DmyStRA3rOlTYyvxvJnDCi41+xRGLVwEyRZ+/bN+rChUwUz+A+2i9qcuxmc8Fkw0cvPJtak0IwDAmkg==
|
integrity sha512-UzgJXuSSywfEJ3lmBmldm9MEiP3XGZ8m5hRfa7dymGqOAMXMHzQaS5PAmC5RdPIcLtUmd7CeFW3feDBadTr0wA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "^7.9.0"
|
"@babel/core" "^7.9.0"
|
||||||
"@babel/generator" "^7.9.6"
|
"@babel/generator" "^7.9.6"
|
||||||
|
|
@ -1671,7 +1671,7 @@
|
||||||
command-line-args "^5.0.2"
|
command-line-args "^5.0.2"
|
||||||
command-line-usage "^6.1.0"
|
command-line-usage "^6.1.0"
|
||||||
deepmerge "^4.2.2"
|
deepmerge "^4.2.2"
|
||||||
es-dev-server "^1.57.0"
|
es-dev-server "^1.57.1"
|
||||||
es-module-lexer "^0.3.13"
|
es-module-lexer "^0.3.13"
|
||||||
fs-extra "^8.1.0"
|
fs-extra "^8.1.0"
|
||||||
glob "^7.1.3"
|
glob "^7.1.3"
|
||||||
|
|
@ -3812,6 +3812,16 @@ color-convert@^2.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
color-name "~1.1.4"
|
color-name "~1.1.4"
|
||||||
|
|
||||||
|
color-convert@~0.5.0:
|
||||||
|
version "0.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd"
|
||||||
|
integrity sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=
|
||||||
|
|
||||||
|
color-diff@^1.1.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/color-diff/-/color-diff-1.2.0.tgz#01a7c806de47dbd5ae571da49e65489666c999a7"
|
||||||
|
integrity sha512-FN7iLBCfb97ElJU2AQXbBAFXPbKmu0XJjPU9GWWmUkIbXka+Im8Q5w1geiL9GB+AktJ4pIA6nRZD1+TlEG6/rA==
|
||||||
|
|
||||||
color-name@1.1.3:
|
color-name@1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||||
|
|
@ -3904,6 +3914,16 @@ concat-map@0.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
|
concat-stream@^1.6.2:
|
||||||
|
version "1.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
|
||||||
|
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
|
||||||
|
dependencies:
|
||||||
|
buffer-from "^1.0.0"
|
||||||
|
inherits "^2.0.3"
|
||||||
|
readable-stream "^2.2.2"
|
||||||
|
typedarray "^0.0.6"
|
||||||
|
|
||||||
concurrently@^5.2.0:
|
concurrently@^5.2.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-5.2.0.tgz#ead55121d08a0fc817085584c123cedec2e08975"
|
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-5.2.0.tgz#ead55121d08a0fc817085584c123cedec2e08975"
|
||||||
|
|
@ -4047,6 +4067,13 @@ create-react-context@0.3.0, create-react-context@^0.3.0:
|
||||||
gud "^1.0.0"
|
gud "^1.0.0"
|
||||||
warning "^4.0.3"
|
warning "^4.0.3"
|
||||||
|
|
||||||
|
cross-env@^7.0.2:
|
||||||
|
version "7.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9"
|
||||||
|
integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==
|
||||||
|
dependencies:
|
||||||
|
cross-spawn "^7.0.1"
|
||||||
|
|
||||||
cross-spawn@^4.0.0:
|
cross-spawn@^4.0.0:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
|
||||||
|
|
@ -4075,7 +4102,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
|
||||||
shebang-command "^1.2.0"
|
shebang-command "^1.2.0"
|
||||||
which "^1.2.9"
|
which "^1.2.9"
|
||||||
|
|
||||||
cross-spawn@^7.0.0:
|
cross-spawn@^7.0.0, cross-spawn@^7.0.1:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||||
|
|
@ -4866,7 +4893,7 @@ es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.5:
|
||||||
string.prototype.trimend "^1.0.1"
|
string.prototype.trimend "^1.0.1"
|
||||||
string.prototype.trimstart "^1.0.1"
|
string.prototype.trimstart "^1.0.1"
|
||||||
|
|
||||||
es-dev-server@^1.18.1, es-dev-server@^1.57.0:
|
es-dev-server@^1.18.1:
|
||||||
version "1.57.0"
|
version "1.57.0"
|
||||||
resolved "https://registry.yarnpkg.com/es-dev-server/-/es-dev-server-1.57.0.tgz#79a30dcaec7a2cd0aa998baa572551794c21ef45"
|
resolved "https://registry.yarnpkg.com/es-dev-server/-/es-dev-server-1.57.0.tgz#79a30dcaec7a2cd0aa998baa572551794c21ef45"
|
||||||
integrity sha512-vCQuXNir9L7HAxIStt2JpWHCKmudpSilhdLngWDbmkLDT+fAgy9YFLYRbs/ppU0VlrhUpjftpVvmEjRsFpib7Q==
|
integrity sha512-vCQuXNir9L7HAxIStt2JpWHCKmudpSilhdLngWDbmkLDT+fAgy9YFLYRbs/ppU0VlrhUpjftpVvmEjRsFpib7Q==
|
||||||
|
|
@ -4936,6 +4963,76 @@ es-dev-server@^1.18.1, es-dev-server@^1.57.0:
|
||||||
useragent "^2.3.0"
|
useragent "^2.3.0"
|
||||||
whatwg-url "^7.0.0"
|
whatwg-url "^7.0.0"
|
||||||
|
|
||||||
|
es-dev-server@^1.57.1:
|
||||||
|
version "1.57.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/es-dev-server/-/es-dev-server-1.57.1.tgz#c6ed4d8f4961215ce9c50f3c58604f047737eebe"
|
||||||
|
integrity sha512-wdYZCVNdCJxM9Z8V+lAqw6XfUTQZRhjbkU4Fdk/UcZqB6gJ2VaaafdBBwue9L3EWu6zVJz63btpA4Xe+kVqGUw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/core" "^7.9.0"
|
||||||
|
"@babel/plugin-proposal-dynamic-import" "^7.8.3"
|
||||||
|
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3"
|
||||||
|
"@babel/plugin-proposal-optional-chaining" "^7.9.0"
|
||||||
|
"@babel/plugin-syntax-class-properties" "^7.8.3"
|
||||||
|
"@babel/plugin-syntax-import-meta" "^7.8.3"
|
||||||
|
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
|
||||||
|
"@babel/plugin-syntax-numeric-separator" "^7.8.3"
|
||||||
|
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
|
||||||
|
"@babel/plugin-transform-template-literals" "^7.8.3"
|
||||||
|
"@babel/preset-env" "^7.9.0"
|
||||||
|
"@koa/cors" "^3.1.0"
|
||||||
|
"@open-wc/building-utils" "^2.18.0"
|
||||||
|
"@rollup/plugin-node-resolve" "^7.1.1"
|
||||||
|
"@rollup/pluginutils" "^3.0.0"
|
||||||
|
"@types/babel__core" "^7.1.3"
|
||||||
|
"@types/browserslist" "^4.8.0"
|
||||||
|
"@types/browserslist-useragent" "^3.0.0"
|
||||||
|
"@types/caniuse-api" "^3.0.0"
|
||||||
|
"@types/command-line-args" "^5.0.0"
|
||||||
|
"@types/command-line-usage" "^5.0.1"
|
||||||
|
"@types/debounce" "^1.2.0"
|
||||||
|
"@types/koa" "^2.0.48"
|
||||||
|
"@types/koa-compress" "^2.0.9"
|
||||||
|
"@types/koa-etag" "^3.0.0"
|
||||||
|
"@types/koa-static" "^4.0.1"
|
||||||
|
"@types/koa__cors" "^3.0.1"
|
||||||
|
"@types/lru-cache" "^5.1.0"
|
||||||
|
"@types/minimatch" "^3.0.3"
|
||||||
|
"@types/path-is-inside" "^1.0.0"
|
||||||
|
"@types/whatwg-url" "^6.4.0"
|
||||||
|
browserslist "^4.9.1"
|
||||||
|
browserslist-useragent "^3.0.2"
|
||||||
|
builtin-modules "^3.1.0"
|
||||||
|
camelcase "^5.3.1"
|
||||||
|
caniuse-api "^3.0.0"
|
||||||
|
caniuse-lite "^1.0.30001033"
|
||||||
|
chokidar "^3.0.0"
|
||||||
|
command-line-args "^5.0.2"
|
||||||
|
command-line-usage "^6.1.0"
|
||||||
|
debounce "^1.2.0"
|
||||||
|
deepmerge "^4.2.2"
|
||||||
|
es-module-lexer "^0.3.13"
|
||||||
|
get-stream "^5.1.0"
|
||||||
|
is-stream "^2.0.0"
|
||||||
|
isbinaryfile "^4.0.2"
|
||||||
|
koa "^2.7.0"
|
||||||
|
koa-compress "^3.0.0"
|
||||||
|
koa-etag "^3.0.0"
|
||||||
|
koa-static "^5.0.0"
|
||||||
|
lru-cache "^5.1.1"
|
||||||
|
mime-types "^2.1.27"
|
||||||
|
minimatch "^3.0.4"
|
||||||
|
open "^7.0.3"
|
||||||
|
parse5 "^5.1.1"
|
||||||
|
path-is-inside "^1.0.2"
|
||||||
|
polyfills-loader "^1.6.1"
|
||||||
|
portfinder "^1.0.21"
|
||||||
|
rollup "^2.7.2"
|
||||||
|
strip-ansi "^5.2.0"
|
||||||
|
systemjs "^6.3.1"
|
||||||
|
tslib "^1.11.1"
|
||||||
|
useragent "^2.3.0"
|
||||||
|
whatwg-url "^7.0.0"
|
||||||
|
|
||||||
es-module-lexer@^0.3.13, es-module-lexer@^0.3.24, es-module-lexer@^0.3.6:
|
es-module-lexer@^0.3.13, es-module-lexer@^0.3.24, es-module-lexer@^0.3.6:
|
||||||
version "0.3.24"
|
version "0.3.24"
|
||||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.3.24.tgz#e6b2900758e9e210d23aec2092efc13ca235adea"
|
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.3.24.tgz#e6b2900758e9e210d23aec2092efc13ca235adea"
|
||||||
|
|
@ -4960,6 +5057,11 @@ es6-error@^4.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
|
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
|
||||||
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
|
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
|
||||||
|
|
||||||
|
es6-promisify@^6.1.1:
|
||||||
|
version "6.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-6.1.1.tgz#46837651b7b06bf6fff893d03f29393668d01621"
|
||||||
|
integrity sha512-HBL8I3mIki5C1Cc9QjKUenHtnG0A5/xA8Q/AllRcfiwl2CZFXGK7ddBiCoRwAix4i2KxcQfjtIVcrVbB3vbmwg==
|
||||||
|
|
||||||
escalade@^3.0.1:
|
escalade@^3.0.1:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4"
|
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4"
|
||||||
|
|
@ -6888,6 +6990,11 @@ js-beautify@^1.8.9:
|
||||||
mkdirp "~1.0.3"
|
mkdirp "~1.0.3"
|
||||||
nopt "^4.0.3"
|
nopt "^4.0.3"
|
||||||
|
|
||||||
|
js-graph-algorithms@1.0.18:
|
||||||
|
version "1.0.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/js-graph-algorithms/-/js-graph-algorithms-1.0.18.tgz#f96ec87bf194f5c0a31365fa0e1d07b7b962d891"
|
||||||
|
integrity sha1-+W7Ie/GU9cCjE2X6Dh0Ht7li2JE=
|
||||||
|
|
||||||
js-levenshtein-esm@^1.2.0:
|
js-levenshtein-esm@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-levenshtein-esm/-/js-levenshtein-esm-1.2.0.tgz#96532c34e0c90df198c9419963c64ca3cf43ae92"
|
resolved "https://registry.yarnpkg.com/js-levenshtein-esm/-/js-levenshtein-esm-1.2.0.tgz#96532c34e0c90df198c9419963c64ca3cf43ae92"
|
||||||
|
|
@ -7378,12 +7485,12 @@ lodash@4.17.11:
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||||
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
|
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
|
||||||
|
|
||||||
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.2.0, lodash@^4.2.1:
|
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15:
|
||||||
version "4.17.15"
|
version "4.17.15"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||||
|
|
||||||
lodash@^4.17.19:
|
lodash@^4.17.19, lodash@^4.17.3, lodash@^4.2.0, lodash@^4.2.1:
|
||||||
version "4.17.19"
|
version "4.17.19"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
||||||
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
||||||
|
|
@ -7443,6 +7550,20 @@ longest-streak@^2.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
|
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
|
||||||
integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
|
integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
|
||||||
|
|
||||||
|
looks-same@^7.2.3:
|
||||||
|
version "7.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/looks-same/-/looks-same-7.2.3.tgz#ded12be01b7848591a32694a8fba48b41baba55c"
|
||||||
|
integrity sha512-e67WnUOWLpLC0+4iOsbtMx1eUBgyx7NDUOq8esSxaSO63YTwrmoppkia+9w9oR1W+QLTw4eTKHv2pVLkGdkVrw==
|
||||||
|
dependencies:
|
||||||
|
color-diff "^1.1.0"
|
||||||
|
concat-stream "^1.6.2"
|
||||||
|
fs-extra "^8.1.0"
|
||||||
|
js-graph-algorithms "1.0.18"
|
||||||
|
lodash "^4.17.3"
|
||||||
|
nested-error-stacks "^2.1.0"
|
||||||
|
parse-color "^1.0.0"
|
||||||
|
pngjs "^3.3.3"
|
||||||
|
|
||||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||||
|
|
@ -7882,6 +8003,18 @@ mkdirp-classic@^0.5.2:
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
|
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
|
||||||
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
|
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
|
||||||
|
|
||||||
|
mkdirp-promise@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1"
|
||||||
|
integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=
|
||||||
|
dependencies:
|
||||||
|
mkdirp "*"
|
||||||
|
|
||||||
|
mkdirp@*, mkdirp@~1.0.3:
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||||
|
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||||
|
|
||||||
mkdirp@0.5.4:
|
mkdirp@0.5.4:
|
||||||
version "0.5.4"
|
version "0.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512"
|
||||||
|
|
@ -7896,11 +8029,6 @@ mkdirp@0.5.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
|
|
||||||
mkdirp@~1.0.3:
|
|
||||||
version "1.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
|
||||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
|
||||||
|
|
||||||
mocha@^6.2.2:
|
mocha@^6.2.2:
|
||||||
version "6.2.3"
|
version "6.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.3.tgz#e648432181d8b99393410212664450a4c1e31912"
|
resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.3.tgz#e648432181d8b99393410212664450a4c1e31912"
|
||||||
|
|
@ -8029,6 +8157,11 @@ negotiator@0.6.2:
|
||||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
||||||
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
|
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
|
||||||
|
|
||||||
|
nested-error-stacks@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"
|
||||||
|
integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==
|
||||||
|
|
||||||
nice-try@^1.0.4:
|
nice-try@^1.0.4:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||||
|
|
@ -8543,6 +8676,13 @@ parse-author@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
author-regex "^1.0.0"
|
author-regex "^1.0.0"
|
||||||
|
|
||||||
|
parse-color@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/parse-color/-/parse-color-1.0.0.tgz#7b748b95a83f03f16a94f535e52d7f3d94658619"
|
||||||
|
integrity sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=
|
||||||
|
dependencies:
|
||||||
|
color-convert "~0.5.0"
|
||||||
|
|
||||||
parse-entities@^1.0.2, parse-entities@^1.1.0, parse-entities@^1.1.2:
|
parse-entities@^1.0.2, parse-entities@^1.1.0, parse-entities@^1.1.2:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50"
|
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50"
|
||||||
|
|
@ -8829,6 +8969,11 @@ plugin-error@^1.0.1:
|
||||||
arr-union "^3.1.0"
|
arr-union "^3.1.0"
|
||||||
extend-shallow "^3.0.2"
|
extend-shallow "^3.0.2"
|
||||||
|
|
||||||
|
pngjs@^3.3.3:
|
||||||
|
version "3.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
|
||||||
|
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
|
||||||
|
|
||||||
pngjs@^5.0.0:
|
pngjs@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
|
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
|
||||||
|
|
@ -9327,7 +9472,7 @@ read-yaml-file@^1.1.0:
|
||||||
string_decoder "^1.1.1"
|
string_decoder "^1.1.1"
|
||||||
util-deprecate "^1.0.1"
|
util-deprecate "^1.0.1"
|
||||||
|
|
||||||
readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||||
version "2.3.7"
|
version "2.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||||
|
|
@ -10998,6 +11143,11 @@ typedarray-to-buffer@^3.1.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-typedarray "^1.0.0"
|
is-typedarray "^1.0.0"
|
||||||
|
|
||||||
|
typedarray@^0.0.6:
|
||||||
|
version "0.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
typescript@^3.8.3:
|
typescript@^3.8.3:
|
||||||
version "3.9.6"
|
version "3.9.6"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a"
|
||||||
|
|
|
||||||