@memlab/e2e 1.0.21 → 1.0.23
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/lib/E2EUtils.d.ts +1 -1
- package/dist/lib/E2EUtils.js +41 -40
- package/package.json +1 -1
package/dist/lib/E2EUtils.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @format
|
|
8
8
|
* @oncall web_perf_infra
|
|
9
9
|
*/
|
|
10
|
-
import
|
|
10
|
+
import { AnyOptions, AnyValue, E2EOperation, E2EStepInfo, IE2EScenarioVisitPlan, IScenario, Nullable, OperationArgs } from '@memlab/core';
|
|
11
11
|
import type { CDPSession, Page } from 'puppeteer';
|
|
12
12
|
declare type ExceptionHandler = (ex: Error) => void;
|
|
13
13
|
declare function checkLastSnapshotChunk(chunk: string): void;
|
package/dist/lib/E2EUtils.js
CHANGED
|
@@ -21,15 +21,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
21
21
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
const fs_1 = __importDefault(require("fs"));
|
|
25
24
|
const core_1 = require("@memlab/core");
|
|
25
|
+
const fs_1 = __importDefault(require("fs"));
|
|
26
|
+
const core_2 = require("@memlab/core");
|
|
26
27
|
const BaseOperation_1 = __importDefault(require("./operations/BaseOperation"));
|
|
27
28
|
const InteractionUtils_1 = __importDefault(require("./operations/InteractionUtils"));
|
|
28
|
-
const
|
|
29
|
+
const core_3 = require("@memlab/core");
|
|
29
30
|
function checkLastSnapshotChunk(chunk) {
|
|
30
31
|
const regex = /\}\s*$/;
|
|
31
32
|
if (!regex.test(chunk)) {
|
|
32
|
-
|
|
33
|
+
core_2.utils.throwError(new Error('resolved `HeapProfiler.takeHeapSnapshot` before writing the last chunk'));
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
// get URL parameter for a specific step
|
|
@@ -46,17 +47,17 @@ function getURLParameter(tab, visitPlan) {
|
|
|
46
47
|
return ret;
|
|
47
48
|
}
|
|
48
49
|
function compareURL(page, url) {
|
|
49
|
-
if (!
|
|
50
|
+
if (!core_2.config.verbose) {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
const actual = unescape(page.url());
|
|
53
54
|
url = unescape(url);
|
|
54
|
-
if (!
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
if (!core_2.utils.isURLEqual(url, actual)) {
|
|
56
|
+
core_2.info.warning('URL changed:');
|
|
57
|
+
core_2.info.lowLevel(` Expected: ${url}`);
|
|
58
|
+
core_2.info.lowLevel('----');
|
|
59
|
+
core_2.info.lowLevel(` Actual: ${actual}`);
|
|
60
|
+
core_2.info.lowLevel('');
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
function logTabProgress(i, visitPlan) {
|
|
@@ -65,32 +66,32 @@ function logTabProgress(i, visitPlan) {
|
|
|
65
66
|
const progress = `[${i + 1}/${len}]`;
|
|
66
67
|
const tabType = tab.type ? `(${tab.type})` : '';
|
|
67
68
|
const msg = `${progress} visiting ${tab.name} ${tabType}`;
|
|
68
|
-
if (
|
|
69
|
-
|
|
69
|
+
if (core_2.config.verbose) {
|
|
70
|
+
core_2.info.topLevel(msg);
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
+
core_2.info.topLevel(core_2.serializer.summarizeTabsOrder(visitPlan.tabsOrder, {
|
|
72
73
|
color: true,
|
|
73
74
|
progress: i,
|
|
74
75
|
}));
|
|
75
|
-
|
|
76
|
+
core_2.browserInfo.addMarker(`[memlab]: ${msg}`);
|
|
76
77
|
}
|
|
77
78
|
function serializeVisitPlan(visitPlan) {
|
|
78
|
-
fs_1.default.writeFileSync(
|
|
79
|
+
fs_1.default.writeFileSync(core_2.config.snapshotSequenceFile, JSON.stringify(visitPlan.tabsOrder, null, 2), 'UTF-8');
|
|
79
80
|
}
|
|
80
81
|
function logMetaData(visitPlan, opt = {}) {
|
|
81
82
|
// save the visiting info to disk
|
|
82
83
|
serializeVisitPlan(visitPlan);
|
|
83
84
|
// save the run meta info to disk
|
|
84
85
|
const runMeta = {
|
|
85
|
-
app:
|
|
86
|
+
app: core_2.config.targetApp,
|
|
86
87
|
type: visitPlan.type,
|
|
87
|
-
interaction:
|
|
88
|
-
browserInfo:
|
|
88
|
+
interaction: core_2.config.targetTab,
|
|
89
|
+
browserInfo: core_2.browserInfo,
|
|
89
90
|
};
|
|
90
|
-
|
|
91
|
+
core_1.runInfoUtils.runMetaInfoManager.saveRunMetaInfo(runMeta);
|
|
91
92
|
// additional post processing of collected data
|
|
92
93
|
if (opt.final) {
|
|
93
|
-
|
|
94
|
+
core_2.config.runningMode.postProcessData(visitPlan);
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
function setPermissions(page, origin) {
|
|
@@ -100,7 +101,7 @@ function setPermissions(page, origin) {
|
|
|
100
101
|
}
|
|
101
102
|
const browser = page.browser();
|
|
102
103
|
const context = browser.defaultBrowserContext();
|
|
103
|
-
yield context.overridePermissions(origin,
|
|
104
|
+
yield context.overridePermissions(origin, core_2.config.grantedPermissions);
|
|
104
105
|
});
|
|
105
106
|
}
|
|
106
107
|
// check if the URL is correct
|
|
@@ -120,7 +121,7 @@ function checkPageReload(page) {
|
|
|
120
121
|
// @ts-expect-error TODO: add Window shim type
|
|
121
122
|
const flag = yield page.evaluate(() => window.__memlab_check_reload);
|
|
122
123
|
if (flag !== 1) {
|
|
123
|
-
|
|
124
|
+
core_2.utils.haltOrThrow('The page is reloaded. MemLab cannot analyze heap across page reloads. ' +
|
|
124
125
|
'Please remove window.reload() calls, page.goto() calls, ' +
|
|
125
126
|
'or any reload logic.');
|
|
126
127
|
}
|
|
@@ -128,8 +129,8 @@ function checkPageReload(page) {
|
|
|
128
129
|
}
|
|
129
130
|
function maybeWaitForConsoleInput(stepId) {
|
|
130
131
|
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
-
if (
|
|
132
|
-
yield
|
|
132
|
+
if (core_2.config.isManualDebug) {
|
|
133
|
+
yield core_2.info.waitForConsole(`Press Enter (or Return) to continue step-${stepId}:`);
|
|
133
134
|
}
|
|
134
135
|
});
|
|
135
136
|
}
|
|
@@ -144,7 +145,7 @@ exceptionHandler = (_ex) => {
|
|
|
144
145
|
ret = yield f.apply(self, args);
|
|
145
146
|
}
|
|
146
147
|
catch (ex) {
|
|
147
|
-
exceptionHandler(
|
|
148
|
+
exceptionHandler(core_2.utils.getError(ex));
|
|
148
149
|
}
|
|
149
150
|
return ret;
|
|
150
151
|
});
|
|
@@ -154,19 +155,19 @@ function applyAsyncWithRetry(f, self, args, options = {}) {
|
|
|
154
155
|
options.retry = options.retry || 0;
|
|
155
156
|
const retry = options.retry;
|
|
156
157
|
const exceptionHandler = (ex) => __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
if (retry <= 0 ||
|
|
158
|
+
if (retry <= 0 || core_2.config.verbose) {
|
|
158
159
|
// if the browser UI is enabled, MemLab should wait for a while
|
|
159
160
|
// so we can have a chance to manually inspect the page
|
|
160
|
-
if (
|
|
161
|
-
yield InteractionUtils_1.default.waitFor(
|
|
161
|
+
if (core_2.config.openDevtoolsConsole) {
|
|
162
|
+
yield InteractionUtils_1.default.waitFor(core_2.config.delayBeforeExitUponException);
|
|
162
163
|
}
|
|
163
|
-
|
|
164
|
+
core_2.utils.haltOrThrow(core_2.utils.getError(ex), {
|
|
164
165
|
printCallback: () => {
|
|
165
|
-
|
|
166
|
+
core_2.info.warning('interaction fail');
|
|
166
167
|
},
|
|
167
168
|
});
|
|
168
169
|
}
|
|
169
|
-
|
|
170
|
+
core_2.info.warning(`interaction fail, making ${retry} more attempt(s)...`);
|
|
170
171
|
if (!!options.delayBeforeRetry && options.delayBeforeRetry > 0) {
|
|
171
172
|
yield InteractionUtils_1.default.waitFor(options.delayBeforeRetry);
|
|
172
173
|
}
|
|
@@ -180,7 +181,7 @@ function applyAsyncWithRetry(f, self, args, options = {}) {
|
|
|
180
181
|
}
|
|
181
182
|
function clearConsole(page) {
|
|
182
183
|
return __awaiter(this, void 0, void 0, function* () {
|
|
183
|
-
if (
|
|
184
|
+
if (core_2.config.clearConsole) {
|
|
184
185
|
yield page.evaluate(() => {
|
|
185
186
|
try {
|
|
186
187
|
console.clear();
|
|
@@ -195,7 +196,7 @@ function clearConsole(page) {
|
|
|
195
196
|
function dispatchOperation(page, operation, opArgs) {
|
|
196
197
|
return __awaiter(this, void 0, void 0, function* () {
|
|
197
198
|
if (!(operation instanceof BaseOperation_1.default)) {
|
|
198
|
-
throw
|
|
199
|
+
throw core_2.utils.haltOrThrow(`unknown operation: ${operation}`);
|
|
199
200
|
}
|
|
200
201
|
yield operation.do(page, opArgs);
|
|
201
202
|
});
|
|
@@ -203,22 +204,22 @@ function dispatchOperation(page, operation, opArgs) {
|
|
|
203
204
|
function waitExtraForTab(tabInfo) {
|
|
204
205
|
return __awaiter(this, void 0, void 0, function* () {
|
|
205
206
|
let delay = 0;
|
|
206
|
-
const mode =
|
|
207
|
+
const mode = core_2.config.runningMode;
|
|
207
208
|
if (tabInfo.type === 'target') {
|
|
208
209
|
if (!mode.shouldExtraWaitForTarget(tabInfo)) {
|
|
209
210
|
return;
|
|
210
211
|
}
|
|
211
|
-
delay +=
|
|
212
|
+
delay += core_2.config.extraWaitingForTarget;
|
|
212
213
|
}
|
|
213
214
|
else if (tabInfo.type === 'final') {
|
|
214
215
|
if (!mode.shouldExtraWaitForFinal(tabInfo)) {
|
|
215
216
|
return;
|
|
216
217
|
}
|
|
217
|
-
delay +=
|
|
218
|
+
delay += core_2.config.extraWaitingForFinal;
|
|
218
219
|
}
|
|
219
220
|
// wait for extra time
|
|
220
221
|
if (delay > 0) {
|
|
221
|
-
|
|
222
|
+
core_2.info.overwrite(`wait extra ${delay / 1000}s for ${tabInfo.type} page...`);
|
|
222
223
|
yield InteractionUtils_1.default.waitFor(delay);
|
|
223
224
|
}
|
|
224
225
|
});
|
|
@@ -243,7 +244,7 @@ function startTrackingHeapAllocation(page, file) {
|
|
|
243
244
|
return __awaiter(this, void 0, void 0, function* () {
|
|
244
245
|
const heap = '';
|
|
245
246
|
fs_1.default.writeFileSync(file, heap, 'UTF-8');
|
|
246
|
-
|
|
247
|
+
core_2.info.lowLevel('tracking heap allocation...');
|
|
247
248
|
const cdpSession = yield page.target().createCDPSession();
|
|
248
249
|
cdpSession.on('HeapProfiler.addHeapSnapshotChunk', data => {
|
|
249
250
|
fs_1.default.appendFileSync(file, data.chunk, 'UTF-8');
|
|
@@ -264,7 +265,7 @@ function getScenarioAppName(scenario = null) {
|
|
|
264
265
|
function getScenarioDefaultAppName() {
|
|
265
266
|
return 'default-app-for-scenario';
|
|
266
267
|
}
|
|
267
|
-
exports.default = (0,
|
|
268
|
+
exports.default = (0, core_3.setInternalValue)({
|
|
268
269
|
applyAsyncWithGuard,
|
|
269
270
|
applyAsyncWithRetry,
|
|
270
271
|
checkLastSnapshotChunk,
|
|
@@ -284,4 +285,4 @@ exports.default = (0, core_2.setInternalValue)({
|
|
|
284
285
|
setPermissions,
|
|
285
286
|
startTrackingHeapAllocation,
|
|
286
287
|
waitExtraForTab,
|
|
287
|
-
}, __filename,
|
|
288
|
+
}, __filename, core_3.constant.internalDir);
|