-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtoMatchScreenshot.ts
More file actions
143 lines (112 loc) · 4.35 KB
/
toMatchScreenshot.ts
File metadata and controls
143 lines (112 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import {randomUUID} from 'node:crypto';
import {join} from 'node:path';
import {isLocalRun} from '../../configurator';
import {
EXPECTED_SCREENSHOTS_DIRECTORY_PATH,
INTERNAL_REPORTS_DIRECTORY_PATH,
SCREENSHOT_NOT_SPECIFIED_ERROR_MESSAGE,
} from '../../constants/internal';
import {getOutputDirectoryName} from '../../context/outputDirectoryName';
import {getFullPackConfig} from '../config';
import {E2edError} from '../error';
import {writeFile} from '../fs';
import {setReadonlyProperty} from '../object';
import {getDimensionsString, getPngDimensions} from '../screenshot';
import {getEmptyAdditionalLogFields} from './getEmptyAdditionalLogFields';
import {getScreenshotMeta} from './getScreenshotMeta';
import {writeScreenshotFromPath} from './writeScreenshotFromPath';
import type {FilePathFromRoot, Selector, ToMatchScreenshotOptions} from '../../types/internal';
import type {Expect} from './Expect';
import {expect as playwrightExpect} from '@playwright/test';
/**
* Checks that the selector screenshot matches the one specified by `expectedScreenshotId`.
* @internal
*/
// eslint-disable-next-line complexity, max-statements
export const toMatchScreenshot = async (
context: Expect,
expectedScreenshotId: string,
options: ToMatchScreenshotOptions,
): Promise<void> => {
const actualValue = context.actualValue as Selector;
const {description} = context;
const {getScreenshotUrlById, readScreenshot} = getFullPackConfig().matchScreenshot;
const assertId = randomUUID();
const screenshotFileName = `${assertId}.png`;
const screenshotPath = join(
EXPECTED_SCREENSHOTS_DIRECTORY_PATH,
screenshotFileName,
) as FilePathFromRoot;
const additionalLogFields = getEmptyAdditionalLogFields({expectedScreenshotId});
setReadonlyProperty(context, 'additionalLogFields', additionalLogFields);
const meta = getScreenshotMeta({actualValue, description, expectedScreenshotId, options});
let expectedScreenshotFound = false;
if (expectedScreenshotId) {
additionalLogFields.expected.url = getScreenshotUrlById(expectedScreenshotId);
const expectedScreenshot = await readScreenshot(expectedScreenshotId, meta);
if (expectedScreenshot !== undefined) {
expectedScreenshotFound = true;
additionalLogFields.expected.dimensions = getDimensionsString(
getPngDimensions(expectedScreenshot),
);
if (!isLocalRun) {
await writeFile(screenshotPath, expectedScreenshot);
}
}
}
const message = expectedScreenshotId
? `Cannot read expected screenshot ${expectedScreenshotId}`
: SCREENSHOT_NOT_SPECIFIED_ERROR_MESSAGE;
if (isLocalRun) {
if (expectedScreenshotFound) {
additionalLogFields.isLocalRun =
'The assertion completed successfully without comparing screenshots because this is a local run (screenshots are taken only when run in docker)';
return;
}
throw new E2edError(message);
}
const {mask = [], ...restOptions} = options;
try {
const playwrightLocator = actualValue.getPlaywrightLocator();
await playwrightExpect(playwrightLocator, description).toHaveScreenshot(screenshotFileName, {
mask: mask.map((selector) => selector.getPlaywrightLocator()),
...restOptions,
});
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
try {
const output = join(INTERNAL_REPORTS_DIRECTORY_PATH, getOutputDirectoryName());
const actualScreenshotPath = join(output, `${assertId}-actual.png`) as FilePathFromRoot;
const diffScreenshotPath = join(output, `${assertId}-diff.png`) as FilePathFromRoot;
const actualScreenshotId = await writeScreenshotFromPath({
additionalLogFields,
meta,
path: actualScreenshotPath,
type: 'actual',
});
await writeScreenshotFromPath({
additionalLogFields,
meta: {...meta, actual: actualScreenshotId},
path: diffScreenshotPath,
type: 'diff',
});
} catch (secondError) {
throw new E2edError(errorMessage, {secondError});
}
throw new E2edError(errorMessage);
}
if (expectedScreenshotFound) {
return;
}
try {
await writeScreenshotFromPath({
additionalLogFields,
meta,
path: screenshotPath,
type: 'actual',
});
} catch (secondError) {
throw new E2edError(message, {secondError});
}
throw new E2edError(message);
};