creevey 0.10.0-beta.2 → 0.10.0-beta.21
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/client/addon/components/Addon.js +17 -7
- package/dist/client/addon/components/Addon.js.map +1 -1
- package/dist/client/addon/components/Panel.js +2 -2
- package/dist/client/addon/components/Panel.js.map +1 -1
- package/dist/client/addon/components/Tools.js +17 -7
- package/dist/client/addon/components/Tools.js.map +1 -1
- package/dist/client/addon/controller.js +4 -5
- package/dist/client/addon/controller.js.map +1 -1
- package/dist/client/addon/withCreevey.d.ts +1 -0
- package/dist/client/addon/withCreevey.js +19 -34
- package/dist/client/addon/withCreevey.js.map +1 -1
- package/dist/client/shared/components/ImagesView/BlendView.js +17 -7
- package/dist/client/shared/components/ImagesView/BlendView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SideBySideView.js +17 -7
- package/dist/client/shared/components/ImagesView/SideBySideView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SlideView.js +17 -7
- package/dist/client/shared/components/ImagesView/SlideView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SwapView.js +29 -7
- package/dist/client/shared/components/ImagesView/SwapView.js.map +1 -1
- package/dist/client/shared/components/PageHeader/ImagePreview.js +1 -0
- package/dist/client/shared/components/PageHeader/ImagePreview.js.map +1 -1
- package/dist/client/shared/components/PageHeader/PageHeader.js +17 -7
- package/dist/client/shared/components/PageHeader/PageHeader.js.map +1 -1
- package/dist/client/shared/components/ResultsPage.js +40 -12
- package/dist/client/shared/components/ResultsPage.js.map +1 -1
- package/dist/client/shared/creeveyClientApi.js +8 -1
- package/dist/client/shared/creeveyClientApi.js.map +1 -1
- package/dist/client/shared/helpers.d.ts +0 -2
- package/dist/client/shared/helpers.js +0 -17
- package/dist/client/shared/helpers.js.map +1 -1
- package/dist/client/web/CreeveyApp.js +41 -14
- package/dist/client/web/CreeveyApp.js.map +1 -1
- package/dist/client/web/CreeveyContext.d.ts +5 -0
- package/dist/client/web/CreeveyContext.js +20 -7
- package/dist/client/web/CreeveyContext.js.map +1 -1
- package/dist/client/web/CreeveyLoader.js +2 -2
- package/dist/client/web/CreeveyLoader.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/Search.js +19 -9
- package/dist/client/web/CreeveyView/SideBar/Search.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBar.js +18 -7
- package/dist/client/web/CreeveyView/SideBar/SideBar.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js +60 -7
- package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js +17 -7
- package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.js +18 -10
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestLink.js +18 -10
- package/dist/client/web/CreeveyView/SideBar/TestLink.js.map +1 -1
- package/dist/client/web/KeyboardEventsContext.d.ts +1 -8
- package/dist/client/web/KeyboardEventsContext.js +79 -64
- package/dist/client/web/KeyboardEventsContext.js.map +1 -1
- package/dist/client/web/assets/{index-DkmZfG9C.js → index-iytWuaD6.js} +104 -104
- package/dist/client/web/index.html +1 -1
- package/dist/client/web/index.js +17 -7
- package/dist/client/web/index.js.map +1 -1
- package/dist/client/web/themes.d.ts +2 -0
- package/dist/client/web/themes.js +22 -0
- package/dist/client/web/themes.js.map +1 -0
- package/dist/creevey.js +13 -5
- package/dist/creevey.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/server/config.js +5 -4
- package/dist/server/config.js.map +1 -1
- package/dist/server/docker.js +37 -20
- package/dist/server/docker.js.map +1 -1
- package/dist/server/index.js +36 -7
- 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 -63
- 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 +10 -9
- package/dist/server/master/start.js.map +1 -1
- package/dist/server/playwright/docker-file.d.ts +2 -1
- package/dist/server/playwright/docker-file.js +6 -4
- package/dist/server/playwright/docker-file.js.map +1 -1
- package/dist/server/playwright/internal.d.ts +3 -3
- package/dist/server/playwright/internal.js +50 -44
- package/dist/server/playwright/internal.js.map +1 -1
- package/dist/server/playwright/webdriver.d.ts +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 +6 -4
- 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 +13 -9
- package/dist/server/reporter.js.map +1 -1
- package/dist/server/selenium/internal.d.ts +3 -4
- package/dist/server/selenium/internal.js +127 -91
- package/dist/server/selenium/internal.js.map +1 -1
- package/dist/server/selenium/selenoid.js +2 -2
- package/dist/server/selenium/selenoid.js.map +1 -1
- package/dist/server/selenium/webdriver.d.ts +1 -1
- package/dist/server/selenium/webdriver.js +1 -1
- package/dist/server/selenium/webdriver.js.map +1 -1
- package/dist/server/telemetry.js +7 -3
- package/dist/server/telemetry.js.map +1 -1
- package/dist/server/utils.d.ts +16 -1
- package/dist/server/utils.js +31 -3
- package/dist/server/utils.js.map +1 -1
- package/dist/server/webdriver.d.ts +3 -4
- 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/match-image.d.ts +4 -4
- package/dist/server/worker/match-image.js +7 -4
- package/dist/server/worker/match-image.js.map +1 -1
- package/dist/server/worker/start.js +24 -14
- package/dist/server/worker/start.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/types.d.ts +32 -13
- package/dist/types.js +13 -1
- package/dist/types.js.map +1 -1
- package/package.json +55 -59
- package/src/client/addon/components/Panel.tsx +2 -2
- package/src/client/addon/controller.ts +13 -6
- package/src/client/addon/withCreevey.ts +27 -13
- package/src/client/shared/components/ImagesView/SwapView.tsx +18 -0
- package/src/client/shared/components/PageHeader/ImagePreview.tsx +1 -0
- package/src/client/shared/components/ResultsPage.tsx +28 -7
- package/src/client/shared/creeveyClientApi.ts +9 -1
- package/src/client/shared/helpers.ts +0 -22
- package/src/client/web/CreeveyApp.tsx +26 -8
- package/src/client/web/CreeveyContext.tsx +9 -0
- package/src/client/web/CreeveyLoader.tsx +1 -1
- package/src/client/web/CreeveyView/SideBar/Search.tsx +3 -3
- package/src/client/web/CreeveyView/SideBar/SideBar.tsx +1 -0
- package/src/client/web/CreeveyView/SideBar/SideBarFooter.tsx +37 -6
- package/src/client/web/CreeveyView/SideBar/SuiteLink.tsx +3 -5
- package/src/client/web/CreeveyView/SideBar/TestLink.tsx +2 -4
- package/src/client/web/KeyboardEventsContext.tsx +61 -73
- package/src/client/web/themes.ts +24 -0
- package/src/creevey.ts +13 -6
- package/src/server/config.ts +5 -4
- package/src/server/docker.ts +41 -23
- package/src/server/index.ts +39 -9
- package/src/server/logger.ts +6 -2
- package/src/server/master/api.ts +1 -1
- package/src/server/master/pool.ts +18 -56
- 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 +13 -9
- package/src/server/playwright/docker-file.ts +7 -4
- package/src/server/playwright/internal.ts +70 -51
- package/src/server/playwright/webdriver.ts +2 -2
- package/src/server/providers/browser.ts +6 -4
- package/src/server/providers/hybrid.ts +1 -1
- package/src/server/reporter.ts +15 -9
- package/src/server/selenium/internal.ts +133 -96
- package/src/server/selenium/selenoid.ts +2 -2
- package/src/server/selenium/webdriver.ts +2 -2
- package/src/server/telemetry.ts +7 -3
- package/src/server/utils.ts +37 -4
- package/src/server/webdriver.ts +11 -16
- package/src/server/worker/chai-image.ts +4 -4
- package/src/server/worker/match-image.ts +12 -8
- package/src/server/worker/start.ts +25 -16
- package/src/shared/index.ts +1 -1
- package/src/types.ts +35 -15
- package/types/global.d.ts +1 -0
- package/.yarnrc.yml +0 -1
- package/chromatic.config.json +0 -5
@@ -1,15 +1,28 @@
|
|
1
1
|
import { Browser, BrowserType, Page, chromium, firefox, webkit } from 'playwright-core';
|
2
|
-
import Logger from 'loglevel';
|
3
2
|
import chalk from 'chalk';
|
4
3
|
import { v4 } from 'uuid';
|
5
4
|
import prefix from 'loglevel-plugin-prefix';
|
6
|
-
import {
|
7
|
-
|
5
|
+
import {
|
6
|
+
BrowserConfigObject,
|
7
|
+
Config,
|
8
|
+
Options,
|
9
|
+
StoriesRaw,
|
10
|
+
StoryInput,
|
11
|
+
StorybookEvents,
|
12
|
+
StorybookGlobals,
|
13
|
+
noop,
|
14
|
+
} from '../../types';
|
8
15
|
import { subscribeOn } from '../messages';
|
9
16
|
import { appendIframePath, getAddresses, LOCALHOST_REGEXP, resolveStorybookUrl, storybookRootID } from '../webdriver';
|
10
|
-
import { isShuttingDown, runSequence } from '../utils';
|
17
|
+
import { isShuttingDown, resolvePlaywrightBrowserType, runSequence } from '../utils';
|
11
18
|
import { colors, logger } from '../logger';
|
12
|
-
import { Args } from '@storybook/csf';
|
19
|
+
import type { Args } from '@storybook/csf';
|
20
|
+
|
21
|
+
const browsers = {
|
22
|
+
chromium,
|
23
|
+
firefox,
|
24
|
+
webkit,
|
25
|
+
};
|
13
26
|
|
14
27
|
async function tryConnect(type: BrowserType, gridUrl: string): Promise<Browser | null> {
|
15
28
|
let timeout: NodeJS.Timeout | null = null;
|
@@ -20,7 +33,7 @@ async function tryConnect(type: BrowserType, gridUrl: string): Promise<Browser |
|
|
20
33
|
(resolve) =>
|
21
34
|
(timeout = setTimeout(() => {
|
22
35
|
isTimeout = true;
|
23
|
-
logger.error(`Can't connect to ${type.name()} playwright browser`, error);
|
36
|
+
logger().error(`Can't connect to ${type.name()} playwright browser`, error);
|
24
37
|
resolve(null);
|
25
38
|
}, 10000)),
|
26
39
|
),
|
@@ -49,13 +62,13 @@ export class InternalBrowser {
|
|
49
62
|
#sessionId: string = v4();
|
50
63
|
#serverHost: string | null = null;
|
51
64
|
#serverPort: number;
|
52
|
-
#
|
65
|
+
#storybookGlobals?: StorybookGlobals;
|
53
66
|
#unsubscribe: () => void = noop;
|
54
|
-
constructor(browser: Browser, page: Page, port: number) {
|
67
|
+
constructor(browser: Browser, page: Page, port: number, storybookGlobals?: StorybookGlobals) {
|
55
68
|
this.#browser = browser;
|
56
69
|
this.#page = page;
|
57
70
|
this.#serverPort = port;
|
58
|
-
this.#
|
71
|
+
this.#storybookGlobals = storybookGlobals;
|
59
72
|
this.#unsubscribe = subscribeOn('shutdown', () => {
|
60
73
|
void this.closeBrowser();
|
61
74
|
});
|
@@ -91,7 +104,12 @@ export class InternalBrowser {
|
|
91
104
|
if (captureElement) {
|
92
105
|
const element = await this.#page.$(captureElement);
|
93
106
|
if (!element) throw new Error(`Element with selector ${captureElement} not found`);
|
94
|
-
|
107
|
+
|
108
|
+
return element.screenshot({
|
109
|
+
animations: 'disabled',
|
110
|
+
mask,
|
111
|
+
style: ':root { overflow: hidden !important; }',
|
112
|
+
});
|
95
113
|
}
|
96
114
|
return this.#page.screenshot({ animations: 'disabled', mask, fullPage: true });
|
97
115
|
}
|
@@ -102,10 +120,11 @@ export class InternalBrowser {
|
|
102
120
|
|
103
121
|
async selectStory(id: string, waitForReady = false): Promise<boolean> {
|
104
122
|
// NOTE: Global variables might be reset after hot reload. I think it's workaround, maybe we need better solution
|
123
|
+
await this.updateStorybookGlobals();
|
105
124
|
await this.updateBrowserGlobalVariables();
|
106
125
|
await this.resetMousePosition();
|
107
126
|
|
108
|
-
|
127
|
+
logger().debug(`Triggering 'SetCurrentStory' event with storyId ${chalk.magenta(id)}`);
|
109
128
|
|
110
129
|
const result = await this.#page.evaluate<
|
111
130
|
[error?: string | null, isCaptureCalled?: boolean] | null,
|
@@ -140,7 +159,7 @@ export class InternalBrowser {
|
|
140
159
|
});
|
141
160
|
});
|
142
161
|
},
|
143
|
-
[story.id, updatedArgs, UPDATE_STORY_ARGS, STORY_RENDERED] as const,
|
162
|
+
[story.id, updatedArgs, StorybookEvents.UPDATE_STORY_ARGS, StorybookEvents.STORY_RENDERED] as const,
|
144
163
|
);
|
145
164
|
}
|
146
165
|
|
@@ -167,26 +186,28 @@ export class InternalBrowser {
|
|
167
186
|
options: Options,
|
168
187
|
): Promise<InternalBrowser | null> {
|
169
188
|
const browserConfig = config.browsers[browserName] as BrowserConfigObject;
|
170
|
-
const {
|
189
|
+
const {
|
190
|
+
storybookUrl: address = config.storybookUrl,
|
191
|
+
viewport,
|
192
|
+
_storybookGlobals,
|
193
|
+
seleniumCapabilities,
|
194
|
+
playwrightOptions,
|
195
|
+
} = browserConfig;
|
171
196
|
|
172
197
|
let browser: Browser | null = null;
|
173
198
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
default:
|
187
|
-
throw new Error(
|
188
|
-
`Unknown browser ${browserConfig.browserName}. Playwright supports browsers: chromium, firefox, webkit`,
|
189
|
-
);
|
199
|
+
if (new URL(gridUrl).protocol === 'ws:') {
|
200
|
+
browser = await tryConnect(browsers[resolvePlaywrightBrowserType(browserConfig.browserName)], gridUrl);
|
201
|
+
} else {
|
202
|
+
if (browserConfig.browserName != 'chrome') {
|
203
|
+
logger().error("Playwright's Selenium Grid feature supports only chrome browser");
|
204
|
+
return null;
|
205
|
+
}
|
206
|
+
|
207
|
+
process.env.SELENIUM_REMOTE_URL = gridUrl;
|
208
|
+
process.env.SELENIUM_REMOTE_CAPABILITIES = JSON.stringify(seleniumCapabilities);
|
209
|
+
|
210
|
+
browser = await chromium.launch(playwrightOptions);
|
190
211
|
}
|
191
212
|
|
192
213
|
if (!browser) {
|
@@ -197,7 +218,7 @@ export class InternalBrowser {
|
|
197
218
|
|
198
219
|
// TODO Add debug output
|
199
220
|
|
200
|
-
const internalBrowser = new InternalBrowser(browser, page, options.port);
|
221
|
+
const internalBrowser = new InternalBrowser(browser, page, options.port, _storybookGlobals);
|
201
222
|
|
202
223
|
try {
|
203
224
|
if (isShuttingDown.current) return null;
|
@@ -205,7 +226,6 @@ export class InternalBrowser {
|
|
205
226
|
browserName,
|
206
227
|
viewport,
|
207
228
|
storybookUrl: address,
|
208
|
-
storybookGlobals: _storybookGlobals,
|
209
229
|
resolveStorybookUrl: config.resolveStorybookUrl,
|
210
230
|
});
|
211
231
|
|
@@ -217,7 +237,7 @@ export class InternalBrowser {
|
|
217
237
|
const error = new Error(`Can't load storybook root page: ${message}`);
|
218
238
|
if (originalError instanceof Error) error.stack = originalError.stack;
|
219
239
|
|
220
|
-
logger.error(error);
|
240
|
+
logger().error(error);
|
221
241
|
|
222
242
|
return null;
|
223
243
|
}
|
@@ -227,32 +247,29 @@ export class InternalBrowser {
|
|
227
247
|
browserName,
|
228
248
|
viewport,
|
229
249
|
storybookUrl,
|
230
|
-
storybookGlobals,
|
231
250
|
resolveStorybookUrl,
|
232
251
|
}: {
|
233
252
|
browserName: string;
|
234
253
|
viewport?: { width: number; height: number };
|
235
254
|
storybookUrl: string;
|
236
|
-
storybookGlobals?: StorybookGlobals;
|
237
255
|
resolveStorybookUrl?: () => Promise<string>;
|
238
256
|
}) {
|
239
257
|
const sessionId = this.#sessionId;
|
240
258
|
|
241
|
-
prefix.apply(
|
259
|
+
prefix.apply(logger(), {
|
242
260
|
format(level) {
|
243
261
|
const levelColor = colors[level.toUpperCase() as keyof typeof colors];
|
244
|
-
return `[${browserName}:${chalk.gray(
|
262
|
+
return `[${browserName}:${chalk.gray(process.pid)}] ${levelColor(level)} => ${chalk.gray(sessionId)}`;
|
245
263
|
},
|
246
264
|
});
|
247
265
|
|
248
|
-
this.#page.setDefaultNavigationTimeout(10000);
|
249
266
|
this.#page.setDefaultTimeout(60000);
|
250
267
|
|
251
268
|
return await runSequence(
|
252
269
|
[
|
253
270
|
() => this.openStorybookPage(storybookUrl, resolveStorybookUrl),
|
254
271
|
() => this.waitForStorybook(),
|
255
|
-
() => this.updateStorybookGlobals(
|
272
|
+
() => this.updateStorybookGlobals(),
|
256
273
|
() => this.resolveCreeveyHost(),
|
257
274
|
() => this.updateBrowserGlobalVariables(),
|
258
275
|
() => this.resizeViewport(viewport),
|
@@ -269,29 +286,30 @@ export class InternalBrowser {
|
|
269
286
|
|
270
287
|
try {
|
271
288
|
if (resolver) {
|
272
|
-
|
289
|
+
logger().debug('Resolving storybook url with custom resolver');
|
273
290
|
|
274
291
|
const resolvedUrl = await resolver();
|
275
292
|
|
276
|
-
|
293
|
+
logger().debug(`Resolver storybook url ${resolvedUrl}`);
|
277
294
|
|
278
295
|
await this.#page.goto(appendIframePath(resolvedUrl));
|
279
296
|
} else {
|
280
|
-
|
297
|
+
// TODO this.#page.setDefaultNavigationTimeout(10000);
|
298
|
+
await resolveStorybookUrl(appendIframePath(storybookUrl), (url) => this.checkUrl(url));
|
281
299
|
}
|
282
300
|
} catch (error) {
|
283
|
-
|
301
|
+
logger().error('Failed to resolve storybook URL', error instanceof Error ? error.message : '');
|
284
302
|
throw error;
|
285
303
|
}
|
286
304
|
}
|
287
305
|
|
288
306
|
private async checkUrl(url: string): Promise<boolean> {
|
289
307
|
try {
|
290
|
-
|
308
|
+
logger().debug(`Opening ${chalk.magenta(url)} and checking the page source`);
|
291
309
|
const response = await this.#page.goto(url, { waitUntil: 'commit' });
|
292
310
|
const source = await response?.text();
|
293
311
|
|
294
|
-
|
312
|
+
logger().debug(`Checking ${chalk.cyan(`#${storybookRootID}`)} existence on ${chalk.magenta(url)}`);
|
295
313
|
return source?.includes(`id="${storybookRootID}"`) ?? false;
|
296
314
|
} catch {
|
297
315
|
return false;
|
@@ -300,7 +318,7 @@ export class InternalBrowser {
|
|
300
318
|
|
301
319
|
private async waitForStorybook(): Promise<void> {
|
302
320
|
// TODO Duplicated code with selenium
|
303
|
-
|
321
|
+
logger().debug('Waiting for `setStories` event to make sure that storybook is initiated');
|
304
322
|
|
305
323
|
const isTimeout = await Promise.race([
|
306
324
|
new Promise<boolean>((resolve) => {
|
@@ -317,9 +335,9 @@ export class InternalBrowser {
|
|
317
335
|
if (typeof window.__STORYBOOK_ADDONS_CHANNEL__ == 'undefined') return true;
|
318
336
|
if (window.__STORYBOOK_ADDONS_CHANNEL__.last(SET_GLOBALS) == undefined) return true;
|
319
337
|
return false;
|
320
|
-
}, SET_GLOBALS);
|
338
|
+
}, StorybookEvents.SET_GLOBALS);
|
321
339
|
} catch (e: unknown) {
|
322
|
-
|
340
|
+
logger().debug('An error has been caught during the script:', e);
|
323
341
|
}
|
324
342
|
} while (wait);
|
325
343
|
return false;
|
@@ -330,13 +348,13 @@ export class InternalBrowser {
|
|
330
348
|
if (isTimeout) throw new Error('Failed to wait `setStories` event');
|
331
349
|
}
|
332
350
|
|
333
|
-
private async updateStorybookGlobals(
|
334
|
-
if (!
|
351
|
+
private async updateStorybookGlobals(): Promise<void> {
|
352
|
+
if (!this.#storybookGlobals) return;
|
335
353
|
|
336
|
-
|
354
|
+
logger().debug('Applying storybook globals');
|
337
355
|
await this.#page.evaluate((globals: StorybookGlobals) => {
|
338
356
|
window.__CREEVEY_UPDATE_GLOBALS__(globals);
|
339
|
-
},
|
357
|
+
}, this.#storybookGlobals);
|
340
358
|
}
|
341
359
|
|
342
360
|
private async resolveCreeveyHost(): Promise<void> {
|
@@ -367,6 +385,7 @@ export class InternalBrowser {
|
|
367
385
|
private async updateBrowserGlobalVariables() {
|
368
386
|
await this.#page.evaluate(
|
369
387
|
([workerId, creeveyHost, creeveyPort]) => {
|
388
|
+
window.__CREEVEY_ENV__ = true;
|
370
389
|
window.__CREEVEY_WORKER_ID__ = workerId;
|
371
390
|
window.__CREEVEY_SERVER_HOST__ = creeveyHost ?? 'localhost';
|
372
391
|
window.__CREEVEY_SERVER_PORT__ = creeveyPort;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/// <reference types="../../../types/playwright-context" />
|
2
|
-
import { Args } from '@storybook/csf';
|
2
|
+
import type { Args } from '@storybook/csf';
|
3
3
|
import { Config, Options, ServerTest, StoriesRaw, StoryInput } from '../../types';
|
4
4
|
import { logger } from '../logger';
|
5
5
|
import { subscribeOn } from '../messages';
|
@@ -53,7 +53,7 @@ export class PlaywrightWebdriver extends CreeveyWebdriverBase {
|
|
53
53
|
try {
|
54
54
|
return await import('./internal.js');
|
55
55
|
} catch (error) {
|
56
|
-
logger.error(error);
|
56
|
+
logger().error(error);
|
57
57
|
return null;
|
58
58
|
}
|
59
59
|
})();
|
@@ -5,6 +5,7 @@ import { isDefined } from '../../types.js';
|
|
5
5
|
import { logger } from '../logger.js';
|
6
6
|
import { deserializeRawStories } from '../../shared/index.js';
|
7
7
|
|
8
|
+
// TODO Don't have updates from stories
|
8
9
|
export const loadStories: StoriesProvider = async (_config, storiesListener, webdriver) => {
|
9
10
|
if (cluster.isPrimary) {
|
10
11
|
return new Promise<StoriesRaw>((resolve) => {
|
@@ -17,13 +18,13 @@ export const loadStories: StoriesProvider = async (_config, storiesListener, web
|
|
17
18
|
if (message.type == 'set') {
|
18
19
|
const { stories, oldTests } = message.payload;
|
19
20
|
if (oldTests.length > 0)
|
20
|
-
logger.warn(
|
21
|
+
logger().warn(
|
21
22
|
`If you use browser stories provider of CSFv3 Storybook feature\n` +
|
22
23
|
`Creevey will not load tests defined in story parameters from following stories:\n` +
|
23
24
|
oldTests.join('\n'),
|
24
25
|
);
|
25
26
|
unsubscribe();
|
26
|
-
resolve(stories);
|
27
|
+
resolve(deserializeRawStories(stories));
|
27
28
|
}
|
28
29
|
});
|
29
30
|
sendStoriesMessage(worker, { type: 'get' });
|
@@ -36,10 +37,11 @@ export const loadStories: StoriesProvider = async (_config, storiesListener, web
|
|
36
37
|
} else {
|
37
38
|
subscribeOn('stories', (message) => {
|
38
39
|
if (message.type == 'get')
|
39
|
-
emitStoriesMessage({ type: 'set', payload: { stories, oldTests: storiesWithOldTests } });
|
40
|
+
emitStoriesMessage({ type: 'set', payload: { stories: rawStories, oldTests: storiesWithOldTests } });
|
40
41
|
if (message.type == 'update') storiesListener(new Map(message.payload));
|
41
42
|
});
|
42
|
-
const
|
43
|
+
const rawStories = (await webdriver?.loadStoriesFromBrowser()) ?? {};
|
44
|
+
const stories = deserializeRawStories(rawStories);
|
43
45
|
|
44
46
|
const storiesWithOldTests: string[] = [];
|
45
47
|
|
@@ -54,7 +54,7 @@ async function parseParams(
|
|
54
54
|
|
55
55
|
if (listener) {
|
56
56
|
chokidar.watch(testFiles).on('change', (filePath) => {
|
57
|
-
logger.debug(`changed: ${filePath}`);
|
57
|
+
logger().debug(`changed: ${filePath}`);
|
58
58
|
|
59
59
|
// doesn't work, always returns {} due modules caching
|
60
60
|
// see https://github.com/nodejs/modules/issues/307
|
package/src/server/reporter.ts
CHANGED
@@ -22,23 +22,24 @@ export class CreeveyReporter {
|
|
22
22
|
// TODO Output in better way, like vitest, maybe
|
23
23
|
constructor(runner: EventEmitter, options: { reporterOptions: { creevey: ReporterOptions } }) {
|
24
24
|
const { sessionId, browserName } = options.reporterOptions.creevey;
|
25
|
-
const testLogger = Logger.getLogger(
|
25
|
+
const testLogger = Logger.getLogger(sessionId);
|
26
26
|
|
27
27
|
prefix.apply(testLogger, {
|
28
28
|
format(level) {
|
29
|
-
return
|
29
|
+
return `[${browserName}:${chalk.gray(process.pid)}] ${testLevels[level]} => ${chalk.gray(sessionId)}`;
|
30
30
|
},
|
31
31
|
});
|
32
32
|
|
33
33
|
runner.on(TEST_EVENTS.TEST_BEGIN, (test: FakeTest) => {
|
34
|
-
testLogger.warn(chalk.cyan(test.
|
34
|
+
testLogger.warn(chalk.cyan(test.fullTitle()));
|
35
35
|
});
|
36
36
|
runner.on(TEST_EVENTS.TEST_PASS, (test: FakeTest) => {
|
37
|
-
testLogger.info(chalk.cyan(test.
|
37
|
+
testLogger.info(chalk.cyan(test.fullTitle()), chalk.gray(`(${test.duration} ms)`));
|
38
38
|
});
|
39
39
|
runner.on(TEST_EVENTS.TEST_FAIL, (test: FakeTest, error) => {
|
40
40
|
testLogger.error(
|
41
|
-
chalk.cyan(test.
|
41
|
+
chalk.cyan(test.fullTitle()),
|
42
|
+
chalk.gray(`(${test.duration} ms)`),
|
42
43
|
'\n ',
|
43
44
|
this.getErrors(
|
44
45
|
error,
|
@@ -76,7 +77,11 @@ export class TeamcityReporter {
|
|
76
77
|
const reporterOptions = options.reporterOptions.creevey;
|
77
78
|
|
78
79
|
runner.on(TEST_EVENTS.TEST_BEGIN, (test: FakeTest) => {
|
79
|
-
console.log(`##teamcity[testStarted name='${this.escape(test.
|
80
|
+
console.log(`##teamcity[testStarted name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
81
|
+
});
|
82
|
+
|
83
|
+
runner.on(TEST_EVENTS.TEST_PASS, (test: FakeTest) => {
|
84
|
+
console.log(`##teamcity[testFinished name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
80
85
|
});
|
81
86
|
|
82
87
|
runner.on(TEST_EVENTS.TEST_FAIL, (test: FakeTest, error: Error) => {
|
@@ -84,6 +89,7 @@ export class TeamcityReporter {
|
|
84
89
|
if (!image) return;
|
85
90
|
const filePath = test
|
86
91
|
.titlePath()
|
92
|
+
.slice(0, -1)
|
87
93
|
.concat(name == browserName ? [] : [browserName])
|
88
94
|
.map(this.escape)
|
89
95
|
.join('/');
|
@@ -97,7 +103,7 @@ export class TeamcityReporter {
|
|
97
103
|
);
|
98
104
|
console.log(
|
99
105
|
`##teamcity[testMetadata testName='${this.escape(
|
100
|
-
test.
|
106
|
+
test.fullTitle(),
|
101
107
|
)}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`,
|
102
108
|
);
|
103
109
|
});
|
@@ -107,10 +113,10 @@ export class TeamcityReporter {
|
|
107
113
|
// 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
|
108
114
|
|
109
115
|
if (reporterOptions.willRetry)
|
110
|
-
console.log(`##teamcity[testFinished name='${this.escape(test.
|
116
|
+
console.log(`##teamcity[testFinished name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
111
117
|
else
|
112
118
|
console.log(
|
113
|
-
`##teamcity[testFailed name='${this.escape(test.
|
119
|
+
`##teamcity[testFailed name='${this.escape(test.fullTitle())}' message='${this.escape(
|
114
120
|
error.message,
|
115
121
|
)}' details='${this.escape(error.stack ?? '')}' flowId='${process.pid}']`,
|
116
122
|
);
|