@memlab/api 1.0.25 → 1.0.27
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/API.d.ts +25 -6
- package/dist/API.d.ts.map +1 -1
- package/dist/API.js +36 -21
- package/dist/__tests__/API/E2EFindMemoryLeaks.test.js +1 -24
- package/dist/__tests__/API/E2EMemoryLeakFilter.test.d.ts +11 -0
- package/dist/__tests__/API/E2EMemoryLeakFilter.test.d.ts.map +1 -0
- package/dist/__tests__/API/E2EMemoryLeakFilter.test.js +121 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/state/APIStateManager.d.ts +26 -0
- package/dist/state/APIStateManager.d.ts.map +1 -0
- package/dist/state/APIStateManager.js +40 -0
- package/dist/state/ConsoleModeManager.d.ts +48 -0
- package/dist/state/ConsoleModeManager.d.ts.map +1 -0
- package/dist/state/ConsoleModeManager.js +106 -0
- package/dist/state/PuppeteerConfigManager.d.ts +21 -0
- package/dist/state/PuppeteerConfigManager.d.ts.map +1 -0
- package/dist/state/PuppeteerConfigManager.js +31 -0
- package/package.json +4 -4
package/dist/API.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { ParsedArgs } from 'minimist';
|
|
11
11
|
import type { AnyFunction, ISerializedInfo, IScenario, Optional } from '@memlab/core';
|
|
12
|
+
import { ConsoleMode } from './state/ConsoleModeManager';
|
|
12
13
|
import { MemLabConfig } from '@memlab/core';
|
|
13
14
|
import { TestPlanner } from '@memlab/e2e';
|
|
14
15
|
import { BaseAnalysis } from '@memlab/heap-analysis';
|
|
@@ -57,6 +58,15 @@ export type RunOptions = {
|
|
|
57
58
|
* skip warmup page load for the target web app
|
|
58
59
|
*/
|
|
59
60
|
skipWarmup?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* specifying the terminal output mode, default is `default`.
|
|
63
|
+
* For more details. please check out {@link ConsoleMode}
|
|
64
|
+
*/
|
|
65
|
+
consoleMode?: ConsoleMode;
|
|
66
|
+
/**
|
|
67
|
+
* specify the Chromium binary for E2E run
|
|
68
|
+
*/
|
|
69
|
+
chromiumBinary?: string;
|
|
60
70
|
};
|
|
61
71
|
/**
|
|
62
72
|
* A data structure holding the result of the {@link run} API call.
|
|
@@ -122,7 +132,7 @@ export declare function warmupAndTakeSnapshots(options?: RunOptions): Promise<Br
|
|
|
122
132
|
* })();
|
|
123
133
|
* ```
|
|
124
134
|
*/
|
|
125
|
-
export declare function run(
|
|
135
|
+
export declare function run(options?: RunOptions): Promise<RunResult>;
|
|
126
136
|
/**
|
|
127
137
|
* This API runs E2E interaction and takes heap snapshots.
|
|
128
138
|
* This is equivalent to running `memlab snapshot` in CLI.
|
|
@@ -147,6 +157,9 @@ export declare function takeSnapshots(options?: RunOptions): Promise<BrowserInte
|
|
|
147
157
|
* This is equivalent to `memlab find-leaks` in CLI.
|
|
148
158
|
*
|
|
149
159
|
* @param runResult return value of a browser interaction run
|
|
160
|
+
* @param options configure memory leak detection run
|
|
161
|
+
* @param options.consoleMode specify the terminal output
|
|
162
|
+
* mode (see {@link ConsoleMode})
|
|
150
163
|
* @returns leak traces detected and clustered from the browser interaction
|
|
151
164
|
* * **Examples**:
|
|
152
165
|
* ```javascript
|
|
@@ -156,12 +169,14 @@ export declare function takeSnapshots(options?: RunOptions): Promise<BrowserInte
|
|
|
156
169
|
* const scenario = {
|
|
157
170
|
* url: () => 'https://www.facebook.com',
|
|
158
171
|
* };
|
|
159
|
-
* const result = await takeSnapshots({scenario});
|
|
160
|
-
* const leaks = findLeaks(result);
|
|
172
|
+
* const result = await takeSnapshots({scenario, consoleMode: 'SILENT'});
|
|
173
|
+
* const leaks = findLeaks(result, {consoleMode: 'CONTINUOUS_TEST'});
|
|
161
174
|
* })();
|
|
162
175
|
* ```
|
|
163
176
|
*/
|
|
164
|
-
export declare function findLeaks(runResult: BaseResultReader
|
|
177
|
+
export declare function findLeaks(runResult: BaseResultReader, options?: {
|
|
178
|
+
consoleMode?: ConsoleMode;
|
|
179
|
+
}): Promise<ISerializedInfo[]>;
|
|
165
180
|
/**
|
|
166
181
|
* This API finds memory leaks by analyzing specified heap snapshots.
|
|
167
182
|
* This is equivalent to `memlab find-leaks` with
|
|
@@ -170,12 +185,16 @@ export declare function findLeaks(runResult: BaseResultReader): Promise<ISeriali
|
|
|
170
185
|
* @param baselineSnapshot the file path of the baseline heap snapshot
|
|
171
186
|
* @param targetSnapshot the file path of the target heap snapshot
|
|
172
187
|
* @param finalSnapshot the file path of the final heap snapshot
|
|
173
|
-
* @param options optionally, you can specify a
|
|
174
|
-
*
|
|
188
|
+
* @param options optionally, you can specify a mode for heap analysis
|
|
189
|
+
* @param options.workDir specify a working directory (other than
|
|
190
|
+
* the default one)
|
|
191
|
+
* @param options.consoleMode specify the terminal output
|
|
192
|
+
* mode (see {@link ConsoleMode})
|
|
175
193
|
* @returns leak traces detected and clustered from the browser interaction
|
|
176
194
|
*/
|
|
177
195
|
export declare function findLeaksBySnapshotFilePaths(baselineSnapshot: string, targetSnapshot: string, finalSnapshot: string, options?: {
|
|
178
196
|
workDir?: string;
|
|
197
|
+
consoleMode?: ConsoleMode;
|
|
179
198
|
}): Promise<ISerializedInfo[]>;
|
|
180
199
|
/**
|
|
181
200
|
* This API analyzes heap snapshot(s) with a specified heap analysis.
|
package/dist/API.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"API.d.ts","sourceRoot":"","sources":["../src/API.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,SAAS,EAGT,QAAQ,EACT,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"API.d.ts","sourceRoot":"","sources":["../src/API.ts"],"names":[],"mappings":"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"}
|
package/dist/API.js
CHANGED
|
@@ -26,6 +26,7 @@ const core_1 = require("@memlab/core");
|
|
|
26
26
|
const e2e_1 = require("@memlab/e2e");
|
|
27
27
|
const APIUtils_1 = __importDefault(require("./lib/APIUtils"));
|
|
28
28
|
const BrowserInteractionResultReader_1 = __importDefault(require("./result-reader/BrowserInteractionResultReader"));
|
|
29
|
+
const APIStateManager_1 = __importDefault(require("./state/APIStateManager"));
|
|
29
30
|
/**
|
|
30
31
|
* This API warms up web server, runs E2E interaction, and takes heap snapshots.
|
|
31
32
|
* This is equivalent to running `memlab warmup-and-snapshot` in CLI.
|
|
@@ -48,15 +49,16 @@ const BrowserInteractionResultReader_1 = __importDefault(require("./result-reade
|
|
|
48
49
|
function warmupAndTakeSnapshots(options = {}) {
|
|
49
50
|
return __awaiter(this, void 0, void 0, function* () {
|
|
50
51
|
const config = getConfigFromRunOptions(options);
|
|
51
|
-
|
|
52
|
-
config.scenario = options.scenario;
|
|
52
|
+
const state = APIStateManager_1.default.getAndUpdateState(config, options);
|
|
53
53
|
const testPlanner = new e2e_1.TestPlanner({ config });
|
|
54
54
|
const { evalInBrowserAfterInitLoad } = options;
|
|
55
55
|
if (!options.skipWarmup) {
|
|
56
56
|
yield warmup({ testPlanner, config, evalInBrowserAfterInitLoad });
|
|
57
57
|
}
|
|
58
58
|
yield testInBrowser({ testPlanner, config, evalInBrowserAfterInitLoad });
|
|
59
|
-
|
|
59
|
+
const ret = BrowserInteractionResultReader_1.default.from(config.workDir);
|
|
60
|
+
APIStateManager_1.default.restoreState(config, state);
|
|
61
|
+
return ret;
|
|
60
62
|
});
|
|
61
63
|
}
|
|
62
64
|
exports.warmupAndTakeSnapshots = warmupAndTakeSnapshots;
|
|
@@ -81,19 +83,19 @@ exports.warmupAndTakeSnapshots = warmupAndTakeSnapshots;
|
|
|
81
83
|
* })();
|
|
82
84
|
* ```
|
|
83
85
|
*/
|
|
84
|
-
function run(
|
|
86
|
+
function run(options = {}) {
|
|
85
87
|
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
-
const config = getConfigFromRunOptions(
|
|
87
|
-
|
|
88
|
-
config.scenario = runOptions.scenario;
|
|
88
|
+
const config = getConfigFromRunOptions(options);
|
|
89
|
+
const state = APIStateManager_1.default.getAndUpdateState(config, options);
|
|
89
90
|
const testPlanner = new e2e_1.TestPlanner({ config });
|
|
90
|
-
const { evalInBrowserAfterInitLoad } =
|
|
91
|
-
if (!
|
|
91
|
+
const { evalInBrowserAfterInitLoad } = options;
|
|
92
|
+
if (!options.skipWarmup) {
|
|
92
93
|
yield warmup({ testPlanner, config, evalInBrowserAfterInitLoad });
|
|
93
94
|
}
|
|
94
95
|
yield testInBrowser({ testPlanner, config, evalInBrowserAfterInitLoad });
|
|
95
96
|
const runResult = BrowserInteractionResultReader_1.default.from(config.workDir);
|
|
96
97
|
const leaks = yield findLeaks(runResult);
|
|
98
|
+
APIStateManager_1.default.restoreState(config, state);
|
|
97
99
|
return { leaks, runResult };
|
|
98
100
|
});
|
|
99
101
|
}
|
|
@@ -119,12 +121,13 @@ exports.run = run;
|
|
|
119
121
|
function takeSnapshots(options = {}) {
|
|
120
122
|
return __awaiter(this, void 0, void 0, function* () {
|
|
121
123
|
const config = getConfigFromRunOptions(options);
|
|
122
|
-
|
|
123
|
-
config.scenario = options.scenario;
|
|
124
|
+
const state = APIStateManager_1.default.getAndUpdateState(config, options);
|
|
124
125
|
const testPlanner = new e2e_1.TestPlanner();
|
|
125
126
|
const { evalInBrowserAfterInitLoad } = options;
|
|
126
127
|
yield testInBrowser({ testPlanner, config, evalInBrowserAfterInitLoad });
|
|
127
|
-
|
|
128
|
+
const ret = BrowserInteractionResultReader_1.default.from(config.workDir);
|
|
129
|
+
APIStateManager_1.default.restoreState(config, state);
|
|
130
|
+
return ret;
|
|
128
131
|
});
|
|
129
132
|
}
|
|
130
133
|
exports.takeSnapshots = takeSnapshots;
|
|
@@ -133,6 +136,9 @@ exports.takeSnapshots = takeSnapshots;
|
|
|
133
136
|
* This is equivalent to `memlab find-leaks` in CLI.
|
|
134
137
|
*
|
|
135
138
|
* @param runResult return value of a browser interaction run
|
|
139
|
+
* @param options configure memory leak detection run
|
|
140
|
+
* @param options.consoleMode specify the terminal output
|
|
141
|
+
* mode (see {@link ConsoleMode})
|
|
136
142
|
* @returns leak traces detected and clustered from the browser interaction
|
|
137
143
|
* * **Examples**:
|
|
138
144
|
* ```javascript
|
|
@@ -142,17 +148,20 @@ exports.takeSnapshots = takeSnapshots;
|
|
|
142
148
|
* const scenario = {
|
|
143
149
|
* url: () => 'https://www.facebook.com',
|
|
144
150
|
* };
|
|
145
|
-
* const result = await takeSnapshots({scenario});
|
|
146
|
-
* const leaks = findLeaks(result);
|
|
151
|
+
* const result = await takeSnapshots({scenario, consoleMode: 'SILENT'});
|
|
152
|
+
* const leaks = findLeaks(result, {consoleMode: 'CONTINUOUS_TEST'});
|
|
147
153
|
* })();
|
|
148
154
|
* ```
|
|
149
155
|
*/
|
|
150
|
-
function findLeaks(runResult) {
|
|
156
|
+
function findLeaks(runResult, options = {}) {
|
|
151
157
|
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
const state = APIStateManager_1.default.getAndUpdateState(core_1.config, options);
|
|
152
159
|
const workDir = runResult.getRootDirectory();
|
|
153
160
|
core_1.fileManager.initDirs(core_1.config, { workDir });
|
|
154
161
|
core_1.config.chaseWeakMapEdge = false;
|
|
155
|
-
|
|
162
|
+
const ret = yield core_1.analysis.checkLeak();
|
|
163
|
+
APIStateManager_1.default.restoreState(core_1.config, state);
|
|
164
|
+
return ret;
|
|
156
165
|
});
|
|
157
166
|
}
|
|
158
167
|
exports.findLeaks = findLeaks;
|
|
@@ -164,12 +173,16 @@ exports.findLeaks = findLeaks;
|
|
|
164
173
|
* @param baselineSnapshot the file path of the baseline heap snapshot
|
|
165
174
|
* @param targetSnapshot the file path of the target heap snapshot
|
|
166
175
|
* @param finalSnapshot the file path of the final heap snapshot
|
|
167
|
-
* @param options optionally, you can specify a
|
|
168
|
-
*
|
|
176
|
+
* @param options optionally, you can specify a mode for heap analysis
|
|
177
|
+
* @param options.workDir specify a working directory (other than
|
|
178
|
+
* the default one)
|
|
179
|
+
* @param options.consoleMode specify the terminal output
|
|
180
|
+
* mode (see {@link ConsoleMode})
|
|
169
181
|
* @returns leak traces detected and clustered from the browser interaction
|
|
170
182
|
*/
|
|
171
183
|
function findLeaksBySnapshotFilePaths(baselineSnapshot, targetSnapshot, finalSnapshot, options = {}) {
|
|
172
184
|
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
const state = APIStateManager_1.default.getAndUpdateState(core_1.config, options);
|
|
173
186
|
core_1.config.useExternalSnapshot = true;
|
|
174
187
|
core_1.config.externalSnapshotFilePaths = [
|
|
175
188
|
baselineSnapshot,
|
|
@@ -178,7 +191,9 @@ function findLeaksBySnapshotFilePaths(baselineSnapshot, targetSnapshot, finalSna
|
|
|
178
191
|
];
|
|
179
192
|
core_1.fileManager.initDirs(core_1.config, { workDir: options.workDir });
|
|
180
193
|
core_1.config.chaseWeakMapEdge = false;
|
|
181
|
-
|
|
194
|
+
const ret = yield core_1.analysis.checkLeak();
|
|
195
|
+
APIStateManager_1.default.restoreState(core_1.config, state);
|
|
196
|
+
return ret;
|
|
182
197
|
});
|
|
183
198
|
}
|
|
184
199
|
exports.findLeaksBySnapshotFilePaths = findLeaksBySnapshotFilePaths;
|
|
@@ -310,9 +325,9 @@ function initBrowserInfoInConfig(browser, options = {}) {
|
|
|
310
325
|
var _a;
|
|
311
326
|
return __awaiter(this, void 0, void 0, function* () {
|
|
312
327
|
const config = (_a = options.config) !== null && _a !== void 0 ? _a : core_1.config;
|
|
313
|
-
core_1.browserInfo.
|
|
328
|
+
core_1.browserInfo.recordPuppeteerConfig(config.puppeteerConfig);
|
|
314
329
|
const version = yield browser.version();
|
|
315
|
-
core_1.browserInfo.
|
|
330
|
+
core_1.browserInfo.recordBrowserVersion(version);
|
|
316
331
|
if (config.verbose) {
|
|
317
332
|
core_1.info.lowLevel(JSON.stringify(core_1.browserInfo, null, 2));
|
|
318
333
|
}
|
|
@@ -58,29 +58,6 @@ test('leak detector can find detached DOM elements', () => __awaiter(void 0, voi
|
|
|
58
58
|
expect(leaks.some(leak => JSON.stringify(leak).includes('_path_1')));
|
|
59
59
|
expect(leaks.some(leak => JSON.stringify(leak).includes('_path_2')));
|
|
60
60
|
}), E2ETestSettings_1.testTimeout);
|
|
61
|
-
test('self-defined leak detector can find TestObject', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
62
|
-
const selfDefinedScenario = {
|
|
63
|
-
app: () => 'test-spa',
|
|
64
|
-
url: () => '',
|
|
65
|
-
action: (page) => __awaiter(void 0, void 0, void 0, function* () { return yield page.click('[data-testid="link-4"]'); }),
|
|
66
|
-
leakFilter: (node) => {
|
|
67
|
-
return node.name === 'TestObject' && node.type === 'object';
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
const workDir = path_1.default.join(os_1.default.tmpdir(), 'memlab-api-test', `${process.pid}`);
|
|
71
|
-
fs_extra_1.default.mkdirsSync(workDir);
|
|
72
|
-
const result = yield (0, index_1.run)({
|
|
73
|
-
scenario: selfDefinedScenario,
|
|
74
|
-
evalInBrowserAfterInitLoad: injectDetachedDOMElements,
|
|
75
|
-
workDir,
|
|
76
|
-
});
|
|
77
|
-
// detected all different leak trace cluster
|
|
78
|
-
expect(result.leaks.length).toBe(1);
|
|
79
|
-
// expect all traces are found
|
|
80
|
-
expect(result.leaks.some(leak => JSON.stringify(leak).includes('_randomObject')));
|
|
81
|
-
const reader = result.runResult;
|
|
82
|
-
expect(path_1.default.resolve(reader.getRootDirectory())).toBe(path_1.default.resolve(workDir));
|
|
83
|
-
}), E2ETestSettings_1.testTimeout);
|
|
84
61
|
function injectDetachedDOMElementsWithPrompt() {
|
|
85
62
|
// @ts-ignore
|
|
86
63
|
window.injectHookForLink4 = () => {
|
|
@@ -121,7 +98,7 @@ test('test runner should work with pages having pop up dialog', () => __awaiter(
|
|
|
121
98
|
return node.name === 'TestObject' && node.type === 'object';
|
|
122
99
|
},
|
|
123
100
|
};
|
|
124
|
-
const workDir = path_1.default.join(os_1.default.tmpdir(), 'memlab-api-test',
|
|
101
|
+
const workDir = path_1.default.join(os_1.default.tmpdir(), 'memlab-api-test', (0, E2ETestSettings_1.getUniqueID)());
|
|
125
102
|
fs_extra_1.default.mkdirsSync(workDir);
|
|
126
103
|
const result = yield (0, index_1.run)({
|
|
127
104
|
scenario: selfDefinedScenario,
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
* @format
|
|
8
|
+
* @oncall web_perf_infra
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=E2EMemoryLeakFilter.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"E2EMemoryLeakFilter.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/API/E2EMemoryLeakFilter.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,121 @@
|
|
|
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
|
+
* @format
|
|
9
|
+
* @oncall web_perf_infra
|
|
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 os_1 = __importDefault(require("os"));
|
|
25
|
+
const path_1 = __importDefault(require("path"));
|
|
26
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
27
|
+
const index_1 = require("../../index");
|
|
28
|
+
const E2ETestSettings_1 = require("./lib/E2ETestSettings");
|
|
29
|
+
beforeEach(E2ETestSettings_1.testSetup);
|
|
30
|
+
function injectDetachedDOMElements() {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
window.injectHookForLink4 = () => {
|
|
33
|
+
class TestObject {
|
|
34
|
+
}
|
|
35
|
+
const arr = [];
|
|
36
|
+
for (let i = 0; i < 23; ++i) {
|
|
37
|
+
arr.push(document.createElement('div'));
|
|
38
|
+
}
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
window.__injectedValue = arr;
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
window._path_1 = { x: { y: document.createElement('div') } };
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
window._path_2 = new Set([document.createElement('div')]);
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
window._randomObject = [new TestObject()];
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
test('self-defined leak detector can find TestObject', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
+
const selfDefinedScenario = {
|
|
51
|
+
app: () => 'test-spa',
|
|
52
|
+
url: () => '',
|
|
53
|
+
action: (page) => __awaiter(void 0, void 0, void 0, function* () { return yield page.click('[data-testid="link-4"]'); }),
|
|
54
|
+
leakFilter: (node) => {
|
|
55
|
+
return node.name === 'TestObject' && node.type === 'object';
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const workDir = path_1.default.join(os_1.default.tmpdir(), 'memlab-api-test', (0, E2ETestSettings_1.getUniqueID)());
|
|
59
|
+
fs_extra_1.default.mkdirsSync(workDir);
|
|
60
|
+
const result = yield (0, index_1.run)({
|
|
61
|
+
scenario: selfDefinedScenario,
|
|
62
|
+
evalInBrowserAfterInitLoad: injectDetachedDOMElements,
|
|
63
|
+
workDir,
|
|
64
|
+
});
|
|
65
|
+
// detected all different leak trace cluster
|
|
66
|
+
expect(result.leaks.length).toBe(1);
|
|
67
|
+
// expect all traces are found
|
|
68
|
+
expect(result.leaks.some(leak => JSON.stringify(leak).includes('_randomObject')));
|
|
69
|
+
const reader = result.runResult;
|
|
70
|
+
expect(path_1.default.resolve(reader.getRootDirectory())).toBe(path_1.default.resolve(workDir));
|
|
71
|
+
}), E2ETestSettings_1.testTimeout);
|
|
72
|
+
test('self-defined retainer trace filter work as expected (part 1)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
const selfDefinedScenario = {
|
|
74
|
+
app: () => 'test-spa',
|
|
75
|
+
url: () => '',
|
|
76
|
+
action: (page) => __awaiter(void 0, void 0, void 0, function* () { return yield page.click('[data-testid="link-4"]'); }),
|
|
77
|
+
retainerReferenceFilter: (edge) => {
|
|
78
|
+
return edge.name_or_index !== '_path_1';
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
const workDir = path_1.default.join(os_1.default.tmpdir(), 'memlab-api-test', (0, E2ETestSettings_1.getUniqueID)());
|
|
82
|
+
fs_extra_1.default.mkdirsSync(workDir);
|
|
83
|
+
const result = yield (0, index_1.run)({
|
|
84
|
+
scenario: selfDefinedScenario,
|
|
85
|
+
evalInBrowserAfterInitLoad: injectDetachedDOMElements,
|
|
86
|
+
workDir,
|
|
87
|
+
});
|
|
88
|
+
// detected all different leak trace cluster
|
|
89
|
+
expect(result.leaks.length).toBe(1);
|
|
90
|
+
// expect the none of the traces to include _path_1
|
|
91
|
+
expect(result.leaks.every(leak => !JSON.stringify(leak).includes('_path_1')));
|
|
92
|
+
// expect some of the traces to include _path_2
|
|
93
|
+
expect(result.leaks.some(leak => JSON.stringify(leak).includes('_path_2')));
|
|
94
|
+
const reader = result.runResult;
|
|
95
|
+
expect(path_1.default.resolve(reader.getRootDirectory())).toBe(path_1.default.resolve(workDir));
|
|
96
|
+
}), E2ETestSettings_1.testTimeout);
|
|
97
|
+
test('self-defined retainer trace filter work as expected (part 2)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
|
+
const selfDefinedScenario = {
|
|
99
|
+
app: () => 'test-spa',
|
|
100
|
+
url: () => '',
|
|
101
|
+
action: (page) => __awaiter(void 0, void 0, void 0, function* () { return yield page.click('[data-testid="link-4"]'); }),
|
|
102
|
+
retainerReferenceFilter: (edge) => {
|
|
103
|
+
return edge.name_or_index !== '_path_2';
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
const workDir = path_1.default.join(os_1.default.tmpdir(), 'memlab-api-test', (0, E2ETestSettings_1.getUniqueID)());
|
|
107
|
+
fs_extra_1.default.mkdirsSync(workDir);
|
|
108
|
+
const result = yield (0, index_1.run)({
|
|
109
|
+
scenario: selfDefinedScenario,
|
|
110
|
+
evalInBrowserAfterInitLoad: injectDetachedDOMElements,
|
|
111
|
+
workDir,
|
|
112
|
+
});
|
|
113
|
+
// detected all different leak trace cluster
|
|
114
|
+
expect(result.leaks.length).toBe(1);
|
|
115
|
+
// expect the none of the traces to include _path_2
|
|
116
|
+
expect(result.leaks.every(leak => !JSON.stringify(leak).includes('_path_2')));
|
|
117
|
+
// expect some of the traces to include _path_1
|
|
118
|
+
expect(result.leaks.some(leak => JSON.stringify(leak).includes('_path_1')));
|
|
119
|
+
const reader = result.runResult;
|
|
120
|
+
expect(path_1.default.resolve(reader.getRootDirectory())).toBe(path_1.default.resolve(workDir));
|
|
121
|
+
}), E2ETestSettings_1.testTimeout);
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
export declare function registerPackage(): Promise<void>;
|
|
12
12
|
export * from './API';
|
|
13
13
|
export * from '@memlab/heap-analysis';
|
|
14
|
+
export * from './state/ConsoleModeManager';
|
|
14
15
|
export { default as BrowserInteractionResultReader } from './result-reader/BrowserInteractionResultReader';
|
|
15
16
|
export { default as SnapshotResultReader } from './result-reader/SnapshotResultReader';
|
|
16
17
|
export { dumpNodeHeapSnapshot, getNodeInnocentHeap, takeNodeMinimalHeap, } from '@memlab/core';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,gBAAgB;AAChB,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;AAED,cAAc,OAAO,CAAC;AACtB,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAC,OAAO,IAAI,8BAA8B,EAAC,MAAM,gDAAgD,CAAC;AACzG,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,sCAAsC,CAAC;AACrF,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,gBAAgB;AAChB,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,gBAAgB;AAChB,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;AAED,cAAc,OAAO,CAAC;AACtB,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EAAC,OAAO,IAAI,8BAA8B,EAAC,MAAM,gDAAgD,CAAC;AACzG,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,sCAAsC,CAAC;AACrF,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,gBAAgB;AAChB,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -47,6 +47,7 @@ function registerPackage() {
|
|
|
47
47
|
exports.registerPackage = registerPackage;
|
|
48
48
|
__exportStar(require("./API"), exports);
|
|
49
49
|
__exportStar(require("@memlab/heap-analysis"), exports);
|
|
50
|
+
__exportStar(require("./state/ConsoleModeManager"), exports);
|
|
50
51
|
var BrowserInteractionResultReader_1 = require("./result-reader/BrowserInteractionResultReader");
|
|
51
52
|
Object.defineProperty(exports, "BrowserInteractionResultReader", { enumerable: true, get: function () { return __importDefault(BrowserInteractionResultReader_1).default; } });
|
|
52
53
|
var SnapshotResultReader_1 = require("./result-reader/SnapshotResultReader");
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
* @format
|
|
8
|
+
* @oncall web_perf_infra
|
|
9
|
+
*/
|
|
10
|
+
import type { MemLabConfig, Optional, PuppeteerConfig } from '@memlab/core';
|
|
11
|
+
import type { ConsoleMode } from './ConsoleModeManager';
|
|
12
|
+
import type { RunOptions } from '../API';
|
|
13
|
+
export declare class APIState {
|
|
14
|
+
modes: Optional<Set<ConsoleMode>>;
|
|
15
|
+
puppeteerConfig: Optional<PuppeteerConfig>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Manage, save, and restore the current state of the API.
|
|
19
|
+
*/
|
|
20
|
+
declare class APIStateManager {
|
|
21
|
+
getAndUpdateState(config: MemLabConfig, options?: RunOptions): APIState;
|
|
22
|
+
restoreState(config: MemLabConfig, state: APIState): void;
|
|
23
|
+
}
|
|
24
|
+
declare const _default: APIStateManager;
|
|
25
|
+
export default _default;
|
|
26
|
+
//# sourceMappingURL=APIStateManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"APIStateManager.d.ts","sourceRoot":"","sources":["../../src/state/APIStateManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,QAAQ,CAAC;AAKvC,qBAAa,QAAQ;IACnB,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IAClC,eAAe,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,cAAM,eAAe;IACnB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,UAAe;IAUhE,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ;CAQnD;;AAED,wBAAqC"}
|
|
@@ -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
|
+
* @format
|
|
9
|
+
* @oncall web_perf_infra
|
|
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
|
+
exports.APIState = void 0;
|
|
16
|
+
const ConsoleModeManager_1 = __importDefault(require("./ConsoleModeManager"));
|
|
17
|
+
const PuppeteerConfigManager_1 = __importDefault(require("./PuppeteerConfigManager"));
|
|
18
|
+
class APIState {
|
|
19
|
+
}
|
|
20
|
+
exports.APIState = APIState;
|
|
21
|
+
/**
|
|
22
|
+
* Manage, save, and restore the current state of the API.
|
|
23
|
+
*/
|
|
24
|
+
class APIStateManager {
|
|
25
|
+
getAndUpdateState(config, options = {}) {
|
|
26
|
+
const state = new APIState();
|
|
27
|
+
state.modes = ConsoleModeManager_1.default.getAndUpdateState(config, options);
|
|
28
|
+
state.puppeteerConfig = PuppeteerConfigManager_1.default.getAndUpdateState(config, options);
|
|
29
|
+
return state;
|
|
30
|
+
}
|
|
31
|
+
restoreState(config, state) {
|
|
32
|
+
if (state.modes) {
|
|
33
|
+
ConsoleModeManager_1.default.restoreState(config, state.modes);
|
|
34
|
+
}
|
|
35
|
+
if (state.puppeteerConfig) {
|
|
36
|
+
PuppeteerConfigManager_1.default.restoreState(config, state.puppeteerConfig);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.default = new APIStateManager();
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
* @format
|
|
8
|
+
* @oncall web_perf_infra
|
|
9
|
+
*/
|
|
10
|
+
import { MemLabConfig, Nullable } from '@memlab/core';
|
|
11
|
+
import type { RunOptions } from '../API';
|
|
12
|
+
/**
|
|
13
|
+
* enum of all console mode options
|
|
14
|
+
*/
|
|
15
|
+
export declare enum ConsoleMode {
|
|
16
|
+
/**
|
|
17
|
+
* mute all terminal output, equivalent to using `--silent`
|
|
18
|
+
*/
|
|
19
|
+
SILENT = "SILENT",
|
|
20
|
+
/**
|
|
21
|
+
* continuous test mode, no terminal output overwrite or animation,
|
|
22
|
+
* equivalent to using `--sc`
|
|
23
|
+
*/
|
|
24
|
+
CONTINUOUS_TEST = "CONTINUOUS_TEST",
|
|
25
|
+
/**
|
|
26
|
+
* the default mode, there could be terminal output overwrite and animation,
|
|
27
|
+
*/
|
|
28
|
+
DEFAULT = "DEFAULT",
|
|
29
|
+
/**
|
|
30
|
+
* verbose mode, there could be terminal output overwrite and animation
|
|
31
|
+
*/
|
|
32
|
+
VERBOSE = "VERBOSE"
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Manage, save, and restore the current state of the Console modes.
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
declare class ConsoleModeManager {
|
|
39
|
+
getAndUpdateState(config: MemLabConfig, options?: RunOptions): Nullable<Set<ConsoleMode>>;
|
|
40
|
+
restoreState(config: MemLabConfig, modes: Nullable<Set<ConsoleMode>>): void;
|
|
41
|
+
private resetConsoleMode;
|
|
42
|
+
private setConsoleMode;
|
|
43
|
+
private getExistingConsoleModes;
|
|
44
|
+
}
|
|
45
|
+
/** @internal */
|
|
46
|
+
declare const _default: ConsoleModeManager;
|
|
47
|
+
export default _default;
|
|
48
|
+
//# sourceMappingURL=ConsoleModeManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsoleModeManager.d.ts","sourceRoot":"","sources":["../../src/state/ConsoleModeManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAkB,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,QAAQ,CAAC;AAEvC;;GAEG;AACH,oBAAY,WAAW;IACrB;;OAEG;IACH,MAAM,WAAW;IACjB;;;OAGG;IACH,eAAe,oBAAoB;IACnC;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,OAAO,YAAY;CACpB;AAED;;;GAGG;AACH,cAAM,kBAAkB;IACtB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,UAAe;IAIhE,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAUpE,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,cAAc;IAmCtB,OAAO,CAAC,uBAAuB;CAehC;AAED,gBAAgB;;AAChB,wBAAwC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
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
|
+
* @format
|
|
9
|
+
* @oncall web_perf_infra
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ConsoleMode = void 0;
|
|
13
|
+
const core_1 = require("@memlab/core");
|
|
14
|
+
/**
|
|
15
|
+
* enum of all console mode options
|
|
16
|
+
*/
|
|
17
|
+
var ConsoleMode;
|
|
18
|
+
(function (ConsoleMode) {
|
|
19
|
+
/**
|
|
20
|
+
* mute all terminal output, equivalent to using `--silent`
|
|
21
|
+
*/
|
|
22
|
+
ConsoleMode["SILENT"] = "SILENT";
|
|
23
|
+
/**
|
|
24
|
+
* continuous test mode, no terminal output overwrite or animation,
|
|
25
|
+
* equivalent to using `--sc`
|
|
26
|
+
*/
|
|
27
|
+
ConsoleMode["CONTINUOUS_TEST"] = "CONTINUOUS_TEST";
|
|
28
|
+
/**
|
|
29
|
+
* the default mode, there could be terminal output overwrite and animation,
|
|
30
|
+
*/
|
|
31
|
+
ConsoleMode["DEFAULT"] = "DEFAULT";
|
|
32
|
+
/**
|
|
33
|
+
* verbose mode, there could be terminal output overwrite and animation
|
|
34
|
+
*/
|
|
35
|
+
ConsoleMode["VERBOSE"] = "VERBOSE";
|
|
36
|
+
})(ConsoleMode = exports.ConsoleMode || (exports.ConsoleMode = {}));
|
|
37
|
+
/**
|
|
38
|
+
* Manage, save, and restore the current state of the Console modes.
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
class ConsoleModeManager {
|
|
42
|
+
getAndUpdateState(config, options = {}) {
|
|
43
|
+
return this.setConsoleMode(config, options.consoleMode, true);
|
|
44
|
+
}
|
|
45
|
+
restoreState(config, modes) {
|
|
46
|
+
if (modes == null) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.resetConsoleMode(config);
|
|
50
|
+
for (const mode of modes) {
|
|
51
|
+
this.setConsoleMode(config, mode, false);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
resetConsoleMode(config) {
|
|
55
|
+
config.muteConsole = false;
|
|
56
|
+
config.isContinuousTest = false;
|
|
57
|
+
config.verbose = false;
|
|
58
|
+
}
|
|
59
|
+
setConsoleMode(config, mode, reset) {
|
|
60
|
+
let existingModes = this.getExistingConsoleModes(config);
|
|
61
|
+
switch (mode) {
|
|
62
|
+
case ConsoleMode.SILENT:
|
|
63
|
+
reset && this.resetConsoleMode(config);
|
|
64
|
+
config.muteConsole = true;
|
|
65
|
+
break;
|
|
66
|
+
case ConsoleMode.CONTINUOUS_TEST:
|
|
67
|
+
reset && this.resetConsoleMode(config);
|
|
68
|
+
config.isContinuousTest = true;
|
|
69
|
+
break;
|
|
70
|
+
case ConsoleMode.DEFAULT:
|
|
71
|
+
reset && this.resetConsoleMode(config);
|
|
72
|
+
config.muteConsole = false;
|
|
73
|
+
config.isContinuousTest = false;
|
|
74
|
+
break;
|
|
75
|
+
case ConsoleMode.VERBOSE:
|
|
76
|
+
reset && this.resetConsoleMode(config);
|
|
77
|
+
config.verbose = true;
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
if (mode == null) {
|
|
81
|
+
existingModes = null;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
throw core_1.utils.haltOrThrow(`Unknown console mode: ${mode}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return existingModes;
|
|
88
|
+
}
|
|
89
|
+
getExistingConsoleModes(config) {
|
|
90
|
+
const modes = new Set([ConsoleMode.DEFAULT]);
|
|
91
|
+
if (config.muteConsole) {
|
|
92
|
+
modes.add(ConsoleMode.SILENT);
|
|
93
|
+
modes.delete(ConsoleMode.DEFAULT);
|
|
94
|
+
}
|
|
95
|
+
if (config.isContinuousTest) {
|
|
96
|
+
modes.add(ConsoleMode.CONTINUOUS_TEST);
|
|
97
|
+
modes.delete(ConsoleMode.DEFAULT);
|
|
98
|
+
}
|
|
99
|
+
if (config.verbose) {
|
|
100
|
+
modes.add(ConsoleMode.VERBOSE);
|
|
101
|
+
}
|
|
102
|
+
return modes;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** @internal */
|
|
106
|
+
exports.default = new ConsoleModeManager();
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
* @format
|
|
8
|
+
* @oncall web_perf_infra
|
|
9
|
+
*/
|
|
10
|
+
import type { MemLabConfig, PuppeteerConfig } from '@memlab/core';
|
|
11
|
+
import type { RunOptions } from '../API';
|
|
12
|
+
/**
|
|
13
|
+
* Manage, save, and restore the current state of the PuppeteerConfig.
|
|
14
|
+
*/
|
|
15
|
+
declare class PuppeteerStateManager {
|
|
16
|
+
getAndUpdateState(config: MemLabConfig, options?: RunOptions): PuppeteerConfig;
|
|
17
|
+
restoreState(config: MemLabConfig, puppeteerConfig: PuppeteerConfig): void;
|
|
18
|
+
}
|
|
19
|
+
declare const _default: PuppeteerStateManager;
|
|
20
|
+
export default _default;
|
|
21
|
+
//# sourceMappingURL=PuppeteerConfigManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PuppeteerConfigManager.d.ts","sourceRoot":"","sources":["../../src/state/PuppeteerConfigManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,QAAQ,CAAC;AAIvC;;GAEG;AACH,cAAM,qBAAqB;IACzB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,UAAe;IAWhE,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe;CAGpE;;AAED,wBAA2C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
* @format
|
|
9
|
+
* @oncall web_perf_infra
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const core_1 = require("@memlab/core");
|
|
13
|
+
/**
|
|
14
|
+
* Manage, save, and restore the current state of the PuppeteerConfig.
|
|
15
|
+
*/
|
|
16
|
+
class PuppeteerStateManager {
|
|
17
|
+
getAndUpdateState(config, options = {}) {
|
|
18
|
+
const existing = config.puppeteerConfig;
|
|
19
|
+
config.puppeteerConfig = Object.assign({}, config.puppeteerConfig);
|
|
20
|
+
config.externalCookiesFile = options.cookiesFile;
|
|
21
|
+
config.scenario = options.scenario;
|
|
22
|
+
if (options.chromiumBinary != null) {
|
|
23
|
+
core_1.utils.setChromiumBinary(config, options.chromiumBinary);
|
|
24
|
+
}
|
|
25
|
+
return existing;
|
|
26
|
+
}
|
|
27
|
+
restoreState(config, puppeteerConfig) {
|
|
28
|
+
config.puppeteerConfig = puppeteerConfig;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.default = new PuppeteerStateManager();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memlab/api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.27",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "memlab API",
|
|
6
6
|
"author": "Liang Gong <lgong@fb.com>",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@memlab/core": "^1.1.
|
|
31
|
-
"@memlab/e2e": "^1.0.
|
|
32
|
-
"@memlab/heap-analysis": "^1.0.
|
|
30
|
+
"@memlab/core": "^1.1.28",
|
|
31
|
+
"@memlab/e2e": "^1.0.28",
|
|
32
|
+
"@memlab/heap-analysis": "^1.0.25",
|
|
33
33
|
"ansi": "^0.3.1",
|
|
34
34
|
"babar": "^0.2.0",
|
|
35
35
|
"chalk": "^4.0.0",
|