@memlab/e2e 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.
Files changed (118) hide show
  1. package/README.md +11 -0
  2. package/dist/BaseSynthesizer.d.ts +63 -0
  3. package/dist/BaseSynthesizer.d.ts.map +1 -0
  4. package/dist/BaseSynthesizer.js +433 -0
  5. package/dist/E2EInteractionManager.d.ts +41 -0
  6. package/dist/E2EInteractionManager.d.ts.map +1 -0
  7. package/dist/E2EInteractionManager.js +347 -0
  8. package/dist/TestRunnerLoader.d.ts +16 -0
  9. package/dist/TestRunnerLoader.d.ts.map +1 -0
  10. package/dist/TestRunnerLoader.js +41 -0
  11. package/dist/TypesThirdParty.d.ts +25 -0
  12. package/dist/TypesThirdParty.d.ts.map +1 -0
  13. package/dist/TypesThirdParty.js +10 -0
  14. package/dist/index.d.ts +16 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +40 -0
  17. package/dist/lib/E2EUtils.d.ts +59 -0
  18. package/dist/lib/E2EUtils.d.ts.map +1 -0
  19. package/dist/lib/E2EUtils.js +286 -0
  20. package/dist/lib/SynthesisUtils.d.ts +25 -0
  21. package/dist/lib/SynthesisUtils.d.ts.map +1 -0
  22. package/dist/lib/SynthesisUtils.js +30 -0
  23. package/dist/lib/operations/BackOperation.d.ts +17 -0
  24. package/dist/lib/operations/BackOperation.d.ts.map +1 -0
  25. package/dist/lib/operations/BackOperation.js +37 -0
  26. package/dist/lib/operations/BackspaceOperation.d.ts +18 -0
  27. package/dist/lib/operations/BackspaceOperation.d.ts.map +1 -0
  28. package/dist/lib/operations/BackspaceOperation.js +36 -0
  29. package/dist/lib/operations/BaseOperation.d.ts +22 -0
  30. package/dist/lib/operations/BaseOperation.d.ts.map +1 -0
  31. package/dist/lib/operations/BaseOperation.js +67 -0
  32. package/dist/lib/operations/CachePageContent.d.ts +22 -0
  33. package/dist/lib/operations/CachePageContent.d.ts.map +1 -0
  34. package/dist/lib/operations/CachePageContent.js +46 -0
  35. package/dist/lib/operations/ClickOperation.d.ts +36 -0
  36. package/dist/lib/operations/ClickOperation.d.ts.map +1 -0
  37. package/dist/lib/operations/ClickOperation.js +131 -0
  38. package/dist/lib/operations/CompoundOperation.d.ts +20 -0
  39. package/dist/lib/operations/CompoundOperation.d.ts.map +1 -0
  40. package/dist/lib/operations/CompoundOperation.js +39 -0
  41. package/dist/lib/operations/EnterOperation.d.ts +18 -0
  42. package/dist/lib/operations/EnterOperation.d.ts.map +1 -0
  43. package/dist/lib/operations/EnterOperation.js +36 -0
  44. package/dist/lib/operations/EscOperation.d.ts +17 -0
  45. package/dist/lib/operations/EscOperation.d.ts.map +1 -0
  46. package/dist/lib/operations/EscOperation.js +36 -0
  47. package/dist/lib/operations/HoverOperation.d.ts +28 -0
  48. package/dist/lib/operations/HoverOperation.d.ts.map +1 -0
  49. package/dist/lib/operations/HoverOperation.js +73 -0
  50. package/dist/lib/operations/InteractionUtils.d.ts +33 -0
  51. package/dist/lib/operations/InteractionUtils.d.ts.map +1 -0
  52. package/dist/lib/operations/InteractionUtils.js +207 -0
  53. package/dist/lib/operations/Operations.d.ts +25 -0
  54. package/dist/lib/operations/Operations.d.ts.map +1 -0
  55. package/dist/lib/operations/Operations.js +45 -0
  56. package/dist/lib/operations/RevertOperation.d.ts +18 -0
  57. package/dist/lib/operations/RevertOperation.d.ts.map +1 -0
  58. package/dist/lib/operations/RevertOperation.js +55 -0
  59. package/dist/lib/operations/RunJSCode.d.ts +25 -0
  60. package/dist/lib/operations/RunJSCode.d.ts.map +1 -0
  61. package/dist/lib/operations/RunJSCode.js +51 -0
  62. package/dist/lib/operations/ScrollOperation.d.ts +27 -0
  63. package/dist/lib/operations/ScrollOperation.d.ts.map +1 -0
  64. package/dist/lib/operations/ScrollOperation.js +85 -0
  65. package/dist/lib/operations/TargetExtraOperation.d.ts +18 -0
  66. package/dist/lib/operations/TargetExtraOperation.d.ts.map +1 -0
  67. package/dist/lib/operations/TargetExtraOperation.js +28 -0
  68. package/dist/lib/operations/TestPlanner.d.ts +46 -0
  69. package/dist/lib/operations/TestPlanner.d.ts.map +1 -0
  70. package/dist/lib/operations/TestPlanner.js +182 -0
  71. package/dist/lib/operations/TypeOperation.d.ts +29 -0
  72. package/dist/lib/operations/TypeOperation.d.ts.map +1 -0
  73. package/dist/lib/operations/TypeOperation.js +64 -0
  74. package/dist/lib/operations/UploadOperation.d.ts +25 -0
  75. package/dist/lib/operations/UploadOperation.d.ts.map +1 -0
  76. package/dist/lib/operations/UploadOperation.js +56 -0
  77. package/dist/lib/operations/WaitForElementOperation.d.ts +32 -0
  78. package/dist/lib/operations/WaitForElementOperation.d.ts.map +1 -0
  79. package/dist/lib/operations/WaitForElementOperation.js +67 -0
  80. package/dist/lib/operations/WaitOperation.d.ts +19 -0
  81. package/dist/lib/operations/WaitOperation.d.ts.map +1 -0
  82. package/dist/lib/operations/WaitOperation.js +42 -0
  83. package/dist/lib/operations/WithCachedPageContent.d.ts +26 -0
  84. package/dist/lib/operations/WithCachedPageContent.d.ts.map +1 -0
  85. package/dist/lib/operations/WithCachedPageContent.js +53 -0
  86. package/dist/lib/operations/XVirtualFrameBuffer.d.ts +15 -0
  87. package/dist/lib/operations/XVirtualFrameBuffer.d.ts.map +1 -0
  88. package/dist/lib/operations/XVirtualFrameBuffer.js +44 -0
  89. package/dist/plugins/DefaultScenarioSynthesizer.d.ts +23 -0
  90. package/dist/plugins/DefaultScenarioSynthesizer.d.ts.map +1 -0
  91. package/dist/plugins/DefaultScenarioSynthesizer.js +61 -0
  92. package/dist/plugins/TestSPAVisitSynthesizer.d.ts +23 -0
  93. package/dist/plugins/TestSPAVisitSynthesizer.d.ts.map +1 -0
  94. package/dist/plugins/TestSPAVisitSynthesizer.js +72 -0
  95. package/dist/plugins/scenarios/test-airbnb.d.ts +14 -0
  96. package/dist/plugins/scenarios/test-airbnb.d.ts.map +1 -0
  97. package/dist/plugins/scenarios/test-airbnb.js +48 -0
  98. package/dist/plugins/scenarios/test-databricks.d.ts +14 -0
  99. package/dist/plugins/scenarios/test-databricks.d.ts.map +1 -0
  100. package/dist/plugins/scenarios/test-databricks.js +40 -0
  101. package/dist/plugins/scenarios/test-ebay.d.ts +14 -0
  102. package/dist/plugins/scenarios/test-ebay.d.ts.map +1 -0
  103. package/dist/plugins/scenarios/test-ebay.js +48 -0
  104. package/dist/plugins/scenarios/test-google-maps.d.ts +14 -0
  105. package/dist/plugins/scenarios/test-google-maps.d.ts.map +1 -0
  106. package/dist/plugins/scenarios/test-google-maps.js +41 -0
  107. package/dist/plugins/scenarios/test-shopify.d.ts +14 -0
  108. package/dist/plugins/scenarios/test-shopify.d.ts.map +1 -0
  109. package/dist/plugins/scenarios/test-shopify.js +40 -0
  110. package/dist/plugins/scenarios/test-youtube.d.ts +14 -0
  111. package/dist/plugins/scenarios/test-youtube.d.ts.map +1 -0
  112. package/dist/plugins/scenarios/test-youtube.js +40 -0
  113. package/package.json +53 -0
  114. package/static/links/index.html +18 -0
  115. package/static/links/min.js +3 -0
  116. package/static/links/package.json +36 -0
  117. package/static/links/src/App.js +48 -0
  118. package/static/links/src/index.js +20 -0
