creevey 0.10.0-beta.4 → 0.10.0-beta.40
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/README.md +19 -41
- 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/withCreevey.d.ts +2 -1
- package/dist/client/addon/withCreevey.js +11 -1
- package/dist/client/addon/withCreevey.js.map +1 -1
- package/dist/client/shared/components/ImagesView/BlendView.d.ts +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.d.ts +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.d.ts +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.d.ts +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.d.ts +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 +20 -8
- package/dist/client/shared/components/PageHeader/PageHeader.js.map +1 -1
- package/dist/client/shared/components/ResultsPage.d.ts +1 -1
- package/dist/client/shared/components/ResultsPage.js +43 -13
- 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 +1 -3
- package/dist/client/shared/helpers.js +4 -19
- package/dist/client/shared/helpers.js.map +1 -1
- package/dist/client/web/CreeveyApp.js +42 -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.d.ts +2 -2
- 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/CreeveyView/SideBar/TestStatusIcon.d.ts +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestsStatus.d.ts +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-B0Xv0lOY.js +802 -0
- 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 +16 -9
- package/dist/creevey.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/server/config.d.ts +1 -1
- package/dist/server/config.js +27 -5
- 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 +56 -32
- package/dist/server/docker.js.map +1 -1
- package/dist/server/index.js +64 -11
- 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 +4 -3
- package/dist/server/master/pool.js +13 -66
- package/dist/server/master/pool.js.map +1 -1
- package/dist/server/master/queue.d.ts +13 -0
- package/dist/server/master/queue.js +71 -0
- package/dist/server/master/queue.js.map +1 -0
- package/dist/server/master/runner.d.ts +3 -0
- package/dist/server/master/runner.js +76 -10
- 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 +13 -11
- package/dist/server/master/start.js.map +1 -1
- package/dist/server/playwright/docker-file.d.ts +1 -1
- package/dist/server/playwright/docker-file.js +15 -6
- 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 +6 -6
- package/dist/server/playwright/internal.js +143 -91
- package/dist/server/playwright/internal.js.map +1 -1
- package/dist/server/playwright/webdriver.d.ts +1 -1
- package/dist/server/playwright/webdriver.js +5 -8
- 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.d.ts +4 -19
- package/dist/server/reporter.js +30 -21
- package/dist/server/reporter.js.map +1 -1
- package/dist/server/selenium/internal.d.ts +3 -4
- package/dist/server/selenium/internal.js +127 -108
- package/dist/server/selenium/internal.js.map +1 -1
- package/dist/server/selenium/selenoid.js +8 -6
- package/dist/server/selenium/selenoid.js.map +1 -1
- package/dist/server/selenium/webdriver.d.ts +1 -1
- package/dist/server/selenium/webdriver.js +5 -9
- package/dist/server/selenium/webdriver.js.map +1 -1
- package/dist/server/telemetry.js +2 -2
- package/dist/server/testsFiles/parser.js +45 -5
- package/dist/server/testsFiles/parser.js.map +1 -1
- package/dist/server/utils.d.ts +19 -1
- package/dist/server/utils.js +87 -8
- package/dist/server/utils.js.map +1 -1
- package/dist/server/webdriver.d.ts +5 -4
- package/dist/server/webdriver.js +23 -10
- 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/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 +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 +45 -73
- package/dist/server/worker/start.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/types.d.ts +40 -8
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/docs/cli.md +12 -0
- package/docs/config.md +179 -165
- package/docs/storybook.md +60 -0
- package/docs/tests.md +50 -45
- package/package.json +64 -63
- package/src/client/addon/components/Panel.tsx +2 -2
- package/src/client/addon/withCreevey.ts +10 -2
- 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/PageHeader/PageHeader.tsx +4 -2
- package/src/client/shared/components/ResultsPage.tsx +31 -8
- package/src/client/shared/creeveyClientApi.ts +9 -1
- package/src/client/shared/helpers.ts +4 -24
- package/src/client/web/CreeveyApp.tsx +27 -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 +16 -10
- package/src/server/config.ts +28 -6
- package/src/server/connection.ts +26 -0
- package/src/server/docker.ts +63 -34
- package/src/server/index.ts +72 -14
- package/src/server/logger.ts +6 -2
- package/src/server/master/api.ts +1 -1
- package/src/server/master/pool.ts +23 -59
- package/src/server/master/queue.ts +77 -0
- package/src/server/master/runner.ts +94 -10
- package/src/server/master/server.ts +1 -1
- package/src/server/master/start.ts +16 -11
- package/src/server/playwright/docker-file.ts +18 -6
- package/src/server/playwright/docker.ts +16 -3
- package/src/server/playwright/index-source.mjs +16 -0
- package/src/server/playwright/internal.ts +182 -111
- package/src/server/playwright/webdriver.ts +6 -9
- package/src/server/providers/browser.ts +6 -4
- package/src/server/providers/hybrid.ts +1 -1
- package/src/server/reporter.ts +37 -34
- package/src/server/selenium/internal.ts +131 -116
- package/src/server/selenium/selenoid.ts +8 -6
- package/src/server/selenium/webdriver.ts +6 -10
- package/src/server/telemetry.ts +2 -2
- package/src/server/testsFiles/parser.ts +52 -4
- package/src/server/utils.ts +97 -9
- package/src/server/webdriver.ts +24 -16
- package/src/server/worker/chai-image.ts +4 -4
- package/src/server/worker/context.ts +14 -0
- package/src/server/worker/match-image.ts +12 -8
- package/src/server/worker/start.ts +49 -86
- package/src/shared/index.ts +1 -1
- package/src/types.ts +44 -8
- package/types/global.d.ts +1 -0
- package/.yarnrc.yml +0 -1
- package/chromatic.config.json +0 -5
- package/dist/client/web/assets/index-DkmZfG9C.js +0 -591
@@ -1,26 +1,11 @@
|
|
1
|
-
import { Images } from '../types.js';
|
2
1
|
import EventEmitter from 'events';
|
3
|
-
interface ReporterOptions {
|
4
|
-
reportDir: string;
|
5
|
-
sessionId: string;
|
6
|
-
browserName: string;
|
7
|
-
willRetry: boolean;
|
8
|
-
images: Partial<Record<string, Partial<Images>>>;
|
9
|
-
}
|
10
2
|
export declare class CreeveyReporter {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
};
|
15
|
-
});
|
3
|
+
private logger;
|
4
|
+
constructor(runner: EventEmitter);
|
5
|
+
private getLogger;
|
16
6
|
private getErrors;
|
17
7
|
}
|
18
8
|
export declare class TeamcityReporter {
|
19
|
-
constructor(runner: EventEmitter
|
20
|
-
reporterOptions: {
|
21
|
-
creevey: ReporterOptions;
|
22
|
-
};
|
23
|
-
});
|
9
|
+
constructor(runner: EventEmitter);
|
24
10
|
private escape;
|
25
11
|
}
|
26
|
-
export {};
|
package/dist/server/reporter.js
CHANGED
@@ -14,25 +14,31 @@ const testLevels = {
|
|
14
14
|
ERROR: chalk_1.default.red('FAIL'),
|
15
15
|
};
|
16
16
|
class CreeveyReporter {
|
17
|
+
logger = null;
|
17
18
|
// TODO Output in better way, like vitest, maybe
|
18
|
-
constructor(runner
|
19
|
-
const { sessionId, browserName } = options.reporterOptions.creevey;
|
20
|
-
const testLogger = loglevel_1.default.getLogger(browserName);
|
21
|
-
loglevel_plugin_prefix_1.default.apply(testLogger, {
|
22
|
-
format(level) {
|
23
|
-
return `${testLevels[level]} => (${browserName}:${chalk_1.default.gray(sessionId)})`;
|
24
|
-
},
|
25
|
-
});
|
19
|
+
constructor(runner) {
|
26
20
|
runner.on(types_js_1.TEST_EVENTS.TEST_BEGIN, (test) => {
|
27
|
-
|
21
|
+
this.getLogger(test.creevey).warn(chalk_1.default.cyan(test.fullTitle()));
|
28
22
|
});
|
29
23
|
runner.on(types_js_1.TEST_EVENTS.TEST_PASS, (test) => {
|
30
|
-
|
24
|
+
this.getLogger(test.creevey).info(chalk_1.default.cyan(test.fullTitle()), chalk_1.default.gray(`(${test.duration} ms)`));
|
31
25
|
});
|
32
26
|
runner.on(types_js_1.TEST_EVENTS.TEST_FAIL, (test, error) => {
|
33
|
-
|
27
|
+
this.getLogger(test.creevey).error(chalk_1.default.cyan(test.fullTitle()), chalk_1.default.gray(`(${test.duration} ms)`), '\n ', this.getErrors(error, (error, imageName) => `${chalk_1.default.bold(imageName ?? test.creevey.browserName)}:${error}`, (error) => error.stack ?? error.message).join('\n '));
|
34
28
|
});
|
35
29
|
}
|
30
|
+
getLogger(options) {
|
31
|
+
if (this.logger)
|
32
|
+
return this.logger;
|
33
|
+
const { sessionId, browserName } = options;
|
34
|
+
const testLogger = loglevel_1.default.getLogger(sessionId);
|
35
|
+
this.logger = loglevel_plugin_prefix_1.default.apply(testLogger, {
|
36
|
+
format(level) {
|
37
|
+
return `[${browserName}:${chalk_1.default.gray(process.pid)}] ${testLevels[level]} => ${chalk_1.default.gray(sessionId)}`;
|
38
|
+
},
|
39
|
+
});
|
40
|
+
return this.logger;
|
41
|
+
}
|
36
42
|
getErrors(error, imageErrorToString, errorToString) {
|
37
43
|
const errors = [];
|
38
44
|
if (!(error instanceof Error)) {
|
@@ -55,18 +61,21 @@ class CreeveyReporter {
|
|
55
61
|
}
|
56
62
|
exports.CreeveyReporter = CreeveyReporter;
|
57
63
|
class TeamcityReporter {
|
58
|
-
constructor(runner
|
59
|
-
const browserName = this.escape(options.reporterOptions.creevey.browserName);
|
60
|
-
const reporterOptions = options.reporterOptions.creevey;
|
64
|
+
constructor(runner) {
|
61
65
|
runner.on(types_js_1.TEST_EVENTS.TEST_BEGIN, (test) => {
|
62
|
-
console.log(`##teamcity[testStarted name='${this.escape(test.
|
66
|
+
console.log(`##teamcity[testStarted name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
67
|
+
});
|
68
|
+
runner.on(types_js_1.TEST_EVENTS.TEST_PASS, (test) => {
|
69
|
+
console.log(`##teamcity[testFinished name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
63
70
|
});
|
64
71
|
runner.on(types_js_1.TEST_EVENTS.TEST_FAIL, (test, error) => {
|
65
|
-
|
72
|
+
const browserName = this.escape(test.creevey.browserName);
|
73
|
+
Object.entries(test.creevey.images).forEach(([name, image]) => {
|
66
74
|
if (!image)
|
67
75
|
return;
|
68
76
|
const filePath = test
|
69
77
|
.titlePath()
|
78
|
+
.slice(0, -1)
|
70
79
|
.concat(name == browserName ? [] : [browserName])
|
71
80
|
.map(this.escape)
|
72
81
|
.join('/');
|
@@ -74,16 +83,16 @@ class TeamcityReporter {
|
|
74
83
|
Object.values(rest)
|
75
84
|
.filter(types_js_1.isDefined)
|
76
85
|
.forEach((fileName) => {
|
77
|
-
console.log(`##teamcity[publishArtifacts '${
|
78
|
-
console.log(`##teamcity[testMetadata testName='${this.escape(test.
|
86
|
+
console.log(`##teamcity[publishArtifacts '${test.creevey.reportDir}/${filePath}/${fileName} => report/${filePath}']`);
|
87
|
+
console.log(`##teamcity[testMetadata testName='${this.escape(test.fullTitle())}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`);
|
79
88
|
});
|
80
89
|
});
|
81
90
|
// Output failed test as passed due TC don't support retry mechanic
|
82
91
|
// 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
|
83
|
-
if (
|
84
|
-
console.log(`##teamcity[testFinished name='${this.escape(test.
|
92
|
+
if (test.creevey.willRetry)
|
93
|
+
console.log(`##teamcity[testFinished name='${this.escape(test.fullTitle())}' flowId='${process.pid}']`);
|
85
94
|
else
|
86
|
-
console.log(`##teamcity[testFailed name='${this.escape(test.
|
95
|
+
console.log(`##teamcity[testFailed name='${this.escape(test.fullTitle())}' message='${this.escape(error.message)}' details='${this.escape(error.stack ?? '')}' flowId='${process.pid}']`);
|
87
96
|
});
|
88
97
|
}
|
89
98
|
escape = (str) => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/server/reporter.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,wDAA8B;AAC9B,oFAA4C;AAC5C,0CAAqF;
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/server/reporter.ts"],"names":[],"mappings":"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"}
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import { Args } from '@storybook/
|
2
|
-
import Logger from 'loglevel';
|
1
|
+
import type { Args } from '@storybook/types';
|
3
2
|
import { WebDriver } from 'selenium-webdriver';
|
4
|
-
import { Config, StoryInput, StoriesRaw, Options, ServerTest } from '../../types.js';
|
3
|
+
import { Config, StorybookGlobals, StoryInput, StoriesRaw, Options, ServerTest } from '../../types.js';
|
5
4
|
export declare class InternalBrowser {
|
6
5
|
#private;
|
7
|
-
constructor(browser: WebDriver, port: number,
|
6
|
+
constructor(browser: WebDriver, port: number, storybookGlobals?: StorybookGlobals);
|
8
7
|
get browser(): WebDriver;
|
9
8
|
closeBrowser(): Promise<void>;
|
10
9
|
takeScreenshot(captureElement?: string | null, ignoreElements?: string | string[] | null): Promise<Buffer>;
|
@@ -58,15 +58,19 @@ async function openUrlAndWaitForPageSource(browser, url, predicate) {
|
|
58
58
|
} while (predicate(source));
|
59
59
|
return source;
|
60
60
|
}
|
61
|
-
async function buildWebdriver(
|
62
|
-
const browserConfig = config.browsers[
|
63
|
-
const { /*customizeBuilder,*/ seleniumCapabilities } = browserConfig;
|
61
|
+
async function buildWebdriver(browser, gridUrl, config, options) {
|
62
|
+
const browserConfig = config.browsers[browser];
|
63
|
+
const { /*customizeBuilder,*/ seleniumCapabilities, browserName } = browserConfig;
|
64
64
|
const url = new URL(gridUrl);
|
65
65
|
url.username = url.username ? '********' : '';
|
66
66
|
url.password = url.password ? '********' : '';
|
67
|
-
logger_js_1.logger.debug(`
|
67
|
+
(0, logger_js_1.logger)().debug(`Connecting to Selenium ${chalk_1.default.magenta(url.toString())}`);
|
68
68
|
// TODO Define some capabilities explicitly and define typings
|
69
|
-
const capabilities = new selenium_webdriver_1.Capabilities({
|
69
|
+
const capabilities = new selenium_webdriver_1.Capabilities({
|
70
|
+
browserName,
|
71
|
+
...seleniumCapabilities,
|
72
|
+
pageLoadStrategy: capabilities_js_1.PageLoadStrategy.EAGER,
|
73
|
+
});
|
70
74
|
const prefs = new selenium_webdriver_1.logging.Preferences();
|
71
75
|
if (options.trace) {
|
72
76
|
for (const type of Object.values(selenium_webdriver_1.logging.Type)) {
|
@@ -76,47 +80,74 @@ async function buildWebdriver(browserName, gridUrl, config, options) {
|
|
76
80
|
// TODO Fetch selenium grid capabilities
|
77
81
|
// TODO Validate browsers, versions, and platform
|
78
82
|
// TODO Use `customizeBuilder`
|
79
|
-
let
|
83
|
+
let webdriver;
|
80
84
|
try {
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
85
|
+
const maxRetries = 5;
|
86
|
+
let retries = 0;
|
87
|
+
do {
|
88
|
+
webdriver = await Promise.race([
|
89
|
+
new Promise((resolve) => {
|
90
|
+
setTimeout(() => {
|
91
|
+
retries += 1;
|
92
|
+
resolve(null);
|
93
|
+
}, 120_000);
|
94
|
+
}),
|
95
|
+
(async () => {
|
96
|
+
if (retries > 0) {
|
97
|
+
(0, logger_js_1.logger)().debug(`Trying to initialize session to Selenium Grid: retried ${retries} of ${maxRetries}`);
|
98
|
+
}
|
99
|
+
const retry = retries;
|
100
|
+
// const ie = new IeOptions();
|
101
|
+
// const edge = new EdgeOptions();
|
102
|
+
// const chrome = new ChromeOptions();
|
103
|
+
// const safari = new SafariOptions();
|
104
|
+
// const firefox = new FirefoxOptions();
|
105
|
+
// edge.enableBidi();
|
106
|
+
// chrome.enableBidi();
|
107
|
+
// firefox.enableBidi();
|
108
|
+
const driver = await new selenium_webdriver_1.Builder()
|
109
|
+
// .setIeOptions(ie)
|
110
|
+
// .setEdgeOptions(edge)
|
111
|
+
// .setChromeOptions(chrome)
|
112
|
+
// .setSafariOptions(safari)
|
113
|
+
// .setFirefoxOptions(firefox)
|
114
|
+
.usingServer(gridUrl)
|
115
|
+
.withCapabilities(capabilities)
|
116
|
+
.setLoggingPrefs(prefs) // NOTE: Should go last
|
117
|
+
.build();
|
118
|
+
// const id = await driver.getWindowHandle();
|
119
|
+
// context = await BrowsingContext(driver, { browsingContextId: id });
|
120
|
+
if (retry != retries) {
|
121
|
+
void driver.quit();
|
122
|
+
return null;
|
123
|
+
}
|
124
|
+
return driver;
|
125
|
+
})(),
|
126
|
+
]);
|
127
|
+
if (webdriver)
|
128
|
+
break;
|
129
|
+
} while (retries < maxRetries);
|
130
|
+
if (!webdriver)
|
131
|
+
throw new Error('Failed to initialize session to Selenium Grid due to many retries');
|
101
132
|
}
|
102
133
|
catch (error) {
|
103
|
-
logger_js_1.logger.error(`
|
134
|
+
(0, logger_js_1.logger)().error(`Failed to start browser:`, error);
|
104
135
|
return null;
|
105
136
|
}
|
106
|
-
return
|
137
|
+
return webdriver;
|
107
138
|
}
|
108
139
|
class InternalBrowser {
|
109
140
|
#isShuttingDown = false;
|
110
141
|
#browser;
|
111
142
|
#serverHost = null;
|
112
143
|
#serverPort;
|
113
|
-
#
|
144
|
+
#storybookGlobals;
|
114
145
|
#unsubscribe = types_js_1.noop;
|
115
146
|
#keepAliveInterval = null;
|
116
|
-
constructor(browser, port,
|
147
|
+
constructor(browser, port, storybookGlobals) {
|
117
148
|
this.#browser = browser;
|
118
149
|
this.#serverPort = port;
|
119
|
-
this.#
|
150
|
+
this.#storybookGlobals = storybookGlobals;
|
120
151
|
this.#unsubscribe = (0, messages_js_1.subscribeOn)('shutdown', () => {
|
121
152
|
void this.closeBrowser();
|
122
153
|
});
|
@@ -141,25 +172,25 @@ class InternalBrowser {
|
|
141
172
|
async takeScreenshot(captureElement, ignoreElements) {
|
142
173
|
let screenshot;
|
143
174
|
const ignoreStyles = await this.insertIgnoreStyles(ignoreElements);
|
144
|
-
if (
|
175
|
+
if ((0, logger_js_1.logger)().getLevel() <= loglevel_1.default.levels.DEBUG) {
|
145
176
|
const { innerWidth, innerHeight } = await this.#browser.executeScript(function () {
|
146
177
|
return {
|
147
178
|
innerWidth: window.innerWidth,
|
148
179
|
innerHeight: window.innerHeight,
|
149
180
|
};
|
150
181
|
});
|
151
|
-
|
182
|
+
(0, logger_js_1.logger)().debug(`Viewport size is: ${innerWidth}x${innerHeight}`);
|
152
183
|
}
|
153
184
|
try {
|
154
185
|
if (!captureElement) {
|
155
|
-
|
186
|
+
(0, logger_js_1.logger)().debug('Capturing viewport screenshot');
|
156
187
|
screenshot = await this.#browser.takeScreenshot();
|
157
|
-
|
188
|
+
(0, logger_js_1.logger)().debug('Viewport screenshot is captured');
|
158
189
|
}
|
159
190
|
else {
|
160
|
-
|
191
|
+
(0, logger_js_1.logger)().debug(`Checking is element ${chalk_1.default.cyan(captureElement)} fit into viewport`);
|
161
192
|
const rects = await this.#browser.executeScript(function (selector) {
|
162
|
-
window.scrollTo(0, 0);
|
193
|
+
window.scrollTo(0, 0);
|
163
194
|
// eslint-disable-next-line no-var
|
164
195
|
var element = document.querySelector(selector);
|
165
196
|
if (!element)
|
@@ -175,9 +206,7 @@ class InternalBrowser {
|
|
175
206
|
},
|
176
207
|
// NOTE page_Offset is used only for IE9-11
|
177
208
|
windowRect: {
|
178
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
179
209
|
top: Math.round(window.scrollY || window.pageYOffset),
|
180
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
181
210
|
left: Math.round(window.scrollX || window.pageXOffset),
|
182
211
|
width: window.innerWidth,
|
183
212
|
height: window.innerHeight,
|
@@ -190,22 +219,20 @@ class InternalBrowser {
|
|
190
219
|
const isFitIntoViewport = elementRect.width + elementRect.left <= windowRect.width &&
|
191
220
|
elementRect.height + elementRect.top <= windowRect.height;
|
192
221
|
if (isFitIntoViewport) {
|
193
|
-
|
222
|
+
(0, logger_js_1.logger)().debug(`Capturing ${chalk_1.default.cyan(captureElement)} with size: ${elementRect.width}x${elementRect.height}`);
|
194
223
|
}
|
195
224
|
else
|
196
|
-
|
225
|
+
(0, logger_js_1.logger)().debug(`Capturing composite screenshot image of ${chalk_1.default.cyan(captureElement)} with size: ${elementRect.width}x${elementRect.height}`);
|
197
226
|
// const element = await browser.findElement(By.css(captureElement));
|
198
227
|
// screenshot = isFitIntoViewport
|
199
228
|
// ? context
|
200
229
|
// ? await context.captureElementScreenshot(await element.getId())
|
201
230
|
// : await browser.findElement(By.css(captureElement)).takeScreenshot()
|
202
|
-
// :
|
203
|
-
// await takeCompositeScreenshot(browser, windowRect, elementRect);
|
231
|
+
// : await takeCompositeScreenshot(browser, windowRect, elementRect);
|
204
232
|
screenshot = isFitIntoViewport
|
205
233
|
? await this.#browser.findElement(selenium_webdriver_1.By.css(captureElement)).takeScreenshot()
|
206
|
-
:
|
207
|
-
|
208
|
-
this.#logger.debug(`${chalk_1.default.cyan(captureElement)} is captured`);
|
234
|
+
: await this.takeCompositeScreenshot(windowRect, elementRect);
|
235
|
+
(0, logger_js_1.logger)().debug(`${chalk_1.default.cyan(captureElement)} is captured`);
|
209
236
|
}
|
210
237
|
}
|
211
238
|
finally {
|
@@ -222,9 +249,10 @@ class InternalBrowser {
|
|
222
249
|
}
|
223
250
|
async selectStory(id, waitForReady = false) {
|
224
251
|
// NOTE: Global variables might be reset after hot reload. I think it's workaround, maybe we need better solution
|
252
|
+
await this.updateStorybookGlobals();
|
225
253
|
await this.updateBrowserGlobalVariables();
|
226
254
|
await this.resetMousePosition();
|
227
|
-
|
255
|
+
(0, logger_js_1.logger)().debug(`Triggering 'SetCurrentStory' event with storyId ${chalk_1.default.magenta(id)}`);
|
228
256
|
const result = await this.#browser.executeAsyncScript(function (storyId, shouldWaitForReady, callback) {
|
229
257
|
if (typeof window.__CREEVEY_SELECT_STORY__ == 'undefined') {
|
230
258
|
callback([
|
@@ -257,14 +285,14 @@ class InternalBrowser {
|
|
257
285
|
return stories;
|
258
286
|
}
|
259
287
|
async afterTest(test) {
|
260
|
-
if (
|
288
|
+
if ((0, logger_js_1.logger)().getLevel() === loglevel_1.default.levels.TRACE) {
|
261
289
|
const output = [];
|
262
290
|
const types = await this.#browser.manage().logs().getAvailableLogTypes();
|
263
291
|
for (const type of types) {
|
264
292
|
const logs = await this.#browser.manage().logs().get(type);
|
265
293
|
output.push(logs.map((log) => JSON.stringify(log.toJSON(), null, 2)).join('\n'));
|
266
294
|
}
|
267
|
-
|
295
|
+
(0, logger_js_1.logger)().debug('----------', (0, utils_js_1.getTestPath)(test).join('/'), '----------\n', output.join('\n'), '\n----------------------------------------------------------------------------------------------------');
|
268
296
|
}
|
269
297
|
}
|
270
298
|
static async getBrowser(browserName, gridUrl, config, options) {
|
@@ -274,7 +302,7 @@ class InternalBrowser {
|
|
274
302
|
const browser = await buildWebdriver(browserName, gridUrl, config, options);
|
275
303
|
if (!browser)
|
276
304
|
return null;
|
277
|
-
const internalBrowser = new InternalBrowser(browser, options.port,
|
305
|
+
const internalBrowser = new InternalBrowser(browser, options.port, _storybookGlobals);
|
278
306
|
try {
|
279
307
|
if (utils_js_1.isShuttingDown.current)
|
280
308
|
return null;
|
@@ -283,22 +311,20 @@ class InternalBrowser {
|
|
283
311
|
gridUrl,
|
284
312
|
viewport,
|
285
313
|
storybookUrl: address,
|
286
|
-
storybookGlobals: _storybookGlobals,
|
287
|
-
resolveStorybookUrl: config.resolveStorybookUrl,
|
288
314
|
});
|
289
315
|
return done ? internalBrowser : null;
|
290
316
|
}
|
291
317
|
catch (originalError) {
|
292
318
|
void internalBrowser.closeBrowser();
|
293
|
-
const message = originalError instanceof Error ? originalError.message : originalError;
|
294
|
-
const error = new Error(`Can't load storybook root page
|
319
|
+
const message = originalError instanceof Error ? originalError.message : (originalError ?? 'Unknown error');
|
320
|
+
const error = new Error(`Can't load storybook root page: ${message}`);
|
295
321
|
if (originalError instanceof Error)
|
296
322
|
error.stack = originalError.stack;
|
297
|
-
logger_js_1.logger.error(error);
|
323
|
+
(0, logger_js_1.logger)().error(error);
|
298
324
|
return null;
|
299
325
|
}
|
300
326
|
}
|
301
|
-
async init({ browserName, gridUrl, viewport, storybookUrl,
|
327
|
+
async init({ browserName, gridUrl, viewport, storybookUrl, }) {
|
302
328
|
const sessionId = (await this.#browser.getSession()).getId();
|
303
329
|
let browserHost = '';
|
304
330
|
try {
|
@@ -309,19 +335,18 @@ class InternalBrowser {
|
|
309
335
|
catch {
|
310
336
|
/* noop */
|
311
337
|
}
|
312
|
-
|
313
|
-
loglevel_plugin_prefix_1.default.apply(this.#logger, {
|
338
|
+
loglevel_plugin_prefix_1.default.apply((0, logger_js_1.logger)(), {
|
314
339
|
format(level) {
|
315
340
|
const levelColor = logger_js_1.colors[level.toUpperCase()];
|
316
|
-
return `[${browserName}:${chalk_1.default.gray(
|
341
|
+
return `[${browserName}:${chalk_1.default.gray(process.pid)}] ${levelColor(level)} => ${chalk_1.default.gray(sessionId)}`;
|
317
342
|
},
|
318
343
|
});
|
319
|
-
|
344
|
+
(0, logger_js_1.logger)().debug(`Connected successful with ${chalk_1.default.green(browserHost)}`);
|
320
345
|
return await (0, utils_js_1.runSequence)([
|
321
|
-
() => this.#browser.manage().setTimeouts({ pageLoad:
|
322
|
-
() => this.openStorybookPage(storybookUrl
|
346
|
+
() => this.#browser.manage().setTimeouts({ pageLoad: 60000, script: 60000 }),
|
347
|
+
() => this.openStorybookPage(storybookUrl),
|
323
348
|
() => this.waitForStorybook(),
|
324
|
-
() => this.updateStorybookGlobals(
|
349
|
+
() => this.updateStorybookGlobals(),
|
325
350
|
() => this.resolveCreeveyHost(),
|
326
351
|
() => this.updateBrowserGlobalVariables(),
|
327
352
|
// NOTE: Selenium draws automation toolbar with some delay after webdriver initialization
|
@@ -333,33 +358,25 @@ class InternalBrowser {
|
|
333
358
|
},
|
334
359
|
], () => !this.#isShuttingDown);
|
335
360
|
}
|
336
|
-
async openStorybookPage(storybookUrl
|
361
|
+
async openStorybookPage(storybookUrl) {
|
337
362
|
if (!webdriver_js_1.LOCALHOST_REGEXP.test(storybookUrl)) {
|
338
363
|
return this.#browser.get((0, webdriver_js_1.appendIframePath)(storybookUrl));
|
339
364
|
}
|
340
365
|
try {
|
341
|
-
|
342
|
-
|
343
|
-
const resolvedUrl = await resolver();
|
344
|
-
this.#logger.debug(`Resolver storybook url ${resolvedUrl}`);
|
345
|
-
await this.#browser.get((0, webdriver_js_1.appendIframePath)(resolvedUrl));
|
346
|
-
}
|
347
|
-
else {
|
348
|
-
// NOTE: getUrlChecker already calls `browser.get` so we don't need another one
|
349
|
-
await (0, webdriver_js_1.resolveStorybookUrl)((0, webdriver_js_1.appendIframePath)(storybookUrl), (url) => this.checkUrl(url), this.#logger);
|
350
|
-
}
|
366
|
+
// NOTE: getUrlChecker already calls `browser.get` so we don't need another one
|
367
|
+
await (0, webdriver_js_1.resolveStorybookUrl)((0, webdriver_js_1.appendIframePath)(storybookUrl), (url) => this.checkUrl(url));
|
351
368
|
}
|
352
369
|
catch (error) {
|
353
|
-
|
370
|
+
(0, logger_js_1.logger)().error('Failed to resolve storybook URL', error instanceof Error ? error.message : '');
|
354
371
|
throw error;
|
355
372
|
}
|
356
373
|
}
|
357
374
|
async checkUrl(url) {
|
358
375
|
try {
|
359
376
|
// NOTE: Before trying a new url, reset the current one
|
360
|
-
|
377
|
+
(0, logger_js_1.logger)().debug(`Opening ${chalk_1.default.magenta('about:blank')} page`);
|
361
378
|
await openUrlAndWaitForPageSource(this.#browser, 'about:blank', (source) => !source.includes('<body></body>'));
|
362
|
-
|
379
|
+
(0, logger_js_1.logger)().debug(`Opening ${chalk_1.default.magenta(url)} and checking the page source`);
|
363
380
|
const source = await openUrlAndWaitForPageSource(this.#browser, url,
|
364
381
|
// NOTE: IE11 can return only `head` without body
|
365
382
|
(source) => source.length == 0 || !/<body([^>]*>).+<\/body>/s.test(source));
|
@@ -368,7 +385,7 @@ class InternalBrowser {
|
|
368
385
|
// because other add significant delay and some of them don't work in earlier chrome versions
|
369
386
|
// Browsers always load page successful even it's failed
|
370
387
|
// So we just check `root` element
|
371
|
-
|
388
|
+
(0, logger_js_1.logger)().debug(`Checking ${chalk_1.default.cyan(`#${webdriver_js_1.storybookRootID}`)} existence on ${chalk_1.default.magenta(url)}`);
|
372
389
|
return source.includes(`id="${webdriver_js_1.storybookRootID}"`);
|
373
390
|
}
|
374
391
|
catch {
|
@@ -376,7 +393,7 @@ class InternalBrowser {
|
|
376
393
|
}
|
377
394
|
}
|
378
395
|
async waitForStorybook() {
|
379
|
-
|
396
|
+
(0, logger_js_1.logger)().debug('Waiting for Storybook to initiate');
|
380
397
|
const isTimeout = await Promise.race([
|
381
398
|
new Promise((resolve) => {
|
382
399
|
setTimeout(() => {
|
@@ -386,37 +403,28 @@ class InternalBrowser {
|
|
386
403
|
(async () => {
|
387
404
|
let wait = true;
|
388
405
|
do {
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
if (window.__STORYBOOK_ADDONS_CHANNEL__.last(SET_GLOBALS) == undefined)
|
398
|
-
return true;
|
399
|
-
return false;
|
400
|
-
}, types_js_1.StorybookEvents.SET_GLOBALS);
|
401
|
-
}
|
402
|
-
catch (e) {
|
403
|
-
this.#logger.debug('An error has been caught during the script:', e);
|
404
|
-
}
|
406
|
+
// TODO Research a different way to ensure storybook is initiated
|
407
|
+
wait = await this.#browser.executeScript(function (SET_GLOBALS) {
|
408
|
+
if (typeof window.__STORYBOOK_ADDONS_CHANNEL__ == 'undefined')
|
409
|
+
return true;
|
410
|
+
if (window.__STORYBOOK_ADDONS_CHANNEL__.last(SET_GLOBALS) == undefined)
|
411
|
+
return true;
|
412
|
+
return false;
|
413
|
+
}, types_js_1.StorybookEvents.SET_GLOBALS);
|
405
414
|
} while (wait);
|
406
415
|
return false;
|
407
416
|
})(),
|
408
417
|
]);
|
409
|
-
// TODO Change the message to describe a reason why it might happen
|
410
418
|
if (isTimeout)
|
411
|
-
throw new Error('Failed to wait
|
419
|
+
throw new Error('Failed to wait Storybook init');
|
412
420
|
}
|
413
|
-
async updateStorybookGlobals(
|
414
|
-
if (!
|
421
|
+
async updateStorybookGlobals() {
|
422
|
+
if (!this.#storybookGlobals)
|
415
423
|
return;
|
416
|
-
|
424
|
+
(0, logger_js_1.logger)().debug('Applying storybook globals');
|
417
425
|
await this.#browser.executeScript(function (globals) {
|
418
426
|
window.__CREEVEY_UPDATE_GLOBALS__(globals);
|
419
|
-
},
|
427
|
+
}, this.#storybookGlobals);
|
420
428
|
}
|
421
429
|
async resolveCreeveyHost() {
|
422
430
|
const addresses = (0, webdriver_js_1.getAddresses)();
|
@@ -448,6 +456,7 @@ class InternalBrowser {
|
|
448
456
|
}
|
449
457
|
async updateBrowserGlobalVariables() {
|
450
458
|
await this.#browser.executeScript(function (workerId, creeveyHost, creeveyPort) {
|
459
|
+
window.__CREEVEY_ENV__ = true;
|
451
460
|
window.__CREEVEY_WORKER_ID__ = workerId;
|
452
461
|
window.__CREEVEY_SERVER_HOST__ = creeveyHost;
|
453
462
|
window.__CREEVEY_SERVER_PORT__ = creeveyPort;
|
@@ -463,7 +472,7 @@ class InternalBrowser {
|
|
463
472
|
innerHeight: window.innerHeight,
|
464
473
|
};
|
465
474
|
});
|
466
|
-
|
475
|
+
(0, logger_js_1.logger)().debug(`Resizing viewport from ${innerWidth}x${innerHeight} to ${viewport.width}x${viewport.height}`);
|
467
476
|
const dWidth = windowRect.width - innerWidth;
|
468
477
|
const dHeight = windowRect.height - innerHeight;
|
469
478
|
await this.#browser
|
@@ -475,7 +484,7 @@ class InternalBrowser {
|
|
475
484
|
});
|
476
485
|
}
|
477
486
|
async resetMousePosition() {
|
478
|
-
|
487
|
+
(0, logger_js_1.logger)().debug('Resetting mouse position to the top-left corner');
|
479
488
|
const browserName = (await this.#browser.getCapabilities()).getBrowserName();
|
480
489
|
const [browserVersion] = (await this.#browser.getCapabilities()).getBrowserVersion()?.split('.') ??
|
481
490
|
(await this.#browser.getCapabilities()).get('version')?.split('.') ??
|
@@ -501,8 +510,9 @@ class InternalBrowser {
|
|
501
510
|
})
|
502
511
|
.perform();
|
503
512
|
}
|
504
|
-
else if (browserName == 'firefox'
|
513
|
+
else if (browserName == 'firefox') {
|
505
514
|
// NOTE Firefox for some reason moving by 0 x 0 move cursor in bottom left corner :sad:
|
515
|
+
// NOTE In recent versions (eg 128.0) moving by 0 x 0 doesn't work at all
|
506
516
|
await this.#browser.actions().move({ origin: selenium_webdriver_1.Origin.VIEWPORT, x: 0, y: 1 }).perform();
|
507
517
|
}
|
508
518
|
else {
|
@@ -514,7 +524,7 @@ class InternalBrowser {
|
|
514
524
|
const ignoreSelectors = Array.prototype.concat(ignoreElements).filter(Boolean);
|
515
525
|
if (!ignoreSelectors.length)
|
516
526
|
return null;
|
517
|
-
|
527
|
+
(0, logger_js_1.logger)().debug('Hiding ignored elements before capturing');
|
518
528
|
return await this.#browser.executeScript(function (ignoreSelectors) {
|
519
529
|
return window.__CREEVEY_INSERT_IGNORE_STYLES__(ignoreSelectors);
|
520
530
|
}, ignoreSelectors);
|
@@ -575,7 +585,7 @@ class InternalBrowser {
|
|
575
585
|
}
|
576
586
|
async removeIgnoreStyles(ignoreStyles) {
|
577
587
|
if (ignoreStyles) {
|
578
|
-
|
588
|
+
(0, logger_js_1.logger)().debug('Revert hiding ignored elements');
|
579
589
|
await this.#browser.executeScript(function (ignoreStyles) {
|
580
590
|
window.__CREEVEY_REMOVE_IGNORE_STYLES__(ignoreStyles);
|
581
591
|
}, ignoreStyles);
|
@@ -606,8 +616,17 @@ class InternalBrowser {
|
|
606
616
|
keepAlive() {
|
607
617
|
this.#keepAliveInterval = setInterval(() => {
|
608
618
|
// NOTE Simple way to keep session alive
|
609
|
-
void this.#browser
|
610
|
-
|
619
|
+
void this.#browser
|
620
|
+
.getCurrentUrl()
|
621
|
+
.then((url) => {
|
622
|
+
(0, logger_js_1.logger)().debug('current url', chalk_1.default.magenta(url));
|
623
|
+
})
|
624
|
+
.catch((error) => {
|
625
|
+
(0, logger_js_1.logger)().error(error);
|
626
|
+
(0, messages_js_1.emitWorkerMessage)({
|
627
|
+
type: 'error',
|
628
|
+
payload: { subtype: 'browser', error: 'Failed to ping browser' },
|
629
|
+
});
|
611
630
|
});
|
612
631
|
}, 10 * 1000);
|
613
632
|
}
|