creevey 0.10.0-beta.9 → 0.10.0-rc.0
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/AUTHORS +2 -0
- package/CHANGELOG.md +281 -0
- package/README.md +19 -41
- package/dist/client/addon/components/Addon.js +18 -8
- 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/TestSelect.js +2 -2
- package/dist/client/addon/components/TestSelect.js.map +1 -1
- package/dist/client/addon/components/Tools.js +19 -9
- package/dist/client/addon/components/Tools.js.map +1 -1
- package/dist/client/addon/controller.d.ts +1 -1
- package/dist/client/addon/controller.js +3 -3
- package/dist/client/addon/controller.js.map +1 -1
- package/dist/client/addon/decorator.d.ts +1 -1
- package/dist/client/addon/makeDecorator.d.ts +9 -0
- package/dist/client/addon/makeDecorator.js +48 -0
- package/dist/client/addon/makeDecorator.js.map +1 -0
- package/dist/client/addon/manager.js +38 -39
- package/dist/client/addon/manager.js.map +1 -1
- package/dist/client/addon/preset.d.ts +0 -1
- package/dist/client/addon/preset.js +3 -2
- package/dist/client/addon/preset.js.map +1 -1
- package/dist/client/addon/preview.d.ts +1 -1
- package/dist/client/addon/withCreevey.d.ts +5 -3
- package/dist/client/addon/withCreevey.js +5 -20
- package/dist/client/addon/withCreevey.js.map +1 -1
- package/dist/client/shared/components/ImagesView/BlendView.d.ts +2 -2
- package/dist/client/shared/components/ImagesView/BlendView.js +18 -8
- package/dist/client/shared/components/ImagesView/BlendView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/ImagesView.js +1 -1
- package/dist/client/shared/components/ImagesView/ImagesView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SideBySideView.d.ts +2 -2
- package/dist/client/shared/components/ImagesView/SideBySideView.js +19 -9
- package/dist/client/shared/components/ImagesView/SideBySideView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SlideView.d.ts +2 -2
- package/dist/client/shared/components/ImagesView/SlideView.js +19 -9
- package/dist/client/shared/components/ImagesView/SlideView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SwapView.d.ts +2 -2
- package/dist/client/shared/components/ImagesView/SwapView.js +19 -9
- package/dist/client/shared/components/ImagesView/SwapView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/common.d.ts +1 -1
- package/dist/client/shared/components/PageFooter/PageFooter.js +1 -1
- package/dist/client/shared/components/PageFooter/PageFooter.js.map +1 -1
- package/dist/client/shared/components/PageFooter/Paging.js +1 -1
- package/dist/client/shared/components/PageFooter/Paging.js.map +1 -1
- package/dist/client/shared/components/PageHeader/ImagePreview.d.ts +2 -2
- package/dist/client/shared/components/PageHeader/ImagePreview.js +1 -1
- package/dist/client/shared/components/PageHeader/ImagePreview.js.map +1 -1
- package/dist/client/shared/components/PageHeader/PageHeader.js +34 -13
- package/dist/client/shared/components/PageHeader/PageHeader.js.map +1 -1
- package/dist/client/shared/components/ResultsPage.d.ts +2 -2
- package/dist/client/shared/components/ResultsPage.js +22 -10
- package/dist/client/shared/components/ResultsPage.js.map +1 -1
- package/dist/client/shared/creeveyClientApi.js +18 -1
- package/dist/client/shared/creeveyClientApi.js.map +1 -1
- package/dist/client/shared/helpers.d.ts +1 -3
- package/dist/client/shared/helpers.js +4 -19
- package/dist/client/shared/helpers.js.map +1 -1
- package/dist/client/web/CreeveyApp.d.ts +1 -0
- package/dist/client/web/CreeveyApp.js +22 -9
- package/dist/client/web/CreeveyApp.js.map +1 -1
- package/dist/client/web/CreeveyContext.d.ts +1 -0
- package/dist/client/web/CreeveyContext.js +18 -7
- package/dist/client/web/CreeveyContext.js.map +1 -1
- package/dist/client/web/CreeveyLoader.d.ts +1 -1
- package/dist/client/web/CreeveyLoader.js +3 -3
- package/dist/client/web/CreeveyLoader.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/Checkbox.d.ts +4 -4
- package/dist/client/web/CreeveyView/SideBar/Checkbox.js +36 -6
- package/dist/client/web/CreeveyView/SideBar/Checkbox.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/Search.js +18 -8
- package/dist/client/web/CreeveyView/SideBar/Search.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBar.js +26 -12
- package/dist/client/web/CreeveyView/SideBar/SideBar.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js +28 -17
- package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js +32 -12
- package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.d.ts +6 -6
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.js +20 -11
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestLink.js +20 -11
- package/dist/client/web/CreeveyView/SideBar/TestLink.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +2 -2
- package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js +2 -2
- package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestsStatus.d.ts +2 -2
- package/dist/client/web/CreeveyView/SideBar/TestsStatus.js +3 -2
- package/dist/client/web/CreeveyView/SideBar/TestsStatus.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/Toggle.js +1 -1
- package/dist/client/web/CreeveyView/SideBar/Toggle.js.map +1 -1
- package/dist/client/web/KeyboardEventsContext.js +17 -7
- package/dist/client/web/KeyboardEventsContext.js.map +1 -1
- package/dist/client/web/assets/index-CtSq3IhG.js +518 -0
- package/dist/client/web/index.html +1 -1
- package/dist/client/web/index.js +26 -11
- 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.d.ts +1 -1
- package/dist/creevey.js +122 -41
- package/dist/creevey.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/playwright/generator.d.ts +25 -0
- package/dist/playwright/generator.js +243 -0
- package/dist/playwright/generator.js.map +1 -0
- package/dist/playwright/helpers.d.ts +2 -0
- package/dist/playwright/helpers.js +29 -0
- package/dist/playwright/helpers.js.map +1 -0
- package/dist/playwright/reporter.d.ts +83 -0
- package/dist/playwright/reporter.js +334 -0
- package/dist/playwright/reporter.js.map +1 -0
- package/dist/playwright/setup.d.ts +3 -0
- package/dist/playwright/setup.js +72 -0
- package/dist/playwright/setup.js.map +1 -0
- package/dist/playwright.d.ts +1 -0
- package/dist/playwright.js +3 -1
- package/dist/playwright.js.map +1 -1
- package/dist/server/compare.d.ts +18 -0
- package/dist/server/compare.js +182 -0
- package/dist/server/compare.js.map +1 -0
- package/dist/server/config.d.ts +3 -3
- package/dist/server/config.js +75 -8
- package/dist/server/config.js.map +1 -1
- package/dist/server/connection.d.ts +3 -0
- package/dist/server/connection.js +28 -0
- package/dist/server/connection.js.map +1 -0
- package/dist/server/docker.d.ts +1 -1
- package/dist/server/docker.js +54 -32
- package/dist/server/docker.js.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +161 -64
- package/dist/server/index.js.map +1 -1
- package/dist/server/master/api.d.ts +11 -6
- package/dist/server/master/api.js +88 -25
- package/dist/server/master/api.js.map +1 -1
- package/dist/server/master/handlers/capture-handler.d.ts +5 -0
- package/dist/server/master/handlers/capture-handler.js +25 -0
- package/dist/server/master/handlers/capture-handler.js.map +1 -0
- package/dist/server/master/handlers/index.d.ts +4 -0
- package/dist/server/master/handlers/index.js +21 -0
- package/dist/server/master/handlers/index.js.map +1 -0
- package/dist/server/master/handlers/ping-handler.d.ts +2 -0
- package/dist/server/master/handlers/ping-handler.js +8 -0
- package/dist/server/master/handlers/ping-handler.js.map +1 -0
- package/dist/server/master/handlers/static-handler.d.ts +1 -0
- package/dist/server/master/handlers/static-handler.js +20 -0
- package/dist/server/master/handlers/static-handler.js.map +1 -0
- package/dist/server/master/handlers/stories-handler.d.ts +4 -0
- package/dist/server/master/handlers/stories-handler.js +24 -0
- package/dist/server/master/handlers/stories-handler.js.map +1 -0
- package/dist/server/master/master.js +7 -24
- package/dist/server/master/master.js.map +1 -1
- package/dist/server/master/pool.d.ts +1 -0
- package/dist/server/master/pool.js +5 -3
- package/dist/server/master/pool.js.map +1 -1
- package/dist/server/master/queue.d.ts +1 -1
- package/dist/server/master/queue.js +14 -6
- package/dist/server/master/queue.js.map +1 -1
- package/dist/server/master/runner.d.ts +6 -6
- package/dist/server/master/runner.js +98 -130
- package/dist/server/master/runner.js.map +1 -1
- package/dist/server/master/server.d.ts +1 -1
- package/dist/server/master/server.js +193 -88
- package/dist/server/master/server.js.map +1 -1
- package/dist/server/master/start.d.ts +1 -2
- package/dist/server/master/start.js +13 -29
- package/dist/server/master/start.js.map +1 -1
- package/dist/server/master/testsManager.d.ts +81 -0
- package/dist/server/master/testsManager.js +282 -0
- package/dist/server/master/testsManager.js.map +1 -0
- package/dist/server/playwright/docker-file.d.ts +1 -1
- package/dist/server/playwright/docker-file.js +17 -8
- package/dist/server/playwright/docker-file.js.map +1 -1
- package/dist/server/playwright/docker.d.ts +2 -1
- package/dist/server/playwright/docker.js +10 -2
- package/dist/server/playwright/docker.js.map +1 -1
- package/dist/server/playwright/index-source.mjs +16 -0
- package/dist/server/playwright/internal.d.ts +7 -7
- package/dist/server/playwright/internal.js +137 -79
- package/dist/server/playwright/internal.js.map +1 -1
- package/dist/server/playwright/webdriver.d.ts +3 -3
- package/dist/server/playwright/webdriver.js +0 -6
- package/dist/server/playwright/webdriver.js.map +1 -1
- package/dist/server/providers/browser.js +4 -3
- package/dist/server/providers/browser.js.map +1 -1
- package/dist/server/providers/hybrid.js +2 -2
- package/dist/server/providers/hybrid.js.map +1 -1
- package/dist/server/report.d.ts +10 -0
- package/dist/server/report.js +45 -0
- package/dist/server/report.js.map +1 -0
- package/dist/server/reporters/creevey.d.ts +7 -0
- package/dist/server/reporters/creevey.js +63 -0
- package/dist/server/reporters/creevey.js.map +1 -0
- package/dist/server/reporters/index.d.ts +2 -0
- package/dist/server/reporters/index.js +16 -0
- package/dist/server/reporters/index.js.map +1 -0
- package/dist/server/reporters/junit.d.ts +16 -0
- package/dist/server/reporters/junit.js +167 -0
- package/dist/server/reporters/junit.js.map +1 -0
- package/dist/server/reporters/teamcity.d.ts +7 -0
- package/dist/server/reporters/teamcity.js +60 -0
- package/dist/server/reporters/teamcity.js.map +1 -0
- package/dist/server/selenium/internal.d.ts +3 -3
- package/dist/server/selenium/internal.js +48 -34
- package/dist/server/selenium/internal.js.map +1 -1
- package/dist/server/selenium/selenoid.js +12 -6
- package/dist/server/selenium/selenoid.js.map +1 -1
- package/dist/server/selenium/webdriver.d.ts +3 -3
- package/dist/server/selenium/webdriver.js +4 -8
- package/dist/server/selenium/webdriver.js.map +1 -1
- package/dist/server/shutdown.d.ts +1 -0
- package/dist/server/shutdown.js +23 -0
- package/dist/server/shutdown.js.map +1 -0
- package/dist/server/stories.d.ts +0 -1
- package/dist/server/stories.js +0 -12
- package/dist/server/stories.js.map +1 -1
- package/dist/server/telemetry.js +3 -3
- package/dist/server/telemetry.js.map +1 -1
- package/dist/server/testsFiles/parser.js +45 -5
- package/dist/server/testsFiles/parser.js.map +1 -1
- package/dist/server/utils.d.ts +23 -0
- package/dist/server/utils.js +113 -13
- package/dist/server/utils.js.map +1 -1
- package/dist/server/webdriver.d.ts +1 -1
- package/dist/server/worker/context.d.ts +3 -0
- package/dist/server/worker/context.js +15 -0
- package/dist/server/worker/context.js.map +1 -0
- package/dist/server/worker/match-image.d.ts +8 -12
- package/dist/server/worker/match-image.js +11 -178
- package/dist/server/worker/match-image.js.map +1 -1
- package/dist/server/worker/start.d.ts +2 -2
- package/dist/server/worker/start.js +27 -63
- package/dist/server/worker/start.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +9 -7
- package/dist/shared/index.js.map +1 -1
- package/dist/types.d.ts +84 -43
- package/dist/types.js +65 -1
- package/dist/types.js.map +1 -1
- package/docs/cli.md +80 -0
- package/docs/config.md +179 -165
- package/docs/examples/playwright-reporer/playwright.config.ts +37 -0
- package/docs/migration-0.9-to-0.10.md +144 -0
- package/docs/playwright-reporter.md +357 -0
- package/docs/storybook.md +60 -0
- package/docs/tests.md +50 -45
- package/package.json +78 -83
- package/playwright.config.mts +46 -0
- package/src/client/addon/components/Addon.tsx +1 -1
- package/src/client/addon/components/Panel.tsx +2 -2
- package/src/client/addon/components/TestSelect.tsx +2 -2
- package/src/client/addon/components/Tools.tsx +2 -2
- package/src/client/addon/controller.ts +4 -4
- package/src/client/addon/makeDecorator.ts +69 -0
- package/src/client/addon/manager.ts +38 -37
- package/src/client/addon/preset.ts +2 -1
- package/src/client/addon/withCreevey.ts +10 -18
- package/src/client/shared/components/ImagesView/BlendView.tsx +1 -1
- package/src/client/shared/components/ImagesView/ImagesView.tsx +1 -1
- package/src/client/shared/components/ImagesView/SideBySideView.tsx +2 -2
- package/src/client/shared/components/ImagesView/SlideView.tsx +2 -2
- package/src/client/shared/components/ImagesView/SwapView.tsx +2 -2
- package/src/client/shared/components/ImagesView/common.ts +1 -1
- package/src/client/shared/components/PageFooter/PageFooter.tsx +1 -1
- package/src/client/shared/components/PageFooter/Paging.tsx +1 -1
- package/src/client/shared/components/PageHeader/ImagePreview.tsx +1 -1
- package/src/client/shared/components/PageHeader/PageHeader.tsx +23 -7
- package/src/client/shared/components/ResultsPage.tsx +6 -4
- package/src/client/shared/creeveyClientApi.ts +19 -1
- package/src/client/shared/helpers.ts +4 -24
- package/src/client/web/CreeveyApp.tsx +5 -2
- package/src/client/web/CreeveyContext.tsx +2 -0
- package/src/client/web/CreeveyLoader.tsx +2 -2
- package/src/client/web/CreeveyView/SideBar/Checkbox.tsx +3 -3
- package/src/client/web/CreeveyView/SideBar/Search.tsx +1 -1
- package/src/client/web/CreeveyView/SideBar/SideBar.tsx +11 -6
- package/src/client/web/CreeveyView/SideBar/SideBarFooter.tsx +21 -19
- package/src/client/web/CreeveyView/SideBar/SideBarHeader.tsx +20 -5
- package/src/client/web/CreeveyView/SideBar/SuiteLink.tsx +10 -8
- package/src/client/web/CreeveyView/SideBar/TestLink.tsx +9 -7
- package/src/client/web/CreeveyView/SideBar/TestStatusIcon.tsx +2 -2
- package/src/client/web/CreeveyView/SideBar/TestsStatus.tsx +3 -2
- package/src/client/web/CreeveyView/SideBar/Toggle.tsx +1 -1
- package/src/client/web/index.tsx +10 -5
- package/src/client/web/themes.ts +24 -0
- package/src/creevey.ts +92 -38
- package/src/playwright/generator.ts +322 -0
- package/src/playwright/helpers.ts +31 -0
- package/src/playwright/reporter.ts +381 -0
- package/src/playwright/setup.ts +84 -0
- package/src/playwright.ts +1 -0
- package/src/server/compare.ts +260 -0
- package/src/server/config.ts +52 -9
- package/src/server/connection.ts +26 -0
- package/src/server/docker.ts +62 -34
- package/src/server/index.ts +161 -79
- package/src/server/master/api.ts +94 -28
- package/src/server/master/handlers/capture-handler.ts +20 -0
- package/src/server/master/handlers/index.ts +4 -0
- package/src/server/master/handlers/ping-handler.ts +6 -0
- package/src/server/master/handlers/static-handler.ts +16 -0
- package/src/server/master/handlers/stories-handler.ts +20 -0
- package/src/server/master/master.ts +10 -27
- package/src/server/master/pool.ts +7 -3
- package/src/server/master/queue.ts +21 -7
- package/src/server/master/runner.ts +123 -134
- package/src/server/master/server.ts +214 -101
- package/src/server/master/start.ts +19 -41
- package/src/server/master/testsManager.ts +316 -0
- package/src/server/playwright/docker-file.ts +20 -8
- package/src/server/playwright/docker.ts +16 -3
- package/src/server/playwright/index-source.mjs +16 -0
- package/src/server/playwright/internal.ts +169 -96
- package/src/server/playwright/webdriver.ts +4 -10
- package/src/server/providers/browser.ts +4 -3
- package/src/server/providers/hybrid.ts +2 -3
- package/src/server/report.ts +51 -0
- package/src/server/reporters/creevey.ts +71 -0
- package/src/server/reporters/index.ts +11 -0
- package/src/server/reporters/junit.ts +207 -0
- package/src/server/reporters/teamcity.ts +74 -0
- package/src/server/selenium/internal.ts +62 -45
- package/src/server/selenium/selenoid.ts +13 -6
- package/src/server/selenium/webdriver.ts +8 -12
- package/src/server/shutdown.ts +19 -0
- package/src/server/stories.ts +1 -12
- package/src/server/telemetry.ts +3 -3
- package/src/server/testsFiles/parser.ts +52 -4
- package/src/server/utils.ts +123 -14
- package/src/server/webdriver.ts +1 -1
- package/src/server/worker/context.ts +14 -0
- package/src/server/worker/match-image.ts +16 -248
- package/src/server/worker/start.ts +32 -75
- package/src/shared/index.ts +10 -8
- package/src/types.ts +91 -58
- package/types/global.d.ts +1 -0
- package/dist/client/web/assets/index-BE9CL5_G.js +0 -591
- package/dist/server/reporter.d.ts +0 -26
- package/dist/server/reporter.js +0 -108
- package/dist/server/reporter.js.map +0 -1
- package/dist/server/update.d.ts +0 -2
- package/dist/server/update.js +0 -53
- package/dist/server/update.js.map +0 -1
- package/src/server/reporter.ts +0 -139
- package/src/server/update.ts +0 -74
@@ -1,10 +1,11 @@
|
|
1
1
|
/// <reference types="../../../types/selenium-context" />
|
2
|
-
import { Args } from '
|
3
|
-
import { Config, StorybookGlobals, StoryInput, StoriesRaw,
|
2
|
+
import type { Args } from 'storybook/internal/types';
|
3
|
+
import { Config, StorybookGlobals, StoryInput, StoriesRaw, ServerTest, WorkerOptions } from '../../types.js';
|
4
4
|
import { subscribeOn } from '../messages.js';
|
5
5
|
import { CreeveyWebdriverBase } from '../webdriver.js';
|
6
6
|
import type { InternalBrowser } from './internal.js';
|
7
7
|
import { logger } from '../logger.js';
|
8
|
+
import { removeWorkerContainer } from '../worker/context.js';
|
8
9
|
|
9
10
|
declare global {
|
10
11
|
interface Window {
|
@@ -21,8 +22,8 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
21
22
|
#browserName: string;
|
22
23
|
#gridUrl: string;
|
23
24
|
#config: Config;
|
24
|
-
#options:
|
25
|
-
constructor(browser: string, gridUrl: string, config: Config, options:
|
25
|
+
#options: WorkerOptions;
|
26
|
+
constructor(browser: string, gridUrl: string, config: Config, options: WorkerOptions) {
|
26
27
|
super();
|
27
28
|
|
28
29
|
this.#browserName = browser;
|
@@ -31,7 +32,9 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
31
32
|
this.#options = options;
|
32
33
|
|
33
34
|
subscribeOn('shutdown', () => {
|
34
|
-
void this.#browser?.closeBrowser().finally(() =>
|
35
|
+
void this.#browser?.closeBrowser().finally(() => {
|
36
|
+
void removeWorkerContainer().finally(() => process.exit());
|
37
|
+
});
|
35
38
|
this.#browser = null;
|
36
39
|
});
|
37
40
|
}
|
@@ -42,7 +45,6 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
42
45
|
|
43
46
|
getSessionId(): Promise<string> {
|
44
47
|
if (!this.#browser) {
|
45
|
-
// TODO Describe the error
|
46
48
|
throw new Error('Browser is not initialized');
|
47
49
|
}
|
48
50
|
|
@@ -89,7 +91,6 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
89
91
|
|
90
92
|
async loadStoriesFromBrowser(): Promise<StoriesRaw> {
|
91
93
|
if (!this.#browser) {
|
92
|
-
// TODO Describe the error
|
93
94
|
throw new Error('Browser is not initialized');
|
94
95
|
}
|
95
96
|
|
@@ -98,7 +99,6 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
98
99
|
|
99
100
|
afterTest(test: ServerTest): Promise<void> {
|
100
101
|
if (!this.#browser) {
|
101
|
-
// TODO Describe the error
|
102
102
|
throw new Error('Browser is not initialized');
|
103
103
|
}
|
104
104
|
|
@@ -110,7 +110,6 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
110
110
|
ignoreElements?: string | string[] | null,
|
111
111
|
): Promise<Buffer> {
|
112
112
|
if (!this.#browser) {
|
113
|
-
// TODO Describe the error
|
114
113
|
throw new Error('Browser is not initialized');
|
115
114
|
}
|
116
115
|
|
@@ -119,7 +118,6 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
119
118
|
|
120
119
|
protected waitForComplete(callback: (isCompleted: boolean) => void): void {
|
121
120
|
if (!this.#browser) {
|
122
|
-
// TODO Describe the error
|
123
121
|
throw new Error('Browser is not initialized');
|
124
122
|
}
|
125
123
|
|
@@ -128,7 +126,6 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
128
126
|
|
129
127
|
protected async selectStory(id: string, waitForReady?: boolean): Promise<boolean> {
|
130
128
|
if (!this.#browser) {
|
131
|
-
// TODO Describe the error
|
132
129
|
throw new Error('Browser is not initialized');
|
133
130
|
}
|
134
131
|
|
@@ -137,7 +134,6 @@ export class SeleniumWebdriver extends CreeveyWebdriverBase {
|
|
137
134
|
|
138
135
|
protected async updateStoryArgs(story: StoryInput, updatedArgs: Args): Promise<void> {
|
139
136
|
if (!this.#browser) {
|
140
|
-
// TODO Describe the error
|
141
137
|
throw new Error('Browser is not initialized');
|
142
138
|
}
|
143
139
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import cluster from 'cluster';
|
2
|
+
import { subscribeOn } from './messages.js';
|
3
|
+
import { shutdownOnException, isShuttingDown } from './utils.js';
|
4
|
+
|
5
|
+
if (cluster.isWorker) {
|
6
|
+
subscribeOn('shutdown', () => {
|
7
|
+
isShuttingDown.current = true;
|
8
|
+
});
|
9
|
+
}
|
10
|
+
|
11
|
+
process.on('uncaughtException', shutdownOnException);
|
12
|
+
process.on('unhandledRejection', shutdownOnException);
|
13
|
+
// TODO SIGINT Stuck with selenium
|
14
|
+
process.on('SIGINT', () => {
|
15
|
+
if (isShuttingDown.current) {
|
16
|
+
process.exit(-1);
|
17
|
+
}
|
18
|
+
isShuttingDown.current = true;
|
19
|
+
});
|
package/src/server/stories.ts
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
import path from 'path';
|
2
|
-
import { mkdirSync, writeFileSync } from 'fs';
|
3
1
|
import { createHash } from 'crypto';
|
4
2
|
import _ from 'lodash';
|
5
3
|
import type {
|
@@ -12,7 +10,7 @@ import type {
|
|
12
10
|
CreeveyTestFunction,
|
13
11
|
CreeveyTestContext,
|
14
12
|
} from '../types.js';
|
15
|
-
import { isDefined
|
13
|
+
import { isDefined } from '../types.js';
|
16
14
|
import { shouldSkip } from './utils.js';
|
17
15
|
|
18
16
|
function storyTestFabric(delay?: number, testFn?: CreeveyTestFunction) {
|
@@ -129,12 +127,3 @@ export async function loadTestsFromStories(
|
|
129
127
|
|
130
128
|
return tests;
|
131
129
|
}
|
132
|
-
|
133
|
-
export function saveTestsJson(tests: Record<string, unknown>, dstPath: string = process.cwd()): void {
|
134
|
-
mkdirSync(dstPath, { recursive: true });
|
135
|
-
writeFileSync(
|
136
|
-
path.join(dstPath, 'tests.json'),
|
137
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
138
|
-
JSON.stringify(tests, (_, value) => (isFunction(value) ? value.toString() : value), 2),
|
139
|
-
);
|
140
|
-
}
|
package/src/server/telemetry.ts
CHANGED
@@ -128,7 +128,7 @@ export async function sendScreenshotsCount(
|
|
128
128
|
repoUrl: repoUrl ?? 'unknown',
|
129
129
|
creeveyVersion: creeveyVersion ?? 'unknown',
|
130
130
|
storybookVersion: storybookVersion ?? 'unknown',
|
131
|
-
options
|
131
|
+
options,
|
132
132
|
gridUrl,
|
133
133
|
screenDir: config.screenDir ? path.relative(gitRootPath ?? process.cwd(), config.screenDir) : undefined,
|
134
134
|
useDocker: config.useDocker,
|
@@ -181,8 +181,8 @@ export async function sendScreenshotsCount(
|
|
181
181
|
const testsMeta = { runId: uuid, tests };
|
182
182
|
|
183
183
|
const fullPathname = buildPathname('tests', testsMeta);
|
184
|
-
// NOTE: Keep request path shorter than
|
185
|
-
const chunksCount = Math.ceil(fullPathname.length /
|
184
|
+
// NOTE: Keep request path shorter than 24k symbols
|
185
|
+
const chunksCount = Math.ceil(fullPathname.length / 24_000);
|
186
186
|
let chunks: string[] = [];
|
187
187
|
if (chunksCount > 1) {
|
188
188
|
const testsString = JSON.stringify(tests);
|
@@ -1,8 +1,58 @@
|
|
1
1
|
import { pathToFileURL } from 'url';
|
2
|
-
import { toId, storyNameFromExport } from '@storybook/csf';
|
3
2
|
import { CreeveyStoryParams, CreeveyTestFunction } from '../../types.js';
|
4
3
|
import { loadThroughTSX } from '../utils.js';
|
5
4
|
|
5
|
+
// NOTE: Copy-pasted from @storybook/csf
|
6
|
+
function toStartCaseStr(str: string) {
|
7
|
+
return str
|
8
|
+
.replace(/_/g, ' ')
|
9
|
+
.replace(/-/g, ' ')
|
10
|
+
.replace(/\./g, ' ')
|
11
|
+
.replace(/([^\n])([A-Z])([a-z])/g, (_, $1, $2, $3) => `${$1} ${$2}${$3}`)
|
12
|
+
.replace(/([a-z])([A-Z])/g, (_, $1, $2) => `${$1} ${$2}`)
|
13
|
+
.replace(/([a-z])([0-9])/gi, (_, $1, $2) => `${$1} ${$2}`)
|
14
|
+
.replace(/([0-9])([a-z])/gi, (_, $1, $2) => `${$1} ${$2}`)
|
15
|
+
.replace(/(\s|^)(\w)/g, (_, $1, $2: string) => `${$1}${$2.toUpperCase()}`)
|
16
|
+
.replace(/ +/g, ' ')
|
17
|
+
.trim();
|
18
|
+
}
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Remove punctuation and illegal characters from a story ID.
|
22
|
+
*
|
23
|
+
* See https://gist.github.com/davidjrice/9d2af51100e41c6c4b4a
|
24
|
+
*/
|
25
|
+
const sanitize = (string: string) => {
|
26
|
+
return (
|
27
|
+
string
|
28
|
+
.toLowerCase()
|
29
|
+
// eslint-disable-next-line no-useless-escape
|
30
|
+
.replace(/[ ’–—―′¿'`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '-')
|
31
|
+
.replace(/-+/g, '-')
|
32
|
+
.replace(/^-+/, '')
|
33
|
+
.replace(/-+$/, '')
|
34
|
+
);
|
35
|
+
};
|
36
|
+
|
37
|
+
const sanitizeSafe = (string: string, part: string) => {
|
38
|
+
const sanitized = sanitize(string);
|
39
|
+
if (sanitized === '') {
|
40
|
+
throw new Error(`Invalid ${part} '${string}', must include alphanumeric characters`);
|
41
|
+
}
|
42
|
+
return sanitized;
|
43
|
+
};
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Generate a storybook ID from a component/kind and story name.
|
47
|
+
*/
|
48
|
+
const toId = (kind: string, name?: string) =>
|
49
|
+
`${sanitizeSafe(kind, 'kind')}${name ? `--${sanitizeSafe(name, 'name')}` : ''}`;
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Transform a CSF named export into a readable story name
|
53
|
+
*/
|
54
|
+
const storyNameFromExport = (key: string) => toStartCaseStr(key);
|
55
|
+
|
6
56
|
export type CreeveyParamsByStoryId = Record<string, CreeveyStoryParams>;
|
7
57
|
|
8
58
|
export default async function parse(files: string[]): Promise<CreeveyParamsByStoryId> {
|
@@ -55,8 +105,6 @@ export const story = (
|
|
55
105
|
|
56
106
|
export const test = (title: string, testFn: CreeveyTestFunction): void => {
|
57
107
|
const storyId = getStoryId(kindTitle, storyTitle);
|
58
|
-
|
59
|
-
result[storyId] = {};
|
60
|
-
}
|
108
|
+
result[storyId] ??= {};
|
61
109
|
result[storyId].tests = Object.assign({}, result[storyId].tests, { [title]: testFn });
|
62
110
|
};
|
package/src/server/utils.ts
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
import fs from 'fs';
|
2
|
-
import
|
2
|
+
import path from 'path';
|
3
|
+
import http from 'http';
|
4
|
+
import https from 'https';
|
5
|
+
import assert from 'assert';
|
3
6
|
import cluster from 'cluster';
|
4
|
-
import
|
7
|
+
import pidtree from 'pidtree';
|
5
8
|
import { fileURLToPath, pathToFileURL } from 'url';
|
6
9
|
import { register as esmRegister } from 'tsx/esm/api';
|
7
10
|
import { register as cjsRegister } from 'tsx/cjs/api';
|
8
11
|
import { SkipOptions, SkipOption, isDefined, TestData, noop, ServerTest, Worker } from '../types.js';
|
9
|
-
import { emitShutdownMessage, sendShutdownMessage } from './messages.js';
|
12
|
+
import { emitShutdownMessage, emitWorkerMessage, sendShutdownMessage } from './messages.js';
|
13
|
+
import { LOCALHOST_REGEXP } from './webdriver.js';
|
14
|
+
import { logger } from './logger.js';
|
10
15
|
|
11
16
|
const importMetaUrl = pathToFileURL(__filename).href;
|
12
17
|
|
@@ -14,6 +19,19 @@ export const isShuttingDown = { current: false };
|
|
14
19
|
|
15
20
|
export const configExt = ['.js', '.mjs', '.ts', '.cjs', '.mts', '.cts'];
|
16
21
|
|
22
|
+
const browserTypes = {
|
23
|
+
chromium: 'chromium',
|
24
|
+
'chromium-headless-shell': 'chromium',
|
25
|
+
chrome: 'chromium',
|
26
|
+
'chrome-beta': 'chromium',
|
27
|
+
msedge: 'chromium',
|
28
|
+
'msedge-beta': 'chromium',
|
29
|
+
'msedge-dev': 'chromium',
|
30
|
+
'bidi-chromium': 'chromium',
|
31
|
+
firefox: 'firefox',
|
32
|
+
webkit: 'webkit',
|
33
|
+
} as const;
|
34
|
+
|
17
35
|
export const skipOptionKeys = ['in', 'kinds', 'stories', 'tests', 'reason'];
|
18
36
|
|
19
37
|
function matchBy(pattern: string | string[] | RegExp | undefined, value: string): boolean {
|
@@ -72,6 +90,18 @@ export function shouldSkipByOption(
|
|
72
90
|
return skipByBrowser && skipByKind && skipByStory && skipByTest && reason;
|
73
91
|
}
|
74
92
|
|
93
|
+
export function shutdownOnException(reason: unknown): void {
|
94
|
+
if (isShuttingDown.current) return;
|
95
|
+
|
96
|
+
const error = reason instanceof Error ? (reason.stack ?? reason.message) : (reason as string);
|
97
|
+
|
98
|
+
logger().error(error);
|
99
|
+
|
100
|
+
process.exitCode = -1;
|
101
|
+
if (cluster.isWorker) emitWorkerMessage({ type: 'error', payload: { subtype: 'unknown', error } });
|
102
|
+
if (cluster.isPrimary) void shutdownWorkers();
|
103
|
+
}
|
104
|
+
|
75
105
|
export async function shutdownWorkers(): Promise<void> {
|
76
106
|
isShuttingDown.current = true;
|
77
107
|
await Promise.all(
|
@@ -82,13 +112,14 @@ export async function shutdownWorkers(): Promise<void> {
|
|
82
112
|
(worker) =>
|
83
113
|
new Promise<void>((resolve) => {
|
84
114
|
const timeout = setTimeout(() => {
|
85
|
-
worker.
|
86
|
-
},
|
115
|
+
if (worker.process.pid) void killTree(worker.process.pid);
|
116
|
+
}, 10_000);
|
87
117
|
worker.on('exit', () => {
|
88
118
|
clearTimeout(timeout);
|
89
119
|
resolve();
|
90
120
|
});
|
91
121
|
sendShutdownMessage(worker);
|
122
|
+
worker.disconnect();
|
92
123
|
}),
|
93
124
|
),
|
94
125
|
);
|
@@ -98,7 +129,7 @@ export async function shutdownWorkers(): Promise<void> {
|
|
98
129
|
export function gracefullyKill(worker: Worker): void {
|
99
130
|
worker.isShuttingDown = true;
|
100
131
|
const timeout = setTimeout(() => {
|
101
|
-
worker.
|
132
|
+
if (worker.process.pid) void killTree(worker.process.pid);
|
102
133
|
}, 10000);
|
103
134
|
worker.on('exit', () => {
|
104
135
|
clearTimeout(timeout);
|
@@ -106,9 +137,34 @@ export function gracefullyKill(worker: Worker): void {
|
|
106
137
|
sendShutdownMessage(worker);
|
107
138
|
}
|
108
139
|
|
140
|
+
export async function killTree(rootPid: number): Promise<void> {
|
141
|
+
const pids = await pidtree(rootPid, { root: true });
|
142
|
+
|
143
|
+
pids.forEach((pid) => {
|
144
|
+
try {
|
145
|
+
process.kill(pid, 'SIGKILL');
|
146
|
+
} catch {
|
147
|
+
/* noop */
|
148
|
+
}
|
149
|
+
});
|
150
|
+
}
|
151
|
+
|
152
|
+
export function shutdownWithError(): void {
|
153
|
+
process.exit(1);
|
154
|
+
}
|
155
|
+
|
156
|
+
export function resolvePlaywrightBrowserType(browserName: string): (typeof browserTypes)[keyof typeof browserTypes] {
|
157
|
+
assert(
|
158
|
+
browserName in browserTypes,
|
159
|
+
new Error(`Failed to match browser name "${browserName}" to playwright browserType`),
|
160
|
+
);
|
161
|
+
|
162
|
+
return browserTypes[browserName as keyof typeof browserTypes];
|
163
|
+
}
|
164
|
+
|
109
165
|
export async function getCreeveyCache(): Promise<string | undefined> {
|
110
166
|
const { default: findCacheDir } = await import('find-cache-dir');
|
111
|
-
return findCacheDir({ name: 'creevey', cwd: dirname(fileURLToPath(importMetaUrl)) });
|
167
|
+
return findCacheDir({ name: 'creevey', cwd: path.dirname(fileURLToPath(importMetaUrl)) });
|
112
168
|
}
|
113
169
|
|
114
170
|
export async function runSequence(seq: (() => unknown)[], predicate: () => boolean): Promise<boolean> {
|
@@ -141,11 +197,12 @@ export function testsToImages(tests: (TestData | undefined)[]): Set<string> {
|
|
141
197
|
|
142
198
|
// https://tuhrig.de/how-to-know-you-are-inside-a-docker-container/
|
143
199
|
export const isInsideDocker =
|
144
|
-
fs.existsSync('/proc/1/cgroup') && fs.readFileSync('/proc/1/cgroup', 'utf-8').includes('docker')
|
200
|
+
(fs.existsSync('/proc/1/cgroup') && fs.readFileSync('/proc/1/cgroup', 'utf-8').includes('docker')) ||
|
201
|
+
process.env.DOCKER === 'true';
|
145
202
|
|
146
203
|
export const downloadBinary = (downloadUrl: string, destination: string): Promise<void> =>
|
147
204
|
new Promise((resolve, reject) =>
|
148
|
-
get(downloadUrl, (response) => {
|
205
|
+
https.get(downloadUrl, (response) => {
|
149
206
|
if (response.statusCode == 302) {
|
150
207
|
const { location } = response.headers;
|
151
208
|
if (!location) {
|
@@ -187,7 +244,7 @@ export function readDirRecursive(dirPath: string): string[] {
|
|
187
244
|
|
188
245
|
export function tryToLoadTestsData(filename: string): Partial<Record<string, ServerTest>> | undefined {
|
189
246
|
try {
|
190
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
247
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, import-x/no-dynamic-require
|
191
248
|
return require(filename) as Partial<Record<string, ServerTest>>;
|
192
249
|
} catch {
|
193
250
|
/* noop */
|
@@ -198,19 +255,71 @@ const [nodeVersion] = process.versions.node.split('.').map(Number);
|
|
198
255
|
export async function loadThroughTSX<T>(
|
199
256
|
callback: (load: (modulePath: string) => Promise<T>) => Promise<T>,
|
200
257
|
): Promise<T> {
|
201
|
-
|
202
|
-
const
|
258
|
+
const unregisterESM = nodeVersion > 18 ? esmRegister() : noop;
|
259
|
+
const unregisterCJS = cjsRegister();
|
203
260
|
|
204
261
|
const result = await callback((modulePath) =>
|
205
262
|
nodeVersion > 18
|
206
263
|
? import(modulePath)
|
207
|
-
: // eslint-disable-next-line @typescript-eslint/no-require-imports
|
264
|
+
: // eslint-disable-next-line @typescript-eslint/no-require-imports, import-x/no-dynamic-require
|
208
265
|
Promise.resolve(require(modulePath) as T),
|
209
266
|
);
|
210
267
|
|
211
268
|
// NOTE: `unregister` type is `(() => Promise<void>) | (() => void)`
|
212
269
|
// eslint-disable-next-line @typescript-eslint/await-thenable, @typescript-eslint/no-confusing-void-expression
|
213
|
-
await
|
270
|
+
await unregisterCJS();
|
271
|
+
// eslint-disable-next-line @typescript-eslint/await-thenable, @typescript-eslint/no-confusing-void-expression
|
272
|
+
await unregisterESM();
|
214
273
|
|
215
274
|
return result;
|
216
275
|
}
|
276
|
+
|
277
|
+
export function waitOnUrl(waitUrl: string, timeout: number, delay: number) {
|
278
|
+
const urls = [waitUrl];
|
279
|
+
if (!LOCALHOST_REGEXP.test(waitUrl)) {
|
280
|
+
const parsedUrl = new URL(waitUrl);
|
281
|
+
parsedUrl.host = 'localhost';
|
282
|
+
urls.push(parsedUrl.toString());
|
283
|
+
}
|
284
|
+
const startTime = Date.now();
|
285
|
+
return Promise.race(
|
286
|
+
urls.map(
|
287
|
+
(url) =>
|
288
|
+
new Promise<void>((resolve, reject) => {
|
289
|
+
const interval = setInterval(() => {
|
290
|
+
http
|
291
|
+
.get(url, (response) => {
|
292
|
+
if (response.statusCode === 200) {
|
293
|
+
clearInterval(interval);
|
294
|
+
resolve();
|
295
|
+
}
|
296
|
+
})
|
297
|
+
.on('error', () => {
|
298
|
+
// Ignore HTTP errors
|
299
|
+
});
|
300
|
+
|
301
|
+
if (Date.now() - startTime > timeout) {
|
302
|
+
clearInterval(interval);
|
303
|
+
reject(new Error(`${url} didn't respond within ${timeout / 1000} seconds`));
|
304
|
+
}
|
305
|
+
}, delay);
|
306
|
+
}),
|
307
|
+
),
|
308
|
+
);
|
309
|
+
}
|
310
|
+
|
311
|
+
/**
|
312
|
+
* Copies static assets to the report directory
|
313
|
+
* @param reportDir Directory where the report will be generated
|
314
|
+
*/
|
315
|
+
export async function copyStatics(reportDir: string): Promise<void> {
|
316
|
+
const clientDir = path.join(path.dirname(fileURLToPath(importMetaUrl)), '../../dist/client/web');
|
317
|
+
const assets = (await fs.promises.readdir(path.join(clientDir, 'assets'), { withFileTypes: true }))
|
318
|
+
.filter((dirent) => dirent.isFile())
|
319
|
+
.map((dirent) => dirent.name);
|
320
|
+
await fs.promises.mkdir(path.join(reportDir, 'assets'), { recursive: true });
|
321
|
+
await fs.promises.copyFile(path.join(clientDir, 'index.html'), path.join(reportDir, 'index.html'));
|
322
|
+
for (const asset of assets) {
|
323
|
+
await fs.promises.copyFile(path.join(clientDir, 'assets', asset), path.join(reportDir, 'assets', asset));
|
324
|
+
}
|
325
|
+
}
|
package/src/server/webdriver.ts
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
import type { Container } from 'dockerode';
|
2
|
+
|
3
|
+
let workerContainer: Container | null = null;
|
4
|
+
|
5
|
+
export function setWorkerContainer(container: Container): void {
|
6
|
+
workerContainer = container;
|
7
|
+
}
|
8
|
+
|
9
|
+
export async function removeWorkerContainer(): Promise<void> {
|
10
|
+
if (workerContainer) {
|
11
|
+
await workerContainer.remove({ force: true });
|
12
|
+
workerContainer = null;
|
13
|
+
}
|
14
|
+
}
|