@vizzly-testing/cli 0.29.2 → 0.29.3
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.
|
@@ -58,6 +58,78 @@ export function createEventsRouter(context) {
|
|
|
58
58
|
res.write(`event: ${eventType}\n`);
|
|
59
59
|
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
|
60
60
|
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Build a lookup map from comparisons array keyed by id
|
|
64
|
+
*/
|
|
65
|
+
const buildComparisonMap = comparisons => {
|
|
66
|
+
let map = new Map();
|
|
67
|
+
for (let c of comparisons) {
|
|
68
|
+
map.set(c.id, c);
|
|
69
|
+
}
|
|
70
|
+
return map;
|
|
71
|
+
};
|
|
72
|
+
const comparisonChanged = (oldComp, newComp) => {
|
|
73
|
+
return JSON.stringify(oldComp) !== JSON.stringify(newComp);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Extract summary fields (everything except comparisons) for diffing
|
|
78
|
+
*/
|
|
79
|
+
const extractSummary = data => {
|
|
80
|
+
let {
|
|
81
|
+
comparisons: _c,
|
|
82
|
+
...summary
|
|
83
|
+
} = data;
|
|
84
|
+
return summary;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Check if summary-level fields changed between old and new data
|
|
89
|
+
*/
|
|
90
|
+
const summaryChanged = (oldData, newData) => {
|
|
91
|
+
let oldSummary = extractSummary(oldData);
|
|
92
|
+
let newSummary = extractSummary(newData);
|
|
93
|
+
return JSON.stringify(oldSummary) !== JSON.stringify(newSummary);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Send incremental updates by diffing old vs new report data.
|
|
98
|
+
* Returns true if any events were sent.
|
|
99
|
+
*/
|
|
100
|
+
const sendIncrementalUpdates = (res, oldData, newData) => {
|
|
101
|
+
let sent = false;
|
|
102
|
+
let oldComparisons = oldData.comparisons || [];
|
|
103
|
+
let newComparisons = newData.comparisons || [];
|
|
104
|
+
let oldMap = buildComparisonMap(oldComparisons);
|
|
105
|
+
let newMap = buildComparisonMap(newComparisons);
|
|
106
|
+
|
|
107
|
+
// New or changed comparisons — sends the full comparison object, not a partial delta
|
|
108
|
+
for (let [id, newComp] of newMap) {
|
|
109
|
+
let oldComp = oldMap.get(id);
|
|
110
|
+
if (!oldComp || comparisonChanged(oldComp, newComp)) {
|
|
111
|
+
sendEvent(res, 'comparisonUpdate', newComp);
|
|
112
|
+
sent = true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Removed comparisons
|
|
117
|
+
for (let [id] of oldMap) {
|
|
118
|
+
if (!newMap.has(id)) {
|
|
119
|
+
sendEvent(res, 'comparisonRemoved', {
|
|
120
|
+
id
|
|
121
|
+
});
|
|
122
|
+
sent = true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Summary-level changes (total, passed, failed, etc.)
|
|
127
|
+
if (summaryChanged(oldData, newData)) {
|
|
128
|
+
sendEvent(res, 'summaryUpdate', extractSummary(newData));
|
|
129
|
+
sent = true;
|
|
130
|
+
}
|
|
131
|
+
return sent;
|
|
132
|
+
};
|
|
61
133
|
return async function handleEventsRoute(req, res, pathname) {
|
|
62
134
|
if (req.method !== 'GET' || pathname !== '/api/events') {
|
|
63
135
|
return false;
|
|
@@ -71,20 +143,28 @@ export function createEventsRouter(context) {
|
|
|
71
143
|
'X-Accel-Buffering': 'no' // Disable nginx buffering
|
|
72
144
|
});
|
|
73
145
|
|
|
74
|
-
// Send initial data immediately
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
sendEvent(res, 'reportData',
|
|
146
|
+
// Send initial full data immediately
|
|
147
|
+
let lastSentData = readReportData();
|
|
148
|
+
if (lastSentData) {
|
|
149
|
+
sendEvent(res, 'reportData', lastSentData);
|
|
78
150
|
}
|
|
79
151
|
|
|
80
152
|
// Debounce file change events (fs.watch can fire multiple times)
|
|
81
153
|
let debounceTimer = null;
|
|
82
154
|
let watcher = null;
|
|
83
155
|
const sendUpdate = () => {
|
|
84
|
-
const
|
|
85
|
-
if (
|
|
86
|
-
|
|
156
|
+
const newData = readReportData();
|
|
157
|
+
if (!newData) return;
|
|
158
|
+
if (!lastSentData) {
|
|
159
|
+
// No previous data — send full payload
|
|
160
|
+
sendEvent(res, 'reportData', newData);
|
|
161
|
+
} else {
|
|
162
|
+
// Diff and send incremental updates
|
|
163
|
+
let sent = sendIncrementalUpdates(res, lastSentData, newData);
|
|
164
|
+
// If nothing changed, skip (no event needed)
|
|
165
|
+
if (!sent) return;
|
|
87
166
|
}
|
|
167
|
+
lastSentData = newData;
|
|
88
168
|
};
|
|
89
169
|
|
|
90
170
|
// Watch for file changes
|