@wordpress/e2e-test-utils-playwright 1.46.0 → 1.47.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/build/admin/index.js +3 -0
- package/build/admin/index.js.map +1 -1
- package/build/admin/visit-site-editor.js +1 -29
- package/build/admin/visit-site-editor.js.map +1 -1
- package/build/admin/wait-for-site-editor.js +41 -0
- package/build/admin/wait-for-site-editor.js.map +1 -0
- package/build/metrics/index.js +59 -3
- package/build/metrics/index.js.map +1 -1
- package/build/request-utils/index.js +2 -0
- package/build/request-utils/index.js.map +1 -1
- package/build/request-utils/preferences.js +34 -0
- package/build/request-utils/preferences.js.map +1 -1
- package/build-types/admin/index.d.ts +3 -0
- package/build-types/admin/index.d.ts.map +1 -1
- package/build-types/admin/visit-site-editor.d.ts.map +1 -1
- package/build-types/admin/wait-for-site-editor.d.ts +12 -0
- package/build-types/admin/wait-for-site-editor.d.ts.map +1 -0
- package/build-types/metrics/index.d.ts +22 -5
- package/build-types/metrics/index.d.ts.map +1 -1
- package/build-types/request-utils/index.d.ts +3 -1
- package/build-types/request-utils/index.d.ts.map +1 -1
- package/build-types/request-utils/preferences.d.ts +11 -0
- package/build-types/request-utils/preferences.d.ts.map +1 -1
- package/package.json +3 -4
- package/build/admin/create-new-post.cjs +0 -51
- package/build/admin/create-new-post.cjs.map +0 -7
- package/build/admin/edit-post.cjs +0 -40
- package/build/admin/edit-post.cjs.map +0 -7
- package/build/admin/get-page-error.cjs +0 -36
- package/build/admin/get-page-error.cjs.map +0 -7
- package/build/admin/index.cjs +0 -59
- package/build/admin/index.cjs.map +0 -7
- package/build/admin/visit-admin-page.cjs +0 -47
- package/build/admin/visit-admin-page.cjs.map +0 -7
- package/build/admin/visit-site-editor.cjs +0 -90
- package/build/admin/visit-site-editor.cjs.map +0 -7
- package/build/config.cjs +0 -45
- package/build/config.cjs.map +0 -7
- package/build/editor/click-block-options-menu-item.cjs +0 -34
- package/build/editor/click-block-options-menu-item.cjs.map +0 -7
- package/build/editor/click-block-toolbar-button.cjs +0 -38
- package/build/editor/click-block-toolbar-button.cjs.map +0 -7
- package/build/editor/get-blocks.cjs +0 -64
- package/build/editor/get-blocks.cjs.map +0 -7
- package/build/editor/get-edited-post-content.cjs +0 -36
- package/build/editor/get-edited-post-content.cjs.map +0 -7
- package/build/editor/index.cjs +0 -97
- package/build/editor/index.cjs.map +0 -7
- package/build/editor/insert-block.cjs +0 -55
- package/build/editor/insert-block.cjs.map +0 -7
- package/build/editor/open-document-settings-sidebar.cjs +0 -42
- package/build/editor/open-document-settings-sidebar.cjs.map +0 -7
- package/build/editor/preview.cjs +0 -42
- package/build/editor/preview.cjs.map +0 -7
- package/build/editor/publish-post.cjs +0 -47
- package/build/editor/publish-post.cjs.map +0 -7
- package/build/editor/save-draft.cjs +0 -34
- package/build/editor/save-draft.cjs.map +0 -7
- package/build/editor/select-blocks.cjs +0 -51
- package/build/editor/select-blocks.cjs.map +0 -7
- package/build/editor/set-content.cjs +0 -39
- package/build/editor/set-content.cjs.map +0 -7
- package/build/editor/set-is-fixed-toolbar.cjs +0 -36
- package/build/editor/set-is-fixed-toolbar.cjs.map +0 -7
- package/build/editor/set-preferences.cjs +0 -43
- package/build/editor/set-preferences.cjs.map +0 -7
- package/build/editor/show-block-toolbar.cjs +0 -35
- package/build/editor/show-block-toolbar.cjs.map +0 -7
- package/build/editor/site-editor.cjs +0 -51
- package/build/editor/site-editor.cjs.map +0 -7
- package/build/editor/switch-editor-tool.cjs +0 -47
- package/build/editor/switch-editor-tool.cjs.map +0 -7
- package/build/editor/switch-to-legacy-canvas.cjs +0 -39
- package/build/editor/switch-to-legacy-canvas.cjs.map +0 -7
- package/build/editor/transform-block-to.cjs +0 -46
- package/build/editor/transform-block-to.cjs.map +0 -7
- package/build/index.cjs +0 -51
- package/build/index.cjs.map +0 -7
- package/build/lighthouse/index.cjs +0 -96
- package/build/lighthouse/index.cjs.map +0 -7
- package/build/metrics/index.cjs +0 -309
- package/build/metrics/index.cjs.map +0 -7
- package/build/page-utils/drag-files.cjs +0 -143
- package/build/page-utils/drag-files.cjs.map +0 -7
- package/build/page-utils/emulate-network-conditions.cjs +0 -99
- package/build/page-utils/emulate-network-conditions.cjs.map +0 -7
- package/build/page-utils/index.cjs +0 -59
- package/build/page-utils/index.cjs.map +0 -7
- package/build/page-utils/is-current-url.cjs +0 -36
- package/build/page-utils/is-current-url.cjs.map +0 -7
- package/build/page-utils/keycodes.cjs +0 -55
- package/build/page-utils/keycodes.cjs.map +0 -7
- package/build/page-utils/press-keys.cjs +0 -165
- package/build/page-utils/press-keys.cjs.map +0 -7
- package/build/page-utils/set-browser-viewport.cjs +0 -39
- package/build/page-utils/set-browser-viewport.cjs.map +0 -7
- package/build/request-utils/blocks.cjs +0 -51
- package/build/request-utils/blocks.cjs.map +0 -7
- package/build/request-utils/comments.cjs +0 -66
- package/build/request-utils/comments.cjs.map +0 -7
- package/build/request-utils/gutenberg-experiments.cjs +0 -56
- package/build/request-utils/gutenberg-experiments.cjs.map +0 -7
- package/build/request-utils/index.cjs +0 -199
- package/build/request-utils/index.cjs.map +0 -7
- package/build/request-utils/login.cjs +0 -48
- package/build/request-utils/login.cjs.map +0 -7
- package/build/request-utils/media.cjs +0 -83
- package/build/request-utils/media.cjs.map +0 -7
- package/build/request-utils/menus.cjs +0 -128
- package/build/request-utils/menus.cjs.map +0 -7
- package/build/request-utils/pages.cjs +0 -66
- package/build/request-utils/pages.cjs.map +0 -7
- package/build/request-utils/patterns.cjs +0 -44
- package/build/request-utils/patterns.cjs.map +0 -7
- package/build/request-utils/plugins.cjs +0 -81
- package/build/request-utils/plugins.cjs.map +0 -7
- package/build/request-utils/posts.cjs +0 -56
- package/build/request-utils/posts.cjs.map +0 -7
- package/build/request-utils/preferences.cjs +0 -41
- package/build/request-utils/preferences.cjs.map +0 -7
- package/build/request-utils/records.cjs +0 -37
- package/build/request-utils/records.cjs.map +0 -7
- package/build/request-utils/rest.cjs +0 -174
- package/build/request-utils/rest.cjs.map +0 -7
- package/build/request-utils/site-settings.cjs +0 -45
- package/build/request-utils/site-settings.cjs.map +0 -7
- package/build/request-utils/templates.cjs +0 -68
- package/build/request-utils/templates.cjs.map +0 -7
- package/build/request-utils/themes.cjs +0 -92
- package/build/request-utils/themes.cjs.map +0 -7
- package/build/request-utils/users.cjs +0 -83
- package/build/request-utils/users.cjs.map +0 -7
- package/build/request-utils/widgets.cjs +0 -79
- package/build/request-utils/widgets.cjs.map +0 -7
- package/build/test.cjs +0 -136
- package/build/test.cjs.map +0 -7
- package/build/types.cjs +0 -19
- package/build/types.cjs.map +0 -7
package/build/metrics/index.cjs
DELETED
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// packages/e2e-test-utils-playwright/src/metrics/index.ts
|
|
21
|
-
var metrics_exports = {};
|
|
22
|
-
__export(metrics_exports, {
|
|
23
|
-
Metrics: () => Metrics
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(metrics_exports);
|
|
26
|
-
var import_path = require("path");
|
|
27
|
-
var Metrics = class {
|
|
28
|
-
browser;
|
|
29
|
-
page;
|
|
30
|
-
trace;
|
|
31
|
-
webVitals = {};
|
|
32
|
-
constructor({ page }) {
|
|
33
|
-
this.page = page;
|
|
34
|
-
this.browser = page.context().browser();
|
|
35
|
-
this.trace = { traceEvents: [] };
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Returns durations from the Server-Timing header.
|
|
39
|
-
*
|
|
40
|
-
* @param fields Optional fields to filter.
|
|
41
|
-
*/
|
|
42
|
-
async getServerTiming(fields = []) {
|
|
43
|
-
return this.page.evaluate(
|
|
44
|
-
(f) => performance.getEntriesByType(
|
|
45
|
-
"navigation"
|
|
46
|
-
)[0].serverTiming.reduce(
|
|
47
|
-
(acc, entry) => {
|
|
48
|
-
if (f.length === 0 || f.includes(entry.name)) {
|
|
49
|
-
acc[entry.name] = entry.duration;
|
|
50
|
-
}
|
|
51
|
-
return acc;
|
|
52
|
-
},
|
|
53
|
-
{}
|
|
54
|
-
),
|
|
55
|
-
fields
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Returns time to first byte (TTFB) using the Navigation Timing API.
|
|
60
|
-
*
|
|
61
|
-
* @see https://web.dev/ttfb/#measure-ttfb-in-javascript
|
|
62
|
-
*
|
|
63
|
-
* @return TTFB value.
|
|
64
|
-
*/
|
|
65
|
-
async getTimeToFirstByte() {
|
|
66
|
-
return await this.page.evaluate(() => {
|
|
67
|
-
const { responseStart, startTime } = performance.getEntriesByType(
|
|
68
|
-
"navigation"
|
|
69
|
-
)[0];
|
|
70
|
-
return responseStart - startTime;
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Returns the Largest Contentful Paint (LCP) value using the dedicated API.
|
|
75
|
-
*
|
|
76
|
-
* @see https://w3c.github.io/largest-contentful-paint/
|
|
77
|
-
* @see https://web.dev/lcp/#measure-lcp-in-javascript
|
|
78
|
-
*
|
|
79
|
-
* @return LCP value.
|
|
80
|
-
*/
|
|
81
|
-
async getLargestContentfulPaint() {
|
|
82
|
-
return await this.page.evaluate(
|
|
83
|
-
() => new Promise((resolve) => {
|
|
84
|
-
new PerformanceObserver((entryList) => {
|
|
85
|
-
const entries = entryList.getEntries();
|
|
86
|
-
const largestPaintEntry = entries.at(-1);
|
|
87
|
-
resolve(largestPaintEntry?.startTime || 0);
|
|
88
|
-
}).observe({
|
|
89
|
-
type: "largest-contentful-paint",
|
|
90
|
-
buffered: true
|
|
91
|
-
});
|
|
92
|
-
})
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Returns the Cumulative Layout Shift (CLS) value using the dedicated API.
|
|
97
|
-
*
|
|
98
|
-
* @see https://github.com/WICG/layout-instability
|
|
99
|
-
* @see https://web.dev/cls/#measure-layout-shifts-in-javascript
|
|
100
|
-
*
|
|
101
|
-
* @return CLS value.
|
|
102
|
-
*/
|
|
103
|
-
async getCumulativeLayoutShift() {
|
|
104
|
-
return await this.page.evaluate(
|
|
105
|
-
() => new Promise((resolve) => {
|
|
106
|
-
let CLS = 0;
|
|
107
|
-
new PerformanceObserver((l) => {
|
|
108
|
-
const entries = l.getEntries();
|
|
109
|
-
entries.forEach((entry) => {
|
|
110
|
-
if (!entry.hadRecentInput) {
|
|
111
|
-
CLS += entry.value;
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
resolve(CLS);
|
|
115
|
-
}).observe({
|
|
116
|
-
type: "layout-shift",
|
|
117
|
-
buffered: true
|
|
118
|
-
});
|
|
119
|
-
})
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Returns the loading durations using the Navigation Timing API. All the
|
|
124
|
-
* durations exclude the server response time.
|
|
125
|
-
*
|
|
126
|
-
* @return Object with loading metrics durations.
|
|
127
|
-
*/
|
|
128
|
-
async getLoadingDurations() {
|
|
129
|
-
return await this.page.evaluate(() => {
|
|
130
|
-
const [
|
|
131
|
-
{
|
|
132
|
-
requestStart,
|
|
133
|
-
responseStart,
|
|
134
|
-
responseEnd,
|
|
135
|
-
domContentLoadedEventEnd,
|
|
136
|
-
loadEventEnd
|
|
137
|
-
}
|
|
138
|
-
] = performance.getEntriesByType(
|
|
139
|
-
"navigation"
|
|
140
|
-
);
|
|
141
|
-
const paintTimings = performance.getEntriesByType(
|
|
142
|
-
"paint"
|
|
143
|
-
);
|
|
144
|
-
const firstPaintStartTime = paintTimings.find(
|
|
145
|
-
({ name }) => name === "first-paint"
|
|
146
|
-
).startTime;
|
|
147
|
-
const firstContentfulPaintStartTime = paintTimings.find(
|
|
148
|
-
({ name }) => name === "first-contentful-paint"
|
|
149
|
-
).startTime;
|
|
150
|
-
return {
|
|
151
|
-
// Server side metric.
|
|
152
|
-
serverResponse: responseStart - requestStart,
|
|
153
|
-
// For client side metrics, consider the end of the response (the
|
|
154
|
-
// browser receives the HTML) as the start time (0).
|
|
155
|
-
firstPaint: firstPaintStartTime - responseEnd,
|
|
156
|
-
domContentLoaded: domContentLoadedEventEnd - responseEnd,
|
|
157
|
-
loaded: loadEventEnd - responseEnd,
|
|
158
|
-
firstContentfulPaint: firstContentfulPaintStartTime - responseEnd,
|
|
159
|
-
timeSinceResponseEnd: performance.now() - responseEnd
|
|
160
|
-
};
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Starts Chromium tracing with predefined options for performance testing.
|
|
165
|
-
*
|
|
166
|
-
* @param options Options to pass to `browser.startTracing()`.
|
|
167
|
-
*/
|
|
168
|
-
async startTracing(options = {}) {
|
|
169
|
-
return await this.browser.startTracing(this.page, {
|
|
170
|
-
screenshots: false,
|
|
171
|
-
categories: ["devtools.timeline"],
|
|
172
|
-
...options
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Stops Chromium tracing and saves the trace.
|
|
177
|
-
*/
|
|
178
|
-
async stopTracing() {
|
|
179
|
-
const traceBuffer = await this.browser.stopTracing();
|
|
180
|
-
const traceJSON = JSON.parse(traceBuffer.toString());
|
|
181
|
-
this.trace = traceJSON;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* @return Durations of all traced `keydown`, `keypress`, and `keyup`
|
|
185
|
-
* events.
|
|
186
|
-
*/
|
|
187
|
-
getTypingEventDurations() {
|
|
188
|
-
return [
|
|
189
|
-
this.getEventDurations("keydown"),
|
|
190
|
-
this.getEventDurations("keypress"),
|
|
191
|
-
this.getEventDurations("keyup")
|
|
192
|
-
];
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* @return Durations of all traced `focus` and `focusin` events.
|
|
196
|
-
*/
|
|
197
|
-
getSelectionEventDurations() {
|
|
198
|
-
return [
|
|
199
|
-
this.getEventDurations("focus"),
|
|
200
|
-
this.getEventDurations("focusin")
|
|
201
|
-
];
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* @return Durations of all traced `click` events.
|
|
205
|
-
*/
|
|
206
|
-
getClickEventDurations() {
|
|
207
|
-
return [this.getEventDurations("click")];
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* @return Durations of all traced `mouseover` and `mouseout` events.
|
|
211
|
-
*/
|
|
212
|
-
getHoverEventDurations() {
|
|
213
|
-
return [
|
|
214
|
-
this.getEventDurations("mouseover"),
|
|
215
|
-
this.getEventDurations("mouseout")
|
|
216
|
-
];
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* @param eventType Type of event to filter.
|
|
220
|
-
* @return Durations of all events of a given type.
|
|
221
|
-
*/
|
|
222
|
-
getEventDurations(eventType) {
|
|
223
|
-
if (this.trace.traceEvents.length === 0) {
|
|
224
|
-
throw new Error(
|
|
225
|
-
"No trace events found. Did you forget to call stopTracing()?"
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
return this.trace.traceEvents.filter(
|
|
229
|
-
(item) => item.cat === "devtools.timeline" && item.name === "EventDispatch" && item?.args?.data?.type === eventType && !!item.dur
|
|
230
|
-
).map((item) => item.dur ? item.dur / 1e3 : 0);
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Initializes the web-vitals library upon next page navigation.
|
|
234
|
-
*
|
|
235
|
-
* Defaults to automatically triggering the navigation,
|
|
236
|
-
* but it can also be done manually.
|
|
237
|
-
*
|
|
238
|
-
* @example
|
|
239
|
-
* ```js
|
|
240
|
-
* await metrics.initWebVitals();
|
|
241
|
-
* console.log( await metrics.getWebVitals() );
|
|
242
|
-
* ```
|
|
243
|
-
*
|
|
244
|
-
* @example
|
|
245
|
-
* ```js
|
|
246
|
-
* await metrics.initWebVitals( false );
|
|
247
|
-
* await page.goto( '/some-other-page' );
|
|
248
|
-
* console.log( await metrics.getWebVitals() );
|
|
249
|
-
* ```
|
|
250
|
-
*
|
|
251
|
-
* @param reload Whether to force navigation by reloading the current page.
|
|
252
|
-
*/
|
|
253
|
-
async initWebVitals(reload = true) {
|
|
254
|
-
await this.page.addInitScript({
|
|
255
|
-
path: (0, import_path.join)(
|
|
256
|
-
__dirname,
|
|
257
|
-
"../../../../node_modules/web-vitals/dist/web-vitals.umd.cjs"
|
|
258
|
-
)
|
|
259
|
-
});
|
|
260
|
-
await this.page.exposeFunction(
|
|
261
|
-
"__reportVitals__",
|
|
262
|
-
(data) => {
|
|
263
|
-
const measurement = JSON.parse(data);
|
|
264
|
-
this.webVitals[measurement.name] = measurement.value;
|
|
265
|
-
}
|
|
266
|
-
);
|
|
267
|
-
await this.page.addInitScript(() => {
|
|
268
|
-
const reportVitals = (measurement) => window.__reportVitals__(JSON.stringify(measurement));
|
|
269
|
-
window.addEventListener("DOMContentLoaded", () => {
|
|
270
|
-
window.webVitals.onCLS(reportVitals);
|
|
271
|
-
window.webVitals.onFCP(reportVitals);
|
|
272
|
-
window.webVitals.onFID(reportVitals);
|
|
273
|
-
window.webVitals.onINP(reportVitals);
|
|
274
|
-
window.webVitals.onLCP(reportVitals);
|
|
275
|
-
window.webVitals.onTTFB(reportVitals);
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
if (reload) {
|
|
279
|
-
await this.page.reload();
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Returns web vitals as collected by the web-vitals library.
|
|
284
|
-
*
|
|
285
|
-
* If the web-vitals library hasn't been loaded on the current page yet,
|
|
286
|
-
* it will be initialized with a page reload.
|
|
287
|
-
*
|
|
288
|
-
* Reloads the page to force web-vitals to report all collected metrics.
|
|
289
|
-
*
|
|
290
|
-
* @return {WebVitalsMeasurements} Web vitals measurements.
|
|
291
|
-
*/
|
|
292
|
-
async getWebVitals() {
|
|
293
|
-
this.webVitals = {};
|
|
294
|
-
const hasScript = await this.page.evaluate(
|
|
295
|
-
// @ts-expect-error This is valid but web-vitals does not register the global types.
|
|
296
|
-
() => typeof window.webVitals !== "undefined"
|
|
297
|
-
);
|
|
298
|
-
if (!hasScript) {
|
|
299
|
-
await this.initWebVitals();
|
|
300
|
-
}
|
|
301
|
-
await this.page.reload();
|
|
302
|
-
return this.webVitals;
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
306
|
-
0 && (module.exports = {
|
|
307
|
-
Metrics
|
|
308
|
-
});
|
|
309
|
-
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/metrics/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * External dependencies\n */\nimport type { Page, Browser } from '@playwright/test';\nimport { join } from 'path';\n// resolution-mode support in TypeScript 5.3 will resolve this.\n// See https://devblogs.microsoft.com/typescript/announcing-typescript-5-3-beta/\n// @ts-expect-error\nimport type { Metric } from 'web-vitals';\n\ntype EventType =\n\t| 'click'\n\t| 'focus'\n\t| 'focusin'\n\t| 'keydown'\n\t| 'keypress'\n\t| 'keyup'\n\t| 'mouseout'\n\t| 'mouseover';\n\ninterface TraceEvent {\n\tcat: string;\n\tname: string;\n\tdur?: number;\n\targs: {\n\t\tdata?: {\n\t\t\ttype: EventType;\n\t\t};\n\t};\n}\n\ninterface Trace {\n\ttraceEvents: TraceEvent[];\n}\n\ntype MetricsConstructorProps = {\n\tpage: Page;\n};\n\ninterface WebVitalsMeasurements {\n\tCLS?: number;\n\tFCP?: number;\n\tFID?: number;\n\tINP?: number;\n\tLCP?: number;\n\tTTFB?: number;\n}\n\nexport class Metrics {\n\tbrowser: Browser;\n\tpage: Page;\n\ttrace: Trace;\n\n\twebVitals: WebVitalsMeasurements = {};\n\n\tconstructor( { page }: MetricsConstructorProps ) {\n\t\tthis.page = page;\n\t\tthis.browser = page.context().browser()!;\n\t\tthis.trace = { traceEvents: [] };\n\t}\n\n\t/**\n\t * Returns durations from the Server-Timing header.\n\t *\n\t * @param fields Optional fields to filter.\n\t */\n\tasync getServerTiming( fields: string[] = [] ) {\n\t\treturn this.page.evaluate< Record< string, number >, string[] >(\n\t\t\t( f: string[] ) =>\n\t\t\t\t(\n\t\t\t\t\tperformance.getEntriesByType(\n\t\t\t\t\t\t'navigation'\n\t\t\t\t\t) as PerformanceNavigationTiming[]\n\t\t\t\t )[ 0 ].serverTiming.reduce(\n\t\t\t\t\t( acc, entry ) => {\n\t\t\t\t\t\tif ( f.length === 0 || f.includes( entry.name ) ) {\n\t\t\t\t\t\t\tacc[ entry.name ] = entry.duration;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn acc;\n\t\t\t\t\t},\n\t\t\t\t\t{} as Record< string, number >\n\t\t\t\t),\n\t\t\tfields\n\t\t);\n\t}\n\n\t/**\n\t * Returns time to first byte (TTFB) using the Navigation Timing API.\n\t *\n\t * @see https://web.dev/ttfb/#measure-ttfb-in-javascript\n\t *\n\t * @return TTFB value.\n\t */\n\tasync getTimeToFirstByte() {\n\t\treturn await this.page.evaluate< number >( () => {\n\t\t\tconst { responseStart, startTime } = (\n\t\t\t\tperformance.getEntriesByType(\n\t\t\t\t\t'navigation'\n\t\t\t\t) as PerformanceNavigationTiming[]\n\t\t\t )[ 0 ];\n\t\t\treturn responseStart - startTime;\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the Largest Contentful Paint (LCP) value using the dedicated API.\n\t *\n\t * @see https://w3c.github.io/largest-contentful-paint/\n\t * @see https://web.dev/lcp/#measure-lcp-in-javascript\n\t *\n\t * @return LCP value.\n\t */\n\tasync getLargestContentfulPaint() {\n\t\treturn await this.page.evaluate< number >(\n\t\t\t() =>\n\t\t\t\tnew Promise( ( resolve ) => {\n\t\t\t\t\tnew PerformanceObserver( ( entryList ) => {\n\t\t\t\t\t\tconst entries = entryList.getEntries();\n\t\t\t\t\t\t// The last entry is the largest contentful paint.\n\t\t\t\t\t\tconst largestPaintEntry = entries.at( -1 );\n\n\t\t\t\t\t\tresolve( largestPaintEntry?.startTime || 0 );\n\t\t\t\t\t} ).observe( {\n\t\t\t\t\t\ttype: 'largest-contentful-paint',\n\t\t\t\t\t\tbuffered: true,\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t);\n\t}\n\n\t/**\n\t * Returns the Cumulative Layout Shift (CLS) value using the dedicated API.\n\t *\n\t * @see https://github.com/WICG/layout-instability\n\t * @see https://web.dev/cls/#measure-layout-shifts-in-javascript\n\t *\n\t * @return CLS value.\n\t */\n\tasync getCumulativeLayoutShift() {\n\t\treturn await this.page.evaluate< number >(\n\t\t\t() =>\n\t\t\t\tnew Promise( ( resolve ) => {\n\t\t\t\t\tlet CLS = 0;\n\n\t\t\t\t\tnew PerformanceObserver( ( l ) => {\n\t\t\t\t\t\tconst entries = l.getEntries() as LayoutShift[];\n\n\t\t\t\t\t\tentries.forEach( ( entry ) => {\n\t\t\t\t\t\t\tif ( ! entry.hadRecentInput ) {\n\t\t\t\t\t\t\t\tCLS += entry.value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\tresolve( CLS );\n\t\t\t\t\t} ).observe( {\n\t\t\t\t\t\ttype: 'layout-shift',\n\t\t\t\t\t\tbuffered: true,\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t);\n\t}\n\n\t/**\n\t * Returns the loading durations using the Navigation Timing API. All the\n\t * durations exclude the server response time.\n\t *\n\t * @return Object with loading metrics durations.\n\t */\n\tasync getLoadingDurations() {\n\t\treturn await this.page.evaluate( () => {\n\t\t\tconst [\n\t\t\t\t{\n\t\t\t\t\trequestStart,\n\t\t\t\t\tresponseStart,\n\t\t\t\t\tresponseEnd,\n\t\t\t\t\tdomContentLoadedEventEnd,\n\t\t\t\t\tloadEventEnd,\n\t\t\t\t},\n\t\t\t] = performance.getEntriesByType(\n\t\t\t\t'navigation'\n\t\t\t) as PerformanceNavigationTiming[];\n\t\t\tconst paintTimings = performance.getEntriesByType(\n\t\t\t\t'paint'\n\t\t\t) as PerformancePaintTiming[];\n\n\t\t\tconst firstPaintStartTime = paintTimings.find(\n\t\t\t\t( { name } ) => name === 'first-paint'\n\t\t\t)!.startTime;\n\n\t\t\tconst firstContentfulPaintStartTime = paintTimings.find(\n\t\t\t\t( { name } ) => name === 'first-contentful-paint'\n\t\t\t)!.startTime;\n\n\t\t\treturn {\n\t\t\t\t// Server side metric.\n\t\t\t\tserverResponse: responseStart - requestStart,\n\t\t\t\t// For client side metrics, consider the end of the response (the\n\t\t\t\t// browser receives the HTML) as the start time (0).\n\t\t\t\tfirstPaint: firstPaintStartTime - responseEnd,\n\t\t\t\tdomContentLoaded: domContentLoadedEventEnd - responseEnd,\n\t\t\t\tloaded: loadEventEnd - responseEnd,\n\t\t\t\tfirstContentfulPaint:\n\t\t\t\t\tfirstContentfulPaintStartTime - responseEnd,\n\t\t\t\ttimeSinceResponseEnd: performance.now() - responseEnd,\n\t\t\t};\n\t\t} );\n\t}\n\n\t/**\n\t * Starts Chromium tracing with predefined options for performance testing.\n\t *\n\t * @param options Options to pass to `browser.startTracing()`.\n\t */\n\tasync startTracing( options = {} ) {\n\t\treturn await this.browser.startTracing( this.page, {\n\t\t\tscreenshots: false,\n\t\t\tcategories: [ 'devtools.timeline' ],\n\t\t\t...options,\n\t\t} );\n\t}\n\n\t/**\n\t * Stops Chromium tracing and saves the trace.\n\t */\n\tasync stopTracing() {\n\t\tconst traceBuffer = await this.browser.stopTracing();\n\t\tconst traceJSON = JSON.parse( traceBuffer.toString() );\n\n\t\tthis.trace = traceJSON;\n\t}\n\n\t/**\n\t * @return Durations of all traced `keydown`, `keypress`, and `keyup`\n\t * events.\n\t */\n\tgetTypingEventDurations() {\n\t\treturn [\n\t\t\tthis.getEventDurations( 'keydown' ),\n\t\t\tthis.getEventDurations( 'keypress' ),\n\t\t\tthis.getEventDurations( 'keyup' ),\n\t\t];\n\t}\n\n\t/**\n\t * @return Durations of all traced `focus` and `focusin` events.\n\t */\n\tgetSelectionEventDurations() {\n\t\treturn [\n\t\t\tthis.getEventDurations( 'focus' ),\n\t\t\tthis.getEventDurations( 'focusin' ),\n\t\t];\n\t}\n\n\t/**\n\t * @return Durations of all traced `click` events.\n\t */\n\tgetClickEventDurations() {\n\t\treturn [ this.getEventDurations( 'click' ) ];\n\t}\n\n\t/**\n\t * @return Durations of all traced `mouseover` and `mouseout` events.\n\t */\n\tgetHoverEventDurations() {\n\t\treturn [\n\t\t\tthis.getEventDurations( 'mouseover' ),\n\t\t\tthis.getEventDurations( 'mouseout' ),\n\t\t];\n\t}\n\n\t/**\n\t * @param eventType Type of event to filter.\n\t * @return Durations of all events of a given type.\n\t */\n\tgetEventDurations( eventType: EventType ) {\n\t\tif ( this.trace.traceEvents.length === 0 ) {\n\t\t\tthrow new Error(\n\t\t\t\t'No trace events found. Did you forget to call stopTracing()?'\n\t\t\t);\n\t\t}\n\n\t\treturn this.trace.traceEvents\n\t\t\t.filter(\n\t\t\t\t( item: TraceEvent ): boolean =>\n\t\t\t\t\titem.cat === 'devtools.timeline' &&\n\t\t\t\t\titem.name === 'EventDispatch' &&\n\t\t\t\t\titem?.args?.data?.type === eventType &&\n\t\t\t\t\t!! item.dur\n\t\t\t)\n\t\t\t.map( ( item ) => ( item.dur ? item.dur / 1000 : 0 ) );\n\t}\n\n\t/**\n\t * Initializes the web-vitals library upon next page navigation.\n\t *\n\t * Defaults to automatically triggering the navigation,\n\t * but it can also be done manually.\n\t *\n\t * @example\n\t * ```js\n\t * await metrics.initWebVitals();\n\t * console.log( await metrics.getWebVitals() );\n\t * ```\n\t *\n\t * @example\n\t * ```js\n\t * await metrics.initWebVitals( false );\n\t * await page.goto( '/some-other-page' );\n\t * console.log( await metrics.getWebVitals() );\n\t * ```\n\t *\n\t * @param reload Whether to force navigation by reloading the current page.\n\t */\n\tasync initWebVitals( reload = true ) {\n\t\tawait this.page.addInitScript( {\n\t\t\tpath: join(\n\t\t\t\t__dirname,\n\t\t\t\t'../../../../node_modules/web-vitals/dist/web-vitals.umd.cjs'\n\t\t\t),\n\t\t} );\n\n\t\tawait this.page.exposeFunction(\n\t\t\t'__reportVitals__',\n\t\t\t( data: string ) => {\n\t\t\t\tconst measurement: Metric = JSON.parse( data );\n\t\t\t\tthis.webVitals[ measurement.name ] = measurement.value;\n\t\t\t}\n\t\t);\n\n\t\tawait this.page.addInitScript( () => {\n\t\t\tconst reportVitals = ( measurement: unknown ) =>\n\t\t\t\twindow.__reportVitals__( JSON.stringify( measurement ) );\n\n\t\t\twindow.addEventListener( 'DOMContentLoaded', () => {\n\t\t\t\t// @ts-expect-error This is valid but web-vitals does not register the global types.\n\t\t\t\twindow.webVitals.onCLS( reportVitals );\n\t\t\t\t// @ts-expect-error This is valid but web-vitals does not register the global types.\n\t\t\t\twindow.webVitals.onFCP( reportVitals );\n\t\t\t\t// @ts-expect-error This is valid but web-vitals does not register the global types.\n\t\t\t\twindow.webVitals.onFID( reportVitals );\n\t\t\t\t// @ts-expect-error This is valid but web-vitals does not register the global types.\n\t\t\t\twindow.webVitals.onINP( reportVitals );\n\t\t\t\t// @ts-expect-error This is valid but web-vitals does not register the global types.\n\t\t\t\twindow.webVitals.onLCP( reportVitals );\n\t\t\t\t// @ts-expect-error This is valid but web-vitals does not register the global types.\n\t\t\t\twindow.webVitals.onTTFB( reportVitals );\n\t\t\t} );\n\t\t} );\n\n\t\tif ( reload ) {\n\t\t\t// By reloading the page the script will be applied.\n\t\t\tawait this.page.reload();\n\t\t}\n\t}\n\n\t/**\n\t * Returns web vitals as collected by the web-vitals library.\n\t *\n\t * If the web-vitals library hasn't been loaded on the current page yet,\n\t * it will be initialized with a page reload.\n\t *\n\t * Reloads the page to force web-vitals to report all collected metrics.\n\t *\n\t * @return {WebVitalsMeasurements} Web vitals measurements.\n\t */\n\tasync getWebVitals() {\n\t\t// Reset values.\n\t\tthis.webVitals = {};\n\n\t\tconst hasScript = await this.page.evaluate(\n\t\t\t// @ts-expect-error This is valid but web-vitals does not register the global types.\n\t\t\t() => typeof window.webVitals !== 'undefined'\n\t\t);\n\n\t\tif ( ! hasScript ) {\n\t\t\tawait this.initWebVitals();\n\t\t}\n\n\t\t// Trigger navigation so the web-vitals library reports values on unload.\n\t\tawait this.page.reload();\n\n\t\treturn this.webVitals;\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// packages/e2e-test-utils-playwright/src/page-utils/drag-files.ts
|
|
21
|
-
var drag_files_exports = {};
|
|
22
|
-
__export(drag_files_exports, {
|
|
23
|
-
dragFiles: () => dragFiles
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(drag_files_exports);
|
|
26
|
-
var import_promises = require("fs/promises");
|
|
27
|
-
var import_path = require("path");
|
|
28
|
-
var import_mime = require("mime");
|
|
29
|
-
async function dragFiles(files) {
|
|
30
|
-
const filesList = Array.isArray(files) ? files : [files];
|
|
31
|
-
const fileObjects = await Promise.all(
|
|
32
|
-
filesList.map(async (filePathOrObject) => {
|
|
33
|
-
if (typeof filePathOrObject !== "string") {
|
|
34
|
-
return {
|
|
35
|
-
name: filePathOrObject.name,
|
|
36
|
-
mimeType: filePathOrObject.mimeType || (0, import_mime.getType)(filePathOrObject.name),
|
|
37
|
-
base64: filePathOrObject.buffer.toString("base64")
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
const base64 = await (0, import_promises.readFile)(filePathOrObject, "base64");
|
|
41
|
-
const name = (0, import_path.basename)(filePathOrObject);
|
|
42
|
-
return {
|
|
43
|
-
name,
|
|
44
|
-
mimeType: (0, import_mime.getType)(filePathOrObject),
|
|
45
|
-
base64
|
|
46
|
-
};
|
|
47
|
-
})
|
|
48
|
-
);
|
|
49
|
-
const dragData = {
|
|
50
|
-
items: fileObjects.map((fileObject) => ({
|
|
51
|
-
mimeType: fileObject.mimeType ?? "File",
|
|
52
|
-
data: fileObject.base64
|
|
53
|
-
})),
|
|
54
|
-
files: fileObjects.map((fileObject) => fileObject.name),
|
|
55
|
-
// Copy = 1, Link = 2, Move = 16.
|
|
56
|
-
dragOperationsMask: 1
|
|
57
|
-
};
|
|
58
|
-
const cdpSession = await this.context.newCDPSession(this.page);
|
|
59
|
-
const position = {
|
|
60
|
-
x: 0,
|
|
61
|
-
y: 0
|
|
62
|
-
};
|
|
63
|
-
return {
|
|
64
|
-
/**
|
|
65
|
-
* Drag the files over an element (fires `dragenter` and `dragover` events).
|
|
66
|
-
*
|
|
67
|
-
* @param selectorOrLocator A selector or a locator to search for an element.
|
|
68
|
-
* @param options The optional options.
|
|
69
|
-
* @param options.position A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the element.
|
|
70
|
-
*/
|
|
71
|
-
dragOver: async (selectorOrLocator, options = {}) => {
|
|
72
|
-
const locator = typeof selectorOrLocator === "string" ? this.page.locator(selectorOrLocator) : selectorOrLocator;
|
|
73
|
-
const boundingBox = await locator.boundingBox();
|
|
74
|
-
if (!boundingBox) {
|
|
75
|
-
throw new Error(
|
|
76
|
-
"Cannot find the element or the element is not visible on the viewport."
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
position.x = boundingBox.x + (options.position?.x ?? boundingBox.width / 2);
|
|
80
|
-
position.y = boundingBox.y + (options.position?.y ?? boundingBox.height / 2);
|
|
81
|
-
await cdpSession.send("Input.dispatchDragEvent", {
|
|
82
|
-
type: "dragEnter",
|
|
83
|
-
...position,
|
|
84
|
-
data: dragData
|
|
85
|
-
});
|
|
86
|
-
await cdpSession.send("Input.dispatchDragEvent", {
|
|
87
|
-
type: "dragOver",
|
|
88
|
-
...position,
|
|
89
|
-
data: dragData
|
|
90
|
-
});
|
|
91
|
-
},
|
|
92
|
-
/**
|
|
93
|
-
* Drop the files at the current position.
|
|
94
|
-
*/
|
|
95
|
-
drop: async () => {
|
|
96
|
-
const topMostElement = await this.page.evaluateHandle(
|
|
97
|
-
({ x, y }) => {
|
|
98
|
-
const element = document.elementFromPoint(x, y);
|
|
99
|
-
if (element instanceof HTMLIFrameElement) {
|
|
100
|
-
const offsetBox = element.getBoundingClientRect();
|
|
101
|
-
return element.contentDocument.elementFromPoint(
|
|
102
|
-
x - offsetBox.x,
|
|
103
|
-
y - offsetBox.y
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
return element;
|
|
107
|
-
},
|
|
108
|
-
position
|
|
109
|
-
);
|
|
110
|
-
const elementHandle = topMostElement.asElement();
|
|
111
|
-
if (!elementHandle) {
|
|
112
|
-
throw new Error("Element not found.");
|
|
113
|
-
}
|
|
114
|
-
const dataTransfer = await elementHandle.evaluateHandle(
|
|
115
|
-
async (_node, _fileObjects) => {
|
|
116
|
-
const dt = new DataTransfer();
|
|
117
|
-
const fileInstances = await Promise.all(
|
|
118
|
-
_fileObjects.map(async (fileObject) => {
|
|
119
|
-
const blob = await fetch(
|
|
120
|
-
`data:${fileObject.mimeType};base64,${fileObject.base64}`
|
|
121
|
-
).then((res) => res.blob());
|
|
122
|
-
return new File([blob], fileObject.name, {
|
|
123
|
-
type: fileObject.mimeType ?? void 0
|
|
124
|
-
});
|
|
125
|
-
})
|
|
126
|
-
);
|
|
127
|
-
fileInstances.forEach((file) => {
|
|
128
|
-
dt.items.add(file);
|
|
129
|
-
});
|
|
130
|
-
return dt;
|
|
131
|
-
},
|
|
132
|
-
fileObjects
|
|
133
|
-
);
|
|
134
|
-
await elementHandle.dispatchEvent("drop", { dataTransfer });
|
|
135
|
-
await cdpSession.detach();
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
140
|
-
0 && (module.exports = {
|
|
141
|
-
dragFiles
|
|
142
|
-
});
|
|
143
|
-
//# sourceMappingURL=drag-files.cjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/page-utils/drag-files.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * External dependencies\n */\nimport { readFile } from 'fs/promises';\nimport { basename } from 'path';\nimport { getType } from 'mime';\n\n/**\n * Internal dependencies\n */\nimport type { PageUtils } from './index';\nimport type { Locator } from '@playwright/test';\n\ntype FileObject = {\n\tname: string;\n\tmimeType?: string;\n\tbuffer: Buffer;\n};\n\ntype Options = {\n\tposition?: { x: number; y: number };\n};\n\n/**\n * Simulate dragging files from outside the current page.\n *\n * @param this\n * @param files The files to be dragged.\n * @return The methods of the drag operation.\n */\nasync function dragFiles(\n\tthis: PageUtils,\n\tfiles: string | string[] | FileObject | FileObject[]\n) {\n\tconst filesList = Array.isArray( files ) ? files : [ files ];\n\tconst fileObjects = await Promise.all(\n\t\tfilesList.map( async ( filePathOrObject ) => {\n\t\t\tif ( typeof filePathOrObject !== 'string' ) {\n\t\t\t\treturn {\n\t\t\t\t\tname: filePathOrObject.name,\n\t\t\t\t\tmimeType:\n\t\t\t\t\t\tfilePathOrObject.mimeType ||\n\t\t\t\t\t\tgetType( filePathOrObject.name ),\n\t\t\t\t\tbase64: filePathOrObject.buffer.toString( 'base64' ),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst base64 = await readFile( filePathOrObject, 'base64' );\n\t\t\tconst name = basename( filePathOrObject );\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\tmimeType: getType( filePathOrObject ),\n\t\t\t\tbase64,\n\t\t\t};\n\t\t} )\n\t);\n\n\t// CDP doesn't actually support dragging files, this is only a _good enough_\n\t// dummy data so that it will correctly send the relevant events.\n\tconst dragData = {\n\t\titems: fileObjects.map( ( fileObject ) => ( {\n\t\t\tmimeType: fileObject.mimeType ?? 'File',\n\t\t\tdata: fileObject.base64,\n\t\t} ) ),\n\t\tfiles: fileObjects.map( ( fileObject ) => fileObject.name ),\n\t\t// Copy = 1, Link = 2, Move = 16.\n\t\tdragOperationsMask: 1,\n\t};\n\n\tconst cdpSession = await this.context.newCDPSession( this.page );\n\n\tconst position = {\n\t\tx: 0,\n\t\ty: 0,\n\t};\n\n\treturn {\n\t\t/**\n\t\t * Drag the files over an element (fires `dragenter` and `dragover` events).\n\t\t *\n\t\t * @param selectorOrLocator A selector or a locator to search for an element.\n\t\t * @param options The optional options.\n\t\t * @param options.position A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the element.\n\t\t */\n\t\tdragOver: async (\n\t\t\tselectorOrLocator: string | Locator,\n\t\t\toptions: Options = {}\n\t\t) => {\n\t\t\tconst locator =\n\t\t\t\ttypeof selectorOrLocator === 'string'\n\t\t\t\t\t? this.page.locator( selectorOrLocator )\n\t\t\t\t\t: selectorOrLocator;\n\t\t\tconst boundingBox = await locator.boundingBox();\n\n\t\t\tif ( ! boundingBox ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Cannot find the element or the element is not visible on the viewport.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tposition.x =\n\t\t\t\tboundingBox.x +\n\t\t\t\t( options.position?.x ?? boundingBox.width / 2 );\n\t\t\tposition.y =\n\t\t\t\tboundingBox.y +\n\t\t\t\t( options.position?.y ?? boundingBox.height / 2 );\n\n\t\t\tawait cdpSession.send( 'Input.dispatchDragEvent', {\n\t\t\t\ttype: 'dragEnter',\n\t\t\t\t...position,\n\t\t\t\tdata: dragData,\n\t\t\t} );\n\t\t\tawait cdpSession.send( 'Input.dispatchDragEvent', {\n\t\t\t\ttype: 'dragOver',\n\t\t\t\t...position,\n\t\t\t\tdata: dragData,\n\t\t\t} );\n\t\t},\n\n\t\t/**\n\t\t * Drop the files at the current position.\n\t\t */\n\t\tdrop: async () => {\n\t\t\tconst topMostElement = await this.page.evaluateHandle(\n\t\t\t\t( { x, y } ) => {\n\t\t\t\t\tconst element = document.elementFromPoint( x, y );\n\t\t\t\t\tif ( element instanceof HTMLIFrameElement ) {\n\t\t\t\t\t\tconst offsetBox = element.getBoundingClientRect();\n\t\t\t\t\t\treturn element.contentDocument!.elementFromPoint(\n\t\t\t\t\t\t\tx - offsetBox.x,\n\t\t\t\t\t\t\ty - offsetBox.y\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn element;\n\t\t\t\t},\n\t\t\t\tposition\n\t\t\t);\n\t\t\tconst elementHandle = topMostElement.asElement();\n\n\t\t\tif ( ! elementHandle ) {\n\t\t\t\tthrow new Error( 'Element not found.' );\n\t\t\t}\n\n\t\t\tconst dataTransfer = await elementHandle.evaluateHandle(\n\t\t\t\tasync ( _node, _fileObjects ) => {\n\t\t\t\t\tconst dt = new DataTransfer();\n\t\t\t\t\tconst fileInstances = await Promise.all(\n\t\t\t\t\t\t_fileObjects.map( async ( fileObject: any ) => {\n\t\t\t\t\t\t\tconst blob = await fetch(\n\t\t\t\t\t\t\t\t`data:${ fileObject.mimeType };base64,${ fileObject.base64 }`\n\t\t\t\t\t\t\t).then( ( res ) => res.blob() );\n\t\t\t\t\t\t\treturn new File( [ blob ], fileObject.name, {\n\t\t\t\t\t\t\t\ttype: fileObject.mimeType ?? undefined,\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t\tfileInstances.forEach( ( file ) => {\n\t\t\t\t\t\tdt.items.add( file );\n\t\t\t\t\t} );\n\n\t\t\t\t\treturn dt;\n\t\t\t\t},\n\t\t\t\tfileObjects\n\t\t\t);\n\n\t\t\tawait elementHandle.dispatchEvent( 'drop', { dataTransfer } );\n\n\t\t\tawait cdpSession.detach();\n\t\t},\n\t};\n}\n\nexport { dragFiles };\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// packages/e2e-test-utils-playwright/src/page-utils/emulate-network-conditions.ts
|
|
21
|
-
var emulate_network_conditions_exports = {};
|
|
22
|
-
__export(emulate_network_conditions_exports, {
|
|
23
|
-
emulateNetworkConditions: () => emulateNetworkConditions
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(emulate_network_conditions_exports);
|
|
26
|
-
var PredefinedNetworkConditions = {
|
|
27
|
-
// Generally aligned with DevTools
|
|
28
|
-
// https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.ts;l=398;drc=225e1240f522ca684473f541ae6dae6cd766dd33.
|
|
29
|
-
"Slow 3G": {
|
|
30
|
-
offline: false,
|
|
31
|
-
// ~500Kbps down
|
|
32
|
-
downloadThroughput: 500 * 1e3 / 8 * 0.8,
|
|
33
|
-
// ~500Kbps up
|
|
34
|
-
uploadThroughput: 500 * 1e3 / 8 * 0.8,
|
|
35
|
-
// 400ms RTT
|
|
36
|
-
latency: 400 * 5
|
|
37
|
-
},
|
|
38
|
-
"Fast 3G": {
|
|
39
|
-
offline: false,
|
|
40
|
-
// ~1.6 Mbps down
|
|
41
|
-
downloadThroughput: 1.6 * 1e3 * 1e3 / 8 * 0.9,
|
|
42
|
-
// ~0.75 Mbps up
|
|
43
|
-
uploadThroughput: 750 * 1e3 / 8 * 0.9,
|
|
44
|
-
// 150ms RTT
|
|
45
|
-
latency: 150 * 3.75
|
|
46
|
-
},
|
|
47
|
-
// alias to Fast 3G to align with Lighthouse (crbug.com/342406608)
|
|
48
|
-
// and DevTools (crbug.com/342406608),
|
|
49
|
-
"Slow 4G": {
|
|
50
|
-
offline: false,
|
|
51
|
-
// ~1.6 Mbps down
|
|
52
|
-
downloadThroughput: 1.6 * 1e3 * 1e3 / 8 * 0.9,
|
|
53
|
-
// ~0.75 Mbps up
|
|
54
|
-
uploadThroughput: 750 * 1e3 / 8 * 0.9,
|
|
55
|
-
// 150ms RTT
|
|
56
|
-
latency: 150 * 3.75
|
|
57
|
-
},
|
|
58
|
-
"Fast 4G": {
|
|
59
|
-
offline: false,
|
|
60
|
-
// 9 Mbps down
|
|
61
|
-
downloadThroughput: 9 * 1e3 * 1e3 / 8 * 0.9,
|
|
62
|
-
// 1.5 Mbps up
|
|
63
|
-
uploadThroughput: 1.5 * 1e3 * 1e3 / 8 * 0.9,
|
|
64
|
-
// 60ms RTT
|
|
65
|
-
latency: 60 * 2.75
|
|
66
|
-
},
|
|
67
|
-
/**
|
|
68
|
-
* Network conditions used for desktop in Lighthouse/PSI.
|
|
69
|
-
*
|
|
70
|
-
* 10,240 kb/s throughput with 40 ms TCP RTT.
|
|
71
|
-
*
|
|
72
|
-
* @see https://github.com/paulirish/lighthouse/blob/f0855904aaffaecf3089169449646960782d7e92/core/config/constants.js#L40-L49
|
|
73
|
-
* @see https://docs.google.com/document/d/1-p4HSp42REEA5-jCBVB6PqQcVhI1nQIblBCNKhPJUXg/edit?tab=t.0#heading=h.jsap7yf4phk6
|
|
74
|
-
*/
|
|
75
|
-
Broadband: {
|
|
76
|
-
offline: false,
|
|
77
|
-
downloadThroughput: 10240 * 1e3 / 8,
|
|
78
|
-
uploadThroughput: 10240 * 1e3 / 8,
|
|
79
|
-
latency: 40
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
async function emulateNetworkConditions(condition) {
|
|
83
|
-
if ("chromium" !== this.browserName) {
|
|
84
|
-
throw new Error(
|
|
85
|
-
"CDP sessions are only supported on Chromium-based browsers"
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
const session = await this.page.context().newCDPSession(this.page);
|
|
89
|
-
await session.send(
|
|
90
|
-
"Network.emulateNetworkConditions",
|
|
91
|
-
"string" === typeof condition ? PredefinedNetworkConditions[condition] : condition
|
|
92
|
-
);
|
|
93
|
-
await session.detach();
|
|
94
|
-
}
|
|
95
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
96
|
-
0 && (module.exports = {
|
|
97
|
-
emulateNetworkConditions
|
|
98
|
-
});
|
|
99
|
-
//# sourceMappingURL=emulate-network-conditions.cjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/page-utils/emulate-network-conditions.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Internal dependencies\n */\nimport type { PageUtils } from './';\n\ninterface NetworkConditions {\n\t/**\n\t * True to emulate internet disconnection.\n\t */\n\toffline: boolean;\n\t/**\n\t * Minimum latency from request sent to response headers received (ms).\n\t */\n\tlatency: number;\n\t/**\n\t * Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.\n\t */\n\tdownloadThroughput: number;\n\t/**\n\t * Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.\n\t */\n\tuploadThroughput: number;\n}\n\n// Defaults from https://github.com/puppeteer/puppeteer/blob/401355610874beac23a51dcb75739a4bb4191a2b/packages/puppeteer-core/src/cdp/PredefinedNetworkConditions.ts.\nconst PredefinedNetworkConditions: Record< string, NetworkConditions > = {\n\t// Generally aligned with DevTools\n\t// https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.ts;l=398;drc=225e1240f522ca684473f541ae6dae6cd766dd33.\n\t'Slow 3G': {\n\t\toffline: false,\n\t\t// ~500Kbps down\n\t\tdownloadThroughput: ( ( 500 * 1000 ) / 8 ) * 0.8,\n\t\t// ~500Kbps up\n\t\tuploadThroughput: ( ( 500 * 1000 ) / 8 ) * 0.8,\n\t\t// 400ms RTT\n\t\tlatency: 400 * 5,\n\t},\n\t'Fast 3G': {\n\t\toffline: false,\n\t\t// ~1.6 Mbps down\n\t\tdownloadThroughput: ( ( 1.6 * 1000 * 1000 ) / 8 ) * 0.9,\n\t\t// ~0.75 Mbps up\n\t\tuploadThroughput: ( ( 750 * 1000 ) / 8 ) * 0.9,\n\t\t// 150ms RTT\n\t\tlatency: 150 * 3.75,\n\t},\n\t// alias to Fast 3G to align with Lighthouse (crbug.com/342406608)\n\t// and DevTools (crbug.com/342406608),\n\t'Slow 4G': {\n\t\toffline: false,\n\t\t// ~1.6 Mbps down\n\t\tdownloadThroughput: ( ( 1.6 * 1000 * 1000 ) / 8 ) * 0.9,\n\t\t// ~0.75 Mbps up\n\t\tuploadThroughput: ( ( 750 * 1000 ) / 8 ) * 0.9,\n\t\t// 150ms RTT\n\t\tlatency: 150 * 3.75,\n\t},\n\t'Fast 4G': {\n\t\toffline: false,\n\t\t// 9 Mbps down\n\t\tdownloadThroughput: ( ( 9 * 1000 * 1000 ) / 8 ) * 0.9,\n\t\t// 1.5 Mbps up\n\t\tuploadThroughput: ( ( 1.5 * 1000 * 1000 ) / 8 ) * 0.9,\n\t\t// 60ms RTT\n\t\tlatency: 60 * 2.75,\n\t},\n\t/**\n\t * Network conditions used for desktop in Lighthouse/PSI.\n\t *\n\t * 10,240 kb/s throughput with 40 ms TCP RTT.\n\t *\n\t * @see https://github.com/paulirish/lighthouse/blob/f0855904aaffaecf3089169449646960782d7e92/core/config/constants.js#L40-L49\n\t * @see https://docs.google.com/document/d/1-p4HSp42REEA5-jCBVB6PqQcVhI1nQIblBCNKhPJUXg/edit?tab=t.0#heading=h.jsap7yf4phk6\n\t */\n\tBroadband: {\n\t\toffline: false,\n\t\tdownloadThroughput: ( 10240 * 1000 ) / 8,\n\t\tuploadThroughput: ( 10240 * 1000 ) / 8,\n\t\tlatency: 40,\n\t},\n};\n\nexport async function emulateNetworkConditions(\n\tthis: PageUtils,\n\tcondition: keyof typeof PredefinedNetworkConditions | NetworkConditions\n) {\n\tif ( 'chromium' !== this.browserName ) {\n\t\tthrow new Error(\n\t\t\t'CDP sessions are only supported on Chromium-based browsers'\n\t\t);\n\t}\n\n\tconst session = await this.page.context().newCDPSession( this.page );\n\tawait session.send(\n\t\t'Network.emulateNetworkConditions',\n\t\t'string' === typeof condition\n\t\t\t? PredefinedNetworkConditions[ condition ]\n\t\t\t: condition\n\t);\n\tawait session.detach();\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBA,IAAM,8BAAmE;AAAA;AAAA;AAAA,EAGxE,WAAW;AAAA,IACV,SAAS;AAAA;AAAA,IAET,oBAAwB,MAAM,MAAS,IAAM;AAAA;AAAA,IAE7C,kBAAsB,MAAM,MAAS,IAAM;AAAA;AAAA,IAE3C,SAAS,MAAM;AAAA,EAChB;AAAA,EACA,WAAW;AAAA,IACV,SAAS;AAAA;AAAA,IAET,oBAAwB,MAAM,MAAO,MAAS,IAAM;AAAA;AAAA,IAEpD,kBAAsB,MAAM,MAAS,IAAM;AAAA;AAAA,IAE3C,SAAS,MAAM;AAAA,EAChB;AAAA;AAAA;AAAA,EAGA,WAAW;AAAA,IACV,SAAS;AAAA;AAAA,IAET,oBAAwB,MAAM,MAAO,MAAS,IAAM;AAAA;AAAA,IAEpD,kBAAsB,MAAM,MAAS,IAAM;AAAA;AAAA,IAE3C,SAAS,MAAM;AAAA,EAChB;AAAA,EACA,WAAW;AAAA,IACV,SAAS;AAAA;AAAA,IAET,oBAAwB,IAAI,MAAO,MAAS,IAAM;AAAA;AAAA,IAElD,kBAAsB,MAAM,MAAO,MAAS,IAAM;AAAA;AAAA,IAElD,SAAS,KAAK;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW;AAAA,IACV,SAAS;AAAA,IACT,oBAAsB,QAAQ,MAAS;AAAA,IACvC,kBAAoB,QAAQ,MAAS;AAAA,IACrC,SAAS;AAAA,EACV;AACD;AAEA,eAAsB,yBAErB,WACC;AACD,MAAK,eAAe,KAAK,aAAc;AACtC,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAEA,QAAM,UAAU,MAAM,KAAK,KAAK,QAAQ,EAAE,cAAe,KAAK,IAAK;AACnE,QAAM,QAAQ;AAAA,IACb;AAAA,IACA,aAAa,OAAO,YACjB,4BAA6B,SAAU,IACvC;AAAA,EACJ;AACA,QAAM,QAAQ,OAAO;AACtB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|