@wdio/visual-service 9.1.5 → 9.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +22 -0
- package/dist/service.js +1 -1
- package/dist/storybook/hooks.d.ts +5 -0
- package/dist/storybook/hooks.d.ts.map +1 -0
- package/dist/storybook/hooks.js +100 -0
- package/package.json +2 -2
- package/dist/storybook/launcher.d.ts.map +0 -1
- package/dist/storybook/launcher.js +0 -122
- /package/dist/{storybook/launcher.d.ts → launcher.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @wdio/visual-service
|
|
2
2
|
|
|
3
|
+
## 9.1.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0a19d78: Fix `clearRuntimeFolder` clearing the actual and diff folders after each spec/feature execution instead of once before all workers start. This caused only the last spec's visual data to be present in the output when running multiple specs.
|
|
8
|
+
|
|
9
|
+
# Committers: 1
|
|
10
|
+
|
|
11
|
+
- Wim Selles ([@wswebcreation](https://github.com/wswebcreation))
|
|
12
|
+
|
|
13
|
+
- ed0bea6: Fix `EISDIR` error when using `resolveSnapshotPath` with the visual service. The service now uses `dirname()` of the resolved path as the baseline folder, preventing it from creating a directory at a path that `expect-webdriverio`'s snapshot service expects to be a file. Fixes #984.
|
|
14
|
+
|
|
15
|
+
# Committers: 1
|
|
16
|
+
|
|
17
|
+
- Wim Selles ([@wswebcreation](https://github.com/wswebcreation))
|
|
18
|
+
|
|
19
|
+
- cbf1d22: Fix incomplete `wdio-ics:options` type augmentation on `WebdriverIO.Capabilities`. The global type declaration now uses the `WdioIcsOptions` interface directly, ensuring all supported properties (`logName`, `name`) are available to TypeScript users in both standalone and multiremote configurations. Fixes #732.
|
|
20
|
+
|
|
21
|
+
# Committers: 1
|
|
22
|
+
|
|
23
|
+
- Wim Selles ([@wswebcreation](https://github.com/wswebcreation))
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [0a19d78]
|
|
26
|
+
- Updated dependencies [ce74703]
|
|
27
|
+
- @wdio/image-comparison-core@1.1.4
|
|
28
|
+
|
|
3
29
|
## 9.1.5
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WicElement } from '@wdio/image-comparison-core';
|
|
2
2
|
import WdioImageComparisonService from './service.js';
|
|
3
|
-
import VisualLauncher from './
|
|
4
|
-
import type { Output, Result, VisualServiceOptions, WdioCheckFullPageMethodOptions, WdioSaveFullPageMethodOptions, WdioSaveElementMethodOptions, WdioSaveScreenMethodOptions, WdioCheckElementMethodOptions, WdioCheckScreenMethodOptions } from './types.js';
|
|
3
|
+
import VisualLauncher from './launcher.js';
|
|
4
|
+
import type { Output, Result, VisualServiceOptions, WdioIcsOptions, WdioCheckFullPageMethodOptions, WdioSaveFullPageMethodOptions, WdioSaveElementMethodOptions, WdioSaveScreenMethodOptions, WdioCheckElementMethodOptions, WdioCheckScreenMethodOptions } from './types.js';
|
|
5
5
|
import type { WaitForStorybookComponentToBeLoaded } from './storybook/Types.js';
|
|
6
6
|
declare global {
|
|
7
7
|
namespace WebdriverIO {
|
|
@@ -50,9 +50,7 @@ declare global {
|
|
|
50
50
|
interface Element {
|
|
51
51
|
}
|
|
52
52
|
interface Capabilities {
|
|
53
|
-
'wdio-ics:options'?:
|
|
54
|
-
logName?: string;
|
|
55
|
-
};
|
|
53
|
+
'wdio-ics:options'?: WdioIcsOptions;
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
56
|
namespace ExpectWebdriverIO {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,0BAA0B,MAAM,cAAc,CAAA;AACrD,OAAO,cAAc,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAIvD,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,SAAS;;gBAGrC,OAAO,EAAE,YAAY;IAK3B,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,sBAAsB;IAQvF,UAAU;CASnB"}
|
package/dist/launcher.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseClass } from '@wdio/image-comparison-core';
|
|
2
|
+
import { prepareStorybook, cleanupStorybook } from './storybook/hooks.js';
|
|
3
|
+
import generateVisualReport from './reporter.js';
|
|
4
|
+
export default class VisualLauncher extends BaseClass {
|
|
5
|
+
#options;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
super(options);
|
|
8
|
+
this.#options = options;
|
|
9
|
+
}
|
|
10
|
+
async onPrepare(config, capabilities) {
|
|
11
|
+
if (this.#options.clearRuntimeFolder) {
|
|
12
|
+
this._clearRuntimeFolders();
|
|
13
|
+
}
|
|
14
|
+
await prepareStorybook(config, capabilities, this.#options, this.folders);
|
|
15
|
+
}
|
|
16
|
+
async onComplete() {
|
|
17
|
+
cleanupStorybook();
|
|
18
|
+
if (this.#options.createJsonReportFiles) {
|
|
19
|
+
new generateVisualReport({ directoryPath: this.folders.actualFolder }).generate();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
package/dist/service.js
CHANGED
|
@@ -91,7 +91,7 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
91
91
|
* We also check `this.#config` because for standalone usage of the service, the config is not available
|
|
92
92
|
*/
|
|
93
93
|
if (this.#config && typeof this.#config.resolveSnapshotPath === 'function' && this.#currentFile && isDefaultBaselineFolder) {
|
|
94
|
-
return this.#config.resolveSnapshotPath(this.#currentFile, '.png');
|
|
94
|
+
return dirname(this.#config.resolveSnapshotPath(this.#currentFile, '.png'));
|
|
95
95
|
}
|
|
96
96
|
return baselineFolder;
|
|
97
97
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Capabilities } from '@wdio/types';
|
|
2
|
+
import type { ClassOptions, Folders } from '@wdio/image-comparison-core';
|
|
3
|
+
export declare function prepareStorybook(config: WebdriverIO.Config, capabilities: Capabilities.TestrunnerCapabilities, options: ClassOptions, folders: Folders): Promise<void>;
|
|
4
|
+
export declare function cleanupStorybook(): void;
|
|
5
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/storybook/hooks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAA6B,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAcnG,wBAAsB,gBAAgB,CAClC,MAAM,EAAE,WAAW,CAAC,MAAM,EAC1B,YAAY,EAAE,YAAY,CAAC,sBAAsB,EACjD,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAsFf;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAiBvC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { rmdirSync } from 'node:fs';
|
|
2
|
+
import logger from '@wdio/logger';
|
|
3
|
+
import { SevereServiceError } from 'webdriverio';
|
|
4
|
+
import { createStorybookCapabilities, createTestFiles, getArgvValue, isCucumberFramework, isStorybookMode, parseSkipStories, scanStorybook, } from './utils.js';
|
|
5
|
+
import { CLIP_SELECTOR, NUM_SHARDS, V6_CLIP_SELECTOR } from '../constants.js';
|
|
6
|
+
const log = logger('@wdio/visual-service');
|
|
7
|
+
export async function prepareStorybook(config, capabilities, options, folders) {
|
|
8
|
+
const isStorybook = isStorybookMode();
|
|
9
|
+
const framework = config.framework;
|
|
10
|
+
const isCucumber = isCucumberFramework(framework);
|
|
11
|
+
if (isCucumber && isStorybook) {
|
|
12
|
+
throw new SevereServiceError('\n\nRunning Storybook in combination with the cucumber framework adapter is not supported.\nOnly Jasmine and Mocha are supported.\n\n');
|
|
13
|
+
}
|
|
14
|
+
if (!isStorybook) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
log.info('Running `@wdio/visual-service` in Storybook mode.');
|
|
18
|
+
const { storiesJson, storybookUrl, tempDir } = await scanStorybook(config, options);
|
|
19
|
+
process.env.VISUAL_STORYBOOK_TEMP_SPEC_FOLDER = tempDir;
|
|
20
|
+
process.env.VISUAL_STORYBOOK_URL = storybookUrl;
|
|
21
|
+
if (typeof capabilities === 'object' && !Array.isArray(capabilities)) {
|
|
22
|
+
throw new SevereServiceError('\n\nRunning Storybook in combination with Multiremote is not supported.\nRemove your `capabilities` property from your config or assign an empty array to it like `capabilities: [],`.\n\n');
|
|
23
|
+
}
|
|
24
|
+
capabilities.length = 0;
|
|
25
|
+
log.info('Clearing the current capabilities.');
|
|
26
|
+
const compareOptions = {
|
|
27
|
+
blockOutSideBar: options.blockOutSideBar,
|
|
28
|
+
blockOutStatusBar: options.blockOutStatusBar,
|
|
29
|
+
blockOutToolBar: options.blockOutToolBar,
|
|
30
|
+
ignoreAlpha: options.ignoreAlpha,
|
|
31
|
+
ignoreAntialiasing: options.ignoreAntialiasing,
|
|
32
|
+
ignoreColors: options.ignoreColors,
|
|
33
|
+
ignoreLess: options.ignoreLess,
|
|
34
|
+
ignoreNothing: options.ignoreNothing,
|
|
35
|
+
rawMisMatchPercentage: options.rawMisMatchPercentage,
|
|
36
|
+
returnAllCompareData: options.returnAllCompareData,
|
|
37
|
+
saveAboveTolerance: options.saveAboveTolerance,
|
|
38
|
+
scaleImagesToSameSize: options.scaleImagesToSameSize,
|
|
39
|
+
};
|
|
40
|
+
// --version
|
|
41
|
+
const versionOption = options?.storybook?.version;
|
|
42
|
+
const versionArgv = getArgvValue('--version', value => Math.floor(parseFloat(value)));
|
|
43
|
+
const version = versionOption ?? versionArgv ?? 7;
|
|
44
|
+
// --numShards
|
|
45
|
+
const maxInstances = config?.maxInstances ?? 1;
|
|
46
|
+
const numShardsOption = options?.storybook?.numShards;
|
|
47
|
+
const numShardsArgv = getArgvValue('--numShards', value => parseInt(value, 10));
|
|
48
|
+
const numShards = Math.min(numShardsOption || numShardsArgv || NUM_SHARDS, maxInstances);
|
|
49
|
+
// --clip
|
|
50
|
+
const clipOption = options?.storybook?.clip;
|
|
51
|
+
const clipArgv = getArgvValue('--clip', value => value !== 'false');
|
|
52
|
+
const clip = clipOption ?? clipArgv ?? true;
|
|
53
|
+
// --clipSelector
|
|
54
|
+
const clipSelectorOption = options?.storybook?.clipSelector;
|
|
55
|
+
const clipSelectorArgv = getArgvValue('--clipSelector', value => value);
|
|
56
|
+
const clipSelector = (clipSelectorOption ?? clipSelectorArgv) ?? (version === 6 ? V6_CLIP_SELECTOR : CLIP_SELECTOR);
|
|
57
|
+
process.env.VISUAL_STORYBOOK_CLIP_SELECTOR = clipSelector;
|
|
58
|
+
// --skipStories
|
|
59
|
+
const skipStoriesOption = options?.storybook?.skipStories;
|
|
60
|
+
const skipStoriesArgv = getArgvValue('--skipStories', value => value);
|
|
61
|
+
const skipStories = skipStoriesOption ?? skipStoriesArgv ?? [];
|
|
62
|
+
const parsedSkipStories = parseSkipStories(skipStories);
|
|
63
|
+
// --additionalSearchParams
|
|
64
|
+
const additionalSearchParamsOption = options?.storybook?.additionalSearchParams;
|
|
65
|
+
const additionalSearchParamsArgv = getArgvValue('--additionalSearchParams', value => new URLSearchParams(value));
|
|
66
|
+
const additionalSearchParams = additionalSearchParamsOption ?? additionalSearchParamsArgv ?? new URLSearchParams();
|
|
67
|
+
const getStoriesBaselinePath = options?.storybook?.getStoriesBaselinePath;
|
|
68
|
+
createTestFiles({
|
|
69
|
+
additionalSearchParams,
|
|
70
|
+
clip,
|
|
71
|
+
clipSelector,
|
|
72
|
+
compareOptions,
|
|
73
|
+
directoryPath: tempDir,
|
|
74
|
+
folders,
|
|
75
|
+
framework,
|
|
76
|
+
getStoriesBaselinePath,
|
|
77
|
+
numShards,
|
|
78
|
+
skipStories: parsedSkipStories,
|
|
79
|
+
storiesJson,
|
|
80
|
+
storybookUrl,
|
|
81
|
+
});
|
|
82
|
+
createStorybookCapabilities(capabilities);
|
|
83
|
+
}
|
|
84
|
+
export function cleanupStorybook() {
|
|
85
|
+
const tempDir = process.env.VISUAL_STORYBOOK_TEMP_SPEC_FOLDER;
|
|
86
|
+
if (!tempDir) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
log.info(`Cleaning up temporary folder for storybook specs: ${tempDir}`);
|
|
90
|
+
try {
|
|
91
|
+
rmdirSync(tempDir, { recursive: true });
|
|
92
|
+
log.info(`Temporary folder for storybook specs has been removed: ${tempDir}`);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
log.error(`Failed to remove temporary folder for storybook specs: ${tempDir} due to: ${err.message}`);
|
|
96
|
+
}
|
|
97
|
+
delete process.env.VISUAL_STORYBOOK_TEMP_SPEC_FOLDER;
|
|
98
|
+
delete process.env.VISUAL_STORYBOOK_URL;
|
|
99
|
+
delete process.env.VISUAL_STORYBOOK_CLIP_SELECTOR;
|
|
100
|
+
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@wdio/visual-service",
|
|
3
3
|
"author": "Wim Selles - wswebcreation",
|
|
4
4
|
"description": "Image comparison / visual regression testing for WebdriverIO",
|
|
5
|
-
"version": "9.1.
|
|
5
|
+
"version": "9.1.6",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://webdriver.io/docs/visual-testing",
|
|
8
8
|
"repository": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@wdio/logger": "^9.18.0",
|
|
25
25
|
"@wdio/types": "^9.20.0",
|
|
26
26
|
"expect-webdriverio": "^5.6.1",
|
|
27
|
-
"@wdio/image-comparison-core": "1.1.
|
|
27
|
+
"@wdio/image-comparison-core": "1.1.4"
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
30
|
"build": "run-s clean build:*",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../../src/storybook/launcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAA8B,MAAM,6BAA6B,CAAA;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAevD,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,SAAS;;gBAGrC,OAAO,EAAE,YAAY;IAK3B,SAAS,CAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,sBAAsB;IA+FxF,UAAU;CAuBnB"}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { rmdirSync } from 'node:fs';
|
|
2
|
-
import logger from '@wdio/logger';
|
|
3
|
-
import { SevereServiceError } from 'webdriverio';
|
|
4
|
-
import { BaseClass } from '@wdio/image-comparison-core';
|
|
5
|
-
import { createStorybookCapabilities, createTestFiles, getArgvValue, isCucumberFramework, isStorybookMode, parseSkipStories, scanStorybook, } from './utils.js';
|
|
6
|
-
import { CLIP_SELECTOR, NUM_SHARDS, V6_CLIP_SELECTOR } from '../constants.js';
|
|
7
|
-
import generateVisualReport from '../reporter.js';
|
|
8
|
-
const log = logger('@wdio/visual-service');
|
|
9
|
-
export default class VisualLauncher extends BaseClass {
|
|
10
|
-
#options;
|
|
11
|
-
constructor(options) {
|
|
12
|
-
super(options);
|
|
13
|
-
this.#options = options;
|
|
14
|
-
}
|
|
15
|
-
async onPrepare(config, capabilities) {
|
|
16
|
-
const isStorybook = isStorybookMode();
|
|
17
|
-
const framework = config.framework;
|
|
18
|
-
const isCucumber = isCucumberFramework(framework);
|
|
19
|
-
if (isCucumber && isStorybook) {
|
|
20
|
-
throw new SevereServiceError('\n\nRunning Storybook in combination with the cucumber framework adapter is not supported.\nOnly Jasmine and Mocha are supported.\n\n');
|
|
21
|
-
}
|
|
22
|
-
else if (isStorybook) {
|
|
23
|
-
log.info('Running `@wdio/visual-service` in Storybook mode.');
|
|
24
|
-
const { storiesJson, storybookUrl, tempDir } = await scanStorybook(config, this.#options);
|
|
25
|
-
// Set an environment variable so it can be used in the onComplete hook
|
|
26
|
-
process.env.VISUAL_STORYBOOK_TEMP_SPEC_FOLDER = tempDir;
|
|
27
|
-
// Add the storybook URL to the environment variables
|
|
28
|
-
process.env.VISUAL_STORYBOOK_URL = storybookUrl;
|
|
29
|
-
// Check the capabilities
|
|
30
|
-
// Multiremote capabilities are not supported
|
|
31
|
-
if (typeof capabilities === 'object' && !Array.isArray(capabilities)) {
|
|
32
|
-
throw new SevereServiceError('\n\nRunning Storybook in combination with Multiremote is not supported.\nRemove your `capabilities` property from your config or assign an empty array to it like `capabilities: [],`.\n\n');
|
|
33
|
-
}
|
|
34
|
-
// Clear the capabilities
|
|
35
|
-
capabilities.length = 0;
|
|
36
|
-
log.info('Clearing the current capabilities.');
|
|
37
|
-
// Get compare options from config
|
|
38
|
-
const compareOptions = {
|
|
39
|
-
blockOutSideBar: this.#options.blockOutSideBar,
|
|
40
|
-
blockOutStatusBar: this.#options.blockOutStatusBar,
|
|
41
|
-
blockOutToolBar: this.#options.blockOutToolBar,
|
|
42
|
-
ignoreAlpha: this.#options.ignoreAlpha,
|
|
43
|
-
ignoreAntialiasing: this.#options.ignoreAntialiasing,
|
|
44
|
-
ignoreColors: this.#options.ignoreColors,
|
|
45
|
-
ignoreLess: this.#options.ignoreLess,
|
|
46
|
-
ignoreNothing: this.#options.ignoreNothing,
|
|
47
|
-
rawMisMatchPercentage: this.#options.rawMisMatchPercentage,
|
|
48
|
-
returnAllCompareData: this.#options.returnAllCompareData,
|
|
49
|
-
saveAboveTolerance: this.#options.saveAboveTolerance,
|
|
50
|
-
scaleImagesToSameSize: this.#options.scaleImagesToSameSize,
|
|
51
|
-
};
|
|
52
|
-
// Determine some run options
|
|
53
|
-
// --version
|
|
54
|
-
const versionOption = this.#options?.storybook?.version;
|
|
55
|
-
const versionArgv = getArgvValue('--version', value => Math.floor(parseFloat(value)));
|
|
56
|
-
const version = versionOption ?? versionArgv ?? 7;
|
|
57
|
-
// --numShards
|
|
58
|
-
const maxInstances = config?.maxInstances ?? 1;
|
|
59
|
-
const numShardsOption = this.#options?.storybook?.numShards;
|
|
60
|
-
const numShardsArgv = getArgvValue('--numShards', value => parseInt(value, 10));
|
|
61
|
-
const numShards = Math.min(numShardsOption || numShardsArgv || NUM_SHARDS, maxInstances);
|
|
62
|
-
// --clip
|
|
63
|
-
const clipOption = this.#options?.storybook?.clip;
|
|
64
|
-
const clipArgv = getArgvValue('--clip', value => value !== 'false');
|
|
65
|
-
const clip = clipOption ?? clipArgv ?? true;
|
|
66
|
-
// --clipSelector
|
|
67
|
-
const clipSelectorOption = this.#options?.storybook?.clipSelector;
|
|
68
|
-
const clipSelectorArgv = getArgvValue('--clipSelector', value => value);
|
|
69
|
-
// V6 has '#root' as the root element, V7 has '#storybook-root'
|
|
70
|
-
const clipSelector = (clipSelectorOption ?? clipSelectorArgv) ?? (version === 6 ? V6_CLIP_SELECTOR : CLIP_SELECTOR);
|
|
71
|
-
// Add the clip selector to the environment variables
|
|
72
|
-
process.env.VISUAL_STORYBOOK_CLIP_SELECTOR = clipSelector;
|
|
73
|
-
// --skipStories
|
|
74
|
-
const skipStoriesOption = this.#options?.storybook?.skipStories;
|
|
75
|
-
const skipStoriesArgv = getArgvValue('--skipStories', value => value);
|
|
76
|
-
const skipStories = skipStoriesOption ?? skipStoriesArgv ?? [];
|
|
77
|
-
const parsedSkipStories = parseSkipStories(skipStories);
|
|
78
|
-
// --additionalSearchParams
|
|
79
|
-
const additionalSearchParamsOption = this.#options?.storybook?.additionalSearchParams;
|
|
80
|
-
const additionalSearchParamsArgv = getArgvValue('--additionalSearchParams', value => new URLSearchParams(value));
|
|
81
|
-
const additionalSearchParams = additionalSearchParamsOption ?? additionalSearchParamsArgv ?? new URLSearchParams();
|
|
82
|
-
const getStoriesBaselinePath = this.#options?.storybook?.getStoriesBaselinePath;
|
|
83
|
-
// Create the test files
|
|
84
|
-
createTestFiles({
|
|
85
|
-
additionalSearchParams,
|
|
86
|
-
clip,
|
|
87
|
-
clipSelector,
|
|
88
|
-
compareOptions,
|
|
89
|
-
directoryPath: tempDir,
|
|
90
|
-
folders: this.folders,
|
|
91
|
-
framework,
|
|
92
|
-
getStoriesBaselinePath,
|
|
93
|
-
numShards,
|
|
94
|
-
skipStories: parsedSkipStories,
|
|
95
|
-
storiesJson,
|
|
96
|
-
storybookUrl,
|
|
97
|
-
});
|
|
98
|
-
// Create the capabilities
|
|
99
|
-
createStorybookCapabilities(capabilities);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
async onComplete() {
|
|
103
|
-
const tempDir = process.env.VISUAL_STORYBOOK_TEMP_SPEC_FOLDER;
|
|
104
|
-
if (tempDir) {
|
|
105
|
-
log.info(`Cleaning up temporary folder for storybook specs: ${tempDir}`);
|
|
106
|
-
try {
|
|
107
|
-
rmdirSync(tempDir, { recursive: true });
|
|
108
|
-
log.info(`Temporary folder for storybook specs has been removed: ${tempDir}`);
|
|
109
|
-
}
|
|
110
|
-
catch (err) {
|
|
111
|
-
log.error(`Failed to remove temporary folder for storybook specs: ${tempDir} due to: ${err.message}`);
|
|
112
|
-
}
|
|
113
|
-
// Remove the environment variables
|
|
114
|
-
delete process.env.VISUAL_STORYBOOK_TEMP_SPEC_FOLDER;
|
|
115
|
-
delete process.env.VISUAL_STORYBOOK_URL;
|
|
116
|
-
delete process.env.VISUAL_STORYBOOK_CLIP_SELECTOR;
|
|
117
|
-
}
|
|
118
|
-
if (this.#options.createJsonReportFiles) {
|
|
119
|
-
new generateVisualReport({ directoryPath: this.folders.actualFolder }).generate();
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
File without changes
|