flexysnap 0.2.7 → 0.3.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/package.json +1 -1
- package/src/annotateWireframe.js +28 -7
- package/src/wireframeComparison.js +46 -47
- package/src/wireframeUtils.js +13 -6
package/package.json
CHANGED
package/src/annotateWireframe.js
CHANGED
|
@@ -60,11 +60,32 @@ async function annotateWireframeFile(wireframeFile, screenshotFile) {
|
|
|
60
60
|
box: { fill: 'rgba(220, 160, 40, 0.4)', stroke: '#E6A500' },
|
|
61
61
|
image: { fill: 'rgba(70, 180, 120, 0.4)', stroke: '#2EBC6F' },
|
|
62
62
|
text: { fill: 'rgba(50, 130, 190, 0.4)', stroke: '#0066CC' },
|
|
63
|
-
error: { fill: 'rgba(211, 47, 47, 0.4)', stroke: '#D32F2F' }
|
|
63
|
+
error: { fill: 'rgba(211, 47, 47, 0.4)', stroke: '#D32F2F' },
|
|
64
|
+
missing: { fill: 'rgba(233, 30, 140, 0.4)', stroke: '#E91E8C' },
|
|
65
|
+
extra: { fill: 'rgba(156, 39, 176, 0.4)', stroke: '#9C27B0' },
|
|
66
|
+
shift: { fill: 'rgba(121, 85, 72, 0.4)', stroke: '#795548' }
|
|
64
67
|
};
|
|
65
68
|
|
|
66
|
-
function
|
|
67
|
-
|
|
69
|
+
function determineColorKey(obj, defaultKey) {
|
|
70
|
+
if (!obj.differences || !Array.isArray(obj.differences) || obj.differences.length === 0) {
|
|
71
|
+
return defaultKey;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const differenceTypes = obj.differences.map(difference => difference.type);
|
|
75
|
+
|
|
76
|
+
if (differenceTypes.includes('missing_text') || differenceTypes.includes('missing_element')) {
|
|
77
|
+
return 'missing';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (differenceTypes.includes('extra_text') || differenceTypes.includes('extra_element')) {
|
|
81
|
+
return 'extra';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (differenceTypes.includes('layout_shift') || differenceTypes.includes('size_mismatch')) {
|
|
85
|
+
return 'shift';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return 'error';
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
function drawBoundingBox(rect, colorKey, dashed = false) {
|
|
@@ -89,20 +110,20 @@ async function annotateWireframeFile(wireframeFile, screenshotFile) {
|
|
|
89
110
|
}
|
|
90
111
|
|
|
91
112
|
for (const elementGroup of wireframe.elementGroups) {
|
|
92
|
-
const dashed = elementGroup.strictPosition === false;
|
|
113
|
+
const dashed = elementGroup.options?.strictPosition === false;
|
|
93
114
|
|
|
94
115
|
for (const element of elementGroup.elements) {
|
|
95
116
|
const rect = element.boundingRect;
|
|
96
117
|
|
|
97
118
|
if (element.type === 'box') {
|
|
98
|
-
const colorKey =
|
|
119
|
+
const colorKey = determineColorKey(element, 'box');
|
|
99
120
|
drawBoundingBox(rect, colorKey, dashed);
|
|
100
121
|
} else if (element.type === 'image') {
|
|
101
|
-
const colorKey =
|
|
122
|
+
const colorKey = determineColorKey(element, 'image');
|
|
102
123
|
drawBoundingBox(rect, colorKey, dashed);
|
|
103
124
|
} else if (element.type === 'text' && element.texts && element.texts.length > 0) {
|
|
104
125
|
for (const text of element.texts) {
|
|
105
|
-
const colorKey =
|
|
126
|
+
const colorKey = determineColorKey(text, 'text');
|
|
106
127
|
drawBoundingBox(text.boundingRect, colorKey, dashed);
|
|
107
128
|
}
|
|
108
129
|
}
|
|
@@ -64,9 +64,10 @@ function createPairings(currentElements, baselineElements) {
|
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
function compareBoundingBoxes(baselineRect, currentRect,
|
|
67
|
+
function compareBoundingBoxes(baselineRect, currentRect, options) {
|
|
68
68
|
const differences = [];
|
|
69
|
-
|
|
69
|
+
const strictPosition = options?.strictPosition !== false;
|
|
70
|
+
const strictSize = options?.strictSize !== false;
|
|
70
71
|
if (strictPosition) {
|
|
71
72
|
const boundingBoxDifference = calculateBoundingBoxDistance(baselineRect, currentRect)
|
|
72
73
|
if (boundingBoxDifference > 10) {
|
|
@@ -110,15 +111,15 @@ function replaceDigitsWithPlaceholder(text) {
|
|
|
110
111
|
return text.replace(/\d+/g, '[digits]');
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
function compareTexts(baselineTexts, currentTexts,
|
|
114
|
-
const {
|
|
115
|
-
|
|
114
|
+
function compareTexts(baselineTexts, currentTexts, options) {
|
|
115
|
+
const {matchedPairs, unmatchedCurrent, unmatchedBaseline} = createPairings(currentTexts, baselineTexts);
|
|
116
|
+
|
|
116
117
|
for (const pairing of matchedPairs) {
|
|
117
118
|
const baselineText = baselineTexts[pairing.baselineIndex];
|
|
118
119
|
const currentText = currentTexts[pairing.currentIndex];
|
|
119
120
|
currentText.differences = [];
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
const maskDigits = options?.maskDigits === true;
|
|
122
123
|
let textsEqual = false
|
|
123
124
|
if (maskDigits) {
|
|
124
125
|
textsEqual = replaceDigitsWithPlaceholder(baselineText.text) !== replaceDigitsWithPlaceholder(currentText.text);
|
|
@@ -136,27 +137,28 @@ function compareTexts(baselineTexts, currentTexts, strictPosition = true, strict
|
|
|
136
137
|
const boundingBoxDifferences = compareBoundingBoxes(
|
|
137
138
|
baselineText.boundingRect,
|
|
138
139
|
currentText.boundingRect,
|
|
139
|
-
|
|
140
|
-
strictSize
|
|
140
|
+
options
|
|
141
141
|
);
|
|
142
142
|
currentText.differences = currentText.differences.concat(boundingBoxDifferences);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
if (options?.extraAllowed !== true)
|
|
147
|
+
for (const currentIndex of unmatchedCurrent) {
|
|
148
|
+
const currentText = currentTexts[currentIndex];
|
|
149
|
+
currentText.differences = [{
|
|
150
|
+
type: 'extra_text',
|
|
151
|
+
}];
|
|
152
|
+
}
|
|
152
153
|
|
|
153
|
-
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
if (options.missingAllowed !== true)
|
|
155
|
+
for (const baselineIndex of unmatchedBaseline) {
|
|
156
|
+
const baselineText = baselineTexts[baselineIndex];
|
|
157
|
+
currentTexts.push(baselineText);
|
|
158
|
+
baselineText.differences = [{
|
|
159
|
+
type: 'missing_text',
|
|
160
|
+
}];
|
|
161
|
+
}
|
|
160
162
|
|
|
161
163
|
for (const currentText of currentTexts) {
|
|
162
164
|
if (currentText.differences?.length === 0) {
|
|
@@ -165,7 +167,7 @@ function compareTexts(baselineTexts, currentTexts, strictPosition = true, strict
|
|
|
165
167
|
}
|
|
166
168
|
}
|
|
167
169
|
|
|
168
|
-
function compareElements(baselineElement, currentElement,
|
|
170
|
+
function compareElements(baselineElement, currentElement, options) {
|
|
169
171
|
if (baselineElement.histogram && currentElement.histogram) {
|
|
170
172
|
const dh = histogramDiff(baselineElement.histogram, currentElement.histogram);
|
|
171
173
|
if (dh > 15) {
|
|
@@ -176,13 +178,12 @@ function compareElements(baselineElement, currentElement, strictPosition = true,
|
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
if (baselineElement.texts.length > 0 || currentElement.texts.length > 0) {
|
|
179
|
-
compareTexts(baselineElement.texts, currentElement.texts,
|
|
181
|
+
compareTexts(baselineElement.texts, currentElement.texts, options);
|
|
180
182
|
} else {
|
|
181
183
|
currentElement.differences = compareBoundingBoxes(
|
|
182
184
|
baselineElement.boundingRect,
|
|
183
185
|
currentElement.boundingRect,
|
|
184
|
-
|
|
185
|
-
strictSize
|
|
186
|
+
options
|
|
186
187
|
);
|
|
187
188
|
}
|
|
188
189
|
}
|
|
@@ -200,11 +201,7 @@ function compareWireframes(baselineWireframe, currentWireframe) {
|
|
|
200
201
|
|
|
201
202
|
expect(baselineElementGroup.selector).toEqual(currentElementGroup.selector);
|
|
202
203
|
|
|
203
|
-
const
|
|
204
|
-
const strictSize = currentElementGroup.strictSize !== false;
|
|
205
|
-
const maskDigits = currentElementGroup.maskDigits === true;
|
|
206
|
-
|
|
207
|
-
const { matchedPairs, unmatchedCurrent, unmatchedBaseline } = createPairings(
|
|
204
|
+
const {matchedPairs, unmatchedCurrent, unmatchedBaseline} = createPairings(
|
|
208
205
|
currentElementGroup.elements,
|
|
209
206
|
baselineElementGroup.elements
|
|
210
207
|
);
|
|
@@ -212,29 +209,31 @@ function compareWireframes(baselineWireframe, currentWireframe) {
|
|
|
212
209
|
for (const pairing of matchedPairs) {
|
|
213
210
|
const baselineElement = baselineElementGroup.elements[pairing.baselineIndex];
|
|
214
211
|
const currentElement = currentElementGroup.elements[pairing.currentIndex];
|
|
215
|
-
compareElements(baselineElement, currentElement,
|
|
212
|
+
compareElements(baselineElement, currentElement, currentElementGroup.options);
|
|
216
213
|
if (currentElement.differences?.length === 0) {
|
|
217
214
|
currentElement.differences = undefined
|
|
218
215
|
}
|
|
219
216
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
217
|
+
|
|
218
|
+
if (currentElementGroup.options?.extraAllowed !== true)
|
|
219
|
+
for (const currentIndex of unmatchedCurrent) {
|
|
220
|
+
const currentElement = currentElementGroup.elements[currentIndex];
|
|
221
|
+
currentElement.differences = [{
|
|
222
|
+
type: 'extra_element',
|
|
223
|
+
}];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (currentElementGroup.options?.missingAllowed !== true)
|
|
227
|
+
for (const baselineIndex of unmatchedBaseline) {
|
|
228
|
+
const baselineElement = baselineElementGroup.elements[baselineIndex];
|
|
229
|
+
currentElementGroup.elements.push(baselineElement);
|
|
230
|
+
baselineElement.differences = [{
|
|
231
|
+
type: 'missing_element',
|
|
232
|
+
}];
|
|
233
|
+
}
|
|
235
234
|
}
|
|
236
235
|
|
|
237
236
|
return currentWireframe;
|
|
238
237
|
}
|
|
239
238
|
|
|
240
|
-
export { compareWireframes };
|
|
239
|
+
export { compareWireframes };
|
package/src/wireframeUtils.js
CHANGED
|
@@ -105,9 +105,13 @@ function scaleWireframeData(wireframeData, scaleFactor) {
|
|
|
105
105
|
function createEmptyElementGroupResult(elementGroup) {
|
|
106
106
|
return {
|
|
107
107
|
...elementGroup,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
options: {
|
|
109
|
+
strictPosition: elementGroup.options?.strictPosition !== false,
|
|
110
|
+
strictSize: elementGroup.options?.strictSize !== false,
|
|
111
|
+
maskDigits: elementGroup.options?.maskDigits !== false,
|
|
112
|
+
extraAllowed: elementGroup.options?.extraAllowed === true,
|
|
113
|
+
missingAllowed: elementGroup.options?.missingAllowed === true
|
|
114
|
+
},
|
|
111
115
|
elements: []
|
|
112
116
|
};
|
|
113
117
|
}
|
|
@@ -197,9 +201,12 @@ async function extractElementGroupData(page, elementGroup, groupIndex, elementId
|
|
|
197
201
|
return results;
|
|
198
202
|
}
|
|
199
203
|
|
|
200
|
-
elementGroup.
|
|
201
|
-
elementGroup.
|
|
202
|
-
elementGroup.
|
|
204
|
+
elementGroup.options = elementGroup.options || {};
|
|
205
|
+
elementGroup.options.strictPosition = elementGroup.options.strictPosition !== false;
|
|
206
|
+
elementGroup.options.strictSize = elementGroup.options.strictSize !== false;
|
|
207
|
+
elementGroup.options.maskDigits = elementGroup.options.maskDigits !== false;
|
|
208
|
+
elementGroup.options.extraAllowed = elementGroup.options.extraAllowed === true;
|
|
209
|
+
elementGroup.options.missingAllowed = elementGroup.options.missingAllowed === true;
|
|
203
210
|
elementGroup.elements = [];
|
|
204
211
|
|
|
205
212
|
let index = 0;
|