@@ -0,0 +1,347 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const fs_1 = __importDefault(require("fs"));
25
+ const path_1 = __importDefault(require("path"));
26
+ const E2EUtils_1 = __importDefault(require("./lib/E2EUtils"));
27
+ const core_1 = require("@memlab/core");
28
+ const InteractionUtils_1 = __importDefault(require("./lib/operations/InteractionUtils"));
29
+ const TestPlanner_1 = __importDefault(require("./lib/operations/TestPlanner"));
30
+ const { logMetaData, setPermissions, logTabProgress, maybeWaitForConsoleInput, applyAsyncWithRetry, compareURL, waitExtraForTab, checkURL, injectPageReloadChecker, checkPageReload, dispatchOperation, clearConsole, getNavigationHistoryLength, checkLastSnapshotChunk, getURLParameter, } = E2EUtils_1.default;
31
+ class E2EInteractionManager {
32
+ constructor(page) {
33
+ this.pageHistoryLength = [];
34
+ this.evalFuncAfterInitLoad = null;
35
+ this.page = page;
36
+ }
37
+ getCDPSession() {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ if (!this.cdpsession) {
40
+ this.cdpsession = yield this.page.target().createCDPSession();
41
+ }
42
+ return this.cdpsession;
43
+ });
44
+ }
45
+ clearCDPSession() {
46
+ this.cdpsession = null;
47
+ }
48
+ setEvalFuncAfterInitLoad(func) {
49
+ this.evalFuncAfterInitLoad = func;
50
+ }
51
+ initialLoad(page, url, opArgs = {}) {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ if (core_1.config.verbose) {
54
+ core_1.info.lowLevel(`loading: ${url}`);
55
+ }
56
+ core_1.info.overwrite('Connecting to web server...');
57
+ yield page.goto(url, {
58
+ timeout: core_1.config.initialPageLoadTimeout,
59
+ waitUntil: 'load',
60
+ });
61
+ // wait extra 10s in continuous test env for the initial page load
62
+ if (core_1.config.isContinuousTest) {
63
+ yield InteractionUtils_1.default.waitFor(10000);
64
+ }
65
+ if (this.evalFuncAfterInitLoad) {
66
+ yield page.evaluate(this.evalFuncAfterInitLoad);
67
+ }
68
+ yield InteractionUtils_1.default.waitUntilLoaded(page, opArgs);
69
+ });
70
+ }
71
+ beforeInteractions() {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ if (core_1.config.verbose) {
74
+ const browserVersion = yield this.page.browser().version();
75
+ core_1.info.lowLevel(`Browser version: ${browserVersion}`);
76
+ const nodeVersion = process.version;
77
+ core_1.info.lowLevel(`Node.js version: ${nodeVersion}`);
78
+ }
79
+ });
80
+ }
81
+ visitAndGetSnapshots(options = {}) {
82
+ var _a;
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ const visitPlan = options.testPlanner
85
+ ? options.testPlanner.getVisitPlan()
86
+ : TestPlanner_1.default.getVisitPlan();
87
+ const runConfig = (_a = options.config) !== null && _a !== void 0 ? _a : core_1.config;
88
+ // notify the running mode the current visit plan
89
+ runConfig.runningMode.beforeRunning(visitPlan);
90
+ logMetaData(visitPlan);
91
+ yield setPermissions(this.page, TestPlanner_1.default.getOrigin());
92
+ yield this.beforeInteractions();
93
+ const baseURL = core_1.utils.normalizeBaseUrl(visitPlan.baseURL);
94
+ yield this.startTrackingHeap();
95
+ for (let i = 0; i < visitPlan.tabsOrder.length; i++) {
96
+ core_1.info.beginSection(`step-${i}`);
97
+ if (runConfig.verbose) {
98
+ core_1.info.lowLevel(new Date().toString());
99
+ }
100
+ const tab = visitPlan.tabsOrder[i];
101
+ const subUrl = tab.url.substr(tab.url.startsWith('/') ? 1 : 0);
102
+ const url = `${baseURL}${subUrl}` + getURLParameter(tab, visitPlan);
103
+ logTabProgress(i, visitPlan);
104
+ yield maybeWaitForConsoleInput(i + 1);
105
+ const opArgs = { isPageLoaded: visitPlan.isPageLoaded };
106
+ yield applyAsyncWithRetry(this.getPageStatistics, this, [url, tab, opArgs], {
107
+ retry: runConfig.interactionFailRetry,
108
+ });
109
+ // dump browser console output in a readable file
110
+ core_1.browserInfo.dump();
111
+ core_1.info.nextLine();
112
+ core_1.info.endSection(`step-${i}`);
113
+ }
114
+ // show progress on console
115
+ core_1.info.topLevel(core_1.serializer.summarizeTabsOrder(visitPlan.tabsOrder, {
116
+ color: true,
117
+ progress: visitPlan.tabsOrder.length,
118
+ }) + '\n');
119
+ // serialize the meta data again (with more runtime and browser info)
120
+ logMetaData(visitPlan, { final: true });
121
+ // dump browser console output in a readable file
122
+ core_1.browserInfo.dump();
123
+ });
124
+ }
125
+ warmupInPage() {
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ const visitPlan = TestPlanner_1.default.getVisitPlan();
128
+ const baseURL = visitPlan.baseURL;
129
+ const len = visitPlan.tabsOrder.length;
130
+ const visited = Object.create(null);
131
+ // randomize order
132
+ const tabs = core_1.utils.shuffleArray(Array.from(visitPlan.tabsOrder));
133
+ const multipler = core_1.config.warmupRepeat;
134
+ for (let i = 0; i < len * multipler; ++i) {
135
+ const tab = tabs[i % len];
136
+ visited[tab.name] |= 0;
137
+ if (++visited[tab.name] > multipler) {
138
+ continue;
139
+ }
140
+ // print current progress
141
+ if (core_1.config.isContinuousTest || core_1.config.verbose) {
142
+ let progress = `[${i + 1}/${len * multipler}]`;
143
+ progress = `${progress}: warming up web server (${tab.name})...`;
144
+ core_1.info.lowLevel(progress);
145
+ }
146
+ else {
147
+ core_1.info.progress(i, len * multipler, { message: 'Warming up web server' });
148
+ }
149
+ // print url
150
+ const urlParams = getURLParameter(tab, visitPlan);
151
+ const url = `${baseURL}${tab.url}${urlParams}`;
152
+ if (core_1.config.verbose) {
153
+ core_1.info.lowLevel(`url: ${url}`);
154
+ }
155
+ // warm up page
156
+ yield this.visitPage(url, {
157
+ mute: true,
158
+ isPageLoaded: visitPlan.isPageLoaded,
159
+ });
160
+ compareURL(this.page, url);
161
+ }
162
+ });
163
+ }
164
+ visitPage(url, options = {}) {
165
+ return __awaiter(this, void 0, void 0, function* () {
166
+ try {
167
+ yield this.page.goto(url, {
168
+ timeout: core_1.config.warmupPageLoadTimeout,
169
+ waitUntil: 'domcontentloaded',
170
+ });
171
+ yield InteractionUtils_1.default.waitUntilLoaded(this.page, options);
172
+ }
173
+ catch (ex) {
174
+ core_1.info.overwrite(core_1.utils.getError(ex).message);
175
+ }
176
+ });
177
+ }
178
+ getPageStatistics(url, tabInfo, opArgs = {}) {
179
+ return __awaiter(this, void 0, void 0, function* () {
180
+ if (core_1.config.verbose) {
181
+ core_1.info.lowLevel('url: ' + url);
182
+ }
183
+ // visit the URL of the first step
184
+ if (tabInfo.idx === 1) {
185
+ yield applyAsyncWithRetry(this.initialLoad, this, [this.page, url, opArgs], {
186
+ retry: core_1.config.initialLoadFailRetry,
187
+ delayBeforeRetry: 3000,
188
+ });
189
+ // only use the interactions for steps other than the first step
190
+ }
191
+ else if (tabInfo.interactions) {
192
+ yield this.interactWithPage(this.page, tabInfo.interactions, opArgs);
193
+ }
194
+ if (tabInfo.type === 'final' || tabInfo.type === 'target') {
195
+ yield waitExtraForTab(tabInfo);
196
+ }
197
+ checkURL(this.page, url);
198
+ // inject marker, which checks if the page is reloaded
199
+ if (tabInfo.idx === 1) {
200
+ yield injectPageReloadChecker(this.page);
201
+ }
202
+ else {
203
+ yield checkPageReload(this.page);
204
+ }
205
+ yield this.fullGC(tabInfo);
206
+ // collect metrics
207
+ yield this.collectMetrics(tabInfo);
208
+ // take screenshot
209
+ const screenShotIdx = tabInfo.screenshot ? tabInfo.idx : 0;
210
+ if (core_1.config.runningMode.shouldTakeScreenShot(tabInfo) && screenShotIdx > 0) {
211
+ yield InteractionUtils_1.default.screenshot(this.page, screenShotIdx);
212
+ }
213
+ // take heap snapshot
214
+ const snapshotIdx = tabInfo.snapshot ? tabInfo.idx : 0;
215
+ if (core_1.config.runningMode.shouldTakeHeapSnapshot(tabInfo) && snapshotIdx > 0) {
216
+ const snapshotFile = path_1.default.join(core_1.config.curDataDir, `s${snapshotIdx}.heapsnapshot`);
217
+ yield this.saveHeapSnapshotToFile(snapshotFile);
218
+ }
219
+ if (tabInfo.postInteractions) {
220
+ yield this.interactWithPage(this.page, tabInfo.postInteractions, opArgs);
221
+ }
222
+ });
223
+ }
224
+ interactWithPage(page, operations, opArgs = {}) {
225
+ return __awaiter(this, void 0, void 0, function* () {
226
+ const args = Object.assign(Object.assign({}, opArgs), { pageHistoryLength: this.pageHistoryLength });
227
+ if (typeof operations === 'function') {
228
+ yield operations(page, args);
229
+ yield InteractionUtils_1.default.waitUntilLoaded(page, args);
230
+ }
231
+ else if (Array.isArray(operations)) {
232
+ for (const op of operations) {
233
+ yield this.interactWithPage(page, op, args);
234
+ }
235
+ }
236
+ else if (operations.kind) {
237
+ yield dispatchOperation(page, operations, args);
238
+ }
239
+ else {
240
+ core_1.utils.throwError(new Error('unknown operation'));
241
+ }
242
+ });
243
+ }
244
+ startTrackingHeap() {
245
+ return __awaiter(this, void 0, void 0, function* () {
246
+ if (core_1.config.verbose) {
247
+ core_1.info.lowLevel('Start tracking JS heap');
248
+ }
249
+ const session = yield this.getCDPSession();
250
+ yield session.send('HeapProfiler.enable');
251
+ });
252
+ }
253
+ writeSnapshotFileFromCDPSession(file, session) {
254
+ return __awaiter(this, void 0, void 0, function* () {
255
+ const writeStream = fs_1.default.createWriteStream(file, { encoding: 'UTF-8' });
256
+ let lastChunk = '';
257
+ const dataHandler = (data) => {
258
+ writeStream.write(data.chunk);
259
+ lastChunk = data.chunk;
260
+ };
261
+ const progressHander = (data) => {
262
+ const percent = ((100 * data.done) / data.total) | 0;
263
+ if (!core_1.config.isContinuousTest) {
264
+ core_1.info.overwrite(`heap snapshot ${percent}% complete`);
265
+ }
266
+ };
267
+ session.on('HeapProfiler.addHeapSnapshotChunk', dataHandler);
268
+ session.on('HeapProfiler.reportHeapSnapshotProgress', progressHander);
269
+ // start taking heap snapshot
270
+ yield session.send('HeapProfiler.takeHeapSnapshot', {
271
+ reportProgress: true,
272
+ captureNumericValue: true,
273
+ });
274
+ checkLastSnapshotChunk(lastChunk);
275
+ session.removeListener('HeapProfiler.addHeapSnapshotChunk', dataHandler);
276
+ session.removeListener('HeapProfiler.reportHeapSnapshotProgress', progressHander);
277
+ writeStream.end();
278
+ });
279
+ }
280
+ saveHeapSnapshotToFile(file) {
281
+ return __awaiter(this, void 0, void 0, function* () {
282
+ core_1.info.beginSection('heap snapshot');
283
+ const start = Date.now();
284
+ const session = yield this.getCDPSession();
285
+ yield this.writeSnapshotFileFromCDPSession(file, session);
286
+ const spanMs = Date.now() - start;
287
+ if (core_1.config.verbose) {
288
+ core_1.info.lowLevel(`duration: ${core_1.utils.getReadableTime(spanMs)}`);
289
+ }
290
+ core_1.info.overwrite('snapshot saved to disk');
291
+ core_1.info.endSection('heap snapshot');
292
+ });
293
+ }
294
+ fullGC(tabInfo) {
295
+ return __awaiter(this, void 0, void 0, function* () {
296
+ if (!core_1.config.runningMode.shouldGC(tabInfo)) {
297
+ return;
298
+ }
299
+ if (core_1.config.clearConsole) {
300
+ yield clearConsole(this.page);
301
+ core_1.info.overwrite('running a full GC (clear console)...');
302
+ }
303
+ else {
304
+ core_1.info.overwrite('running a full GC...');
305
+ }
306
+ // force GC 6 times to release feedback_cells
307
+ yield this.forceGC(6);
308
+ });
309
+ }
310
+ forceGC(repeat = 1) {
311
+ return __awaiter(this, void 0, void 0, function* () {
312
+ const client = yield this.getCDPSession();
313
+ for (let i = 0; i < repeat; i++) {
314
+ yield client.send('HeapProfiler.collectGarbage');
315
+ // wait for a while and let GC do the job
316
+ yield InteractionUtils_1.default.waitFor(200);
317
+ }
318
+ yield InteractionUtils_1.default.waitFor(core_1.config.waitAfterGC);
319
+ });
320
+ }
321
+ collectMetrics(tabInfo) {
322
+ var _a;
323
+ return __awaiter(this, void 0, void 0, function* () {
324
+ // collect navigation history info
325
+ const historyLength = yield getNavigationHistoryLength(this.page);
326
+ this.pageHistoryLength.push(historyLength);
327
+ if (!core_1.config.runningMode.shouldGetMetrics(tabInfo)) {
328
+ return;
329
+ }
330
+ yield this.forceGC();
331
+ // collect heap size
332
+ const builtInMetrics = yield this.page.metrics();
333
+ const size = core_1.utils.getReadableBytes(builtInMetrics.JSHeapUsedSize);
334
+ core_1.info.midLevel(`Heap size: ${size}`);
335
+ tabInfo.JSHeapUsedSize = (_a = builtInMetrics.JSHeapUsedSize) !== null && _a !== void 0 ? _a : 0;
336
+ // collect additional metrics
337
+ const metrics = yield core_1.config.runningMode.getAdditionalMetrics(this.page, tabInfo);
338
+ for (const key of Object.keys(metrics)) {
339
+ if (Object.prototype.hasOwnProperty.call(tabInfo, key)) {
340
+ core_1.info.warning(`overwriting metrics: ${key}`);
341
+ }
342
+ }
343
+ tabInfo.metrics = metrics;
344
+ });
345
+ }
346
+ }
347
+ exports.default = E2EInteractionManager;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ import type { E2EScenarioSynthesizerConstructor } from '@memlab/core';
11
+ declare class TestRunnerLoader {
12
+ load(): E2EScenarioSynthesizerConstructor[];
13
+ }
14
+ declare const _default: TestRunnerLoader;
15
+ export default _default;
16
+ //# sourceMappingURL=TestRunnerLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestRunnerLoader.d.ts","sourceRoot":"","sources":["../src/TestRunnerLoader.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAC,iCAAiC,EAAC,MAAM,cAAc,CAAC;AAIpE,cAAM,gBAAgB;IACpB,IAAI,IAAI,iCAAiC,EAAE;CAuB5C;;AAED,wBAAsC"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const path_1 = __importDefault(require("path"));
16
+ const core_1 = require("@memlab/core");
17
+ const BaseSynthesizer_1 = __importDefault(require("./BaseSynthesizer"));
18
+ class TestRunnerLoader {
19
+ load() {
20
+ const ret = [];
21
+ const dir = path_1.default.join(__dirname, 'plugins');
22
+ core_1.fileManager.iterateAllFiles(dir, (file) => {
23
+ if (!file.endsWith('Synthesizer.js')) {
24
+ return;
25
+ }
26
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
27
+ const importedEntity = require(file);
28
+ if (!importedEntity.default) {
29
+ return;
30
+ }
31
+ const constructor = importedEntity.default;
32
+ if (typeof constructor !== 'function' ||
33
+ !(constructor.prototype instanceof BaseSynthesizer_1.default)) {
34
+ return;
35
+ }
36
+ ret.push(constructor);
37
+ });
38
+ return ret;
39
+ }
40
+ }
41
+ exports.default = new TestRunnerLoader();
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ declare module 'xvfb' {
11
+ interface XvfbParams {
12
+ silent: boolean;
13
+ xvfb_args: string[];
14
+ timeout: number;
15
+ }
16
+ export default class Xvfb {
17
+ constructor(params: XvfbParams);
18
+ start: (callback: (error: Error) => unknown | null) => void;
19
+ stop: (callback: (error: Error) => unknown | null) => void;
20
+ startSync: () => void;
21
+ stopSync: () => void;
22
+ display: () => string;
23
+ }
24
+ }
25
+ //# sourceMappingURL=TypesThirdParty.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypesThirdParty.d.ts","sourceRoot":"","sources":["../src/TypesThirdParty.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,UAAU;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB;IACD,MAAM,CAAC,OAAO,OAAO,IAAI;oBACX,MAAM,EAAE,UAAU;QAC9B,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;QAC5D,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;QAC3D,SAAS,EAAE,MAAM,IAAI,CAAC;QACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,MAAM,CAAC;KACvB;CACF"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ export { default as defaultTestPlanner } from './lib/operations/TestPlanner';
11
+ export * from './lib/operations/TestPlanner';
12
+ export { default as Xvfb } from './lib/operations/XVirtualFrameBuffer';
13
+ export { default as E2EInteractionManager } from './E2EInteractionManager';
14
+ export { default as BaseSynthesizer } from './BaseSynthesizer';
15
+ export { default as E2EUtils } from './lib/E2EUtils';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAC3E,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAC,OAAO,IAAI,qBAAqB,EAAC,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @emails oncall+ws_labs
9
+ * @format
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
23
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.E2EUtils = exports.BaseSynthesizer = exports.E2EInteractionManager = exports.Xvfb = exports.defaultTestPlanner = void 0;
30
+ var TestPlanner_1 = require("./lib/operations/TestPlanner");
31
+ Object.defineProperty(exports, "defaultTestPlanner", { enumerable: true, get: function () { return __importDefault(TestPlanner_1).default; } });
32
+ __exportStar(require("./lib/operations/TestPlanner"), exports);
33
+ var XVirtualFrameBuffer_1 = require("./lib/operations/XVirtualFrameBuffer");
34
+ Object.defineProperty(exports, "Xvfb", { enumerable: true, get: function () { return __importDefault(XVirtualFrameBuffer_1).default; } });
35
+ var E2EInteractionManager_1 = require("./E2EInteractionManager");
36
+ Object.defineProperty(exports, "E2EInteractionManager", { enumerable: true, get: function () { return __importDefault(E2EInteractionManager_1).default; } });
37
+ var BaseSynthesizer_1 = require("./BaseSynthesizer");
38
+ Object.defineProperty(exports, "BaseSynthesizer", { enumerable: true, get: function () { return __importDefault(BaseSynthesizer_1).default; } });
39
+ var E2EUtils_1 = require("./lib/E2EUtils");
40
+ Object.defineProperty(exports, "E2EUtils", { enumerable: true, get: function () { return __importDefault(E2EUtils_1).default; } });
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @emails oncall+ws_labs
8
+ * @format
9
+ */
10
+ import type { AnyOptions, AnyValue, E2EOperation, E2EStepInfo, IE2EScenarioVisitPlan, IScenario, Nullable, OperationArgs } from '@memlab/core';
11
+ import type { CDPSession, Page } from 'puppeteer';
12
+ declare type ExceptionHandler = (ex: Error) => void;
13
+ declare function checkLastSnapshotChunk(chunk: string): void;
14
+ declare function getURLParameter(tab: E2EStepInfo, visitPlan: IE2EScenarioVisitPlan): string;
15
+ declare function compareURL(page: Page, url: string): void;
16
+ declare function logTabProgress(i: number, visitPlan: IE2EScenarioVisitPlan): void;
17
+ declare function serializeVisitPlan(visitPlan: IE2EScenarioVisitPlan): void;
18
+ declare function logMetaData(visitPlan: IE2EScenarioVisitPlan, opt?: AnyOptions & {
19
+ final?: boolean;
20
+ }): void;
21
+ declare function setPermissions(page: Page, origin: Nullable<string>): Promise<void>;
22
+ declare function checkURL(page: Page, intendedURL: string): void;
23
+ declare function injectPageReloadChecker(page: Page): Promise<void>;
24
+ declare function checkPageReload(page: Page): Promise<void>;
25
+ declare function maybeWaitForConsoleInput(stepId: number): Promise<void>;
26
+ declare function applyAsyncWithGuard(f: (...args: AnyValue[]) => Promise<AnyValue>, self: AnyValue, args: AnyValue[], exceptionHandler?: ExceptionHandler): Promise<AnyValue>;
27
+ declare function applyAsyncWithRetry(f: (...args: AnyValue[]) => Promise<AnyValue>, self: AnyValue, args: AnyValue[], options?: AnyOptions & {
28
+ retry?: number;
29
+ delayBeforeRetry?: number;
30
+ }): Promise<void>;
31
+ declare function clearConsole(page: Page): Promise<void>;
32
+ declare function dispatchOperation(page: Page, operation: E2EOperation, opArgs: OperationArgs): Promise<void>;
33
+ declare function waitExtraForTab(tabInfo: E2EStepInfo): Promise<void>;
34
+ declare function getNavigationHistoryLength(page: Page): Promise<number>;
35
+ declare function startTrackingHeapAllocation(page: Page, file: string): Promise<CDPSession>;
36
+ declare function getScenarioAppName(scenario?: Nullable<IScenario>): string;
37
+ declare const _default: {
38
+ applyAsyncWithGuard: typeof applyAsyncWithGuard;
39
+ applyAsyncWithRetry: typeof applyAsyncWithRetry;
40
+ checkLastSnapshotChunk: typeof checkLastSnapshotChunk;
41
+ checkPageReload: typeof checkPageReload;
42
+ checkURL: typeof checkURL;
43
+ clearConsole: typeof clearConsole;
44
+ compareURL: typeof compareURL;
45
+ dispatchOperation: typeof dispatchOperation;
46
+ getNavigationHistoryLength: typeof getNavigationHistoryLength;
47
+ getScenarioAppName: typeof getScenarioAppName;
48
+ getURLParameter: typeof getURLParameter;
49
+ injectPageReloadChecker: typeof injectPageReloadChecker;
50
+ logMetaData: typeof logMetaData;
51
+ logTabProgress: typeof logTabProgress;
52
+ maybeWaitForConsoleInput: typeof maybeWaitForConsoleInput;
53
+ serializeVisitPlan: typeof serializeVisitPlan;
54
+ setPermissions: typeof setPermissions;
55
+ startTrackingHeapAllocation: typeof startTrackingHeapAllocation;
56
+ waitExtraForTab: typeof waitExtraForTab;
57
+ };
58
+ export default _default;
59
+ //# sourceMappingURL=E2EUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"E2EUtils.d.ts","sourceRoot":"","sources":["../../src/lib/E2EUtils.ts"],"names":[],"mappings":"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"}