creevey 0.10.0-beta.4 → 0.10.0-beta.6
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/dist/creevey.js +12 -5
- package/dist/creevey.js.map +1 -1
- package/dist/server/config.js +2 -1
- package/dist/server/config.js.map +1 -1
- package/dist/server/docker.js +2 -2
- package/dist/server/docker.js.map +1 -1
- package/dist/server/index.js +4 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/logger.d.ts +2 -1
- package/dist/server/logger.js +7 -3
- package/dist/server/logger.js.map +1 -1
- package/dist/server/master/api.js +1 -1
- package/dist/server/master/api.js.map +1 -1
- package/dist/server/master/pool.d.ts +3 -3
- package/dist/server/master/pool.js +10 -65
- package/dist/server/master/pool.js.map +1 -1
- package/dist/server/master/queue.d.ts +13 -0
- package/dist/server/master/queue.js +64 -0
- package/dist/server/master/queue.js.map +1 -0
- package/dist/server/master/runner.d.ts +1 -0
- package/dist/server/master/runner.js +4 -1
- package/dist/server/master/runner.js.map +1 -1
- package/dist/server/master/server.js +1 -1
- package/dist/server/master/server.js.map +1 -1
- package/dist/server/master/start.js +4 -4
- package/dist/server/master/start.js.map +1 -1
- package/dist/server/playwright/internal.js +17 -20
- package/dist/server/playwright/internal.js.map +1 -1
- package/dist/server/playwright/webdriver.js +1 -1
- package/dist/server/playwright/webdriver.js.map +1 -1
- package/dist/server/providers/browser.js +1 -1
- package/dist/server/providers/browser.js.map +1 -1
- package/dist/server/providers/hybrid.js +1 -1
- package/dist/server/providers/hybrid.js.map +1 -1
- package/dist/server/reporter.js +3 -3
- package/dist/server/reporter.js.map +1 -1
- package/dist/server/selenium/internal.d.ts +1 -2
- package/dist/server/selenium/internal.js +105 -81
- package/dist/server/selenium/internal.js.map +1 -1
- package/dist/server/selenium/webdriver.js +1 -1
- package/dist/server/selenium/webdriver.js.map +1 -1
- package/dist/server/utils.d.ts +2 -1
- package/dist/server/utils.js +11 -0
- package/dist/server/utils.js.map +1 -1
- package/dist/server/webdriver.d.ts +2 -3
- package/dist/server/webdriver.js +10 -9
- package/dist/server/webdriver.js.map +1 -1
- package/dist/server/worker/chai-image.d.ts +1 -2
- package/dist/server/worker/chai-image.js +4 -3
- package/dist/server/worker/chai-image.js.map +1 -1
- package/dist/server/worker/start.js +7 -10
- package/dist/server/worker/start.js.map +1 -1
- package/dist/types.d.ts +6 -2
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/creevey.ts +12 -6
- package/src/server/config.ts +2 -1
- package/src/server/docker.ts +2 -2
- package/src/server/index.ts +4 -4
- package/src/server/logger.ts +6 -2
- package/src/server/master/api.ts +1 -1
- package/src/server/master/pool.ts +18 -58
- package/src/server/master/queue.ts +64 -0
- package/src/server/master/runner.ts +4 -1
- package/src/server/master/server.ts +1 -1
- package/src/server/master/start.ts +7 -4
- package/src/server/playwright/internal.ts +17 -20
- package/src/server/playwright/webdriver.ts +1 -1
- package/src/server/providers/browser.ts +1 -1
- package/src/server/providers/hybrid.ts +1 -1
- package/src/server/reporter.ts +3 -2
- package/src/server/selenium/internal.ts +107 -81
- package/src/server/selenium/webdriver.ts +1 -1
- package/src/server/utils.ts +12 -1
- package/src/server/webdriver.ts +10 -15
- package/src/server/worker/chai-image.ts +4 -4
- package/src/server/worker/start.ts +7 -11
- package/src/types.ts +6 -2
- package/.yarnrc.yml +0 -1
package/src/server/utils.ts
CHANGED
@@ -6,7 +6,7 @@ import { fileURLToPath, pathToFileURL } from 'url';
|
|
6
6
|
import { createRequire } from 'module';
|
7
7
|
import { register as esmRegister } from 'tsx/esm/api';
|
8
8
|
import { register as cjsRegister } from 'tsx/cjs/api';
|
9
|
-
import { SkipOptions, SkipOption, isDefined, TestData, noop, ServerTest } from '../types.js';
|
9
|
+
import { SkipOptions, SkipOption, isDefined, TestData, noop, ServerTest, Worker } from '../types.js';
|
10
10
|
import { emitShutdownMessage, sendShutdownMessage } from './messages.js';
|
11
11
|
|
12
12
|
const importMetaUrl = pathToFileURL(__filename).href;
|
@@ -96,6 +96,17 @@ export async function shutdownWorkers(): Promise<void> {
|
|
96
96
|
emitShutdownMessage();
|
97
97
|
}
|
98
98
|
|
99
|
+
export function gracefullyKill(worker: Worker): void {
|
100
|
+
worker.isShuttingDown = true;
|
101
|
+
const timeout = setTimeout(() => {
|
102
|
+
worker.kill();
|
103
|
+
}, 10000);
|
104
|
+
worker.on('exit', () => {
|
105
|
+
clearTimeout(timeout);
|
106
|
+
});
|
107
|
+
sendShutdownMessage(worker);
|
108
|
+
}
|
109
|
+
|
99
110
|
export async function getCreeveyCache(): Promise<string | undefined> {
|
100
111
|
const { default: findCacheDir } = await import('find-cache-dir');
|
101
112
|
return findCacheDir({ name: 'creevey', cwd: dirname(fileURLToPath(importMetaUrl)) });
|
package/src/server/webdriver.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
import Logger from 'loglevel';
|
2
1
|
import chalk from 'chalk';
|
3
2
|
import { networkInterfaces } from 'os';
|
4
|
-
import { logger
|
3
|
+
import { logger } from './logger.js';
|
5
4
|
import { Args } from '@storybook/csf';
|
6
5
|
import {
|
7
6
|
isDefined,
|
@@ -22,15 +21,15 @@ const DOCKER_INTERNAL = 'host.docker.internal';
|
|
22
21
|
export async function resolveStorybookUrl(
|
23
22
|
storybookUrl: string,
|
24
23
|
checkUrl: (url: string) => Promise<boolean>,
|
25
|
-
logger: Logger.Logger = defaultLogger,
|
26
24
|
): Promise<string> {
|
27
|
-
logger.debug('Resolving storybook url');
|
25
|
+
logger().debug('Resolving storybook url');
|
28
26
|
const addresses = getAddresses();
|
27
|
+
// TODO Use Promise.race?
|
29
28
|
for (const ip of addresses) {
|
30
29
|
const resolvedUrl = storybookUrl.replace(LOCALHOST_REGEXP, ip);
|
31
|
-
logger.debug(`Checking storybook availability on ${chalk.magenta(resolvedUrl)}`);
|
30
|
+
logger().debug(`Checking storybook availability on ${chalk.magenta(resolvedUrl)}`);
|
32
31
|
if (await checkUrl(resolvedUrl)) {
|
33
|
-
logger.debug(`Resolved storybook url ${chalk.magenta(resolvedUrl)}`);
|
32
|
+
logger().debug(`Resolved storybook url ${chalk.magenta(resolvedUrl)}`);
|
34
33
|
return resolvedUrl;
|
35
34
|
}
|
36
35
|
}
|
@@ -74,11 +73,7 @@ export abstract class CreeveyWebdriverBase implements CreeveyWebdriver {
|
|
74
73
|
|
75
74
|
abstract afterTest(test: ServerTest): Promise<void>;
|
76
75
|
|
77
|
-
async switchStory(
|
78
|
-
story: StoryInput,
|
79
|
-
context: BaseCreeveyTestContext,
|
80
|
-
logger: Logger.Logger,
|
81
|
-
): Promise<CreeveyTestContext> {
|
76
|
+
async switchStory(story: StoryInput, context: BaseCreeveyTestContext): Promise<CreeveyTestContext> {
|
82
77
|
const { id, title, name, parameters } = story;
|
83
78
|
const {
|
84
79
|
captureElement = `#${storybookRootID}`,
|
@@ -86,7 +81,7 @@ export abstract class CreeveyWebdriverBase implements CreeveyWebdriver {
|
|
86
81
|
ignoreElements,
|
87
82
|
} = (parameters.creevey ?? {}) as CreeveyStoryParams;
|
88
83
|
|
89
|
-
logger.debug(`Switching to story ${chalk.cyan(title)}/${chalk.cyan(name)} by id ${chalk.magenta(id)}`);
|
84
|
+
logger().debug(`Switching to story ${chalk.cyan(title)}/${chalk.cyan(name)} by id ${chalk.magenta(id)}`);
|
90
85
|
|
91
86
|
let storyPlayResolver: (isCompleted: boolean) => void;
|
92
87
|
let waitForComplete = new Promise<boolean>((resolve) => (storyPlayResolver = resolve));
|
@@ -107,7 +102,7 @@ export abstract class CreeveyWebdriverBase implements CreeveyWebdriver {
|
|
107
102
|
const isCaptureCalled = await this.selectStory(id, waitForReady);
|
108
103
|
|
109
104
|
if (isCaptureCalled) {
|
110
|
-
logger.debug(`Capturing screenshots from ${chalk.magenta(id)} story's \`play()\` function`);
|
105
|
+
logger().debug(`Capturing screenshots from ${chalk.magenta(id)} story's \`play()\` function`);
|
111
106
|
while (!(await waitForComplete)) {
|
112
107
|
waitForComplete = new Promise<boolean>((resolve) => (storyPlayResolver = resolve));
|
113
108
|
}
|
@@ -115,8 +110,8 @@ export abstract class CreeveyWebdriverBase implements CreeveyWebdriver {
|
|
115
110
|
|
116
111
|
unsubscribe();
|
117
112
|
|
118
|
-
if (isCaptureCalled) logger.debug(`Story ${chalk.magenta(id)} completed capturing`);
|
119
|
-
else logger.debug(`Story ${chalk.magenta(id)} ready for capturing`);
|
113
|
+
if (isCaptureCalled) logger().debug(`Story ${chalk.magenta(id)} completed capturing`);
|
114
|
+
else logger().debug(`Story ${chalk.magenta(id)} ready for capturing`);
|
120
115
|
|
121
116
|
return Object.assign(
|
122
117
|
{
|
@@ -1,8 +1,8 @@
|
|
1
|
-
import
|
1
|
+
import { logger } from '../logger';
|
2
|
+
|
2
3
|
export default function (
|
3
4
|
matchImage: (image: Buffer, imageName?: string) => Promise<void>,
|
4
5
|
matchImages: (images: Record<string, Buffer>) => Promise<void>,
|
5
|
-
logger: Logger.Logger,
|
6
6
|
) {
|
7
7
|
let isWarningShown = false;
|
8
8
|
return function chaiImage({ Assertion }: Chai.ChaiStatic, utils: Chai.ChaiUtils): void {
|
@@ -11,7 +11,7 @@ export default function (
|
|
11
11
|
'matchImage',
|
12
12
|
async function (this: Record<string, unknown>, imageName?: string) {
|
13
13
|
if (!isWarningShown) {
|
14
|
-
logger.warn(
|
14
|
+
logger().warn(
|
15
15
|
'`expect(...).to.matchImage()` is deprecated and will be removed in the next major release. Please use `context.matchImage()` instead.',
|
16
16
|
);
|
17
17
|
isWarningShown = true;
|
@@ -23,7 +23,7 @@ export default function (
|
|
23
23
|
|
24
24
|
utils.addMethod(Assertion.prototype, 'matchImages', async function (this: Record<string, unknown>) {
|
25
25
|
if (!isWarningShown) {
|
26
|
-
logger.warn(
|
26
|
+
logger().warn(
|
27
27
|
'`expect(...).to.matchImages()` is deprecated and will be removed in the next major release. Please use `context.matchImages()` instead.',
|
28
28
|
);
|
29
29
|
isWarningShown = true;
|
@@ -1,6 +1,4 @@
|
|
1
1
|
import chai from 'chai';
|
2
|
-
import chalk from 'chalk';
|
3
|
-
import Logger from 'loglevel';
|
4
2
|
import EventEmitter from 'events';
|
5
3
|
import {
|
6
4
|
BaseCreeveyTestContext,
|
@@ -86,7 +84,7 @@ function runHandler(browserName: string, images: Partial<Record<string, Images>>
|
|
86
84
|
|
87
85
|
async function setupWebdriver(webdriver: CreeveyWebdriver): Promise<[string, CreeveyWebdriver] | undefined> {
|
88
86
|
if ((await webdriver.openBrowser(true)) == null) {
|
89
|
-
logger.error('Failed to start browser');
|
87
|
+
logger().error('Failed to start browser');
|
90
88
|
emitWorkerMessage({
|
91
89
|
type: 'error',
|
92
90
|
payload: { subtype: 'browser', error: 'Failed to start browser' },
|
@@ -125,8 +123,6 @@ export async function start(browser: string, gridUrl: string, config: Config, op
|
|
125
123
|
|
126
124
|
if (!webdriver || !sessionId) return;
|
127
125
|
|
128
|
-
const workerLogger = Logger.getLogger(`${browser}:${chalk.gray(sessionId)}`);
|
129
|
-
|
130
126
|
const reporterOptions = {
|
131
127
|
...config.reporterOptions,
|
132
128
|
creevey: {
|
@@ -150,13 +146,13 @@ export async function start(browser: string, gridUrl: string, config: Config, op
|
|
150
146
|
const { matchImage, matchImages } = options.odiff
|
151
147
|
? getOdiffMatchers(imagesContext, config)
|
152
148
|
: await getMatchers(imagesContext, config);
|
153
|
-
chai.use(chaiImage(matchImage, matchImages
|
149
|
+
chai.use(chaiImage(matchImage, matchImages));
|
154
150
|
|
155
151
|
const tests = await (async () => {
|
156
152
|
try {
|
157
153
|
return await getTestsFromStories(config, browser, webdriver);
|
158
154
|
} catch (error) {
|
159
|
-
|
155
|
+
logger().error('Failed to get tests from stories:', error);
|
160
156
|
emitWorkerMessage({
|
161
157
|
type: 'error',
|
162
158
|
payload: { subtype: 'browser', error: serializeError(error) },
|
@@ -174,7 +170,7 @@ export async function start(browser: string, gridUrl: string, config: Config, op
|
|
174
170
|
|
175
171
|
if (!test) {
|
176
172
|
const error = `Test with id ${message.payload.id} not found`;
|
177
|
-
|
173
|
+
logger().error(error);
|
178
174
|
emitWorkerMessage({
|
179
175
|
type: 'error',
|
180
176
|
payload: { subtype: 'test', error },
|
@@ -235,7 +231,7 @@ export async function start(browser: string, gridUrl: string, config: Config, op
|
|
235
231
|
}, config.testTimeout),
|
236
232
|
),
|
237
233
|
(async () => {
|
238
|
-
const context = await webdriver.switchStory(test.story, baseContext
|
234
|
+
const context = await webdriver.switchStory(test.story, baseContext);
|
239
235
|
await test.fn(context);
|
240
236
|
})(),
|
241
237
|
]);
|
@@ -261,7 +257,7 @@ export async function start(browser: string, gridUrl: string, config: Config, op
|
|
261
257
|
|
262
258
|
runHandler(baseContext.browserName, imagesContext.images, error);
|
263
259
|
})().catch((error: unknown) => {
|
264
|
-
|
260
|
+
logger().error('Unexpected error:', error);
|
265
261
|
emitWorkerMessage({
|
266
262
|
type: 'error',
|
267
263
|
payload: { subtype: 'test', error: serializeError(error) },
|
@@ -269,7 +265,7 @@ export async function start(browser: string, gridUrl: string, config: Config, op
|
|
269
265
|
});
|
270
266
|
});
|
271
267
|
|
272
|
-
|
268
|
+
logger().info('Browser is ready');
|
273
269
|
|
274
270
|
emitWorkerMessage({ type: 'ready' });
|
275
271
|
}
|
package/src/types.ts
CHANGED
@@ -4,7 +4,6 @@ import type Pixelmatch from 'pixelmatch';
|
|
4
4
|
import type { ODiffOptions } from 'odiff-bin';
|
5
5
|
import type { expect } from 'chai';
|
6
6
|
import type EventEmitter from 'events';
|
7
|
-
import type Logger from 'loglevel';
|
8
7
|
import { LaunchOptions } from 'playwright-core';
|
9
8
|
// import type { Browser } from 'playwright-core';
|
10
9
|
|
@@ -164,7 +163,7 @@ export interface CreeveyWebdriver {
|
|
164
163
|
openBrowser(fresh?: boolean): Promise<CreeveyWebdriver | null>;
|
165
164
|
closeBrowser(): Promise<void>;
|
166
165
|
loadStoriesFromBrowser(): Promise<StoriesRaw>;
|
167
|
-
switchStory(story: StoryInput, context: BaseCreeveyTestContext
|
166
|
+
switchStory(story: StoryInput, context: BaseCreeveyTestContext): Promise<CreeveyTestContext>;
|
168
167
|
afterTest(test: ServerTest): Promise<void>;
|
169
168
|
}
|
170
169
|
|
@@ -307,6 +306,11 @@ export interface Config {
|
|
307
306
|
* The `--ui` CLI option ignores this option
|
308
307
|
*/
|
309
308
|
failFast: boolean;
|
309
|
+
/**
|
310
|
+
* Start workers in sequential queue
|
311
|
+
* @default false
|
312
|
+
*/
|
313
|
+
useWorkerQueue: boolean;
|
310
314
|
/**
|
311
315
|
* Specify platform for docker images
|
312
316
|
*/
|
package/.yarnrc.yml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
nodeLinker: node-modules
|