@wdio/visual-service 4.0.0 → 4.0.2

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 CHANGED
@@ -1,5 +1,30 @@
1
1
  # @wdio/visual-service
2
2
 
3
+ ## 4.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - f878cab: # 🚀 Feature
8
+
9
+ - Add device support for Storybook, it can be used like this
10
+
11
+ ```sh
12
+ npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --devices="iPhone 14 Pro Max","Pixel 3 XL"
13
+ ```
14
+
15
+ #### Committers: 1
16
+
17
+ - Wim Selles ([@wswebcreation](https://github.com/wswebcreation))
18
+
19
+ - Updated dependencies [f878cab]
20
+ - webdriver-image-comparison@5.0.1
21
+
22
+ ## 4.0.1
23
+
24
+ ### Patch Changes
25
+
26
+ - bb4ece7: Fix storybook filtering
27
+
3
28
  ## 4.0.0
4
29
 
5
30
  ### Major Changes
@@ -77,4 +77,13 @@ export type ScanStorybookReturnData = {
77
77
  storybookUrl: string;
78
78
  tempDir: string;
79
79
  };
80
+ export type EmulatedDeviceType = {
81
+ name: string;
82
+ screen: {
83
+ dpr: number;
84
+ width: number;
85
+ height: number;
86
+ };
87
+ userAgent: string;
88
+ };
80
89
  //# sourceMappingURL=Types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../src/storybook/Types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAA;AACtF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;CACL;AAED,MAAM,WAAW,QAAQ;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,WAAW,UAAU;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,MAAM,OAAO,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,qBAAqB,GAAG;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAC,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACxB,CAAA;AAED,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC/B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACxB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC/B,SAAS,EAAE,aAAa,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACxB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvE,MAAM,MAAM,uBAAuB,GAAG;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAA"}
1
+ {"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../src/storybook/Types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { EmulatedDeviceType } from './Types.js';
2
+ export declare const deviceDescriptors: EmulatedDeviceType[];
3
+ //# sourceMappingURL=deviceDescriptors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviceDescriptors.d.ts","sourceRoot":"","sources":["../../src/storybook/deviceDescriptors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAIpD,eAAO,MAAM,iBAAiB,EAAE,kBAAkB,EAyNjD,CAAA"}
@@ -0,0 +1,220 @@
1
+ // This is a reflection of what the Chromium Devtools provides for device emulation
2
+ // https://source.chromium.org/chromium/chromium/src/+/main:out/fuchsia-Debug/gen/third_party/devtools-frontend/src/front_end/models/emulation/emulation.js?q=%22iPhone%204%22&ss=chromium
3
+ export const deviceDescriptors = [
4
+ {
5
+ 'name': 'iPad Mini',
6
+ 'screen': {
7
+ 'dpr': 2,
8
+ 'width': 1024,
9
+ 'height': 768
10
+ },
11
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'
12
+ },
13
+ {
14
+ 'name': 'iPad',
15
+ 'screen': {
16
+ 'dpr': 2,
17
+ 'width': 1024,
18
+ 'height': 768
19
+ },
20
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1'
21
+ },
22
+ {
23
+ 'name': 'iPad Pro',
24
+ 'screen': {
25
+ 'dpr': 2,
26
+ 'width': 1366,
27
+ 'height': 1024
28
+ },
29
+ 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1'
30
+ },
31
+ {
32
+ 'name': 'iPhone SE',
33
+ 'screen': {
34
+ 'dpr': 2,
35
+ 'width': 320,
36
+ 'height': 568
37
+ },
38
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/17.4 Mobile/14E304 Safari/602.1'
39
+ },
40
+ {
41
+ 'name': 'iPhone X',
42
+ 'screen': {
43
+ 'dpr': 3,
44
+ 'width': 375,
45
+ 'height': 812
46
+ },
47
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.4 Mobile/15A372 Safari/604.1'
48
+ },
49
+ {
50
+ 'name': 'iPhone XR',
51
+ 'screen': {
52
+ 'dpr': 3,
53
+ 'width': 414,
54
+ 'height': 896
55
+ },
56
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1'
57
+ },
58
+ {
59
+ 'name': 'iPhone 13',
60
+ 'screen': {
61
+ 'dpr': 3,
62
+ 'width': 390,
63
+ 'height': 844
64
+ },
65
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1'
66
+ },
67
+ {
68
+ 'name': 'iPhone 14 Plus',
69
+ 'screen': {
70
+ 'dpr': 3,
71
+ 'width': 428,
72
+ 'height': 926
73
+ },
74
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1'
75
+ },
76
+ {
77
+ 'name': 'iPhone 14 Pro',
78
+ 'screen': {
79
+ 'dpr': 3,
80
+ 'width': 393,
81
+ 'height': 852
82
+ },
83
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1'
84
+ },
85
+ {
86
+ 'name': 'iPhone 14 Pro Max',
87
+ 'screen': {
88
+ 'dpr': 3,
89
+ 'width': 430,
90
+ 'height': 932
91
+ },
92
+ 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1'
93
+ },
94
+ {
95
+ 'name': 'Pixel 2',
96
+ 'screen': {
97
+ 'dpr': 2.625,
98
+ 'width': 411,
99
+ 'height': 731,
100
+ },
101
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36'
102
+ },
103
+ {
104
+ 'name': 'Pixel 2 XL',
105
+ 'screen': {
106
+ 'dpr': 3.5,
107
+ 'width': 411,
108
+ 'height': 823,
109
+ },
110
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36'
111
+ },
112
+ {
113
+ 'name': 'Pixel 3',
114
+ 'screen': {
115
+ 'dpr': 2.75,
116
+ 'width': 393,
117
+ 'height': 786,
118
+ },
119
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36'
120
+ },
121
+ {
122
+ 'name': 'Pixel 4',
123
+ 'screen': {
124
+ 'dpr': 3,
125
+ 'width': 353,
126
+ 'height': 745,
127
+ },
128
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36'
129
+ },
130
+ {
131
+ 'name': 'Pixel 3 XL',
132
+ 'screen': {
133
+ 'dpr': 2.75,
134
+ 'width': 393,
135
+ 'height': 786,
136
+ },
137
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 11; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.181 Mobile Safari/537.36'
138
+ },
139
+ {
140
+ 'name': 'Pixel 7',
141
+ 'screen': {
142
+ 'dpr': 2.625,
143
+ 'width': 412,
144
+ 'height': 915,
145
+ },
146
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36'
147
+ },
148
+ {
149
+ 'name': 'Samsung Galaxy A51/71',
150
+ 'screen': {
151
+ 'dpr': 2.625,
152
+ 'width': 412,
153
+ 'height': 914,
154
+ },
155
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36'
156
+ },
157
+ {
158
+ 'name': 'Samsung Galaxy S8+',
159
+ 'screen': {
160
+ 'dpr': 4,
161
+ 'width': 360,
162
+ 'height': 740,
163
+ },
164
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36'
165
+ },
166
+ {
167
+ 'name': 'Galaxy Z Fold 5',
168
+ 'screen': {
169
+ 'dpr': 2.625,
170
+ 'width': 344,
171
+ 'height': 882,
172
+ },
173
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36'
174
+ },
175
+ {
176
+ 'name': 'Galaxy S8',
177
+ 'screen': {
178
+ 'dpr': 3,
179
+ 'width': 360,
180
+ 'height': 740,
181
+ },
182
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36'
183
+ },
184
+ {
185
+ 'name': 'Galaxy S9+',
186
+ 'screen': {
187
+ 'dpr': 4.5,
188
+ 'width': 320,
189
+ 'height': 658,
190
+ },
191
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36'
192
+ },
193
+ {
194
+ 'name': 'Galaxy Tab S4',
195
+ 'screen': {
196
+ 'dpr': 2.25,
197
+ 'width': 712,
198
+ 'height': 1138,
199
+ },
200
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36',
201
+ },
202
+ {
203
+ 'name': 'Surface Pro 7',
204
+ 'screen': {
205
+ 'dpr': 2,
206
+ 'height': 912,
207
+ 'width': 1368,
208
+ },
209
+ 'userAgent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
210
+ },
211
+ {
212
+ 'name': 'Surface Duo',
213
+ 'screen': {
214
+ 'dpr': 2.5,
215
+ 'height': 540,
216
+ 'width': 720,
217
+ },
218
+ 'userAgent': 'Mozilla/5.0 (Linux; Android 11.0; Surface Duo) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36'
219
+ },
220
+ ];
@@ -1 +1 @@
1
- {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../../src/storybook/launcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AActD,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,SAAS;;gBAGrC,OAAO,EAAE,YAAY;IAK3B,SAAS,CAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,kBAAkB;IA0DpF,UAAU;CAenB"}
1
+ {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../../src/storybook/launcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AActD,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,SAAS;;gBAGrC,OAAO,EAAE,YAAY;IAK3B,SAAS,CAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,kBAAkB;IAoEpF,UAAU;CAenB"}
@@ -23,6 +23,14 @@ export default class VisualLauncher extends BaseClass {
23
23
  const { storiesJson, storybookUrl, tempDir } = await scanStorybook(config, log, this.#options);
24
24
  // Set an environment variable so it can be used in the onComplete hook
25
25
  process.env.VISUAL_STORYBOOK_TEMP_SPEC_FOLDER = tempDir;
26
+ // Check the capabilities
27
+ // Multiremote capabilities are not supported
28
+ if (typeof capabilities === 'object' && !Array.isArray(capabilities)) {
29
+ 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');
30
+ }
31
+ // Clear the capabilities
32
+ capabilities.length = 0;
33
+ log.info('Clearing the current capabilities.');
26
34
  // Determine some run options
27
35
  // --version
28
36
  const versionOption = this.#options?.storybook?.version;
@@ -1,7 +1,7 @@
1
1
  import type { Logger } from '@wdio/logger';
2
- import type { Capabilities, Options } from '@wdio/types';
2
+ import type { Options } from '@wdio/types';
3
3
  import type { ClassOptions } from 'webdriver-image-comparison';
4
- import type { CategoryComponent, CreateItContent, CreateTestContent, CreateTestFileOptions, ScanStorybookReturnData, Stories } from './Types.js';
4
+ import type { CategoryComponent, CreateItContent, CreateTestContent, CreateTestFileOptions, ScanStorybookReturnData, Stories, EmulatedDeviceType, CapabilityMap } from './Types.js';
5
5
  /**
6
6
  * Check if we run for Storybook
7
7
  */
@@ -59,10 +59,15 @@ export declare function createFileData(describeTitle: string, testContent: strin
59
59
  * Create the test files
60
60
  */
61
61
  export declare function createTestFiles({ clip, clipSelector, directoryPath, folders, framework, log, numShards, skipStories, storiesJson, storybookUrl }: CreateTestFileOptions, createTestCont?: typeof createTestContent, createFileD?: typeof createFileData, writeTestF?: typeof writeTestFile): void;
62
+ export declare function createChromeCapabilityWithEmulation({ screen: { width, height, dpr }, name, userAgent }: EmulatedDeviceType, isHeadless: boolean): WebdriverIO.Capabilities;
63
+ /**
64
+ * Throw an error message if the capabilities are not set up correctly
65
+ */
66
+ export declare function capabilitiesErrorMessage(browsers: string[], capabilityMap: CapabilityMap, devices: string[], deviceDescriptors: EmulatedDeviceType[], isMobileEmulation: boolean): void;
62
67
  /**
63
68
  * Create the storybook capabilities based on the specified browsers
64
69
  */
65
- export declare function createStorybookCapabilities(capabilities: Capabilities.RemoteCapabilities, log: Logger): void;
70
+ export declare function createStorybookCapabilities(capabilities: WebdriverIO.Capabilities[], log: Logger, createChromeCapabilityWithEmulationFunc?: typeof createChromeCapabilityWithEmulation, capabilitiesErrorMessageFunc?: typeof capabilitiesErrorMessage): void;
66
71
  /**
67
72
  * Scan the storybook instance
68
73
  */
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/storybook/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/storybook/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAK1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EACR,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EAErB,uBAAuB,EACvB,OAAO,EAGP,kBAAkB,EAClB,aAAa,EAChB,MAAM,YAAY,CAAA;AAGnB;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,iBAUxD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY/C;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAMzE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBlE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,GAAG,GAAG,CAcpF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,eAAe,UAmC/I;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QASpG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,iBAAiB,EAEjG,MAAM,oBAAa,GACpB,MAAM,CAIR;AAkDD;;GAEG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAOjF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC3B,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,qBAAqB,EAExI,cAAc,2BAAoB,EAClC,WAAW,wBAAiB,EAC5B,UAAU,uBAAgB,QA8B7B;AAED,wBAAgB,mCAAmC,CAC/C,EAAE,MAAM,EAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,kBAAkB,EACtE,UAAU,EAAE,OAAO,GACpB,WAAW,CAAC,YAAY,CAqB1B;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,MAAM,EAAE,EAClB,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,MAAM,EAAE,EACjB,iBAAiB,EAAE,kBAAkB,EAAE,EACvC,iBAAiB,EAAE,OAAO,QAiB7B;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACvC,YAAY,EAAE,WAAW,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,MAAM,EAErD,uCAAuC,6CAAsC,EAC7E,4BAA4B,kCAA2B,QAsF1D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAC/B,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,YAAY,EAErB,UAAU,sBAAe,EACzB,mBAAmB,iCAA0B,EAC7C,eAAe,qBAAc,EAC7B,kBAAkB,wBAAiB,GACpC,OAAO,CAAC,uBAAuB,CAAC,CAqBlC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAmB/F"}
@@ -2,6 +2,7 @@ import fetch from 'node-fetch';
2
2
  import { mkdirSync, writeFileSync } from 'node:fs';
3
3
  import { tmpdir } from 'node:os';
4
4
  import { join, resolve } from 'node:path';
5
+ import { deviceDescriptors } from './deviceDescriptors.js';
5
6
  /**
6
7
  * Check if we run for Storybook
7
8
  */
@@ -231,7 +232,8 @@ export function createTestFiles({ clip, clipSelector, directoryPath, folders, fr
231
232
  createTestCont = createTestContent, createFileD = createFileData, writeTestF = writeTestFile) {
232
233
  const storiesArray = Object.values(storiesJson)
233
234
  // By default only keep the stories, not the docs
234
- .filter((storyData) => storyData?.type === 'story' || !storyData.parameters?.docsOnly);
235
+ // storyData?.type === 'story' is V7+, storyData.parameters?.docsOnly is V6
236
+ .filter((storyData) => storyData.type === 'story' || (storyData.parameters && !storyData.parameters.docsOnly));
235
237
  const fileNamePrefix = 'visual-storybook';
236
238
  const createTestContentData = { clip, clipSelector, folders, framework, skipStories, stories: storiesArray, storybookUrl };
237
239
  if (numShards === 1) {
@@ -254,65 +256,128 @@ createTestCont = createTestContent, createFileD = createFileData, writeTestF = w
254
256
  }
255
257
  }
256
258
  }
259
+ export function createChromeCapabilityWithEmulation({ screen: { width, height, dpr }, name, userAgent }, isHeadless) {
260
+ return {
261
+ browserName: 'chrome',
262
+ 'goog:chromeOptions': {
263
+ args: [
264
+ 'disable-infobars',
265
+ ...(isHeadless ? ['--headless'] : []),
266
+ ],
267
+ mobileEmulation: {
268
+ deviceMetrics: {
269
+ width,
270
+ height,
271
+ pixelRatio: dpr,
272
+ },
273
+ userAgent,
274
+ },
275
+ },
276
+ 'wdio-ics:options': {
277
+ logName: `local-chrome-${name.replace(/\s+/g, '-')}`,
278
+ },
279
+ };
280
+ }
281
+ /**
282
+ * Throw an error message if the capabilities are not set up correctly
283
+ */
284
+ export function capabilitiesErrorMessage(browsers, capabilityMap, devices, deviceDescriptors, isMobileEmulation) {
285
+ let errorMessage = 'No capabilities were added. Please ensure that ';
286
+ const browserIssues = browsers.some((browser) => !(browser in capabilityMap));
287
+ const deviceIssues = isMobileEmulation && devices.some((deviceName) => !deviceDescriptors.some(device => device.name === deviceName));
288
+ if (browserIssues && deviceIssues) {
289
+ errorMessage += `the browsers '${browsers.join(',')}' and devices '${devices.join(',')}' are supported.`;
290
+ }
291
+ else if (browserIssues) {
292
+ errorMessage += `the browsers '${browsers.join(',')}' are supported.`;
293
+ }
294
+ else if (deviceIssues) {
295
+ errorMessage += `the devices '${devices.join(',')}' are supported.`;
296
+ }
297
+ else {
298
+ errorMessage += 'the specified configuration is correct.';
299
+ }
300
+ throw new Error(errorMessage);
301
+ }
257
302
  /**
258
303
  * Create the storybook capabilities based on the specified browsers
259
304
  */
260
- export function createStorybookCapabilities(capabilities, log) {
305
+ export function createStorybookCapabilities(capabilities, log,
306
+ // For testing purposes only
307
+ createChromeCapabilityWithEmulationFunc = createChromeCapabilityWithEmulation, capabilitiesErrorMessageFunc = capabilitiesErrorMessage) {
308
+ if (!Array.isArray(capabilities)) {
309
+ log.error('The capabilities are not an array');
310
+ return;
311
+ }
261
312
  const isHeadless = getArgvValue('--headless', value => value !== 'false') ?? true;
262
313
  const browsers = getArgvValue('--browsers', (value) => value.split(',')) ?? ['chrome'];
263
- if (Array.isArray(capabilities)) {
264
- const chromeCapability = {
265
- browserName: 'chrome',
266
- 'goog:chromeOptions': {
267
- args: [
268
- 'disable-infobars',
269
- ...(isHeadless ? ['--headless'] : []),
270
- ],
271
- },
272
- 'wdio-ics:options': {
273
- logName: 'local-chrome',
274
- },
275
- };
276
- const firefoxCapability = {
277
- browserName: 'firefox',
278
- 'moz:firefoxOptions': {
279
- args: [...(isHeadless ? ['-headless'] : []),]
280
- },
281
- 'wdio-ics:options': {
282
- logName: 'local-firefox',
283
- },
284
- };
285
- const safariCapability = {
286
- browserName: 'safari',
287
- 'wdio-ics:options': {
288
- logName: 'local-safari',
289
- },
290
- };
291
- const edgeCapability = {
292
- browserName: 'MicrosoftEdge',
293
- 'ms:edgeOptions': {
294
- args: [...(isHeadless ? ['--headless'] : [])]
295
- },
296
- 'wdio-ics:options': {
297
- logName: 'local-edge',
298
- },
299
- };
300
- const capabilityMap = {
301
- chrome: chromeCapability,
302
- firefox: firefoxCapability,
303
- safari: safariCapability,
304
- edge: edgeCapability,
305
- };
306
- const newCapabilities = browsers
307
- .filter((browser) => browser in capabilityMap)
308
- .map((browser) => capabilityMap[browser]);
309
- capabilities.length = 0;
310
- // Add the new capability to the capabilities array
311
- capabilities.push(...newCapabilities);
314
+ const devices = getArgvValue('--devices', (value) => value.split(',')) ?? [];
315
+ const isMobileEmulation = devices.length > 0;
316
+ const chromeCapability = {
317
+ browserName: 'chrome',
318
+ 'goog:chromeOptions': {
319
+ args: [
320
+ 'disable-infobars',
321
+ ...(isHeadless ? ['--headless'] : []),
322
+ ],
323
+ },
324
+ 'wdio-ics:options': {
325
+ logName: 'local-chrome',
326
+ },
327
+ };
328
+ const edgeCapability = {
329
+ browserName: 'MicrosoftEdge',
330
+ 'ms:edgeOptions': {
331
+ args: [...(isHeadless ? ['--headless'] : [])],
332
+ },
333
+ 'wdio-ics:options': {
334
+ logName: 'local-edge',
335
+ },
336
+ };
337
+ const firefoxCapability = {
338
+ browserName: 'firefox',
339
+ 'moz:firefoxOptions': {
340
+ args: [...(isHeadless ? ['-headless'] : []),]
341
+ },
342
+ 'wdio-ics:options': {
343
+ logName: 'local-firefox',
344
+ },
345
+ };
346
+ const safariCapability = {
347
+ browserName: 'safari',
348
+ 'wdio-ics:options': {
349
+ logName: 'local-safari',
350
+ },
351
+ };
352
+ const capabilityMap = {
353
+ chrome: chromeCapability,
354
+ edge: edgeCapability,
355
+ firefox: firefoxCapability,
356
+ safari: safariCapability,
357
+ };
358
+ const standardCapabilities = browsers
359
+ .filter((browser) => browser in capabilityMap && browser.toLowerCase() !== 'chrome')
360
+ .map((browser) => capabilityMap[browser]);
361
+ capabilities.push(...standardCapabilities);
362
+ if (isMobileEmulation) {
363
+ devices.forEach((deviceName) => {
364
+ const foundDevice = deviceDescriptors.find((device) => device.name === deviceName);
365
+ if (foundDevice) {
366
+ const chromeMobileCapability = createChromeCapabilityWithEmulationFunc(foundDevice, isHeadless);
367
+ capabilities.push(chromeMobileCapability);
368
+ }
369
+ else {
370
+ log.error(`The device ${deviceName} is not supported. Please choose from the following devices: ${deviceDescriptors.map(device => device.name).join(', ')}`);
371
+ }
372
+ });
312
373
  }
313
- else {
314
- log.error('The capabilities are not an array');
374
+ else if (browsers.includes('chrome')) {
375
+ capabilities.push(chromeCapability);
376
+ }
377
+ if (capabilities.length === 0) {
378
+ capabilitiesErrorMessageFunc(browsers, capabilityMap, devices, deviceDescriptors, isMobileEmulation);
315
379
  }
380
+ log.info('Added new storybook capabilities:', JSON.stringify(capabilities, null, 2));
316
381
  }
317
382
  /**
318
383
  * Scan the storybook instance
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": "4.0.0",
5
+ "version": "4.0.2",
6
6
  "license": "MIT",
7
7
  "homepage": "https://webdriver.io/docs/visual-testing",
8
8
  "repository": {
@@ -23,7 +23,7 @@
23
23
  "@wdio/logger": "^8.28.0",
24
24
  "@wdio/types": "^8.32.4",
25
25
  "node-fetch": "^3.3.2",
26
- "webdriver-image-comparison": "^5.0.0"
26
+ "webdriver-image-comparison": "^5.0.1"
27
27
  },
28
28
  "scripts": {
29
29
  "build": "run-s clean build:*",