@memlab/api 2.0.2 → 2.0.4
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.
|
@@ -27,6 +27,9 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
27
27
|
const index_1 = require("../../index");
|
|
28
28
|
const E2ETestSettings_1 = require("./lib/E2ETestSettings");
|
|
29
29
|
beforeEach(E2ETestSettings_1.testSetup);
|
|
30
|
+
function hasPathEdgeWithName(leak, edgeName) {
|
|
31
|
+
return Object.keys(leak).some(key => key.includes(`--${edgeName} (`));
|
|
32
|
+
}
|
|
30
33
|
function injectDetachedDOMElements() {
|
|
31
34
|
// @ts-ignore
|
|
32
35
|
window.injectHookForLink4 = () => {
|
|
@@ -74,8 +77,11 @@ test('self-defined retainer trace filter work as expected (part 1)', () => __awa
|
|
|
74
77
|
app: () => 'test-spa',
|
|
75
78
|
url: () => '',
|
|
76
79
|
action: (page) => __awaiter(void 0, void 0, void 0, function* () { return yield page.click('[data-testid="link-4"]'); }),
|
|
77
|
-
retainerReferenceFilter: (edge) => {
|
|
78
|
-
|
|
80
|
+
retainerReferenceFilter: (edge, _snapshot, isReferenceUsedByDefault) => {
|
|
81
|
+
if (edge.name_or_index === '_path_1') {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return isReferenceUsedByDefault;
|
|
79
85
|
},
|
|
80
86
|
};
|
|
81
87
|
const workDir = path_1.default.join(os_1.default.tmpdir(), 'memlab-api-test', (0, E2ETestSettings_1.getUniqueID)());
|
|
@@ -85,12 +91,12 @@ test('self-defined retainer trace filter work as expected (part 1)', () => __awa
|
|
|
85
91
|
evalInBrowserAfterInitLoad: injectDetachedDOMElements,
|
|
86
92
|
workDir,
|
|
87
93
|
});
|
|
88
|
-
// detected
|
|
89
|
-
expect(result.leaks.length).
|
|
90
|
-
// expect
|
|
91
|
-
expect(result.leaks.every(leak => !
|
|
92
|
-
// expect some of the
|
|
93
|
-
expect(result.leaks.some(leak =>
|
|
94
|
+
// detected leak trace clusters
|
|
95
|
+
expect(result.leaks.length).toBeGreaterThanOrEqual(1);
|
|
96
|
+
// expect none of the retainer trace paths to go through _path_1
|
|
97
|
+
expect(result.leaks.every(leak => !hasPathEdgeWithName(leak, '_path_1'))).toBe(true);
|
|
98
|
+
// expect some of the retainer trace paths to go through _path_2
|
|
99
|
+
expect(result.leaks.some(leak => hasPathEdgeWithName(leak, '_path_2'))).toBe(true);
|
|
94
100
|
const reader = result.runResult;
|
|
95
101
|
expect(path_1.default.resolve(reader.getRootDirectory())).toBe(path_1.default.resolve(workDir));
|
|
96
102
|
}), E2ETestSettings_1.testTimeout);
|
|
@@ -99,8 +105,11 @@ test('self-defined retainer trace filter work as expected (part 2)', () => __awa
|
|
|
99
105
|
app: () => 'test-spa',
|
|
100
106
|
url: () => '',
|
|
101
107
|
action: (page) => __awaiter(void 0, void 0, void 0, function* () { return yield page.click('[data-testid="link-4"]'); }),
|
|
102
|
-
retainerReferenceFilter: (edge) => {
|
|
103
|
-
|
|
108
|
+
retainerReferenceFilter: (edge, _snapshot, isReferenceUsedByDefault) => {
|
|
109
|
+
if (edge.name_or_index === '_path_2') {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
return isReferenceUsedByDefault;
|
|
104
113
|
},
|
|
105
114
|
};
|
|
106
115
|
const workDir = path_1.default.join(os_1.default.tmpdir(), 'memlab-api-test', (0, E2ETestSettings_1.getUniqueID)());
|
|
@@ -110,12 +119,12 @@ test('self-defined retainer trace filter work as expected (part 2)', () => __awa
|
|
|
110
119
|
evalInBrowserAfterInitLoad: injectDetachedDOMElements,
|
|
111
120
|
workDir,
|
|
112
121
|
});
|
|
113
|
-
// detected
|
|
114
|
-
expect(result.leaks.length).
|
|
115
|
-
// expect
|
|
116
|
-
expect(result.leaks.every(leak => !
|
|
117
|
-
// expect some of the
|
|
118
|
-
expect(result.leaks.some(leak =>
|
|
122
|
+
// detected leak trace clusters
|
|
123
|
+
expect(result.leaks.length).toBeGreaterThanOrEqual(1);
|
|
124
|
+
// expect none of the retainer trace paths to go through _path_2
|
|
125
|
+
expect(result.leaks.every(leak => !hasPathEdgeWithName(leak, '_path_2'))).toBe(true);
|
|
126
|
+
// expect some of the retainer trace paths to go through _path_1
|
|
127
|
+
expect(result.leaks.some(leak => hasPathEdgeWithName(leak, '_path_1'))).toBe(true);
|
|
119
128
|
const reader = result.runResult;
|
|
120
129
|
expect(path_1.default.resolve(reader.getRootDirectory())).toBe(path_1.default.resolve(workDir));
|
|
121
130
|
}), E2ETestSettings_1.testTimeout);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeapParserTestUtils.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/heap/lib/HeapParserTestUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"HeapParserTestUtils.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/heap/lib/HeapParserTestUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAWhD,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,IAAI,EACxB,eAAe,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,OAAO,GACpD,OAAO,CAAC,IAAI,CAAC,CAGf"}
|
|
@@ -23,6 +23,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.isExpectedSnapshot = isExpectedSnapshot;
|
|
25
25
|
const fs_1 = __importDefault(require("fs"));
|
|
26
|
+
const os_1 = __importDefault(require("os"));
|
|
26
27
|
const path_1 = __importDefault(require("path"));
|
|
27
28
|
const core_1 = require("@memlab/core");
|
|
28
29
|
const puppeteer = core_1.config.isFB
|
|
@@ -69,21 +70,27 @@ const TEST_URL = 'about:blank';
|
|
|
69
70
|
function dumpHeap(snapshotFile, leakInjector) {
|
|
70
71
|
return __awaiter(this, void 0, void 0, function* () {
|
|
71
72
|
core_1.utils.tryToMutePuppeteerWarning();
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
73
|
+
const userDataDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'memlab-heap-test-'));
|
|
74
|
+
try {
|
|
75
|
+
const browser = yield puppeteer.launch(Object.assign(Object.assign({}, core_1.config.puppeteerConfig), { userDataDir }));
|
|
76
|
+
const page = yield browser.newPage();
|
|
77
|
+
// set page size
|
|
78
|
+
yield page.setViewport({
|
|
79
|
+
width: 1680,
|
|
80
|
+
height: 1050,
|
|
81
|
+
deviceScaleFactor: 1,
|
|
82
|
+
});
|
|
83
|
+
// visit page
|
|
84
|
+
yield page.goto(TEST_URL);
|
|
85
|
+
// insert a memory leak object
|
|
86
|
+
yield page.evaluate(leakInjector);
|
|
87
|
+
// take a heap snapshot
|
|
88
|
+
yield saveSnapshotToFile(page, snapshotFile);
|
|
89
|
+
yield browser.close();
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
fs_1.default.rmSync(userDataDir, { recursive: true, force: true });
|
|
93
|
+
}
|
|
87
94
|
});
|
|
88
95
|
}
|
|
89
96
|
let fileId = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memlab/api",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "memlab API",
|
|
6
6
|
"author": "Liang Gong <lgong@meta.com>",
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@memlab/core": "^2.0.
|
|
31
|
-
"@memlab/e2e": "^2.0.
|
|
32
|
-
"@memlab/heap-analysis": "^2.0.
|
|
30
|
+
"@memlab/core": "^2.0.4",
|
|
31
|
+
"@memlab/e2e": "^2.0.4",
|
|
32
|
+
"@memlab/heap-analysis": "^2.0.4",
|
|
33
33
|
"ansi": "^0.3.1",
|
|
34
34
|
"babar": "^0.2.0",
|
|
35
35
|
"chalk": "^4.0.0",
|
|
36
36
|
"fs-extra": "^4.0.2",
|
|
37
37
|
"minimist": "^1.2.8",
|
|
38
|
-
"puppeteer": "
|
|
39
|
-
"puppeteer-core": "
|
|
38
|
+
"puppeteer": "24.31.0",
|
|
39
|
+
"puppeteer-core": "24.31.0",
|
|
40
40
|
"string-width": "^4.2.0",
|
|
41
41
|
"util.promisify": "^1.1.1",
|
|
42
42
|
"xvfb": "^0.4.0"
|