-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathhelpers.ts
More file actions
75 lines (55 loc) · 1.89 KB
/
helpers.ts
File metadata and controls
75 lines (55 loc) · 1.89 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
interface StyleDeclaration extends Record<string, string> {
property: string;
value: string;
}
function normalizeStyles(css: Partial<CSSStyleDeclaration>): StyleDeclaration {
const normalizer = document.createElement("div");
document.body.appendChild(normalizer);
const { expectedStyle } = Object.entries(css).reduce(
(acc, [property, value]) => {
if (typeof value !== "string") {
return acc;
}
normalizer.style.setProperty(property, value);
const normalizedValue = window
.getComputedStyle(normalizer)
.getPropertyValue(property)
.trim();
return {
expectedStyle: {
...acc.expectedStyle,
[property]: normalizedValue,
},
};
},
{ expectedStyle: {} as StyleDeclaration },
);
document.body.removeChild(normalizer);
return expectedStyle;
}
function getReceivedStyle (props: string[], received: CSSStyleDeclaration): StyleDeclaration {
return props.reduce((acc, prop) => {
const actualStyle = received.getPropertyValue(prop).trim();
return actualStyle
? { ...acc, [prop]: actualStyle }
: acc;
}, {} as StyleDeclaration);
}
export const getExpectedAndReceivedStyles =
(actual: Element, expected: Partial<CSSStyleDeclaration>): StyleDeclaration[] => {
if (!actual.ownerDocument.defaultView) {
throw new Error("The element is not attached to a document with a default view.");
}
if (!(actual instanceof HTMLElement)) {
throw new Error("The element is not an HTMLElement.");
}
const window = actual.ownerDocument.defaultView;
const rawElementStyles = window.getComputedStyle(actual);
const expectedStyle = normalizeStyles(expected);
const styleKeys = Object.keys(expectedStyle);
const elementProcessedStyle = getReceivedStyle(styleKeys, rawElementStyles);
return [
expectedStyle,
elementProcessedStyle,
];
};