@wdio/visual-service 5.1.1 → 5.2.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/CHANGELOG.md +154 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +8 -0
- package/dist/reporter.d.ts +14 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +97 -0
- package/dist/service.d.ts +4 -4
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +178 -62
- package/dist/storybook/launcher.d.ts.map +1 -1
- package/dist/storybook/launcher.js +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +10 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +28 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,159 @@
|
|
|
1
1
|
# @wdio/visual-service
|
|
2
2
|
|
|
3
|
+
## 5.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0b01b64: ### @wdio/visual-service
|
|
8
|
+
|
|
9
|
+
#### 🚀 New Features
|
|
10
|
+
|
|
11
|
+
**Added Reporting output**
|
|
12
|
+
You now have the option to export the compare results into a JSON report file. By enabling the module option `createJsonReportFiles: true`, each image that is compared will create a report stored in the `actual` folder, next to each `actual` image result.
|
|
13
|
+
|
|
14
|
+
The output will look like this:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"parent": "check methods",
|
|
19
|
+
"test": "should fail comparing with a baseline",
|
|
20
|
+
"tag": "examplePageFail",
|
|
21
|
+
"instanceData": {
|
|
22
|
+
"browser": {
|
|
23
|
+
"name": "chrome-headless-shell",
|
|
24
|
+
"version": "126.0.6478.183"
|
|
25
|
+
},
|
|
26
|
+
"platform": {
|
|
27
|
+
"name": "mac",
|
|
28
|
+
"version": "not-known"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"commandName": "checkScreen",
|
|
32
|
+
"boundingBoxes": {
|
|
33
|
+
"diffBoundingBoxes": [
|
|
34
|
+
{
|
|
35
|
+
"left": 1088,
|
|
36
|
+
"top": 717,
|
|
37
|
+
"right": 1186,
|
|
38
|
+
"bottom": 730
|
|
39
|
+
}
|
|
40
|
+
//....
|
|
41
|
+
],
|
|
42
|
+
"ignoredBoxes": [
|
|
43
|
+
{
|
|
44
|
+
"left": 159,
|
|
45
|
+
"top": 652,
|
|
46
|
+
"right": 356,
|
|
47
|
+
"bottom": 703
|
|
48
|
+
}
|
|
49
|
+
//...
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"fileData": {
|
|
53
|
+
"actualFilePath": "/Users/wswebcreation/Git/wdio/visual-testing/.tmp/actual/desktop_chrome-headless-shellexamplePageFail-local-chrome-latest-1366x768.png",
|
|
54
|
+
"baselineFilePath": "/Users/wswebcreation/Git/wdio/visual-testing/localBaseline/desktop_chrome-headless-shellexamplePageFail-local-chrome-latest-1366x768.png",
|
|
55
|
+
"diffFilePath": "/Users/wswebcreation/Git/wdio/visual-testing/.tmp/diff/desktop_chrome-headless-shell/examplePageFail-local-chrome-latest-1366x768png",
|
|
56
|
+
"fileName": "examplePageFail-local-chrome-latest-1366x768.png",
|
|
57
|
+
"size": {
|
|
58
|
+
"actual": {
|
|
59
|
+
"height": 768,
|
|
60
|
+
"width": 1366
|
|
61
|
+
},
|
|
62
|
+
"baseline": {
|
|
63
|
+
"height": 768,
|
|
64
|
+
"width": 1366
|
|
65
|
+
},
|
|
66
|
+
"diff": {
|
|
67
|
+
"height": 768,
|
|
68
|
+
"width": 1366
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"misMatchPercentage": "12.90",
|
|
73
|
+
"rawMisMatchPercentage": 12.900729014153246
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
When all tests are executed, a new JSON file with the collection of the comparisons will be generated and can be found in the root of your actual folder. The data is grouped by:
|
|
78
|
+
|
|
79
|
+
- `describe` for Jasmine/Mocha or `Feature` for CucumberJS
|
|
80
|
+
- `it` for Jasmine/Mocha or `Scenario` for CucumberJS
|
|
81
|
+
|
|
82
|
+
and then sorted by:
|
|
83
|
+
|
|
84
|
+
- `commandName`, which are the compare method names used to compare the images
|
|
85
|
+
- `instanceData`, browser first, then device, then platform
|
|
86
|
+
|
|
87
|
+
it will look like this
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
[
|
|
91
|
+
{
|
|
92
|
+
"description": "check methods",
|
|
93
|
+
"data": [
|
|
94
|
+
{
|
|
95
|
+
"test": "should fail comparing with a baseline",
|
|
96
|
+
"data": [
|
|
97
|
+
{
|
|
98
|
+
"tag": "examplePageFail",
|
|
99
|
+
"instanceData": {},
|
|
100
|
+
"commandName": "checkScreen",
|
|
101
|
+
"framework": "mocha",
|
|
102
|
+
"boundingBoxes": {
|
|
103
|
+
"diffBoundingBoxes": [],
|
|
104
|
+
"ignoredBoxes": []
|
|
105
|
+
},
|
|
106
|
+
"fileData": {},
|
|
107
|
+
"misMatchPercentage": "14.34",
|
|
108
|
+
"rawMisMatchPercentage": 14.335403703025868
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"tag": "exampleElementFail",
|
|
112
|
+
"instanceData": {},
|
|
113
|
+
"commandName": "checkElement",
|
|
114
|
+
"framework": "mocha",
|
|
115
|
+
"boundingBoxes": {
|
|
116
|
+
"diffBoundingBoxes": [],
|
|
117
|
+
"ignoredBoxes": []
|
|
118
|
+
},
|
|
119
|
+
"fileData": {},
|
|
120
|
+
"misMatchPercentage": "1.34",
|
|
121
|
+
"rawMisMatchPercentage": 1.335403703025868
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The report data will give you the opportunity to build your own visual report without doing all the magic and data collection yourself.
|
|
131
|
+
|
|
132
|
+
### webdriver-image-comparison
|
|
133
|
+
|
|
134
|
+
#### 🚀 New Features
|
|
135
|
+
|
|
136
|
+
- Add support to generate single JSON report files
|
|
137
|
+
|
|
138
|
+
### @wdio/ocr-service
|
|
139
|
+
|
|
140
|
+
#### 💅 Polish
|
|
141
|
+
|
|
142
|
+
- Refactored the CLI to use `@inquirer/prompts` instead of `inquirer`
|
|
143
|
+
|
|
144
|
+
### Committers: 1
|
|
145
|
+
|
|
146
|
+
- Wim Selles ([@wswebcreation](https://github.com/wswebcreation))
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Patch Changes
|
|
153
|
+
|
|
154
|
+
- Updated dependencies [0b01b64]
|
|
155
|
+
- webdriver-image-comparison@6.1.0
|
|
156
|
+
|
|
3
157
|
## 5.1.1
|
|
4
158
|
|
|
5
159
|
### Patch Changes
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export declare const V6_CLIP_SELECTOR = "#root > :first-child:not(script):not(style)";
|
|
2
2
|
export declare const CLIP_SELECTOR = "#storybook-root > :first-child:not(script):not(style)";
|
|
3
3
|
export declare const NUM_SHARDS = 1;
|
|
4
|
+
export declare const PAGE_OPTIONS_MAP: {
|
|
5
|
+
[key: string]: string;
|
|
6
|
+
};
|
|
4
7
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,gDAAgD,CAAA;AAC7E,eAAO,MAAM,aAAa,0DAA0D,CAAA;AACpF,eAAO,MAAM,UAAU,IAAI,CAAA"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,gDAAgD,CAAA;AAC7E,eAAO,MAAM,aAAa,0DAA0D,CAAA;AACpF,eAAO,MAAM,UAAU,IAAI,CAAA;AAC3B,eAAO,MAAM,gBAAgB,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAOrD,CAAA"}
|
package/dist/constants.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
export const V6_CLIP_SELECTOR = '#root > :first-child:not(script):not(style)';
|
|
2
2
|
export const CLIP_SELECTOR = '#storybook-root > :first-child:not(script):not(style)';
|
|
3
3
|
export const NUM_SHARDS = 1;
|
|
4
|
+
export const PAGE_OPTIONS_MAP = {
|
|
5
|
+
'saveScreen': 'saveScreenOptions',
|
|
6
|
+
'saveFullPageScreen': 'saveFullPageOptions',
|
|
7
|
+
'saveTabbablePage': 'saveTabbableOptions',
|
|
8
|
+
'checkScreen': 'checkScreenOptions',
|
|
9
|
+
'checkFullPageScreen': 'checkFullPageOptions',
|
|
10
|
+
'checkTabbablePage': 'checkTabbableOptions'
|
|
11
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare class VisualReportGenerator {
|
|
2
|
+
directoryPath: string;
|
|
3
|
+
constructor({ directoryPath }: {
|
|
4
|
+
directoryPath: string;
|
|
5
|
+
});
|
|
6
|
+
generate(): void;
|
|
7
|
+
private readJsonFilesRecursively;
|
|
8
|
+
private readDirectory;
|
|
9
|
+
private readJsonFile;
|
|
10
|
+
private groupAndSortTestData;
|
|
11
|
+
private writeJsonToFile;
|
|
12
|
+
}
|
|
13
|
+
export default VisualReportGenerator;
|
|
14
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAiBA,cAAM,qBAAqB;IACvB,aAAa,EAAE,MAAM,CAAA;gBAET,EAAE,aAAa,EAAE,EAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAC;IAI9C,QAAQ,IAAI,IAAI;IAcvB,OAAO,CAAC,wBAAwB;IAOhC,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,oBAAoB;IAsD5B,OAAO,CAAC,eAAe;CAG1B;AAED,eAAe,qBAAqB,CAAA"}
|
package/dist/reporter.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import logger from '@wdio/logger';
|
|
4
|
+
const log = logger('@wdio/visual-service:webdriver-image-comparison-reporter');
|
|
5
|
+
class VisualReportGenerator {
|
|
6
|
+
directoryPath;
|
|
7
|
+
constructor({ directoryPath }) {
|
|
8
|
+
this.directoryPath = directoryPath;
|
|
9
|
+
}
|
|
10
|
+
generate() {
|
|
11
|
+
try {
|
|
12
|
+
log.info('Generating visual report...');
|
|
13
|
+
const testData = this.readJsonFilesRecursively(this.directoryPath);
|
|
14
|
+
log.info('Read all json files');
|
|
15
|
+
const groupedAndSortedData = this.groupAndSortTestData(testData);
|
|
16
|
+
log.info('Grouped and sorted data');
|
|
17
|
+
this.writeJsonToFile(join(this.directoryPath, 'output.json'), groupedAndSortedData);
|
|
18
|
+
log.info('Report generated');
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
log.error('Error generating visual report:', e);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
readJsonFilesRecursively(directory) {
|
|
25
|
+
log.info(`Reading json files from ${directory}`);
|
|
26
|
+
const testData = [];
|
|
27
|
+
this.readDirectory(directory, testData);
|
|
28
|
+
return testData;
|
|
29
|
+
}
|
|
30
|
+
readDirectory(dir, testData) {
|
|
31
|
+
const items = fs.readdirSync(dir);
|
|
32
|
+
items.forEach(item => {
|
|
33
|
+
const fullPath = join(dir, item);
|
|
34
|
+
const stat = fs.statSync(fullPath);
|
|
35
|
+
if (stat.isDirectory()) {
|
|
36
|
+
this.readDirectory(fullPath, testData);
|
|
37
|
+
}
|
|
38
|
+
else if (stat.isFile() && item.endsWith('-report.json')) {
|
|
39
|
+
this.readJsonFile(fullPath, testData);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
readJsonFile(filePath, testData) {
|
|
44
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
45
|
+
const jsonContent = JSON.parse(fileContent);
|
|
46
|
+
testData.push(jsonContent); // Add JSON content to testData array
|
|
47
|
+
}
|
|
48
|
+
groupAndSortTestData(testData) {
|
|
49
|
+
const groupedData = [];
|
|
50
|
+
// Grouping by description and test
|
|
51
|
+
testData.forEach(report => {
|
|
52
|
+
const mainTestName = report.description;
|
|
53
|
+
let mainGroup = groupedData.find(group => group.description === mainTestName);
|
|
54
|
+
if (!mainGroup) {
|
|
55
|
+
mainGroup = { description: mainTestName, data: [] };
|
|
56
|
+
groupedData.push(mainGroup);
|
|
57
|
+
}
|
|
58
|
+
let testGroup = mainGroup.data.find(test => test.test === report.test);
|
|
59
|
+
if (!testGroup) {
|
|
60
|
+
testGroup = { test: report.test, data: [] };
|
|
61
|
+
mainGroup.data.push(testGroup);
|
|
62
|
+
}
|
|
63
|
+
testGroup.data.push(report);
|
|
64
|
+
});
|
|
65
|
+
// Sorting within each group
|
|
66
|
+
groupedData.forEach(mainGroup => {
|
|
67
|
+
mainGroup.data.forEach(testGroup => {
|
|
68
|
+
testGroup.data.sort((a, b) => {
|
|
69
|
+
// Sort by commandName
|
|
70
|
+
if (a.commandName !== b.commandName) {
|
|
71
|
+
return a.commandName.localeCompare(b.commandName);
|
|
72
|
+
}
|
|
73
|
+
// Sort by instanceData (browser first, then device, then platform)
|
|
74
|
+
const aBrowserName = a.instanceData.browser?.name || '';
|
|
75
|
+
const bBrowserName = b.instanceData.browser?.name || '';
|
|
76
|
+
if (aBrowserName !== bBrowserName) {
|
|
77
|
+
return aBrowserName.localeCompare(bBrowserName);
|
|
78
|
+
}
|
|
79
|
+
const aDeviceName = a.instanceData.deviceName || '';
|
|
80
|
+
const bDeviceName = b.instanceData.deviceName || '';
|
|
81
|
+
if (aDeviceName !== bDeviceName) {
|
|
82
|
+
return aDeviceName.localeCompare(bDeviceName);
|
|
83
|
+
}
|
|
84
|
+
if (a.instanceData.platform.name !== b.instanceData.platform.name) {
|
|
85
|
+
return a.instanceData.platform.name.localeCompare(b.instanceData.platform.name);
|
|
86
|
+
}
|
|
87
|
+
return 0;
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
return groupedData;
|
|
92
|
+
}
|
|
93
|
+
writeJsonToFile(filePath, data) {
|
|
94
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export default VisualReportGenerator;
|
package/dist/service.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { Frameworks } from '@wdio/types';
|
|
2
|
-
import type { ClassOptions } from 'webdriver-image-comparison';
|
|
3
2
|
import { BaseClass } from 'webdriver-image-comparison';
|
|
3
|
+
import type { VisualServiceOptions } from './types.js';
|
|
4
4
|
export default class WdioImageComparisonService extends BaseClass {
|
|
5
5
|
#private;
|
|
6
|
-
private _browser?;
|
|
7
6
|
private _isNativeContext;
|
|
8
|
-
constructor(options:
|
|
7
|
+
constructor(options: VisualServiceOptions, _: WebdriverIO.Capabilities, config: WebdriverIO.Config);
|
|
9
8
|
/**
|
|
10
9
|
* Set up the service if users want to use it in standalone mode
|
|
11
10
|
*/
|
|
12
11
|
remoteSetup(browser: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser): Promise<void>;
|
|
13
12
|
before(capabilities: WebdriverIO.Capabilities, _specs: string[], browser: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser): Promise<void>;
|
|
14
|
-
beforeTest(test: Frameworks.Test): void
|
|
13
|
+
beforeTest(test: Frameworks.Test): Promise<void>;
|
|
14
|
+
beforeScenario(world: Frameworks.World): void;
|
|
15
15
|
afterCommand(commandName: string, _args: string[], result: number | string, error: any): void;
|
|
16
16
|
}
|
|
17
17
|
//# sourceMappingURL=service.d.ts.map
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,UAAU,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,UAAU,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EACH,SAAS,EAWZ,MAAM,4BAA4B,CAAA;AAYnC,OAAO,KAAK,EAA+C,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAenG,MAAM,CAAC,OAAO,OAAO,0BAA2B,SAAQ,SAAS;;IAM7D,OAAO,CAAC,gBAAgB,CAA+B;gBAE3C,OAAO,EAAE,oBAAoB,EAAE,CAAC,EAAE,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM;IAOlG;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,kBAAkB;IAIzE,MAAM,CACR,YAAY,EAAE,WAAW,CAAC,YAAY,EACtC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,kBAAkB;IAgC3D,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI;IAOtC,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK;IAItC,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,GAAG;CAsWzF"}
|
package/dist/service.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import logger from '@wdio/logger';
|
|
2
2
|
import { expect } from '@wdio/globals';
|
|
3
3
|
import { dirname, normalize, resolve } from 'node:path';
|
|
4
|
-
import { BaseClass, checkElement, checkFullPageScreen, checkScreen, saveElement, saveFullPageScreen, saveScreen, saveTabbablePage, checkTabbablePage, FOLDERS, } from 'webdriver-image-comparison';
|
|
5
|
-
import {
|
|
4
|
+
import { BaseClass, checkElement, checkFullPageScreen, checkScreen, saveElement, saveFullPageScreen, saveScreen, saveTabbablePage, checkTabbablePage, FOLDERS, DEFAULT_TEST_CONTEXT, } from 'webdriver-image-comparison';
|
|
5
|
+
import { SevereServiceError } from 'webdriverio';
|
|
6
|
+
import { determineNativeContext, enrichTestContext, getFolders, getInstanceData, getNativeContext } from './utils.js';
|
|
6
7
|
import { toMatchScreenSnapshot, toMatchFullPageSnapshot, toMatchElementSnapshot, toMatchTabbablePageSnapshot } from './matcher.js';
|
|
7
8
|
import { waitForStorybookComponentToBeLoaded } from './storybook/utils.js';
|
|
9
|
+
import { PAGE_OPTIONS_MAP } from './constants.js';
|
|
8
10
|
const log = logger('@wdio/visual-service');
|
|
9
11
|
const elementCommands = { saveElement, checkElement };
|
|
10
12
|
const pageCommands = {
|
|
@@ -20,12 +22,14 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
20
22
|
#config;
|
|
21
23
|
#currentFile;
|
|
22
24
|
#currentFilePath;
|
|
23
|
-
|
|
25
|
+
#testContext;
|
|
26
|
+
#browser;
|
|
24
27
|
_isNativeContext;
|
|
25
28
|
constructor(options, _, config) {
|
|
26
29
|
super(options);
|
|
27
30
|
this.#config = config;
|
|
28
31
|
this._isNativeContext = undefined;
|
|
32
|
+
this.#testContext = DEFAULT_TEST_CONTEXT;
|
|
29
33
|
}
|
|
30
34
|
/**
|
|
31
35
|
* Set up the service if users want to use it in standalone mode
|
|
@@ -34,11 +38,11 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
34
38
|
await this.before(browser.capabilities, [], browser);
|
|
35
39
|
}
|
|
36
40
|
async before(capabilities, _specs, browser) {
|
|
37
|
-
this
|
|
38
|
-
this._isNativeContext = determineNativeContext(this
|
|
39
|
-
if (!this.
|
|
41
|
+
this.#browser = browser;
|
|
42
|
+
this._isNativeContext = determineNativeContext(this.#browser);
|
|
43
|
+
if (!this.#browser.isMultiremote) {
|
|
40
44
|
log.info('Adding commands to global browser');
|
|
41
|
-
await this.#addCommandsToBrowser(this
|
|
45
|
+
await this.#addCommandsToBrowser(this.#browser);
|
|
42
46
|
}
|
|
43
47
|
else {
|
|
44
48
|
await this.#extendMultiremoteBrowser(capabilities);
|
|
@@ -62,15 +66,20 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
62
66
|
log.warn('Expect package not found. This means that the custom matchers `toMatchScreenSnapshot|toMatchFullPageSnapshot|toMatchElementSnapshot|toMatchTabbablePageSnapshot` are not added and can not be used. Please make sure to add it to your `package.json` if you want to use the Visual custom matchers.');
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
|
-
beforeTest(test) {
|
|
69
|
+
async beforeTest(test) {
|
|
66
70
|
this.#currentFile = (test.file || test.filename);
|
|
67
71
|
this.#currentFilePath = resolve(dirname(this.#currentFile), FOLDERS.DEFAULT.BASE);
|
|
72
|
+
this.#testContext = this.#getTestContext(test);
|
|
73
|
+
}
|
|
74
|
+
// For Cucumber only
|
|
75
|
+
beforeScenario(world) {
|
|
76
|
+
this.#testContext = this.#getTestContext(world);
|
|
68
77
|
}
|
|
69
78
|
afterCommand(commandName, _args, result, error) {
|
|
70
79
|
// This is for the cases where in the E2E tests we switch to a WEBVIEW or back to NATIVE_APP context
|
|
71
80
|
if (commandName === 'getContext' && error === undefined && typeof result === 'string') {
|
|
72
81
|
// Multiremote logic is handled in the `before` method during an event listener
|
|
73
|
-
this._isNativeContext = this
|
|
82
|
+
this._isNativeContext = this.#browser?.isMultiremote ? this._isNativeContext : result.includes('NATIVE');
|
|
74
83
|
}
|
|
75
84
|
}
|
|
76
85
|
#getBaselineFolder() {
|
|
@@ -94,7 +103,7 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
94
103
|
* Add commands to the Multi Remote browser object
|
|
95
104
|
*/
|
|
96
105
|
async #extendMultiremoteBrowser(capabilities) {
|
|
97
|
-
const browser = this
|
|
106
|
+
const browser = this.#browser;
|
|
98
107
|
const browserNames = Object.keys(capabilities);
|
|
99
108
|
/**
|
|
100
109
|
* Add all the commands to each browser in the Multi Remote
|
|
@@ -125,7 +134,7 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
125
134
|
*/
|
|
126
135
|
async #addCommandsToBrowser(currentBrowser) {
|
|
127
136
|
const instanceData = await getInstanceData(currentBrowser);
|
|
128
|
-
const isNativeContext = getNativeContext(this
|
|
137
|
+
const isNativeContext = getNativeContext(this.#browser, currentBrowser, this._isNativeContext);
|
|
129
138
|
for (const [commandName, command] of Object.entries(elementCommands)) {
|
|
130
139
|
this.#addElementCommand(currentBrowser, commandName, command, instanceData, isNativeContext);
|
|
131
140
|
}
|
|
@@ -140,17 +149,32 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
140
149
|
log.info(`Adding element command "${commandName}" to browser object`);
|
|
141
150
|
const self = this;
|
|
142
151
|
browser.addCommand(commandName, function (element, tag, elementOptions = {}) {
|
|
152
|
+
const elementOptionsKey = commandName === 'saveElement' ? 'saveElementOptions' : 'checkElementOptions';
|
|
143
153
|
return command({
|
|
144
|
-
|
|
145
|
-
|
|
154
|
+
methods: {
|
|
155
|
+
executor: (script, ...varArgs) => {
|
|
156
|
+
return this.execute.bind(browser)(script, ...varArgs);
|
|
157
|
+
},
|
|
158
|
+
getElementRect: this.getElementRect.bind(browser),
|
|
159
|
+
screenShot: this.takeScreenshot.bind(browser),
|
|
160
|
+
takeElementScreenshot: this.takeElementScreenshot.bind(browser),
|
|
161
|
+
},
|
|
162
|
+
instanceData,
|
|
163
|
+
folders: getFolders(elementOptions, self.folders, self.#getBaselineFolder()),
|
|
164
|
+
element,
|
|
165
|
+
tag,
|
|
166
|
+
[elementOptionsKey]: {
|
|
167
|
+
wic: self.defaultOptions,
|
|
168
|
+
method: elementOptions,
|
|
146
169
|
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
170
|
+
isNativeContext,
|
|
171
|
+
testContext: enrichTestContext({
|
|
172
|
+
commandName,
|
|
173
|
+
currentTestContext: self.#testContext,
|
|
174
|
+
instanceData,
|
|
175
|
+
tag,
|
|
176
|
+
})
|
|
177
|
+
});
|
|
154
178
|
});
|
|
155
179
|
}
|
|
156
180
|
/**
|
|
@@ -159,24 +183,77 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
159
183
|
#addPageCommand(browser, commandName, command, instanceData, isNativeContext) {
|
|
160
184
|
log.info(`Adding browser command "${commandName}" to browser object`);
|
|
161
185
|
const self = this;
|
|
186
|
+
const pageOptionsKey = PAGE_OPTIONS_MAP[commandName];
|
|
162
187
|
if (commandName === 'waitForStorybookComponentToBeLoaded') {
|
|
163
188
|
browser.addCommand(commandName, (options) => waitForStorybookComponentToBeLoaded(options));
|
|
164
189
|
}
|
|
165
190
|
else {
|
|
166
191
|
browser.addCommand(commandName, function (tag, pageOptions = {}) {
|
|
167
192
|
return command({
|
|
168
|
-
|
|
169
|
-
|
|
193
|
+
methods: {
|
|
194
|
+
executor: (script, ...varArgs) => {
|
|
195
|
+
return this.execute.bind(browser)(script, ...varArgs);
|
|
196
|
+
},
|
|
197
|
+
getElementRect: this.getElementRect.bind(browser),
|
|
198
|
+
screenShot: this.takeScreenshot.bind(browser),
|
|
170
199
|
},
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
200
|
+
instanceData,
|
|
201
|
+
folders: getFolders(pageOptions, self.folders, self.#getBaselineFolder()),
|
|
202
|
+
tag,
|
|
203
|
+
[pageOptionsKey]: {
|
|
204
|
+
wic: self.defaultOptions,
|
|
205
|
+
method: pageOptions,
|
|
206
|
+
},
|
|
207
|
+
isNativeContext,
|
|
208
|
+
testContext: enrichTestContext({
|
|
209
|
+
commandName,
|
|
210
|
+
currentTestContext: self.#testContext,
|
|
211
|
+
instanceData,
|
|
212
|
+
tag,
|
|
213
|
+
})
|
|
214
|
+
});
|
|
177
215
|
});
|
|
178
216
|
}
|
|
179
217
|
}
|
|
218
|
+
#addMultiremoteElementCommand(browser, browserNames, commandName, command) {
|
|
219
|
+
log.info(`Adding element command "${commandName}" to Multi browser object`);
|
|
220
|
+
const self = this;
|
|
221
|
+
browser.addCommand(commandName, async function (tag, element, pageOptions = {}) {
|
|
222
|
+
const returnData = {};
|
|
223
|
+
const elementOptionsKey = commandName === 'saveElement' ? 'saveElementOptions' : 'checkElementOptions';
|
|
224
|
+
for (const browserName of browserNames) {
|
|
225
|
+
const browserInstance = browser.getInstance(browserName);
|
|
226
|
+
const isNativeContext = getNativeContext(self.#browser, browserInstance, self._isNativeContext);
|
|
227
|
+
const instanceData = await getInstanceData(browserInstance);
|
|
228
|
+
returnData[browserName] = await command({
|
|
229
|
+
methods: {
|
|
230
|
+
executor: (script, ...varArgs) => {
|
|
231
|
+
return browserInstance.execute.bind(browserInstance)(script, ...varArgs);
|
|
232
|
+
},
|
|
233
|
+
getElementRect: browserInstance.getElementRect.bind(browserInstance),
|
|
234
|
+
screenShot: browserInstance.takeScreenshot.bind(browserInstance),
|
|
235
|
+
takeElementScreenshot: browserInstance.takeElementScreenshot.bind(browserInstance),
|
|
236
|
+
},
|
|
237
|
+
instanceData,
|
|
238
|
+
folders: getFolders(pageOptions, self.folders, self.#getBaselineFolder()),
|
|
239
|
+
tag,
|
|
240
|
+
element,
|
|
241
|
+
[elementOptionsKey]: {
|
|
242
|
+
wic: self.defaultOptions,
|
|
243
|
+
method: pageOptions,
|
|
244
|
+
},
|
|
245
|
+
isNativeContext,
|
|
246
|
+
testContext: enrichTestContext({
|
|
247
|
+
commandName,
|
|
248
|
+
currentTestContext: self.#testContext,
|
|
249
|
+
instanceData,
|
|
250
|
+
tag,
|
|
251
|
+
})
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
return returnData;
|
|
255
|
+
});
|
|
256
|
+
}
|
|
180
257
|
#addMultiremoteCommand(browser, browserNames, commandName, command) {
|
|
181
258
|
log.info(`Adding browser command "${commandName}" to Multi browser object`);
|
|
182
259
|
const self = this;
|
|
@@ -186,51 +263,41 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
186
263
|
else {
|
|
187
264
|
browser.addCommand(commandName, async function (tag, pageOptions = {}) {
|
|
188
265
|
const returnData = {};
|
|
266
|
+
const pageOptionsKey = PAGE_OPTIONS_MAP[commandName];
|
|
189
267
|
for (const browserName of browserNames) {
|
|
190
268
|
const browserInstance = browser.getInstance(browserName);
|
|
191
|
-
const isNativeContext = getNativeContext(self
|
|
269
|
+
const isNativeContext = getNativeContext(self.#browser, browserInstance, self._isNativeContext);
|
|
192
270
|
const instanceData = await getInstanceData(browserInstance);
|
|
193
271
|
returnData[browserName] = await command({
|
|
194
|
-
|
|
195
|
-
|
|
272
|
+
methods: {
|
|
273
|
+
executor: (script, ...varArgs) => {
|
|
274
|
+
return browserInstance.execute.bind(browserInstance)(script, ...varArgs);
|
|
275
|
+
},
|
|
276
|
+
getElementRect: browserInstance.getElementRect.bind(browserInstance),
|
|
277
|
+
screenShot: browserInstance.takeScreenshot.bind(browserInstance),
|
|
196
278
|
},
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
279
|
+
instanceData,
|
|
280
|
+
folders: getFolders(pageOptions, self.folders, self.#getBaselineFolder()),
|
|
281
|
+
tag,
|
|
282
|
+
[pageOptionsKey]: {
|
|
283
|
+
wic: self.defaultOptions,
|
|
284
|
+
method: pageOptions,
|
|
285
|
+
},
|
|
286
|
+
isNativeContext,
|
|
287
|
+
testContext: enrichTestContext({
|
|
288
|
+
commandName,
|
|
289
|
+
currentTestContext: self.#testContext,
|
|
290
|
+
instanceData,
|
|
291
|
+
tag,
|
|
292
|
+
})
|
|
293
|
+
});
|
|
203
294
|
}
|
|
204
295
|
return returnData;
|
|
205
296
|
});
|
|
206
297
|
}
|
|
207
298
|
}
|
|
208
|
-
#addMultiremoteElementCommand(browser, browserNames, commandName, command) {
|
|
209
|
-
log.info(`Adding element command "${commandName}" to Multi browser object`);
|
|
210
|
-
const self = this;
|
|
211
|
-
browser.addCommand(commandName, async function (tag, element, pageOptions = {}) {
|
|
212
|
-
const returnData = {};
|
|
213
|
-
for (const browserName of browserNames) {
|
|
214
|
-
const browserInstance = browser.getInstance(browserName);
|
|
215
|
-
const isNativeContext = getNativeContext(self._browser, browserInstance, self._isNativeContext);
|
|
216
|
-
const instanceData = await getInstanceData(browserInstance);
|
|
217
|
-
returnData[browserName] = await command({
|
|
218
|
-
executor: (script, ...varArgs) => {
|
|
219
|
-
return browserInstance.execute.bind(browserInstance)(script, ...varArgs);
|
|
220
|
-
},
|
|
221
|
-
getElementRect: browserInstance.getElementRect.bind(browserInstance),
|
|
222
|
-
screenShot: browserInstance.takeScreenshot.bind(browserInstance),
|
|
223
|
-
takeElementScreenshot: browserInstance.takeElementScreenshot.bind(browserInstance),
|
|
224
|
-
}, instanceData, getFolders(pageOptions, self.folders, self.#getBaselineFolder()), tag, element, {
|
|
225
|
-
wic: self.defaultOptions,
|
|
226
|
-
method: pageOptions,
|
|
227
|
-
}, isNativeContext);
|
|
228
|
-
}
|
|
229
|
-
return returnData;
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
299
|
#setupMultiremoteContextListener() {
|
|
233
|
-
const multiremoteBrowser = this
|
|
300
|
+
const multiremoteBrowser = this.#browser;
|
|
234
301
|
const browserInstances = multiremoteBrowser.instances;
|
|
235
302
|
for (const instanceName of browserInstances) {
|
|
236
303
|
const instance = multiremoteBrowser[instanceName];
|
|
@@ -246,4 +313,53 @@ export default class WdioImageComparisonService extends BaseClass {
|
|
|
246
313
|
});
|
|
247
314
|
}
|
|
248
315
|
}
|
|
316
|
+
#getTestContext(test) {
|
|
317
|
+
const framework = this.#config?.framework;
|
|
318
|
+
if (framework === 'mocha' && test) {
|
|
319
|
+
return {
|
|
320
|
+
...this.#testContext,
|
|
321
|
+
framework: 'mocha',
|
|
322
|
+
parent: test.parent,
|
|
323
|
+
title: test.title,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
else if (framework === 'jasmine' && test) {
|
|
327
|
+
/**
|
|
328
|
+
* When using Jasmine as the framework the title/parent are not set as with mocha.
|
|
329
|
+
*
|
|
330
|
+
* `fullName` contains all describe(), and it() separated by a space.
|
|
331
|
+
* `description` contains the current it() statement.
|
|
332
|
+
*
|
|
333
|
+
* e.g.:
|
|
334
|
+
* With the following configuration
|
|
335
|
+
*
|
|
336
|
+
* describe('x', () => {
|
|
337
|
+
* describe('y', () => {
|
|
338
|
+
* it('z', () => {});
|
|
339
|
+
* })
|
|
340
|
+
* })
|
|
341
|
+
*
|
|
342
|
+
* fullName will be "x y z"
|
|
343
|
+
* description will be "z"
|
|
344
|
+
*
|
|
345
|
+
*/
|
|
346
|
+
const { description: title, fullName } = test;
|
|
347
|
+
return {
|
|
348
|
+
...this.#testContext,
|
|
349
|
+
framework: 'jasmine',
|
|
350
|
+
parent: fullName?.replace(` ${title}`, ''),
|
|
351
|
+
title: title,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
else if (framework === 'cucumber' && test) {
|
|
355
|
+
return {
|
|
356
|
+
...this.#testContext,
|
|
357
|
+
framework: 'cucumber',
|
|
358
|
+
// @ts-ignore
|
|
359
|
+
parent: test?.gherkinDocument?.feature?.name,
|
|
360
|
+
title: test?.pickle?.name,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
throw new SevereServiceError(`Framework ${framework} is not supported by the Visual Service and should be either "mocha", "jasmine" or "cucumber".`);
|
|
364
|
+
}
|
|
249
365
|
}
|
|
@@ -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;
|
|
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;AAetD,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;IAuEpF,UAAU;CAuBnB"}
|
|
@@ -4,6 +4,7 @@ import { SevereServiceError } from 'webdriverio';
|
|
|
4
4
|
import { BaseClass } from 'webdriver-image-comparison';
|
|
5
5
|
import { createStorybookCapabilities, createTestFiles, getArgvValue, isCucumberFramework, isStorybookMode, parseSkipStories, scanStorybook, } from './utils.js';
|
|
6
6
|
import { CLIP_SELECTOR, NUM_SHARDS, V6_CLIP_SELECTOR } from '../constants.js';
|
|
7
|
+
import generateVisualReport from '../reporter.js';
|
|
7
8
|
const log = logger('@wdio/visual-service');
|
|
8
9
|
export default class VisualLauncher extends BaseClass {
|
|
9
10
|
#options;
|
|
@@ -91,5 +92,8 @@ export default class VisualLauncher extends BaseClass {
|
|
|
91
92
|
delete process.env.VISUAL_STORYBOOK_URL;
|
|
92
93
|
delete process.env.VISUAL_STORYBOOK_CLIP_SELECTOR;
|
|
93
94
|
}
|
|
95
|
+
if (this.#options.createJsonReportFiles) {
|
|
96
|
+
new generateVisualReport({ directoryPath: this.folders.actualFolder }).generate();
|
|
97
|
+
}
|
|
94
98
|
}
|
|
95
99
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,YAAY,EACf,MAAM,4BAA4B,CAAA;AAEnC,KAAK,WAAW,GAAG;IACf,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAAC;CAC3C,CAAC;AACF,MAAM,MAAM,MAAM,GAAG,WAAW,GAAG,gBAAgB,CAAC;AACpD,KAAK,WAAW,GAAG;IACf,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,GAAG,MAAM,CAAC;CACtD,CAAC;AACF,MAAM,MAAM,MAAM,GAAG,WAAW,GAAG,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AACjE,MAAM,MAAM,wBAAwB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACpB,CAAA;AAED,MAAM,WAAW,oBAAoB;IACjC,YAAY,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAC9D,oBAAoB,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;CAChD;AAED,MAAM,WAAW,8BACb,SAAQ,IAAI,CAAC,0BAA0B,EAAE,MAAM,oBAAoB,CAAC,EAChE,oBAAoB;CAAG;AAC/B,MAAM,WAAW,6BACb,SAAQ,IAAI,CAAC,yBAAyB,EAAE,MAAM,oBAAoB,CAAC,EAC/D,oBAAoB;CAAG;AAC/B,MAAM,WAAW,4BACb,SAAQ,IAAI,CAAC,wBAAwB,EAAE,MAAM,oBAAoB,CAAC,EAC9D,oBAAoB;CAAG;AAC/B,MAAM,WAAW,2BACb,SAAQ,IAAI,CAAC,uBAAuB,EAAE,MAAM,oBAAoB,CAAC,EAC7D,oBAAoB;CAAG;AAC/B,MAAM,WAAW,6BACb,SAAQ,IAAI,CAAC,yBAAyB,EAAE,MAAM,oBAAoB,CAAC,EAC/D,oBAAoB;CAAG;AAC/B,MAAM,WAAW,4BACb,SAAQ,IAAI,CAAC,wBAAwB,EAAE,MAAM,oBAAoB,CAAC,EAC9D,oBAAoB;CAAG;AAE/B,MAAM,WAAW,oBAAqB,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,YAAY,EACf,MAAM,4BAA4B,CAAA;AAEnC,KAAK,WAAW,GAAG;IACf,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAAC;CAC3C,CAAC;AACF,MAAM,MAAM,MAAM,GAAG,WAAW,GAAG,gBAAgB,CAAC;AACpD,KAAK,WAAW,GAAG;IACf,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,GAAG,MAAM,CAAC;CACtD,CAAC;AACF,MAAM,MAAM,MAAM,GAAG,WAAW,GAAG,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AACjE,MAAM,MAAM,wBAAwB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACpB,CAAA;AAED,MAAM,WAAW,oBAAoB;IACjC,YAAY,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAC9D,oBAAoB,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;CAChD;AAED,MAAM,WAAW,8BACb,SAAQ,IAAI,CAAC,0BAA0B,EAAE,MAAM,oBAAoB,CAAC,EAChE,oBAAoB;CAAG;AAC/B,MAAM,WAAW,6BACb,SAAQ,IAAI,CAAC,yBAAyB,EAAE,MAAM,oBAAoB,CAAC,EAC/D,oBAAoB;CAAG;AAC/B,MAAM,WAAW,4BACb,SAAQ,IAAI,CAAC,wBAAwB,EAAE,MAAM,oBAAoB,CAAC,EAC9D,oBAAoB;CAAG;AAC/B,MAAM,WAAW,2BACb,SAAQ,IAAI,CAAC,uBAAuB,EAAE,MAAM,oBAAoB,CAAC,EAC7D,oBAAoB;CAAG;AAC/B,MAAM,WAAW,6BACb,SAAQ,IAAI,CAAC,yBAAyB,EAAE,MAAM,oBAAoB,CAAC,EAC/D,oBAAoB;CAAG;AAC/B,MAAM,WAAW,4BACb,SAAQ,IAAI,CAAC,wBAAwB,EAAE,MAAM,oBAAoB,CAAC,EAC9D,oBAAoB;CAAG;AAE/B,MAAM,WAAW,oBAAqB,SAAQ,YAAY;CAAG"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Folders, InstanceData, CheckScreenMethodOptions, SaveScreenMethodOptions, CheckFullPageMethodOptions, SaveFullPageMethodOptions, CheckElementMethodOptions, SaveElementMethodOptions } from 'webdriver-image-comparison';
|
|
1
|
+
import type { Folders, InstanceData, CheckScreenMethodOptions, SaveScreenMethodOptions, CheckFullPageMethodOptions, SaveFullPageMethodOptions, CheckElementMethodOptions, SaveElementMethodOptions, TestContext } from 'webdriver-image-comparison';
|
|
2
2
|
import type { NativeContextType } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Get the folders data
|
|
@@ -38,5 +38,14 @@ export declare function determineNativeContext(driver: WebdriverIO.Browser | Web
|
|
|
38
38
|
* Get the native context for the current browser
|
|
39
39
|
*/
|
|
40
40
|
export declare function getNativeContext(browser: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser, currentBrowser: WebdriverIO.Browser, nativeContext: NativeContextType): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Make sure we have all the data for the test context
|
|
43
|
+
*/
|
|
44
|
+
export declare function enrichTestContext({ commandName, currentTestContext: { framework, parent, title, }, instanceData: { appName, browserName, browserVersion, deviceName, isAndroid, isIOS, isMobile, platformName, platformVersion, }, tag, }: {
|
|
45
|
+
commandName: string;
|
|
46
|
+
currentTestContext: TestContext;
|
|
47
|
+
instanceData: InstanceData;
|
|
48
|
+
tag: string;
|
|
49
|
+
}): TestContext;
|
|
41
50
|
export {};
|
|
42
51
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,OAAO,EACP,YAAY,EACZ,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,OAAO,EACP,YAAY,EACZ,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,WAAW,EACd,MAAM,4BAA4B,CAAA;AAEnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAOnD;;;;;GAKG;AACH,KAAK,sBAAsB,GACrB,yBAAyB,GACzB,0BAA0B,GAC1B,wBAAwB,GACxB,wBAAwB,GACxB,yBAAyB,GACzB,uBAAuB,CAAC;AAE9B,wBAAgB,UAAU,CACtB,aAAa,EAAE,sBAAsB,EACrC,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,MAAM,GACxB,OAAO,CAMT;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,iBAAiB,SAAI,GAAG;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACjB,CAKA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE;IAAC,MAAM,EAAC,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,GAAG,MAAM,CAOhH;AA4GD;;GAEG;AACH,wBAAsB,eAAe,CAAC,cAAc,EAAE,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CA4DhG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAE,IAAI,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAGtG;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,kBAAkB,GAC7D,iBAAiB,CA0BnB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,kBAAkB,EAC7D,cAAc,EAAE,WAAW,CAAC,OAAO,EACnC,aAAa,EAAE,iBAAiB,GACjC,OAAO,CAQT;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,EACI,WAAW,EACX,kBAAkB,EAAE,EAChB,SAAS,EACT,MAAM,EACN,KAAK,GACR,EACD,YAAY,EAAE,EACV,OAAO,EACP,WAAW,EACX,cAAc,EACd,UAAU,EACV,SAAS,EACT,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,eAAe,GAClB,EACD,GAAG,GACN,EACD;IACI,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,WAAW,CAAC;IAChC,YAAY,EAAE,YAAY,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;CACf,GACF,WAAW,CAuBb"}
|
package/dist/utils.js
CHANGED
|
@@ -137,7 +137,7 @@ export async function getInstanceData(currentBrowser) {
|
|
|
137
137
|
// @ts-ignore
|
|
138
138
|
platformVersion: rawPlatformVersion = NOT_KNOWN, } = currentCapabilities;
|
|
139
139
|
const appName = rawApp !== NOT_KNOWN
|
|
140
|
-
? rawApp.replace(/\\/g, '/').split('/').pop().replace(/[^a-zA-Z0-9]/g, '_')
|
|
140
|
+
? rawApp.replace(/\\/g, '/').split('/').pop().replace(/[^a-zA-Z0-9.]/g, '_')
|
|
141
141
|
: NOT_KNOWN;
|
|
142
142
|
const deviceName = getDeviceName(currentBrowser);
|
|
143
143
|
const nativeWebScreenshot = !!(requestedCapabilities['appium:nativeWebScreenshot']);
|
|
@@ -206,3 +206,30 @@ export function getNativeContext(browser, currentBrowser, nativeContext) {
|
|
|
206
206
|
}
|
|
207
207
|
return false;
|
|
208
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Make sure we have all the data for the test context
|
|
211
|
+
*/
|
|
212
|
+
export function enrichTestContext({ commandName, currentTestContext: { framework, parent, title, }, instanceData: { appName, browserName, browserVersion, deviceName, isAndroid, isIOS, isMobile, platformName, platformVersion, }, tag, }) {
|
|
213
|
+
return {
|
|
214
|
+
commandName,
|
|
215
|
+
instanceData: {
|
|
216
|
+
app: appName,
|
|
217
|
+
browser: {
|
|
218
|
+
name: browserName,
|
|
219
|
+
version: browserVersion,
|
|
220
|
+
},
|
|
221
|
+
deviceName,
|
|
222
|
+
isMobile,
|
|
223
|
+
isAndroid,
|
|
224
|
+
isIOS,
|
|
225
|
+
platform: {
|
|
226
|
+
name: platformName,
|
|
227
|
+
version: platformVersion,
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
framework,
|
|
231
|
+
parent,
|
|
232
|
+
tag,
|
|
233
|
+
title,
|
|
234
|
+
};
|
|
235
|
+
}
|
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": "5.
|
|
5
|
+
"version": "5.2.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://webdriver.io/docs/visual-testing",
|
|
8
8
|
"repository": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@wdio/logger": "^8.38.0",
|
|
25
25
|
"@wdio/types": "^8.39.0",
|
|
26
26
|
"node-fetch": "^3.3.2",
|
|
27
|
-
"webdriver-image-comparison": "^6.0
|
|
27
|
+
"webdriver-image-comparison": "^6.1.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {},
|
|
30
30
|
"scripts": {
|