creevey 0.9.0-beta.2 → 0.9.0-beta.20
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/.yarn/install-state.gz +0 -0
- package/.yarnrc.yml +1 -0
- package/CHANGELOG.md +51 -0
- package/README.md +9 -1
- package/addon/README.md +3 -0
- package/addon/package.json +5 -0
- package/docs/config.md +29 -26
- package/jest.config.js +6 -0
- package/lib/cjs/cli.js +1 -0
- package/lib/cjs/client/addon/Manager.js +170 -390
- package/lib/cjs/client/addon/components/Addon.js +17 -45
- package/lib/cjs/client/addon/components/Icons.js +12 -14
- package/lib/cjs/client/addon/components/Panel.js +21 -30
- package/lib/cjs/client/addon/components/TestSelect.js +20 -31
- package/lib/cjs/client/addon/components/Tools.js +35 -65
- package/lib/cjs/client/addon/decorator.js +1 -4
- package/lib/cjs/client/addon/index.js +27 -0
- package/lib/cjs/client/addon/preset.js +3 -76
- package/lib/cjs/client/addon/preview.js +11 -0
- package/lib/cjs/client/addon/readyForCapture.js +1 -4
- package/lib/cjs/client/addon/register.js +43 -82
- package/lib/cjs/client/addon/utils.js +4 -8
- package/lib/cjs/client/addon/withCreevey.js +145 -404
- package/lib/cjs/client/shared/components/ImagesView/BlendView.js +25 -35
- package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +29 -41
- package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +46 -83
- package/lib/cjs/client/shared/components/ImagesView/SlideView.js +39 -67
- package/lib/cjs/client/shared/components/ImagesView/SwapView.js +26 -57
- package/lib/cjs/client/shared/components/ImagesView/index.js +9 -14
- package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +13 -16
- package/lib/cjs/client/shared/components/PageFooter/Paging.js +16 -37
- package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +42 -34
- package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +40 -84
- package/lib/cjs/client/shared/components/ResultsPage.js +42 -99
- package/lib/cjs/client/shared/creeveyClientApi.js +56 -93
- package/lib/cjs/client/shared/helpers.js +149 -274
- package/lib/cjs/client/shared/viewMode.js +5 -9
- package/lib/cjs/client/web/192.js +1 -0
- package/lib/cjs/client/web/632.js +43 -0
- package/lib/cjs/client/web/794.js +1 -0
- package/lib/cjs/client/web/main.js +79 -38
- package/lib/cjs/client/web/main.js.LICENSE.txt +34 -0
- package/lib/cjs/creevey.js +15 -30
- package/lib/cjs/index.js +0 -15
- package/lib/cjs/server/config.js +16 -36
- package/lib/cjs/server/docker.js +8 -34
- package/lib/cjs/server/index.js +9 -34
- package/lib/cjs/server/logger.js +7 -20
- package/lib/cjs/server/master/api.js +1 -14
- package/lib/cjs/server/master/index.js +25 -49
- package/lib/cjs/server/master/master.js +6 -21
- package/lib/cjs/server/master/pool.js +10 -53
- package/lib/cjs/server/master/runner.js +65 -105
- package/lib/cjs/server/master/server.js +10 -29
- package/lib/cjs/server/messages.js +14 -62
- package/lib/cjs/server/selenium/browser.js +149 -185
- package/lib/cjs/server/selenium/index.js +0 -4
- package/lib/cjs/server/selenium/selenoid.js +18 -44
- package/lib/cjs/server/stories.js +35 -57
- package/lib/cjs/server/storybook/providers/browser.js +15 -29
- package/lib/cjs/server/storybook/providers/hybrid.js +16 -37
- package/lib/cjs/server/telemetry.js +167 -0
- package/lib/cjs/server/testsFiles/parser.js +3 -19
- package/lib/cjs/server/testsFiles/register.js +8 -14
- package/lib/cjs/server/update.js +4 -25
- package/lib/cjs/server/utils.js +35 -76
- package/lib/cjs/server/worker/chai-image.js +1 -27
- package/lib/cjs/server/worker/helpers.js +2 -12
- package/lib/cjs/server/worker/index.js +1 -3
- package/lib/cjs/server/worker/reporter.js +16 -43
- package/lib/cjs/server/worker/worker.js +32 -72
- package/lib/cjs/shared/index.js +87 -0
- package/lib/cjs/shared/serializeRegExp.js +34 -0
- package/lib/cjs/types.js +11 -20
- package/lib/esm/cli.js +1 -1
- package/lib/esm/client/addon/Manager.js +170 -381
- package/lib/esm/client/addon/components/Addon.js +15 -34
- package/lib/esm/client/addon/components/Icons.js +10 -6
- package/lib/esm/client/addon/components/Panel.js +20 -18
- package/lib/esm/client/addon/components/TestSelect.js +19 -23
- package/lib/esm/client/addon/components/Tools.js +33 -49
- package/lib/esm/client/addon/decorator.js +1 -1
- package/lib/esm/client/addon/index.js +2 -0
- package/lib/esm/client/addon/preset.js +2 -56
- package/lib/esm/client/addon/preview.js +5 -0
- package/lib/esm/client/addon/readyForCapture.js +1 -3
- package/lib/esm/client/addon/register.js +41 -67
- package/lib/esm/client/addon/utils.js +3 -7
- package/lib/esm/client/addon/withCreevey.js +142 -388
- package/lib/esm/client/shared/components/ImagesView/BlendView.js +22 -18
- package/lib/esm/client/shared/components/ImagesView/ImagesView.js +27 -25
- package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +43 -63
- package/lib/esm/client/shared/components/ImagesView/SlideView.js +36 -47
- package/lib/esm/client/shared/components/ImagesView/SwapView.js +23 -40
- package/lib/esm/client/shared/components/PageFooter/PageFooter.js +12 -8
- package/lib/esm/client/shared/components/PageFooter/Paging.js +15 -29
- package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +40 -25
- package/lib/esm/client/shared/components/PageHeader/PageHeader.js +38 -66
- package/lib/esm/client/shared/components/ResultsPage.js +39 -75
- package/lib/esm/client/shared/creeveyClientApi.js +56 -90
- package/lib/esm/client/shared/helpers.js +133 -230
- package/lib/esm/client/shared/viewMode.js +4 -4
- package/lib/esm/client/web/192.js +1 -0
- package/lib/esm/client/web/632.js +43 -0
- package/lib/esm/client/web/794.js +1 -0
- package/lib/esm/client/web/index.html +19 -0
- package/lib/esm/client/web/main.js +79 -0
- package/lib/esm/client/web/main.js.LICENSE.txt +34 -0
- package/lib/esm/creevey.js +13 -16
- package/lib/esm/index.js +1 -4
- package/lib/esm/server/config.js +9 -16
- package/lib/esm/server/docker.js +6 -14
- package/lib/esm/server/index.js +8 -22
- package/lib/esm/server/logger.js +0 -1
- package/lib/esm/server/master/api.js +0 -9
- package/lib/esm/server/master/index.js +25 -35
- package/lib/esm/server/master/master.js +2 -7
- package/lib/esm/server/master/pool.js +8 -41
- package/lib/esm/server/master/runner.js +64 -90
- package/lib/esm/server/master/server.js +9 -11
- package/lib/esm/server/messages.js +8 -42
- package/lib/esm/server/selenium/browser.js +147 -163
- package/lib/esm/server/selenium/selenoid.js +16 -27
- package/lib/esm/server/stories.js +34 -46
- package/lib/esm/server/storybook/providers/browser.js +12 -17
- package/lib/esm/server/storybook/providers/hybrid.js +11 -22
- package/lib/esm/server/telemetry.js +160 -0
- package/lib/esm/server/testsFiles/parser.js +0 -6
- package/lib/esm/server/testsFiles/register.js +6 -7
- package/lib/esm/server/update.js +1 -13
- package/lib/esm/server/utils.js +20 -41
- package/lib/esm/server/worker/chai-image.js +0 -21
- package/lib/esm/server/worker/helpers.js +2 -9
- package/lib/esm/server/worker/reporter.js +15 -29
- package/lib/esm/server/worker/worker.js +31 -48
- package/lib/esm/shared/index.js +77 -0
- package/lib/esm/shared/serializeRegExp.js +24 -0
- package/lib/esm/types.js +5 -1
- package/lib/types/client/addon/Manager.d.ts +3 -3
- package/lib/types/client/addon/components/Addon.d.ts +1 -0
- package/lib/types/client/addon/components/Icons.d.ts +1 -0
- package/lib/types/client/addon/components/Panel.d.ts +1 -0
- package/lib/types/client/addon/components/Tools.d.ts +1 -0
- package/lib/types/client/addon/decorator.d.ts +1 -1
- package/lib/types/client/addon/index.d.ts +2 -0
- package/lib/types/client/addon/preset.d.ts +2 -24
- package/lib/types/client/addon/preview.d.ts +4 -0
- package/lib/types/client/addon/utils.d.ts +1 -0
- package/lib/types/client/addon/withCreevey.d.ts +4 -3
- package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +3 -1
- package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +3 -1
- package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +3 -1
- package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +3 -1
- package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +3 -1
- package/lib/types/client/shared/components/ResultsPage.d.ts +3 -1
- package/lib/types/client/web/CreeveyLoader.d.ts +1 -1
- package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +6 -3
- package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +1 -0
- package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +19 -14
- package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +3 -1
- package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +3 -1
- package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +1 -0
- package/lib/types/client/web/KeyboardEventsContext.d.ts +4 -2
- package/lib/types/index.d.ts +4 -1
- package/lib/types/server/logger.d.ts +6 -2
- package/lib/types/server/messages.d.ts +14 -12
- package/lib/types/server/selenium/browser.d.ts +5 -3
- package/lib/types/server/storybook/providers/browser.d.ts +2 -4
- package/lib/types/server/storybook/providers/hybrid.d.ts +2 -4
- package/lib/types/server/telemetry.d.ts +2 -0
- package/lib/types/server/utils.d.ts +5 -1
- package/lib/types/shared/index.d.ts +7 -0
- package/lib/types/shared/serializeRegExp.d.ts +9 -0
- package/lib/types/types.d.ts +29 -36
- package/package.json +132 -133
- package/types/global.d.ts +5 -0
- package/lib/cjs/client/web/1.js +0 -13
- package/lib/cjs/client/web/2.js +0 -1
- package/lib/cjs/server/extract.js +0 -50
- package/lib/cjs/server/loaders/babel/creevey-plugin.js +0 -88
- package/lib/cjs/server/loaders/babel/helpers.js +0 -479
- package/lib/cjs/server/loaders/babel/register.js +0 -126
- 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 -286
- package/lib/cjs/server/loaders/webpack/creevey-loader.js +0 -174
- package/lib/cjs/server/loaders/webpack/dummy-hmr.js +0 -44
- 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/storybook/entry.js +0 -68
- package/lib/cjs/server/storybook/helpers.js +0 -165
- package/lib/cjs/server/storybook/providers/nodejs.js +0 -239
- package/lib/cjs/shared.js +0 -124
- package/lib/esm/server/extract.js +0 -34
- package/lib/esm/server/loaders/babel/creevey-plugin.js +0 -74
- package/lib/esm/server/loaders/babel/helpers.js +0 -462
- package/lib/esm/server/loaders/babel/register.js +0 -105
- 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 -263
- package/lib/esm/server/loaders/webpack/creevey-loader.js +0 -153
- package/lib/esm/server/loaders/webpack/dummy-hmr.js +0 -36
- 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/storybook/entry.js +0 -44
- package/lib/esm/server/storybook/helpers.js +0 -106
- package/lib/esm/server/storybook/providers/nodejs.js +0 -217
- package/lib/esm/shared.js +0 -93
- package/lib/types/server/extract.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 -2
- 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/storybook/entry.d.ts +0 -18
- package/lib/types/server/storybook/helpers.d.ts +0 -24
- package/lib/types/server/storybook/providers/nodejs.d.ts +0 -9
- package/lib/types/shared.d.ts +0 -16
- package/preset.js +0 -9
- package/storybook-static/stories.json +0 -21
- package/types/mdx.d.ts +0 -6
@@ -0,0 +1,34 @@
|
|
1
|
+
/*
|
2
|
+
object-assign
|
3
|
+
(c) Sindre Sorhus
|
4
|
+
@license MIT
|
5
|
+
*/
|
6
|
+
|
7
|
+
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
8
|
+
|
9
|
+
/** @license React v0.20.2
|
10
|
+
* scheduler.production.min.js
|
11
|
+
*
|
12
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
13
|
+
*
|
14
|
+
* This source code is licensed under the MIT license found in the
|
15
|
+
* LICENSE file in the root directory of this source tree.
|
16
|
+
*/
|
17
|
+
|
18
|
+
/** @license React v17.0.2
|
19
|
+
* react-dom.production.min.js
|
20
|
+
*
|
21
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
22
|
+
*
|
23
|
+
* This source code is licensed under the MIT license found in the
|
24
|
+
* LICENSE file in the root directory of this source tree.
|
25
|
+
*/
|
26
|
+
|
27
|
+
/** @license React v17.0.2
|
28
|
+
* react.production.min.js
|
29
|
+
*
|
30
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
31
|
+
*
|
32
|
+
* This source code is licensed under the MIT license found in the
|
33
|
+
* LICENSE file in the root directory of this source tree.
|
34
|
+
*/
|
package/lib/esm/creevey.js
CHANGED
@@ -6,12 +6,9 @@ import { emitWorkerMessage } from './server/messages';
|
|
6
6
|
import { isShuttingDown, shutdown, shutdownWorkers } from './server/utils';
|
7
7
|
import { setDefaultLevel, levels } from 'loglevel';
|
8
8
|
import { logger } from './server/logger';
|
9
|
-
|
10
9
|
function shutdownOnException(reason) {
|
11
|
-
var _reason$stack;
|
12
|
-
|
13
10
|
if (isShuttingDown.current) return;
|
14
|
-
const error = reason instanceof Error ?
|
11
|
+
const error = reason instanceof Error ? reason.stack ?? reason.message : reason;
|
15
12
|
logger.error(error);
|
16
13
|
process.exitCode = -1;
|
17
14
|
if (cluster.isWorker) emitWorkerMessage({
|
@@ -20,16 +17,15 @@ function shutdownOnException(reason) {
|
|
20
17
|
error
|
21
18
|
}
|
22
19
|
});
|
23
|
-
if (cluster.
|
20
|
+
if (cluster.isPrimary && !isShuttingDown.current) void shutdownWorkers();
|
24
21
|
}
|
25
|
-
|
26
22
|
process.on('uncaughtException', shutdownOnException);
|
27
23
|
process.on('unhandledRejection', shutdownOnException);
|
28
24
|
if (cluster.isWorker) process.on('SIGINT', noop);
|
29
|
-
if (cluster.
|
25
|
+
if (cluster.isPrimary) process.on('SIGINT', shutdown);
|
30
26
|
const argv = minimist(process.argv.slice(2), {
|
31
|
-
string: ['browser', 'config', 'reporter', 'reportDir', 'screenDir'],
|
32
|
-
boolean: ['debug', '
|
27
|
+
string: ['browser', 'config', 'reporter', 'reportDir', 'screenDir', 'storybookUrl'],
|
28
|
+
boolean: ['debug', 'trace', 'ui', 'saveReport', 'tests'],
|
33
29
|
default: {
|
34
30
|
port: 3000,
|
35
31
|
saveReport: true
|
@@ -38,19 +34,20 @@ const argv = minimist(process.argv.slice(2), {
|
|
38
34
|
port: 'p',
|
39
35
|
config: 'c',
|
40
36
|
debug: 'd',
|
41
|
-
update: 'u'
|
42
|
-
extract: 'e'
|
37
|
+
update: 'u'
|
43
38
|
}
|
44
|
-
});
|
39
|
+
});
|
45
40
|
|
46
|
-
|
47
|
-
|
48
|
-
if (argv.
|
41
|
+
// @ts-expect-error: define log level for storybook
|
42
|
+
global.LOGLEVEL = argv.trace ? 'trace' : argv.debug ? 'debug' : 'warn';
|
43
|
+
if (argv.trace) {
|
44
|
+
logger.setDefaultLevel(levels.TRACE);
|
45
|
+
setDefaultLevel(levels.TRACE);
|
46
|
+
} else if (argv.debug) {
|
49
47
|
logger.setDefaultLevel(levels.DEBUG);
|
50
48
|
setDefaultLevel(levels.DEBUG);
|
51
49
|
} else {
|
52
50
|
logger.setDefaultLevel(levels.INFO);
|
53
51
|
setDefaultLevel(levels.INFO);
|
54
52
|
}
|
55
|
-
|
56
53
|
void creevey(argv);
|
package/lib/esm/index.js
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
export * from './types';
|
2
|
-
// export * from './client/addon/readyForCapture';
|
3
|
-
|
1
|
+
export * from './types';
|
4
2
|
export { loadStories as browserStoriesProvider } from './server/storybook/providers/browser';
|
5
|
-
export { loadStories as nodejsStoriesProvider } from './server/storybook/providers/nodejs';
|
6
3
|
export { loadStories as hybridStoriesProvider } from './server/storybook/providers/hybrid';
|
7
4
|
export * from './server/testsFiles/parser';
|
package/lib/esm/server/config.js
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
import fs from 'fs';
|
2
2
|
import path from 'path';
|
3
|
-
import { isCSFv3Enabled, isStorybookVersionGreaterThan, isStorybookVersionLessThan, storybookDirRef } from './storybook/helpers';
|
4
|
-
import { loadStories as nodejsStoriesProvider } from './storybook/providers/nodejs';
|
5
3
|
import { loadStories as browserStoriesProvider } from './storybook/providers/browser';
|
6
4
|
import { isDefined } from '../types';
|
7
5
|
export const defaultBrowser = 'chrome';
|
8
6
|
export const defaultConfig = {
|
7
|
+
disableTelemetry: false,
|
9
8
|
useDocker: true,
|
10
|
-
useWebpackToExtractTests: false,
|
11
9
|
dockerImage: 'aerokube/selenoid:latest-release',
|
12
10
|
dockerImagePlatform: '',
|
13
11
|
pullImages: true,
|
@@ -15,7 +13,6 @@ export const defaultConfig = {
|
|
15
13
|
storybookUrl: 'http://localhost:6006',
|
16
14
|
screenDir: path.resolve('images'),
|
17
15
|
reportDir: path.resolve('report'),
|
18
|
-
storybookDir: path.resolve('.storybook'),
|
19
16
|
maxRetries: 0,
|
20
17
|
diffOptions: {
|
21
18
|
threshold: 0,
|
@@ -28,7 +25,6 @@ export const defaultConfig = {
|
|
28
25
|
babelOptions: _ => _,
|
29
26
|
testsRegex: /\.creevey\.(t|j)s$/
|
30
27
|
};
|
31
|
-
|
32
28
|
function normalizeBrowserConfig(name, config) {
|
33
29
|
if (typeof config == 'boolean') return {
|
34
30
|
browserName: name
|
@@ -38,35 +34,32 @@ function normalizeBrowserConfig(name, config) {
|
|
38
34
|
};
|
39
35
|
return config;
|
40
36
|
}
|
41
|
-
|
42
37
|
function resolveConfigPath(configPath) {
|
43
38
|
const rootDir = process.cwd();
|
44
39
|
const configDir = path.resolve('.creevey');
|
45
|
-
|
46
40
|
if (isDefined(configPath)) {
|
47
41
|
configPath = path.resolve(configPath);
|
48
42
|
} else if (fs.existsSync(configDir)) {
|
49
|
-
configPath = path.join(configDir, 'config');
|
43
|
+
configPath = path.join(configDir, 'config');
|
44
|
+
// TODO We already find file with extension, why not use it?
|
50
45
|
} else if (fs.readdirSync(rootDir).find(filename => filename.startsWith('creevey.config'))) {
|
51
46
|
configPath = path.join(rootDir, 'creevey.config');
|
52
47
|
}
|
53
|
-
|
54
48
|
return configPath;
|
55
49
|
}
|
56
|
-
|
57
50
|
export async function readConfig(options) {
|
58
51
|
const configPath = resolveConfigPath(options.config);
|
59
|
-
const userConfig = {
|
52
|
+
const userConfig = {
|
53
|
+
...defaultConfig
|
60
54
|
};
|
61
55
|
if (isDefined(configPath)) Object.assign(userConfig, (await import(configPath)).default);
|
62
|
-
|
63
|
-
if (isStorybookVersionLessThan(6, 2)) userConfig.useWebpackToExtractTests = true;
|
64
|
-
if (!userConfig.storiesProvider) userConfig.storiesProvider = (await isCSFv3Enabled()) && isStorybookVersionGreaterThan(5) ? browserStoriesProvider : nodejsStoriesProvider;
|
65
|
-
if (userConfig.storiesProvider == browserStoriesProvider && isStorybookVersionLessThan(6)) throw new Error("Creevey browser stories provider doesn't support Storybook 5.x or older versions");
|
56
|
+
if (!userConfig.storiesProvider) userConfig.storiesProvider = browserStoriesProvider;
|
66
57
|
if (options.failFast != undefined) userConfig.failFast = Boolean(options.failFast);
|
67
58
|
if (options.reportDir) userConfig.reportDir = path.resolve(options.reportDir);
|
68
|
-
if (options.screenDir) userConfig.screenDir = path.resolve(options.screenDir);
|
59
|
+
if (options.screenDir) userConfig.screenDir = path.resolve(options.screenDir);
|
60
|
+
if (options.storybookUrl) userConfig.storybookUrl = options.storybookUrl;
|
69
61
|
|
62
|
+
// NOTE: Hack to pass typescript checking
|
70
63
|
const config = userConfig;
|
71
64
|
Object.entries(config.browsers).forEach(([browser, browserConfig]) => config.browsers[browser] = normalizeBrowserConfig(browser, browserConfig));
|
72
65
|
return config;
|
package/lib/esm/server/docker.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import cluster
|
1
|
+
import cluster from 'cluster';
|
2
2
|
import { isDockerMessage } from '../types';
|
3
3
|
import { subscribeOn, sendDockerMessage, emitDockerMessage } from './messages';
|
4
4
|
import { isInsideDocker, LOCALHOST_REGEXP } from './utils';
|
@@ -7,14 +7,11 @@ import { Writable } from 'stream';
|
|
7
7
|
import ora from 'ora';
|
8
8
|
import { logger } from './logger';
|
9
9
|
const docker = new Dockerode();
|
10
|
-
|
11
10
|
class DevNull extends Writable {
|
12
11
|
_write(_chunk, _encoding, callback) {
|
13
12
|
setImmediate(callback);
|
14
13
|
}
|
15
|
-
|
16
14
|
}
|
17
|
-
|
18
15
|
export async function pullImages(images, {
|
19
16
|
auth,
|
20
17
|
platform
|
@@ -23,30 +20,27 @@ export async function pullImages(images, {
|
|
23
20
|
if (auth) args.authconfig = auth;
|
24
21
|
if (platform) args.platform = platform;
|
25
22
|
logger.info('Pull docker images');
|
26
|
-
|
27
23
|
for (const image of images) {
|
28
24
|
await new Promise((resolve, reject) => {
|
29
|
-
const spinner = ora(`${image}: Pull start`).start();
|
25
|
+
const spinner = ora(`${image}: Pull start`).start();
|
30
26
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
31
28
|
docker.pull(image, args, function (pullError, stream) {
|
32
29
|
if (pullError) {
|
33
30
|
spinner.fail();
|
34
31
|
return reject(pullError);
|
35
|
-
}
|
36
|
-
|
32
|
+
}
|
37
33
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
38
35
|
docker.modem.followProgress(stream, onFinished, onProgress);
|
39
|
-
|
40
36
|
function onFinished(error) {
|
41
37
|
if (error) {
|
42
38
|
spinner.fail();
|
43
39
|
return reject(error);
|
44
40
|
}
|
45
|
-
|
46
41
|
spinner.succeed(`${image}: Pull complete`);
|
47
42
|
resolve();
|
48
43
|
}
|
49
|
-
|
50
44
|
function onProgress(event) {
|
51
45
|
if (!/^[a-z0-9]{12}$/i.test(event.id)) return;
|
52
46
|
spinner.text = `${image}: [${event.id}] ${event.status} ${event.progress ? `${event.progress}` : ''}`;
|
@@ -63,13 +57,11 @@ export async function runImage(image, args, options, debug) {
|
|
63
57
|
}
|
64
58
|
})).map(async info => {
|
65
59
|
const container = docker.getContainer(info.Id);
|
66
|
-
|
67
60
|
try {
|
68
61
|
await container.stop();
|
69
62
|
} catch (_) {
|
70
63
|
/* noop */
|
71
64
|
}
|
72
|
-
|
73
65
|
await container.remove();
|
74
66
|
}));
|
75
67
|
const hub = docker.run(image, args, debug ? process.stdout : new DevNull(), options, error => {
|
@@ -91,7 +83,7 @@ export async function runImage(image, args, options, debug) {
|
|
91
83
|
});
|
92
84
|
}
|
93
85
|
export default async function (config, browser, startContainer) {
|
94
|
-
if (
|
86
|
+
if (cluster.isPrimary) {
|
95
87
|
const host = await startContainer();
|
96
88
|
let gridUrl = 'http://localhost:4444/wd/hub';
|
97
89
|
gridUrl = isInsideDocker ? gridUrl.replace(LOCALHOST_REGEXP, host) : gridUrl;
|
package/lib/esm/server/index.js
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
import cluster from 'cluster';
|
2
2
|
import { readConfig, defaultBrowser } from './config';
|
3
|
-
import { logger } from './logger';
|
3
|
+
import { logger } from './logger';
|
4
4
|
|
5
|
+
// NOTE: Impure function, mutate config by adding gridUrl prop
|
5
6
|
async function startWebdriverServer(config, options) {
|
6
7
|
if (config.useDocker) {
|
7
8
|
return (await import('./docker')).default(config, options.browser, async () => (await import('./selenium/selenoid')).startSelenoidContainer(config, options.debug));
|
@@ -9,54 +10,39 @@ async function startWebdriverServer(config, options) {
|
|
9
10
|
return (await import('./selenium/selenoid')).startSelenoidStandalone(config, options.debug);
|
10
11
|
}
|
11
12
|
}
|
12
|
-
|
13
13
|
export default async function (options) {
|
14
14
|
const config = await readConfig(options);
|
15
15
|
const {
|
16
16
|
browser = defaultBrowser,
|
17
|
-
extract,
|
18
17
|
tests,
|
19
18
|
update,
|
20
|
-
webpack,
|
21
19
|
ui,
|
22
20
|
port
|
23
21
|
} = options;
|
24
|
-
if (!config) return;
|
22
|
+
if (!config) return;
|
25
23
|
|
24
|
+
// NOTE: We don't need docker nor selenoid for webpack or update options
|
26
25
|
if (!(config.gridUrl || Object.values(config.browsers).every(({
|
27
26
|
gridUrl
|
28
|
-
}) => gridUrl)) && !
|
27
|
+
}) => gridUrl)) && !tests && !update) {
|
29
28
|
await startWebdriverServer(config, options);
|
30
29
|
}
|
31
|
-
|
32
30
|
switch (true) {
|
33
|
-
case Boolean(extract) || tests:
|
34
|
-
{
|
35
|
-
return (await import('./extract')).default(config, options);
|
36
|
-
}
|
37
|
-
|
38
31
|
case Boolean(update):
|
39
32
|
{
|
40
33
|
return (await import('./update')).default(config, typeof update == 'string' ? update : undefined);
|
41
34
|
}
|
42
|
-
|
43
|
-
case webpack:
|
44
|
-
{
|
45
|
-
logger.info('Starting Webpack Compiler');
|
46
|
-
return (await import('./loaders/webpack/compile')).default(config, options);
|
47
|
-
}
|
48
|
-
|
49
|
-
case cluster.isMaster:
|
35
|
+
case cluster.isPrimary:
|
50
36
|
{
|
51
37
|
logger.info('Starting Master Process');
|
52
38
|
const resolveApi = (await import('./master/server')).default(config.reportDir, port, ui);
|
53
39
|
return (await import('./master')).default(config, options, resolveApi);
|
54
40
|
}
|
55
|
-
|
56
41
|
default:
|
57
42
|
{
|
58
43
|
logger.info(`Starting Worker for ${browser}`);
|
59
|
-
return (await import('./worker')).default(config, {
|
44
|
+
return (await import('./worker')).default(config, {
|
45
|
+
...options,
|
60
46
|
browser
|
61
47
|
});
|
62
48
|
}
|
package/lib/esm/server/logger.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import WebSocket from 'ws';
|
2
2
|
import { logger } from '../logger';
|
3
|
-
|
4
3
|
function broadcast(wss, message) {
|
5
4
|
wss.clients.forEach(ws => {
|
6
5
|
if (ws.readyState === WebSocket.OPEN) {
|
@@ -8,7 +7,6 @@ function broadcast(wss, message) {
|
|
8
7
|
}
|
9
8
|
});
|
10
9
|
}
|
11
|
-
|
12
10
|
export default function creeveyApi(runner) {
|
13
11
|
return {
|
14
12
|
subscribe(wss) {
|
@@ -17,15 +15,12 @@ export default function creeveyApi(runner) {
|
|
17
15
|
payload
|
18
16
|
}));
|
19
17
|
},
|
20
|
-
|
21
18
|
handleMessage(ws, message) {
|
22
19
|
if (typeof message != 'string') {
|
23
20
|
logger.info('unhandled message', message);
|
24
21
|
return;
|
25
22
|
}
|
26
|
-
|
27
23
|
const command = JSON.parse(message);
|
28
|
-
|
29
24
|
switch (command.type) {
|
30
25
|
case 'status':
|
31
26
|
{
|
@@ -35,19 +30,16 @@ export default function creeveyApi(runner) {
|
|
35
30
|
}));
|
36
31
|
return;
|
37
32
|
}
|
38
|
-
|
39
33
|
case 'start':
|
40
34
|
{
|
41
35
|
runner.start(command.payload);
|
42
36
|
return;
|
43
37
|
}
|
44
|
-
|
45
38
|
case 'stop':
|
46
39
|
{
|
47
40
|
runner.stop();
|
48
41
|
return;
|
49
42
|
}
|
50
|
-
|
51
43
|
case 'approve':
|
52
44
|
{
|
53
45
|
void runner.approve(command.payload);
|
@@ -55,6 +47,5 @@ export default function creeveyApi(runner) {
|
|
55
47
|
}
|
56
48
|
}
|
57
49
|
}
|
58
|
-
|
59
50
|
};
|
60
51
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import path from 'path';
|
2
|
-
import {
|
2
|
+
import { copyFile, readdir, mkdir, existsSync, writeFile } from 'fs';
|
3
3
|
import { promisify } from 'util';
|
4
4
|
import master from './master';
|
5
5
|
import creeveyApi from './api';
|
@@ -7,10 +7,11 @@ import { isDefined } from '../../types';
|
|
7
7
|
import { shutdown, shutdownWorkers, testsToImages, readDirRecursive } from '../utils';
|
8
8
|
import { subscribeOn } from '../messages';
|
9
9
|
import { logger } from '../logger';
|
10
|
+
import { sendScreenshotsCount } from '../telemetry';
|
11
|
+
const writeFileAsync = promisify(writeFile);
|
10
12
|
const copyFileAsync = promisify(copyFile);
|
11
13
|
const readdirAsync = promisify(readdir);
|
12
14
|
const mkdirAsync = promisify(mkdir);
|
13
|
-
|
14
15
|
async function copyStatics(reportDir) {
|
15
16
|
const clientDir = path.join(__dirname, '../../client/web');
|
16
17
|
const files = (await readdirAsync(clientDir, {
|
@@ -19,12 +20,10 @@ async function copyStatics(reportDir) {
|
|
19
20
|
await mkdirAsync(reportDir, {
|
20
21
|
recursive: true
|
21
22
|
});
|
22
|
-
|
23
23
|
for (const file of files) {
|
24
24
|
await copyFileAsync(path.join(clientDir, file), path.join(reportDir, file));
|
25
25
|
}
|
26
26
|
}
|
27
|
-
|
28
27
|
function reportDataModule(data) {
|
29
28
|
return `
|
30
29
|
(function (root, factory) {
|
@@ -36,44 +35,34 @@ function reportDataModule(data) {
|
|
36
35
|
}(this, function () { return ${JSON.stringify(data)} }));
|
37
36
|
`;
|
38
37
|
}
|
39
|
-
|
40
38
|
function outputUnnecessaryImages(imagesDir, images) {
|
41
39
|
if (!existsSync(imagesDir)) return;
|
42
40
|
const unnecessaryImages = readDirRecursive(imagesDir).map(imagePath => path.posix.relative(imagesDir, imagePath)).filter(imagePath => !images.has(imagePath));
|
43
|
-
|
44
41
|
if (unnecessaryImages.length > 0) {
|
45
42
|
logger.warn('We found unnecessary screenshot images, those can be safely removed:\n', unnecessaryImages.join('\n'));
|
46
43
|
}
|
47
44
|
}
|
48
|
-
|
49
45
|
export default async function (config, options, resolveApi) {
|
50
46
|
let runner = null;
|
51
|
-
|
52
47
|
if (config.hooks.before) {
|
53
48
|
await config.hooks.before();
|
54
49
|
}
|
55
|
-
|
56
50
|
subscribeOn('shutdown', () => {
|
57
51
|
var _config$hooks$after, _config$hooks;
|
58
|
-
|
59
52
|
return (_config$hooks$after = (_config$hooks = config.hooks).after) === null || _config$hooks$after === void 0 ? void 0 : _config$hooks$after.call(_config$hooks);
|
60
53
|
});
|
61
54
|
process.removeListener('SIGINT', shutdown);
|
62
55
|
process.on('SIGINT', () => {
|
63
56
|
var _runner, _runner2;
|
64
|
-
|
65
|
-
(_runner = runner) === null || _runner === void 0 ? void 0 : _runner.removeAllListeners('stop');
|
66
|
-
|
57
|
+
(_runner = runner) === null || _runner === void 0 || _runner.removeAllListeners('stop');
|
67
58
|
if ((_runner2 = runner) !== null && _runner2 !== void 0 && _runner2.isRunning) {
|
68
59
|
var _runner4;
|
69
|
-
|
70
60
|
// TODO Better handle stop
|
71
61
|
void Promise.race([new Promise(resolve => setTimeout(resolve, 10000)), new Promise(resolve => {
|
72
62
|
var _runner3;
|
73
|
-
|
74
63
|
return (_runner3 = runner) === null || _runner3 === void 0 ? void 0 : _runner3.once('stop', resolve);
|
75
64
|
})]).then(() => shutdownWorkers());
|
76
|
-
(_runner4 = runner) === null || _runner4 === void 0
|
65
|
+
(_runner4 = runner) === null || _runner4 === void 0 || _runner4.stop();
|
77
66
|
} else {
|
78
67
|
void shutdownWorkers();
|
79
68
|
}
|
@@ -83,43 +72,44 @@ export default async function (config, options, resolveApi) {
|
|
83
72
|
debug: options.debug,
|
84
73
|
port: options.port
|
85
74
|
});
|
86
|
-
|
87
75
|
if (options.saveReport) {
|
88
|
-
await copyStatics(config.reportDir);
|
89
76
|
runner.on('stop', () => {
|
90
|
-
|
91
|
-
|
92
|
-
|
77
|
+
void copyStatics(config.reportDir).then(() => {
|
78
|
+
var _runner5;
|
79
|
+
return writeFileAsync(path.join(config.reportDir, 'data.js'), reportDataModule((_runner5 = runner) === null || _runner5 === void 0 ? void 0 : _runner5.status.tests));
|
80
|
+
});
|
93
81
|
});
|
94
82
|
}
|
95
|
-
|
96
83
|
if (options.ui) {
|
97
84
|
resolveApi(creeveyApi(runner));
|
98
85
|
logger.info(`Started on http://localhost:${options.port}`);
|
99
86
|
} else {
|
100
87
|
if (Object.values(runner.status.tests).filter(test => test && !test.skip).length == 0) {
|
101
|
-
logger.warn("Don't have any tests to run");
|
102
|
-
|
88
|
+
logger.warn("Don't have any tests to run");
|
89
|
+
// eslint-disable-next-line no-process-exit
|
103
90
|
void shutdownWorkers().then(() => process.exit());
|
104
91
|
return;
|
105
92
|
}
|
106
|
-
|
107
93
|
runner.once('stop', () => {
|
108
|
-
var
|
109
|
-
|
110
|
-
const tests = Object.values((_runner$status$tests = (_runner6 = runner) === null || _runner6 === void 0 ? void 0 : _runner6.status.tests) !== null && _runner$status$tests !== void 0 ? _runner$status$tests : {});
|
94
|
+
var _runner6, _runner7;
|
95
|
+
const tests = Object.values(((_runner6 = runner) === null || _runner6 === void 0 ? void 0 : _runner6.status.tests) ?? {});
|
111
96
|
const isSuccess = tests.filter(isDefined).filter(({
|
112
97
|
skip
|
113
98
|
}) => !skip).every(({
|
114
99
|
status
|
115
|
-
}) => status == 'success');
|
116
|
-
|
100
|
+
}) => status == 'success');
|
101
|
+
// TODO output summary
|
117
102
|
process.exitCode = isSuccess ? 0 : -1;
|
118
|
-
if (!config.failFast) outputUnnecessaryImages(config.screenDir, testsToImages(tests));
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
103
|
+
if (!config.failFast) outputUnnecessaryImages(config.screenDir, testsToImages(tests));
|
104
|
+
sendScreenshotsCount(config, options, (_runner7 = runner) === null || _runner7 === void 0 ? void 0 : _runner7.status).catch(reason => {
|
105
|
+
const error = reason instanceof Error ? reason.stack ?? reason.message : reason;
|
106
|
+
logger.warn(`Can't send telemetry: ${error}`);
|
107
|
+
}).finally(() => {
|
108
|
+
// eslint-disable-next-line no-process-exit
|
109
|
+
void shutdownWorkers().then(() => process.exit());
|
110
|
+
});
|
111
|
+
});
|
112
|
+
// TODO grep
|
123
113
|
runner.start(Object.keys(runner.status.tests));
|
124
114
|
}
|
125
115
|
}
|
@@ -2,8 +2,6 @@ import path from 'path';
|
|
2
2
|
import { isDefined } from '../../types';
|
3
3
|
import { loadTestsFromStories, saveTestsJson } from '../stories';
|
4
4
|
import Runner from './runner';
|
5
|
-
import { startWebpackCompiler } from '../loaders/webpack/start';
|
6
|
-
|
7
5
|
function mergeTests(testsWithReports, testsFromStories) {
|
8
6
|
Object.values(testsFromStories).filter(isDefined).forEach(test => {
|
9
7
|
const testWithReport = testsWithReports[test.id];
|
@@ -15,18 +13,15 @@ function mergeTests(testsWithReports, testsFromStories) {
|
|
15
13
|
});
|
16
14
|
return testsFromStories;
|
17
15
|
}
|
18
|
-
|
19
16
|
export default async function master(config, options) {
|
20
|
-
if (config.useWebpackToExtractTests) await startWebpackCompiler();
|
21
17
|
const runner = new Runner(config);
|
22
18
|
const reportDataPath = path.join(config.reportDir, 'data.js');
|
23
19
|
let testsFromReport = {};
|
24
|
-
|
25
20
|
try {
|
26
21
|
testsFromReport = await import(reportDataPath);
|
27
|
-
} catch (error) {
|
22
|
+
} catch (error) {
|
23
|
+
// Ignore error
|
28
24
|
}
|
29
|
-
|
30
25
|
await runner.init();
|
31
26
|
const tests = await loadTestsFromStories(Object.keys(config.browsers), listener => config.storiesProvider(config, options, listener), testsDiff => {
|
32
27
|
runner.updateTests(testsDiff);
|