creevey 0.8.1-beta.1 → 0.8.1-sb7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/package.json +22 -19
- package/lib/cjs/cli.js +0 -5
- package/lib/cjs/client/addon/Manager.js +0 -264
- package/lib/cjs/client/addon/components/Addon.js +0 -55
- package/lib/cjs/client/addon/components/Icons.js +0 -46
- package/lib/cjs/client/addon/components/Panel.js +0 -72
- package/lib/cjs/client/addon/components/TestSelect.js +0 -65
- package/lib/cjs/client/addon/components/Tools.js +0 -95
- package/lib/cjs/client/addon/decorator.js +0 -11
- package/lib/cjs/client/addon/index.js +0 -31
- package/lib/cjs/client/addon/preset.ie11.js +0 -74
- package/lib/cjs/client/addon/preset.js +0 -62
- package/lib/cjs/client/addon/readyForCapture.js +0 -12
- package/lib/cjs/client/addon/register.js +0 -72
- package/lib/cjs/client/addon/utils.js +0 -42
- package/lib/cjs/client/addon/withCreevey.js +0 -350
- package/lib/cjs/client/shared/components/ImagesView/BlendView.js +0 -87
- package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +0 -92
- package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +0 -154
- package/lib/cjs/client/shared/components/ImagesView/SlideView.js +0 -166
- package/lib/cjs/client/shared/components/ImagesView/SwapView.js +0 -91
- package/lib/cjs/client/shared/components/ImagesView/index.js +0 -45
- package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +0 -50
- package/lib/cjs/client/shared/components/PageFooter/Paging.js +0 -94
- package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +0 -82
- package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +0 -119
- package/lib/cjs/client/shared/components/ResultsPage.js +0 -143
- package/lib/cjs/client/shared/creeveyClientApi.js +0 -76
- package/lib/cjs/client/shared/helpers.js +0 -411
- package/lib/cjs/client/shared/viewMode.js +0 -17
- package/lib/cjs/client/web/142.js +0 -2
- package/lib/cjs/client/web/142.js.LICENSE.txt +0 -12
- package/lib/cjs/client/web/32.js +0 -1
- package/lib/cjs/client/web/551.js +0 -1
- package/lib/cjs/client/web/566.js +0 -2
- package/lib/cjs/client/web/566.js.LICENSE.txt +0 -31
- package/lib/cjs/client/web/691.js +0 -2
- package/lib/cjs/client/web/691.js.LICENSE.txt +0 -8
- package/lib/cjs/client/web/725.js +0 -1
- package/lib/cjs/client/web/index.html +0 -19
- package/lib/cjs/client/web/main.js +0 -2
- package/lib/cjs/client/web/main.js.LICENSE.txt +0 -49
- package/lib/cjs/creevey.js +0 -69
- package/lib/cjs/index.js +0 -39
- package/lib/cjs/server/config.js +0 -93
- package/lib/cjs/server/docker.js +0 -146
- package/lib/cjs/server/extract.js +0 -46
- package/lib/cjs/server/index.js +0 -83
- package/lib/cjs/server/loaders/babel/creevey-plugin.js +0 -86
- package/lib/cjs/server/loaders/babel/helpers.js +0 -469
- package/lib/cjs/server/loaders/babel/register.js +0 -124
- package/lib/cjs/server/loaders/hooks/mdx.js +0 -30
- package/lib/cjs/server/loaders/hooks/svelte.js +0 -65
- package/lib/cjs/server/loaders/webpack/compile.js +0 -269
- package/lib/cjs/server/loaders/webpack/creevey-loader.js +0 -172
- package/lib/cjs/server/loaders/webpack/dummy-hmr.js +0 -39
- package/lib/cjs/server/loaders/webpack/mdx-loader.js +0 -72
- package/lib/cjs/server/loaders/webpack/start.js +0 -41
- package/lib/cjs/server/logger.js +0 -48
- package/lib/cjs/server/master/api.js +0 -71
- package/lib/cjs/server/master/index.js +0 -152
- package/lib/cjs/server/master/master.js +0 -57
- package/lib/cjs/server/master/pool.js +0 -197
- package/lib/cjs/server/master/runner.js +0 -281
- package/lib/cjs/server/master/server.js +0 -131
- package/lib/cjs/server/messages.js +0 -264
- package/lib/cjs/server/selenium/browser.js +0 -656
- package/lib/cjs/server/selenium/index.js +0 -31
- package/lib/cjs/server/selenium/selenoid.js +0 -172
- package/lib/cjs/server/stories.js +0 -153
- package/lib/cjs/server/storybook/entry.js +0 -53
- package/lib/cjs/server/storybook/helpers.js +0 -158
- package/lib/cjs/server/storybook/providers/browser.js +0 -74
- package/lib/cjs/server/storybook/providers/nodejs.js +0 -239
- package/lib/cjs/server/update.js +0 -79
- package/lib/cjs/server/utils.js +0 -169
- package/lib/cjs/server/worker/chai-image.js +0 -142
- package/lib/cjs/server/worker/helpers.js +0 -69
- package/lib/cjs/server/worker/index.js +0 -15
- package/lib/cjs/server/worker/reporter.js +0 -108
- package/lib/cjs/server/worker/worker.js +0 -268
- package/lib/cjs/shared/index.js +0 -101
- package/lib/cjs/shared/serializeRegExp.js +0 -42
- package/lib/cjs/types.js +0 -74
- package/lib/esm/cli.js +0 -4
- package/lib/esm/client/addon/Manager.js +0 -248
- package/lib/esm/client/addon/components/Addon.js +0 -39
- package/lib/esm/client/addon/components/Icons.js +0 -31
- package/lib/esm/client/addon/components/Panel.js +0 -53
- package/lib/esm/client/addon/components/TestSelect.js +0 -51
- package/lib/esm/client/addon/components/Tools.js +0 -74
- package/lib/esm/client/addon/decorator.js +0 -2
- package/lib/esm/client/addon/index.js +0 -2
- package/lib/esm/client/addon/preset.ie11.js +0 -59
- package/lib/esm/client/addon/preset.js +0 -41
- package/lib/esm/client/addon/readyForCapture.js +0 -5
- package/lib/esm/client/addon/register.js +0 -51
- package/lib/esm/client/addon/utils.js +0 -32
- package/lib/esm/client/addon/withCreevey.js +0 -323
- package/lib/esm/client/shared/components/ImagesView/BlendView.js +0 -67
- package/lib/esm/client/shared/components/ImagesView/ImagesView.js +0 -69
- package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +0 -131
- package/lib/esm/client/shared/components/ImagesView/SlideView.js +0 -143
- package/lib/esm/client/shared/components/ImagesView/SwapView.js +0 -71
- package/lib/esm/client/shared/components/ImagesView/index.js +0 -5
- package/lib/esm/client/shared/components/PageFooter/PageFooter.js +0 -36
- package/lib/esm/client/shared/components/PageFooter/Paging.js +0 -80
- package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +0 -68
- package/lib/esm/client/shared/components/PageHeader/PageHeader.js +0 -97
- package/lib/esm/client/shared/components/ResultsPage.js +0 -115
- package/lib/esm/client/shared/creeveyClientApi.js +0 -67
- package/lib/esm/client/shared/helpers.js +0 -353
- package/lib/esm/client/shared/viewMode.js +0 -6
- package/lib/esm/creevey.js +0 -54
- package/lib/esm/index.js +0 -3
- package/lib/esm/server/config.js +0 -70
- package/lib/esm/server/docker.js +0 -123
- package/lib/esm/server/extract.js +0 -32
- package/lib/esm/server/index.js +0 -64
- package/lib/esm/server/loaders/babel/creevey-plugin.js +0 -72
- package/lib/esm/server/loaders/babel/helpers.js +0 -452
- package/lib/esm/server/loaders/babel/register.js +0 -103
- package/lib/esm/server/loaders/hooks/mdx.js +0 -15
- package/lib/esm/server/loaders/hooks/svelte.js +0 -49
- package/lib/esm/server/loaders/webpack/compile.js +0 -246
- package/lib/esm/server/loaders/webpack/creevey-loader.js +0 -152
- package/lib/esm/server/loaders/webpack/dummy-hmr.js +0 -32
- package/lib/esm/server/loaders/webpack/mdx-loader.js +0 -58
- package/lib/esm/server/loaders/webpack/start.js +0 -27
- package/lib/esm/server/logger.js +0 -20
- package/lib/esm/server/master/api.js +0 -60
- package/lib/esm/server/master/index.js +0 -131
- package/lib/esm/server/master/master.js +0 -38
- package/lib/esm/server/master/pool.js +0 -176
- package/lib/esm/server/master/runner.js +0 -259
- package/lib/esm/server/master/server.js +0 -107
- package/lib/esm/server/messages.js +0 -232
- package/lib/esm/server/selenium/browser.js +0 -623
- package/lib/esm/server/selenium/index.js +0 -2
- package/lib/esm/server/selenium/selenoid.js +0 -149
- package/lib/esm/server/stories.js +0 -135
- package/lib/esm/server/storybook/entry.js +0 -27
- package/lib/esm/server/storybook/helpers.js +0 -97
- package/lib/esm/server/storybook/providers/browser.js +0 -58
- package/lib/esm/server/storybook/providers/nodejs.js +0 -216
- package/lib/esm/server/update.js +0 -61
- package/lib/esm/server/utils.js +0 -128
- package/lib/esm/server/worker/chai-image.js +0 -130
- package/lib/esm/server/worker/helpers.js +0 -60
- package/lib/esm/server/worker/index.js +0 -1
- package/lib/esm/server/worker/reporter.js +0 -86
- package/lib/esm/server/worker/worker.js +0 -238
- package/lib/esm/shared/index.js +0 -78
- package/lib/esm/shared/serializeRegExp.js +0 -24
- package/lib/esm/types.js +0 -43
- package/lib/types/cli.d.ts +0 -1
- package/lib/types/client/addon/Manager.d.ts +0 -37
- package/lib/types/client/addon/components/Addon.d.ts +0 -8
- package/lib/types/client/addon/components/Icons.d.ts +0 -7
- package/lib/types/client/addon/components/Panel.d.ts +0 -9
- package/lib/types/client/addon/components/TestSelect.d.ts +0 -8
- package/lib/types/client/addon/components/Tools.d.ts +0 -6
- package/lib/types/client/addon/decorator.d.ts +0 -1
- package/lib/types/client/addon/index.d.ts +0 -2
- package/lib/types/client/addon/preset.d.ts +0 -23
- package/lib/types/client/addon/preset.ie11.d.ts +0 -10
- package/lib/types/client/addon/readyForCapture.d.ts +0 -6
- package/lib/types/client/addon/register.d.ts +0 -3
- package/lib/types/client/addon/utils.d.ts +0 -3
- package/lib/types/client/addon/withCreevey.d.ts +0 -24
- package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +0 -3
- package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +0 -24
- package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +0 -3
- package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +0 -3
- package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +0 -3
- package/lib/types/client/shared/components/ImagesView/index.d.ts +0 -5
- package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +0 -8
- package/lib/types/client/shared/components/PageFooter/Paging.d.ts +0 -7
- package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +0 -12
- package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +0 -16
- package/lib/types/client/shared/components/ResultsPage.d.ts +0 -18
- package/lib/types/client/shared/creeveyClientApi.d.ts +0 -9
- package/lib/types/client/shared/helpers.d.ts +0 -46
- package/lib/types/client/shared/viewMode.d.ts +0 -4
- package/lib/types/client/web/CreeveyApp.d.ts +0 -11
- package/lib/types/client/web/CreeveyContext.d.ts +0 -11
- package/lib/types/client/web/CreeveyLoader.d.ts +0 -2
- package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +0 -19
- package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +0 -6
- package/lib/types/client/web/CreeveyView/SideBar/SideBar.d.ts +0 -14
- package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +0 -12
- package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +0 -33
- package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +0 -7
- package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +0 -10
- package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +0 -9
- package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +0 -6
- package/lib/types/client/web/CreeveyView/SideBar/index.d.ts +0 -1
- package/lib/types/client/web/KeyboardEventsContext.d.ts +0 -13
- package/lib/types/client/web/index.d.ts +0 -4
- package/lib/types/creevey.d.ts +0 -1
- package/lib/types/index.d.ts +0 -2
- package/lib/types/server/config.d.ts +0 -4
- package/lib/types/server/docker.d.ts +0 -7
- package/lib/types/server/extract.d.ts +0 -2
- package/lib/types/server/index.d.ts +0 -2
- package/lib/types/server/loaders/babel/creevey-plugin.d.ts +0 -1
- package/lib/types/server/loaders/babel/helpers.d.ts +0 -19
- package/lib/types/server/loaders/babel/register.d.ts +0 -5
- package/lib/types/server/loaders/hooks/mdx.d.ts +0 -1
- package/lib/types/server/loaders/hooks/svelte.d.ts +0 -1
- package/lib/types/server/loaders/webpack/compile.d.ts +0 -2
- package/lib/types/server/loaders/webpack/creevey-loader.d.ts +0 -4
- package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +0 -10
- package/lib/types/server/loaders/webpack/mdx-loader.d.ts +0 -6
- package/lib/types/server/loaders/webpack/start.d.ts +0 -1
- package/lib/types/server/logger.d.ts +0 -10
- package/lib/types/server/master/api.d.ts +0 -7
- package/lib/types/server/master/index.d.ts +0 -3
- package/lib/types/server/master/master.d.ts +0 -7
- package/lib/types/server/master/pool.d.ts +0 -31
- package/lib/types/server/master/runner.d.ts +0 -26
- package/lib/types/server/master/server.d.ts +0 -2
- package/lib/types/server/messages.d.ts +0 -29
- package/lib/types/server/selenium/browser.d.ts +0 -19
- package/lib/types/server/selenium/index.d.ts +0 -2
- package/lib/types/server/selenium/selenoid.d.ts +0 -3
- package/lib/types/server/stories.d.ts +0 -8
- package/lib/types/server/storybook/entry.d.ts +0 -17
- package/lib/types/server/storybook/helpers.d.ts +0 -24
- package/lib/types/server/storybook/providers/browser.d.ts +0 -2
- package/lib/types/server/storybook/providers/nodejs.d.ts +0 -6
- package/lib/types/server/update.d.ts +0 -2
- package/lib/types/server/utils.d.ts +0 -23
- package/lib/types/server/worker/chai-image.d.ts +0 -6
- package/lib/types/server/worker/helpers.d.ts +0 -8
- package/lib/types/server/worker/index.d.ts +0 -1
- package/lib/types/server/worker/reporter.d.ts +0 -8
- package/lib/types/server/worker/worker.d.ts +0 -4
- package/lib/types/shared/index.d.ts +0 -7
- package/lib/types/shared/serializeRegExp.d.ts +0 -9
- package/lib/types/types.d.ts +0 -486
package/lib/esm/server/update.js
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
import path from 'path';
|
2
|
-
import fs, { mkdirSync } from 'fs';
|
3
|
-
import micromatch from 'micromatch';
|
4
|
-
import { isDefined } from '../types';
|
5
|
-
|
6
|
-
function tryToLoadTestsData(filename) {
|
7
|
-
try {
|
8
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
9
|
-
return require(filename);
|
10
|
-
} catch (_) {
|
11
|
-
/* noop */
|
12
|
-
}
|
13
|
-
}
|
14
|
-
|
15
|
-
const actualRegex = /^(.*)-actual-(\d+)\.png$/i;
|
16
|
-
|
17
|
-
function approve(dirents, srcPath, dstPath, testPaths, isMatch) {
|
18
|
-
dirents.filter(dirent => dirent.isFile()).map(dirent => actualRegex.exec(dirent.name)).filter(isDefined).filter(([fileName, imageName]) => !testPaths || testPaths.find(([token]) => token == imageName) && isMatch(path.join(srcPath, fileName))).reduce((images, [, imageName, retry]) => Number(retry) > (images.get(imageName) ?? -1) ? images.set(imageName, Number(retry)) : images, new Map()).forEach((retry, imageName) => {
|
19
|
-
mkdirSync(dstPath, {
|
20
|
-
recursive: true
|
21
|
-
});
|
22
|
-
fs.copyFileSync(path.join(srcPath, `${imageName}-actual-${retry}.png`), path.join(dstPath, `${imageName}.png`));
|
23
|
-
});
|
24
|
-
}
|
25
|
-
|
26
|
-
function traverse(srcPath, dstPath, testPaths, isMatch) {
|
27
|
-
const dirents = fs.readdirSync(srcPath, {
|
28
|
-
withFileTypes: true
|
29
|
-
});
|
30
|
-
approve(dirents, srcPath, dstPath, testPaths, isMatch);
|
31
|
-
dirents.filter(dirent => dirent.isDirectory()).map(dirent => [dirent.name, testPaths === null || testPaths === void 0 ? void 0 : testPaths.map(([token, ...restPath]) => token == dirent.name ? restPath : null).filter(isDefined)]).filter(([, paths]) => !paths || paths.length > 0).forEach(([dirname, paths]) => traverse(path.join(srcPath, dirname), path.join(dstPath, dirname), paths, isMatch));
|
32
|
-
}
|
33
|
-
|
34
|
-
export default function update(config, grepPattern) {
|
35
|
-
const {
|
36
|
-
reportDir,
|
37
|
-
screenDir
|
38
|
-
} = config;
|
39
|
-
const isMatch = grepPattern ? micromatch.matcher(grepPattern, {
|
40
|
-
contains: true
|
41
|
-
}) : () => true;
|
42
|
-
const testsMeta = tryToLoadTestsData(`${reportDir}/tests.json`);
|
43
|
-
const testsReport = tryToLoadTestsData(`${reportDir}/data`);
|
44
|
-
let testPaths = null;
|
45
|
-
|
46
|
-
if (testsMeta && testsReport) {
|
47
|
-
testPaths = Object.values(testsMeta).filter(isDefined).filter(({
|
48
|
-
id
|
49
|
-
}) => {
|
50
|
-
var _testsReport$id;
|
51
|
-
|
52
|
-
return ((_testsReport$id = testsReport[id]) === null || _testsReport$id === void 0 ? void 0 : _testsReport$id.status) == 'failed';
|
53
|
-
}).map(({
|
54
|
-
storyPath,
|
55
|
-
testName,
|
56
|
-
browser
|
57
|
-
}) => [...storyPath, ...(testName ? [testName] : []), browser]);
|
58
|
-
}
|
59
|
-
|
60
|
-
traverse(reportDir, screenDir, testPaths, value => isMatch(path.relative(reportDir, value)));
|
61
|
-
}
|
package/lib/esm/server/utils.js
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
import { createWriteStream, existsSync, readFileSync, unlink } from 'fs';
|
2
|
-
import cluster from 'cluster';
|
3
|
-
import { isDefined, noop, isFunction } from '../types';
|
4
|
-
import { emitShutdownMessage, sendShutdownMessage } from './messages';
|
5
|
-
import findCacheDir from 'find-cache-dir';
|
6
|
-
import { get } from 'https';
|
7
|
-
export const isShuttingDown = {
|
8
|
-
current: false
|
9
|
-
};
|
10
|
-
export const LOCALHOST_REGEXP = /(localhost|127\.0\.0\.1)/i;
|
11
|
-
export const extensions = ['.js', '.jsx', '.ts', '.tsx'];
|
12
|
-
export const skipOptionKeys = ['in', 'kinds', 'stories', 'tests', 'reason'];
|
13
|
-
|
14
|
-
function matchBy(pattern, value) {
|
15
|
-
return typeof pattern == 'string' && pattern == value || Array.isArray(pattern) && pattern.includes(value) || pattern instanceof RegExp && pattern.test(value) || !isDefined(pattern);
|
16
|
-
}
|
17
|
-
|
18
|
-
export function shouldSkip(browser, meta, skipOptions, test) {
|
19
|
-
if (typeof skipOptions != 'object') {
|
20
|
-
return skipOptions;
|
21
|
-
}
|
22
|
-
|
23
|
-
for (const skipKey in skipOptions) {
|
24
|
-
const reason = shouldSkipByOption(browser, meta, skipOptions[skipKey], skipKey, test);
|
25
|
-
if (reason) return reason;
|
26
|
-
}
|
27
|
-
|
28
|
-
return false;
|
29
|
-
}
|
30
|
-
export function shouldSkipByOption(browser, meta, skipOption, reason, test) {
|
31
|
-
if (Array.isArray(skipOption)) {
|
32
|
-
for (const skip of skipOption) {
|
33
|
-
const result = shouldSkipByOption(browser, meta, skip, reason, test);
|
34
|
-
if (result) return result;
|
35
|
-
}
|
36
|
-
|
37
|
-
return false;
|
38
|
-
}
|
39
|
-
|
40
|
-
const {
|
41
|
-
in: browsers,
|
42
|
-
kinds,
|
43
|
-
stories,
|
44
|
-
tests
|
45
|
-
} = skipOption;
|
46
|
-
const {
|
47
|
-
kind,
|
48
|
-
story
|
49
|
-
} = meta;
|
50
|
-
const skipByBrowser = matchBy(browsers, browser);
|
51
|
-
const skipByKind = matchBy(kinds, kind);
|
52
|
-
const skipByStory = matchBy(stories, story);
|
53
|
-
const skipByTest = !isDefined(test) || matchBy(tests, test);
|
54
|
-
return skipByBrowser && skipByKind && skipByStory && skipByTest && reason;
|
55
|
-
}
|
56
|
-
export async function shutdownWorkers() {
|
57
|
-
isShuttingDown.current = true;
|
58
|
-
await Promise.all(Object.values(cluster.workers ?? {}).filter(isDefined).filter(worker => worker.isConnected()).map(worker => new Promise(resolve => {
|
59
|
-
const timeout = setTimeout(() => worker.kill(), 10000);
|
60
|
-
worker.on('exit', () => {
|
61
|
-
clearTimeout(timeout);
|
62
|
-
resolve();
|
63
|
-
});
|
64
|
-
sendShutdownMessage(worker);
|
65
|
-
})));
|
66
|
-
emitShutdownMessage();
|
67
|
-
}
|
68
|
-
export function shutdown() {
|
69
|
-
// eslint-disable-next-line no-process-exit
|
70
|
-
process.exit();
|
71
|
-
}
|
72
|
-
export function getCreeveyCache() {
|
73
|
-
return findCacheDir({
|
74
|
-
name: 'creevey',
|
75
|
-
cwd: __dirname
|
76
|
-
});
|
77
|
-
}
|
78
|
-
export async function runSequence(seq, predicate) {
|
79
|
-
for (const fn of seq) {
|
80
|
-
if (predicate()) await fn();
|
81
|
-
}
|
82
|
-
}
|
83
|
-
export function testsToImages(tests) {
|
84
|
-
return new Set([].concat(...tests.filter(isDefined).map(({
|
85
|
-
browser,
|
86
|
-
testName,
|
87
|
-
storyPath,
|
88
|
-
results
|
89
|
-
}) => {
|
90
|
-
var _results$slice$;
|
91
|
-
|
92
|
-
return Object.keys((results === null || results === void 0 ? void 0 : (_results$slice$ = results.slice(-1)[0]) === null || _results$slice$ === void 0 ? void 0 : _results$slice$.images) ?? {}).map(image => `${[...storyPath, testName, browser, browser == image ? undefined : image].filter(isDefined).join('/')}.png`);
|
93
|
-
})));
|
94
|
-
} // https://tuhrig.de/how-to-know-you-are-inside-a-docker-container/
|
95
|
-
|
96
|
-
export const isInsideDocker = existsSync('/proc/1/cgroup') && /docker/.test(readFileSync('/proc/1/cgroup', 'utf8'));
|
97
|
-
export const downloadBinary = (downloadUrl, destination) => new Promise((resolve, reject) => get(downloadUrl, response => {
|
98
|
-
if (response.statusCode == 302) {
|
99
|
-
const {
|
100
|
-
location
|
101
|
-
} = response.headers;
|
102
|
-
if (!location) return reject(new Error(`Couldn't download selenoid. Status code: ${response.statusCode ?? 'UNKNOWN'}`));
|
103
|
-
return resolve(downloadBinary(location, destination));
|
104
|
-
}
|
105
|
-
|
106
|
-
if (response.statusCode != 200) return reject(new Error(`Couldn't download selenoid. Status code: ${response.statusCode ?? 'UNKNOWN'}`));
|
107
|
-
const fileStream = createWriteStream(destination);
|
108
|
-
response.pipe(fileStream);
|
109
|
-
fileStream.on('finish', () => {
|
110
|
-
fileStream.close();
|
111
|
-
resolve();
|
112
|
-
});
|
113
|
-
fileStream.on('error', error => {
|
114
|
-
unlink(destination, noop);
|
115
|
-
reject(error);
|
116
|
-
});
|
117
|
-
}));
|
118
|
-
export function removeProps(obj, propPath) {
|
119
|
-
const [prop, ...restPath] = propPath;
|
120
|
-
|
121
|
-
if (restPath.length > 0) {
|
122
|
-
if (typeof prop == 'string') obj[prop] && removeProps(obj[prop], restPath);
|
123
|
-
if (isFunction(prop)) Object.keys(obj).filter(prop).forEach(key => obj[key] && removeProps(obj[key], restPath));
|
124
|
-
} else {
|
125
|
-
if (typeof prop == 'string') delete obj[prop];
|
126
|
-
if (isFunction(prop)) Object.keys(obj).filter(prop).forEach(key => delete obj[key]);
|
127
|
-
}
|
128
|
-
}
|
@@ -1,130 +0,0 @@
|
|
1
|
-
import { PNG } from 'pngjs';
|
2
|
-
import pixelmatch from 'pixelmatch';
|
3
|
-
|
4
|
-
function normalizeImageSize(image, width, height) {
|
5
|
-
const normalizedImage = Buffer.alloc(4 * width * height);
|
6
|
-
|
7
|
-
for (let y = 0; y < height; y++) {
|
8
|
-
for (let x = 0; x < width; x++) {
|
9
|
-
const i = (y * width + x) * 4;
|
10
|
-
|
11
|
-
if (x < image.width && y < image.height) {
|
12
|
-
const j = (y * image.width + x) * 4;
|
13
|
-
normalizedImage[i + 0] = image.data[j + 0];
|
14
|
-
normalizedImage[i + 1] = image.data[j + 1];
|
15
|
-
normalizedImage[i + 2] = image.data[j + 2];
|
16
|
-
normalizedImage[i + 3] = image.data[j + 3];
|
17
|
-
} else {
|
18
|
-
normalizedImage[i + 0] = 0;
|
19
|
-
normalizedImage[i + 1] = 0;
|
20
|
-
normalizedImage[i + 2] = 0;
|
21
|
-
normalizedImage[i + 3] = 0;
|
22
|
-
}
|
23
|
-
}
|
24
|
-
}
|
25
|
-
|
26
|
-
return normalizedImage;
|
27
|
-
}
|
28
|
-
|
29
|
-
function hasDiffPixels(diff) {
|
30
|
-
for (let i = 0; i < diff.length; i += 4) {
|
31
|
-
if (diff[i + 0] == 255 && diff[i + 1] == 0 && diff[i + 2] == 0 && diff[i + 3] == 255) return true;
|
32
|
-
}
|
33
|
-
|
34
|
-
return false;
|
35
|
-
}
|
36
|
-
|
37
|
-
function compareImages(expect, actual, diffOptions) {
|
38
|
-
const expectImage = PNG.sync.read(expect);
|
39
|
-
const actualImage = PNG.sync.read(actual);
|
40
|
-
const width = Math.max(actualImage.width, expectImage.width);
|
41
|
-
const height = Math.max(actualImage.height, expectImage.height);
|
42
|
-
const diffImage = new PNG({
|
43
|
-
width,
|
44
|
-
height
|
45
|
-
});
|
46
|
-
let actualImageData = actualImage.data;
|
47
|
-
|
48
|
-
if (actualImage.width < width || actualImage.height < height) {
|
49
|
-
actualImageData = normalizeImageSize(actualImage, width, height);
|
50
|
-
}
|
51
|
-
|
52
|
-
let expectImageData = expectImage.data;
|
53
|
-
|
54
|
-
if (expectImage.width < width || expectImage.height < height) {
|
55
|
-
expectImageData = normalizeImageSize(expectImage, width, height);
|
56
|
-
}
|
57
|
-
|
58
|
-
pixelmatch(expectImageData, actualImageData, diffImage.data, width, height, diffOptions);
|
59
|
-
return {
|
60
|
-
isEqual: !hasDiffPixels(diffImage.data),
|
61
|
-
diff: PNG.sync.write(diffImage)
|
62
|
-
};
|
63
|
-
}
|
64
|
-
|
65
|
-
export default function (getExpected, diffOptions) {
|
66
|
-
return function chaiImage({
|
67
|
-
Assertion
|
68
|
-
}, utils) {
|
69
|
-
async function assertImage(actual, imageName) {
|
70
|
-
let onCompare = () => Promise.resolve();
|
71
|
-
|
72
|
-
let expected = await getExpected(imageName);
|
73
|
-
if (!(expected instanceof Buffer) && expected != null) ({
|
74
|
-
expected,
|
75
|
-
onCompare
|
76
|
-
} = expected);
|
77
|
-
|
78
|
-
if (expected == null) {
|
79
|
-
await onCompare(actual);
|
80
|
-
return imageName ? `Expected image '${imageName}' does not exists` : 'Expected image does not exists';
|
81
|
-
}
|
82
|
-
|
83
|
-
if (actual.equals(expected)) return await onCompare(actual);
|
84
|
-
const {
|
85
|
-
isEqual,
|
86
|
-
diff
|
87
|
-
} = compareImages(expected, actual, diffOptions);
|
88
|
-
if (isEqual) return await onCompare(actual);
|
89
|
-
await onCompare(actual, expected, diff);
|
90
|
-
return imageName ? `Expected image '${imageName}' to match` : 'Expected image to match';
|
91
|
-
}
|
92
|
-
|
93
|
-
utils.addMethod(Assertion.prototype, 'matchImage', async function matchImage(imageName) {
|
94
|
-
const actual = utils.flag(this, 'object');
|
95
|
-
const errorMessage = await assertImage(typeof actual == 'string' ? Buffer.from(actual, 'base64') : actual, imageName);
|
96
|
-
|
97
|
-
if (errorMessage) {
|
98
|
-
throw createImageError(imageName ? {
|
99
|
-
[imageName]: errorMessage
|
100
|
-
} : errorMessage);
|
101
|
-
}
|
102
|
-
});
|
103
|
-
utils.addMethod(Assertion.prototype, 'matchImages', async function matchImages() {
|
104
|
-
const errors = {};
|
105
|
-
await Promise.all(Object.entries(utils.flag(this, 'object')).map(async ([imageName, imageOrBase64]) => {
|
106
|
-
let errorMessage;
|
107
|
-
|
108
|
-
try {
|
109
|
-
errorMessage = await assertImage(typeof imageOrBase64 == 'string' ? Buffer.from(imageOrBase64, 'base64') : imageOrBase64, imageName);
|
110
|
-
} catch (error) {
|
111
|
-
errorMessage = error.stack;
|
112
|
-
}
|
113
|
-
|
114
|
-
if (errorMessage) {
|
115
|
-
errors[imageName] = errorMessage;
|
116
|
-
}
|
117
|
-
}));
|
118
|
-
|
119
|
-
if (Object.keys(errors).length > 0) {
|
120
|
-
throw createImageError(errors);
|
121
|
-
}
|
122
|
-
});
|
123
|
-
};
|
124
|
-
}
|
125
|
-
|
126
|
-
function createImageError(imageErrors) {
|
127
|
-
const error = new Error('Expected image to match');
|
128
|
-
error.images = imageErrors;
|
129
|
-
return error;
|
130
|
-
}
|
@@ -1,60 +0,0 @@
|
|
1
|
-
import { Suite, Test } from 'mocha';
|
2
|
-
import { isDefined } from '../../types';
|
3
|
-
import { loadTestsFromStories } from '../stories';
|
4
|
-
|
5
|
-
function findOrCreateSuite(name, parent) {
|
6
|
-
const suite = parent.suites.find(({
|
7
|
-
title
|
8
|
-
}) => title == name) || new Suite(name, parent.ctx);
|
9
|
-
|
10
|
-
if (!suite.parent) {
|
11
|
-
suite.parent = parent;
|
12
|
-
parent.addSuite(suite);
|
13
|
-
}
|
14
|
-
|
15
|
-
return suite;
|
16
|
-
}
|
17
|
-
|
18
|
-
function createTest(name, fn, skip = false) {
|
19
|
-
const test = new Test(name, skip ? undefined : fn);
|
20
|
-
test.pending = Boolean(skip); // NOTE Can't define skip reason in mocha https://github.com/mochajs/mocha/issues/2026
|
21
|
-
|
22
|
-
test.skipReason = skip;
|
23
|
-
return test;
|
24
|
-
}
|
25
|
-
|
26
|
-
function addTest(rootSuite, test) {
|
27
|
-
const [testName, ...suitePath] = [...test.storyPath, test.testName].reverse().filter(isDefined);
|
28
|
-
const suite = suitePath.reduceRight((subSuite, suiteName) => findOrCreateSuite(suiteName, subSuite), rootSuite);
|
29
|
-
const mochaTest = createTest(testName, test.fn, test.skip);
|
30
|
-
suite.addTest(mochaTest);
|
31
|
-
mochaTest.ctx = Object.setPrototypeOf({
|
32
|
-
id: test.id,
|
33
|
-
story: test.story
|
34
|
-
}, suite.ctx);
|
35
|
-
return mochaTest;
|
36
|
-
}
|
37
|
-
|
38
|
-
function removeTestOrSuite(testOrSuite) {
|
39
|
-
const {
|
40
|
-
parent
|
41
|
-
} = testOrSuite;
|
42
|
-
if (!parent) return;
|
43
|
-
if (testOrSuite instanceof Test) parent.tests = parent.tests.filter(test => test != testOrSuite);
|
44
|
-
if (testOrSuite instanceof Suite) parent.suites = parent.suites.filter(suite => suite != testOrSuite);
|
45
|
-
if (parent.tests.length == 0 && parent.suites.length == 0) removeTestOrSuite(parent);
|
46
|
-
}
|
47
|
-
|
48
|
-
export async function addTestsFromStories(rootSuite, config, {
|
49
|
-
browser,
|
50
|
-
...options
|
51
|
-
}) {
|
52
|
-
const mochaTestsById = new Map();
|
53
|
-
const tests = await loadTestsFromStories([browser], listener => config.storiesProvider(config, options, listener), testsDiff => Object.entries(testsDiff).forEach(([id, newTest]) => {
|
54
|
-
const oldTest = mochaTestsById.get(id);
|
55
|
-
mochaTestsById.delete(id);
|
56
|
-
if (oldTest) removeTestOrSuite(oldTest);
|
57
|
-
if (newTest) mochaTestsById.set(id, addTest(rootSuite, newTest));
|
58
|
-
}));
|
59
|
-
Object.values(tests).filter(isDefined).forEach(test => mochaTestsById.set(test.id, addTest(rootSuite, test)));
|
60
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
export { default } from './worker';
|
@@ -1,86 +0,0 @@
|
|
1
|
-
import chalk from 'chalk';
|
2
|
-
import { reporters } from 'mocha';
|
3
|
-
import prefix from 'loglevel-plugin-prefix';
|
4
|
-
import { isDefined, isImageError } from '../../types';
|
5
|
-
import { getLogger } from '../logger';
|
6
|
-
const testLevels = {
|
7
|
-
INFO: chalk.green('PASS'),
|
8
|
-
WARN: chalk.yellow('START'),
|
9
|
-
ERROR: chalk.red('FAIL')
|
10
|
-
};
|
11
|
-
export class CreeveyReporter extends reporters.Base {
|
12
|
-
constructor(runner, options) {
|
13
|
-
super(runner);
|
14
|
-
const {
|
15
|
-
sessionId,
|
16
|
-
topLevelSuite
|
17
|
-
} = options.reporterOptions;
|
18
|
-
const testLogger = getLogger(topLevelSuite);
|
19
|
-
prefix.apply(testLogger, {
|
20
|
-
format(level) {
|
21
|
-
return `${testLevels[level]} => (${topLevelSuite}:${chalk.gray(sessionId)})`;
|
22
|
-
}
|
23
|
-
|
24
|
-
});
|
25
|
-
runner.on('test', test => testLogger.warn(chalk.cyan(test.titlePath().join('/'))));
|
26
|
-
runner.on('pass', test => testLogger.info(chalk.cyan(test.titlePath().join('/'))));
|
27
|
-
runner.on('fail', (test, error) => testLogger.error(chalk.cyan(test.titlePath().join('/')), '\n ', getErrors(error, (error, imageName) => `${chalk.bold(imageName ?? topLevelSuite)}:${error}`, error => `${error.stack ?? error.message}`).join('\n ')));
|
28
|
-
}
|
29
|
-
|
30
|
-
}
|
31
|
-
export class TeamcityReporter extends reporters.Base {
|
32
|
-
constructor(runner, options) {
|
33
|
-
super(runner);
|
34
|
-
const topLevelSuite = this.escape(options.reporterOptions.topLevelSuite);
|
35
|
-
const reporterOptions = options.reporterOptions;
|
36
|
-
runner.on('suite', suite => suite.root ? console.log(`##teamcity[testSuiteStarted name='${topLevelSuite}' flowId='${process.pid}']`) : console.log(`##teamcity[testSuiteStarted name='${this.escape(suite.title)}' flowId='${process.pid}']`));
|
37
|
-
runner.on('test', test => console.log(`##teamcity[testStarted name='${this.escape(test.title)}' flowId='${process.pid}']`));
|
38
|
-
runner.on('fail', (test, error) => {
|
39
|
-
Object.entries(reporterOptions.images).forEach(([name, image]) => {
|
40
|
-
if (!image) return;
|
41
|
-
const filePath = test.titlePath().concat(name == topLevelSuite ? [] : [topLevelSuite]).map(this.escape).join('/'); // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
42
|
-
|
43
|
-
const {
|
44
|
-
error,
|
45
|
-
...rest
|
46
|
-
} = image;
|
47
|
-
Object.values(rest).filter(isDefined).forEach(fileName => {
|
48
|
-
console.log(`##teamcity[publishArtifacts '${reporterOptions.reportDir}/${filePath}/${fileName} => report/${filePath}']`);
|
49
|
-
console.log(`##teamcity[testMetadata testName='${this.escape(test.title)}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`);
|
50
|
-
});
|
51
|
-
}); // Output failed test as passed due TC don't support retry mechanic
|
52
|
-
// https://teamcity-support.jetbrains.com/hc/en-us/community/posts/207216829-Count-test-as-successful-if-at-least-one-try-is-successful?page=1#community_comment_207394125
|
53
|
-
|
54
|
-
reporterOptions.willRetry ? console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`) : console.log(`##teamcity[testFailed name='${this.escape(test.title)}' message='${this.escape(error.message)}' details='${this.escape(error.stack ?? '')}' flowId='${process.pid}']`);
|
55
|
-
});
|
56
|
-
runner.on('pending', test => console.log(`##teamcity[testIgnored name='${this.escape(test.title)}' message='${this.escape(typeof test.skipReason == 'boolean' ? test.title : test.skipReason)}' flowId='${process.pid}']`));
|
57
|
-
runner.on('test end', test => console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`));
|
58
|
-
runner.on('suite end', suite => suite.root || console.log(`##teamcity[testSuiteFinished name='${this.escape(suite.title)}' flowId='${process.pid}']`));
|
59
|
-
runner.on('end', () => console.log(`##teamcity[testSuiteFinished name='${topLevelSuite}' flowId='${process.pid}']`));
|
60
|
-
}
|
61
|
-
|
62
|
-
escape = str => {
|
63
|
-
if (!str) return '';
|
64
|
-
return str.toString() // eslint-disable-next-line no-control-regex
|
65
|
-
.replace(/\x1B.*?m/g, '').replace(/\|/g, '||').replace(/\n/g, '|n').replace(/\r/g, '|r').replace(/\[/g, '|[').replace(/\]/g, '|]').replace(/\u0085/g, '|x').replace(/\u2028/g, '|l').replace(/\u2029/g, '|p').replace(/'/g, "|'");
|
66
|
-
};
|
67
|
-
}
|
68
|
-
|
69
|
-
function getErrors(error, imageErrorToString, errorToString) {
|
70
|
-
const errors = [];
|
71
|
-
|
72
|
-
if (!(error instanceof Error)) {
|
73
|
-
errors.push(error);
|
74
|
-
} else if (!isImageError(error)) {
|
75
|
-
errors.push(errorToString(error));
|
76
|
-
} else if (typeof error.images == 'string') {
|
77
|
-
errors.push(imageErrorToString(error.images));
|
78
|
-
} else {
|
79
|
-
const imageErrors = error.images;
|
80
|
-
Object.keys(imageErrors).forEach(imageName => {
|
81
|
-
errors.push(imageErrorToString(imageErrors[imageName] ?? '', imageName));
|
82
|
-
});
|
83
|
-
}
|
84
|
-
|
85
|
-
return errors;
|
86
|
-
}
|