@percy/core 1.0.0-beta.76 → 1.0.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/dist/network.js DELETED
@@ -1,365 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = exports.Network = void 0;
7
-
8
- var _logger = _interopRequireDefault(require("@percy/logger"));
9
-
10
- var _utils = require("./utils");
11
-
12
- var _discovery = require("./discovery");
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
-
16
- function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
17
-
18
- function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
19
-
20
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
21
-
22
- function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
23
-
24
- function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
25
-
26
- function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
27
-
28
- var _pending = /*#__PURE__*/new WeakMap();
29
-
30
- var _requests = /*#__PURE__*/new WeakMap();
31
-
32
- var _intercepts = /*#__PURE__*/new WeakMap();
33
-
34
- var _authentications = /*#__PURE__*/new WeakMap();
35
-
36
- // The Interceptor class creates common handlers for dealing with intercepting asset requests
37
- // for a given page using various devtools protocol events and commands.
38
- class Network {
39
- constructor(page, options) {
40
- var _options$networkIdleT, _options$requestHeade, _options$userAgent;
41
-
42
- _defineProperty(this, "log", (0, _logger.default)('core:network'));
43
-
44
- _classPrivateFieldInitSpec(this, _pending, {
45
- writable: true,
46
- value: new Map()
47
- });
48
-
49
- _classPrivateFieldInitSpec(this, _requests, {
50
- writable: true,
51
- value: new Map()
52
- });
53
-
54
- _classPrivateFieldInitSpec(this, _intercepts, {
55
- writable: true,
56
- value: new Map()
57
- });
58
-
59
- _classPrivateFieldInitSpec(this, _authentications, {
60
- writable: true,
61
- value: new Set()
62
- });
63
-
64
- _defineProperty(this, "_handleAuthRequired", async (session, event) => {
65
- var _this$authorization;
66
-
67
- let {
68
- username,
69
- password
70
- } = (_this$authorization = this.authorization) !== null && _this$authorization !== void 0 ? _this$authorization : {};
71
- let {
72
- requestId
73
- } = event;
74
- let response = 'Default';
75
-
76
- if (_classPrivateFieldGet(this, _authentications).has(requestId)) {
77
- response = 'CancelAuth';
78
- } else if (username || password) {
79
- response = 'ProvideCredentials';
80
-
81
- _classPrivateFieldGet(this, _authentications).add(requestId);
82
- }
83
-
84
- await session.send('Fetch.continueWithAuth', {
85
- requestId: event.requestId,
86
- authChallengeResponse: {
87
- response,
88
- username,
89
- password
90
- }
91
- });
92
- });
93
-
94
- _defineProperty(this, "_handleRequestPaused", async (session, event) => {
95
- let {
96
- networkId: requestId,
97
- requestId: interceptId,
98
- resourceType
99
- } = event;
100
-
101
- let pending = _classPrivateFieldGet(this, _pending).get(requestId);
102
-
103
- _classPrivateFieldGet(this, _pending).delete(requestId); // guard against redirects with the same requestId
104
-
105
-
106
- if ((pending === null || pending === void 0 ? void 0 : pending.request.url) === event.request.url && pending.request.method === event.request.method) {
107
- await this._handleRequest(session, { ...pending,
108
- resourceType,
109
- interceptId
110
- });
111
- } else {
112
- // track the session that intercepted the request
113
- _classPrivateFieldGet(this, _intercepts).set(requestId, { ...event,
114
- session
115
- });
116
- }
117
- });
118
-
119
- _defineProperty(this, "_handleRequestWillBeSent", async event => {
120
- let {
121
- requestId,
122
- request
123
- } = event; // do not handle data urls
124
-
125
- if (request.url.startsWith('data:')) return;
126
-
127
- if (this.interceptEnabled) {
128
- let intercept = _classPrivateFieldGet(this, _intercepts).get(requestId);
129
-
130
- _classPrivateFieldGet(this, _pending).set(requestId, event);
131
-
132
- if (intercept) {
133
- // handle the request with the session that intercepted it
134
- let {
135
- session,
136
- requestId: interceptId,
137
- resourceType
138
- } = intercept;
139
- await this._handleRequest(session, { ...event,
140
- resourceType,
141
- interceptId
142
- });
143
-
144
- _classPrivateFieldGet(this, _intercepts).delete(requestId);
145
- }
146
- }
147
- });
148
-
149
- _defineProperty(this, "_handleRequest", async (session, event) => {
150
- var _this$onRequest;
151
-
152
- let {
153
- request,
154
- requestId,
155
- interceptId,
156
- resourceType
157
- } = event;
158
- let redirectChain = []; // if handling a redirected request, associate the response and add to its redirect chain
159
-
160
- if (event.redirectResponse && _classPrivateFieldGet(this, _requests).has(requestId)) {
161
- let req = _classPrivateFieldGet(this, _requests).get(requestId);
162
-
163
- redirectChain = [...req.redirectChain, req]; // clean up interim requests
164
-
165
- this._forgetRequest(req, true);
166
- }
167
-
168
- request.type = resourceType;
169
- request.requestId = requestId;
170
- request.interceptId = interceptId;
171
- request.redirectChain = redirectChain;
172
-
173
- _classPrivateFieldGet(this, _requests).set(requestId, request);
174
-
175
- await ((_this$onRequest = this.onRequest) === null || _this$onRequest === void 0 ? void 0 : _this$onRequest.call(this, { ...request,
176
- // call to continue the request as-is
177
- continue: () => session.send('Fetch.continueRequest', {
178
- requestId: interceptId
179
- }),
180
- // call to respond with a specific status, content, and headers
181
- respond: ({
182
- status,
183
- content,
184
- headers
185
- }) => session.send('Fetch.fulfillRequest', {
186
- requestId: interceptId,
187
- responseCode: status || 200,
188
- body: Buffer.from(content).toString('base64'),
189
- responseHeaders: Object.entries(headers || {}).map(([name, value]) => {
190
- return {
191
- name: name.toLowerCase(),
192
- value: String(value)
193
- };
194
- })
195
- }),
196
- // call to fail or abort the request
197
- abort: error => session.send('Fetch.failRequest', {
198
- requestId: interceptId,
199
- // istanbul note: this check used to be necessary and might be again in the future if we
200
- // ever need to abort a request due to reasons other than failures
201
- errorReason: error ? 'Failed' :
202
- /* istanbul ignore next */
203
- 'Aborted'
204
- })
205
- }));
206
- });
207
-
208
- _defineProperty(this, "_handleResponseReceived", (session, event) => {
209
- let {
210
- requestId,
211
- response
212
- } = event;
213
-
214
- let request = _classPrivateFieldGet(this, _requests).get(requestId);
215
- /* istanbul ignore if: race condition paranioa */
216
-
217
-
218
- if (!request) return;
219
- request.response = response;
220
-
221
- request.response.buffer = async () => {
222
- let result = await session.send('Network.getResponseBody', {
223
- requestId
224
- });
225
- return Buffer.from(result.body, result.base64Encoded ? 'base64' : 'utf8');
226
- };
227
- });
228
-
229
- _defineProperty(this, "_handleEventSourceMessageReceived", event => {
230
- let request = _classPrivateFieldGet(this, _requests).get(event.requestId);
231
- /* istanbul ignore else: race condition paranioa */
232
-
233
-
234
- if (request) this._forgetRequest(request);
235
- });
236
-
237
- _defineProperty(this, "_handleLoadingFinished", async event => {
238
- var _this$onRequestFinish;
239
-
240
- let request = _classPrivateFieldGet(this, _requests).get(event.requestId);
241
- /* istanbul ignore if: race condition paranioa */
242
-
243
-
244
- if (!request) return;
245
- await ((_this$onRequestFinish = this.onRequestFinished) === null || _this$onRequestFinish === void 0 ? void 0 : _this$onRequestFinish.call(this, request));
246
-
247
- this._forgetRequest(request);
248
- });
249
-
250
- _defineProperty(this, "_handleLoadingFailed", async event => {
251
- var _this$onRequestFailed;
252
-
253
- let request = _classPrivateFieldGet(this, _requests).get(event.requestId);
254
- /* istanbul ignore if: race condition paranioa */
255
-
256
-
257
- if (!request) return;
258
- request.error = event.errorText;
259
- await ((_this$onRequestFailed = this.onRequestFailed) === null || _this$onRequestFailed === void 0 ? void 0 : _this$onRequestFailed.call(this, request));
260
-
261
- this._forgetRequest(request);
262
- });
263
-
264
- this.page = page;
265
- this.timeout = (_options$networkIdleT = options.networkIdleTimeout) !== null && _options$networkIdleT !== void 0 ? _options$networkIdleT : 100;
266
- this.authorization = options.authorization;
267
- this.requestHeaders = (_options$requestHeade = options.requestHeaders) !== null && _options$requestHeade !== void 0 ? _options$requestHeade : {};
268
- this.userAgent = (_options$userAgent = options.userAgent) !== null && _options$userAgent !== void 0 ? _options$userAgent : // by default, emulate a non-headless browser
269
- page.session.browser.version.userAgent.replace('Headless', '');
270
- this.interceptEnabled = !!options.intercept;
271
- this.meta = options.meta;
272
-
273
- if (this.interceptEnabled) {
274
- this.onRequest = (0, _discovery.createRequestHandler)(this, options.intercept);
275
- this.onRequestFinished = (0, _discovery.createRequestFinishedHandler)(this, options.intercept);
276
- this.onRequestFailed = (0, _discovery.createRequestFailedHandler)(this, options.intercept);
277
- }
278
- }
279
-
280
- watch(session) {
281
- session.on('Network.requestWillBeSent', this._handleRequestWillBeSent);
282
- session.on('Network.responseReceived', this._handleResponseReceived.bind(this, session));
283
- session.on('Network.eventSourceMessageReceived', this._handleEventSourceMessageReceived);
284
- session.on('Network.loadingFinished', this._handleLoadingFinished);
285
- session.on('Network.loadingFailed', this._handleLoadingFailed);
286
- let commands = [session.send('Network.enable'), session.send('Network.setBypassServiceWorker', {
287
- bypass: true
288
- }), session.send('Network.setCacheDisabled', {
289
- cacheDisabled: true
290
- }), session.send('Network.setUserAgentOverride', {
291
- userAgent: this.userAgent
292
- }), session.send('Network.setExtraHTTPHeaders', {
293
- headers: this.requestHeaders
294
- })];
295
-
296
- if (this.interceptEnabled && session.isDocument) {
297
- session.on('Fetch.requestPaused', this._handleRequestPaused.bind(this, session));
298
- session.on('Fetch.authRequired', this._handleAuthRequired.bind(this, session));
299
- commands.push(session.send('Fetch.enable', {
300
- handleAuthRequests: true,
301
- patterns: [{
302
- urlPattern: '*'
303
- }]
304
- }));
305
- }
306
-
307
- return Promise.all(commands);
308
- } // Resolves after the timeout when there are no more in-flight requests.
309
-
310
-
311
- async idle(filter = () => true, timeout = this.timeout) {
312
- let requests = [];
313
- this.log.debug(`Wait for ${timeout}ms idle`, this.meta);
314
- await (0, _utils.waitFor)(() => {
315
- if (this.page.session.closedReason) {
316
- throw new Error(`Network error: ${this.page.session.closedReason}`);
317
- }
318
-
319
- requests = Array.from(_classPrivateFieldGet(this, _requests).values()).filter(filter);
320
- return requests.length === 0;
321
- }, {
322
- timeout: Network.TIMEOUT,
323
- idle: timeout
324
- }).catch(error => {
325
- // throw a better timeout error
326
- if (error.message.startsWith('Timeout')) {
327
- let msg = 'Timed out waiting for network requests to idle.';
328
-
329
- if (this.log.shouldLog('debug')) {
330
- msg += `\n\n ${['Active requests:', ...requests.map(r => r.url)].join('\n - ')}\n`;
331
- }
332
-
333
- throw new Error(msg);
334
- } else {
335
- throw error;
336
- }
337
- });
338
- } // Called when a request should be removed from various trackers
339
-
340
-
341
- _forgetRequest({
342
- requestId,
343
- interceptId
344
- }, keepPending) {
345
- _classPrivateFieldGet(this, _requests).delete(requestId);
346
-
347
- _classPrivateFieldGet(this, _authentications).delete(interceptId);
348
-
349
- if (!keepPending) {
350
- _classPrivateFieldGet(this, _pending).delete(requestId);
351
-
352
- _classPrivateFieldGet(this, _intercepts).delete(requestId);
353
- }
354
- } // Called when a request requires authentication. Responds to the auth request with any
355
- // provided authorization credentials.
356
-
357
-
358
- }
359
-
360
- exports.Network = Network;
361
-
362
- _defineProperty(Network, "TIMEOUT", 30000);
363
-
364
- var _default = Network;
365
- exports.default = _default;
package/dist/page.js DELETED
@@ -1,293 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = exports.Page = void 0;
7
-
8
- var _fs = require("fs");
9
-
10
- var _logger = _interopRequireDefault(require("@percy/logger"));
11
-
12
- var _network = _interopRequireDefault(require("./network"));
13
-
14
- var _utils = require("./utils");
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
-
20
- class Page {
21
- constructor(_session, options) {
22
- var _options$enableJavaSc;
23
-
24
- _defineProperty(this, "log", (0, _logger.default)('core:page'));
25
-
26
- _defineProperty(this, "_handleAttachedToTarget", event => {
27
- let session = !event ? this.session : this.session.children.get(event.sessionId);
28
- /* istanbul ignore if: sanity check */
29
-
30
- if (!session) return;
31
- let commands = [this.network.watch(session)];
32
-
33
- if (session.isDocument) {
34
- session.on('Target.attachedToTarget', this._handleAttachedToTarget);
35
- commands.push(session.send('Page.enable'), session.send('Page.setLifecycleEventsEnabled', {
36
- enabled: true
37
- }), session.send('Security.setIgnoreCertificateErrors', {
38
- ignore: true
39
- }), session.send('Emulation.setScriptExecutionDisabled', {
40
- value: !this.enableJavaScript
41
- }), session.send('Target.setAutoAttach', {
42
- waitForDebuggerOnStart: false,
43
- autoAttach: true,
44
- flatten: true
45
- }));
46
- }
47
-
48
- return Promise.all(commands).catch(session._handleClosedError);
49
- });
50
-
51
- _defineProperty(this, "_handleExecutionContextCreated", event => {
52
- if (this.session.targetId === event.context.auxData.frameId) {
53
- this.contextId = event.context.id;
54
- }
55
- });
56
-
57
- _defineProperty(this, "_handleExecutionContextDestroyed", event => {
58
- /* istanbul ignore next: context cleared is usually called first */
59
- if (this.contextId === event.executionContextId) {
60
- this.contextId = null;
61
- }
62
- });
63
-
64
- _defineProperty(this, "_handleExecutionContextsCleared", () => {
65
- this.contextId = null;
66
- });
67
-
68
- this.session = _session;
69
- this.enableJavaScript = (_options$enableJavaSc = options.enableJavaScript) !== null && _options$enableJavaSc !== void 0 ? _options$enableJavaSc : true;
70
- this.network = new _network.default(this, options);
71
- this.meta = options.meta;
72
-
73
- _session.on('Runtime.executionContextCreated', this._handleExecutionContextCreated);
74
-
75
- _session.on('Runtime.executionContextDestroyed', this._handleExecutionContextDestroyed);
76
-
77
- _session.on('Runtime.executionContextsCleared', this._handleExecutionContextsCleared);
78
-
79
- _session.send('Runtime.enable').catch(_session._handleClosedError);
80
-
81
- this.log.debug('Page created');
82
- } // Close the page
83
-
84
-
85
- async close() {
86
- await this.session.close();
87
- this.log.debug('Page closed', this.meta);
88
- } // Resize the page to the specified width and height
89
-
90
-
91
- async resize({
92
- width,
93
- height
94
- }) {
95
- this.log.debug(`Resize page to ${width}x${height}`);
96
- await this.session.send('Emulation.setDeviceMetricsOverride', {
97
- deviceScaleFactor: 1,
98
- mobile: false,
99
- height,
100
- width
101
- });
102
- } // Go to a URL and wait for navigation to occur
103
-
104
-
105
- async goto(url, {
106
- waitUntil = 'load'
107
- } = {}) {
108
- this.log.debug(`Navigate to: ${url}`, this.meta);
109
-
110
- let navigate = async () => {
111
- // set cookies before navigation so we can default the domain to this hostname
112
- if (this.session.browser.cookies.length) {
113
- let defaultDomain = (0, _utils.hostname)(url);
114
- await this.session.send('Network.setCookies', {
115
- // spread is used to make a shallow copy of the cookie
116
- cookies: this.session.browser.cookies.map(({ ...cookie
117
- }) => {
118
- if (!cookie.url) cookie.domain || (cookie.domain = defaultDomain);
119
- return cookie;
120
- })
121
- });
122
- } // handle navigation errors
123
-
124
-
125
- let res = await this.session.send('Page.navigate', {
126
- url
127
- });
128
- if (res.errorText) throw new Error(res.errorText);
129
- };
130
-
131
- let handlers = [// wait until navigation and the correct lifecycle
132
- ['Page.frameNavigated', e => this.session.targetId === e.frame.id], ['Page.lifecycleEvent', e => this.session.targetId === e.frameId && e.name === waitUntil]].map(([name, cond]) => {
133
- let handler = e => cond(e) && (handler.finished = true) && handler.off();
134
-
135
- handler.off = () => this.session.off(name, handler);
136
-
137
- this.session.on(name, handler);
138
- return handler;
139
- });
140
-
141
- try {
142
- // trigger navigation and poll for handlers to have finished
143
- await Promise.all([navigate(), (0, _utils.waitFor)(() => {
144
- if (this.session.closedReason) {
145
- throw new Error(this.session.closedReason);
146
- }
147
-
148
- return handlers.every(handler => handler.finished);
149
- }, Page.TIMEOUT)]);
150
- } catch (error) {
151
- // remove handlers and modify the error message
152
- for (let handler of handlers) handler.off();
153
-
154
- throw Object.assign(error, {
155
- message: `Navigation failed: ${error.message}`
156
- });
157
- }
158
-
159
- this.log.debug('Page navigated', this.meta);
160
- } // Evaluate JS functions within the page's execution context
161
-
162
-
163
- async eval(fn, ...args) {
164
- let fnbody = fn.toString(); // we might have a function shorthand if this fails
165
-
166
- /* eslint-disable-next-line no-new, no-new-func */
167
-
168
- try {
169
- new Function(`(${fnbody})`);
170
- } catch (error) {
171
- fnbody = fnbody.startsWith('async ') ? fnbody.replace(/^async/, 'async function') : `function ${fnbody}`;
172
- /* eslint-disable-next-line no-new, no-new-func */
173
-
174
- try {
175
- new Function(`(${fnbody})`);
176
- } catch (error) {
177
- throw new Error('The provided function is not serializable');
178
- }
179
- } // wrap the function body with percy helpers
180
-
181
-
182
- fnbody = 'function withPercyHelpers() {\n' + [`return (${fnbody})({ generatePromise, waitFor }, ...arguments);`, `${_utils.generatePromise}`, `${_utils.waitFor}`].join('\n\n') + '}';
183
- /* istanbul ignore else: ironic. */
184
-
185
- if (fnbody.includes('cov_')) {
186
- // remove coverage statements during testing
187
- fnbody = fnbody.replace(/cov_.*?(;\n?|,)\s*/g, '');
188
- } // send the call function command
189
-
190
-
191
- let {
192
- result,
193
- exceptionDetails
194
- } = await this.session.send('Runtime.callFunctionOn', {
195
- functionDeclaration: fnbody,
196
- arguments: args.map(value => ({
197
- value
198
- })),
199
- executionContextId: this.contextId,
200
- returnByValue: true,
201
- awaitPromise: true,
202
- userGesture: true
203
- });
204
-
205
- if (exceptionDetails) {
206
- throw exceptionDetails.exception.description;
207
- } else {
208
- return result.value;
209
- }
210
- } // Evaluate one or more scripts in succession
211
-
212
-
213
- async evaluate(scripts) {
214
- var _scripts;
215
-
216
- scripts && (scripts = [].concat(scripts));
217
- if (!((_scripts = scripts) !== null && _scripts !== void 0 && _scripts.length)) return;
218
- this.log.debug('Evaluate JavaScript', { ...this.meta,
219
- scripts
220
- });
221
-
222
- for (let script of scripts) {
223
- if (typeof script === 'string') {
224
- script = `async eval() {\n${script}\n}`;
225
- }
226
-
227
- await this.eval(script);
228
- }
229
- } // Take a snapshot after waiting for any timeout, waiting for any selector, executing any scripts,
230
- // and waiting for the network idle
231
-
232
-
233
- async snapshot({
234
- name,
235
- waitForTimeout,
236
- waitForSelector,
237
- execute,
238
- ...options
239
- }) {
240
- this.log.debug(`Taking snapshot: ${name}`, this.meta); // wait for any specified timeout
241
-
242
- if (waitForTimeout) {
243
- this.log.debug(`Wait for ${waitForTimeout}ms timeout`, this.meta);
244
- await new Promise(resolve => setTimeout(resolve, waitForTimeout));
245
- } // wait for any specified selector
246
-
247
-
248
- if (waitForSelector) {
249
- this.log.debug(`Wait for selector: ${waitForSelector}`, this.meta);
250
- /* istanbul ignore next: no instrumenting injected code */
251
-
252
- await this.eval(function waitForSelector({
253
- waitFor
254
- }, selector, timeout) {
255
- return waitFor(() => !!document.querySelector(selector), timeout).catch(() => Promise.reject(new Error(`Failed to find "${selector}"`)));
256
- }, waitForSelector, Page.TIMEOUT);
257
- } // execute any javascript
258
-
259
-
260
- await this.evaluate(typeof execute === 'object' && !Array.isArray(execute) ? execute.beforeSnapshot : execute); // wait for any final network activity before capturing the dom snapshot
261
-
262
- await this.network.idle(); // inject @percy/dom for serialization by evaluating the file contents which adds a global
263
- // PercyDOM object that we can later check against
264
-
265
- /* istanbul ignore next: no instrumenting injected code */
266
-
267
- if (await this.eval(() => !window.PercyDOM)) {
268
- this.log.debug('Inject @percy/dom', this.meta);
269
- let script = await _fs.promises.readFile(require.resolve('@percy/dom'), 'utf-8');
270
- await this.eval(new Function(script));
271
- /* eslint-disable-line no-new-func */
272
- } // serialize and capture a DOM snapshot
273
-
274
-
275
- this.log.debug('Serialize DOM', this.meta);
276
- /* istanbul ignore next: no instrumenting injected code */
277
-
278
- return await this.eval((_, options) => ({
279
- /* eslint-disable-next-line no-undef */
280
- dom: PercyDOM.serialize(options),
281
- url: document.URL
282
- }), options);
283
- } // Initialize newly attached pages and iframes with page options
284
-
285
-
286
- }
287
-
288
- exports.Page = Page;
289
-
290
- _defineProperty(Page, "TIMEOUT", 30000);
291
-
292
- var _default = Page;
293
- exports.default = _default;