mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-01 08:34:02 +03:00
fix: better formatting for sparse arrays (#20379)
Right now arrays preview yields all array elements. In case of a sparse array with a single element on index 10000000, this results in a large string that OOM Node.js. This patch changes pretty-printing. For example: ```ts // Given this array const a = []; a[10] = 1; // Before this patch, pretty printing will yield: "[,,,,,,,,1]" // With this patch, pretty printing yields: "[empty x 9, 1]" ``` The new array pretty-printing is equal to what Chrome DevTools do to render sparse arrays. Fixes #20347
This commit is contained in:
parent
5b93c1d2f9
commit
9ca9b08d90
@ -137,11 +137,7 @@ function renderPreview(object: Protocol.Runtime.RemoteObject): string | undefine
|
||||
tokens.push(`${name}: ${value}`);
|
||||
return `{${tokens.join(', ')}}`;
|
||||
}
|
||||
if (object.subtype === 'array' && object.preview) {
|
||||
const result = [];
|
||||
for (const { name, value } of object.preview.properties)
|
||||
result[+name] = value;
|
||||
return '[' + String(result) + ']';
|
||||
}
|
||||
if (object.subtype === 'array' && object.preview)
|
||||
return js.sparseArrayToString(object.preview.properties);
|
||||
return object.description;
|
||||
}
|
||||
|
@ -328,3 +328,27 @@ export class JavaScriptErrorInEvaluate extends Error {
|
||||
export function isJavaScriptErrorInEvaluate(error: Error) {
|
||||
return error instanceof JavaScriptErrorInEvaluate;
|
||||
}
|
||||
|
||||
export function sparseArrayToString(entries: { name: string, value?: any }[]): string {
|
||||
const arrayEntries = [];
|
||||
for (const { name, value } of entries) {
|
||||
const index = +name;
|
||||
if (isNaN(index) || index < 0)
|
||||
continue;
|
||||
arrayEntries.push({ index, value });
|
||||
}
|
||||
arrayEntries.sort((a, b) => a.index - b.index);
|
||||
let lastIndex = -1;
|
||||
const tokens = [];
|
||||
for (const { index, value } of arrayEntries) {
|
||||
const emptyItems = index - lastIndex - 1;
|
||||
if (emptyItems === 1)
|
||||
tokens.push(`empty`);
|
||||
else if (emptyItems > 1)
|
||||
tokens.push(`empty x ${emptyItems}`);
|
||||
tokens.push(String(value));
|
||||
lastIndex = index;
|
||||
}
|
||||
|
||||
return '[' + tokens.join(', ') + ']';
|
||||
}
|
||||
|
@ -142,11 +142,7 @@ function renderPreview(object: Protocol.Runtime.RemoteObject): string | undefine
|
||||
tokens.push(`${name}: ${value}`);
|
||||
return `{${tokens.join(', ')}}`;
|
||||
}
|
||||
if (object.subtype === 'array' && object.preview) {
|
||||
const result = [];
|
||||
for (const { name, value } of object.preview.properties!)
|
||||
result[+name] = value;
|
||||
return '[' + String(result) + ']';
|
||||
}
|
||||
if (object.subtype === 'array' && object.preview)
|
||||
return js.sparseArrayToString(object.preview.properties!);
|
||||
return object.description;
|
||||
}
|
||||
|
@ -32,6 +32,23 @@ it('should work for complicated objects', async ({ page, browserName }) => {
|
||||
expect(aHandle.toString()).toBe('JSHandle@object');
|
||||
});
|
||||
|
||||
it('should beautifully render sparse arrays', async ({ page, browserName }) => {
|
||||
const [msg] = await Promise.all([
|
||||
page.waitForEvent('console'),
|
||||
page.evaluateHandle(() => {
|
||||
const a = [];
|
||||
a[1] = 1;
|
||||
a[10] = 2;
|
||||
a[100] = 3;
|
||||
console.log(a);
|
||||
}),
|
||||
]);
|
||||
if (browserName === 'firefox')
|
||||
expect(msg.text()).toBe('Array');
|
||||
else
|
||||
expect(msg.text()).toBe('[empty, 1, empty x 8, 2, empty x 89, 3]');
|
||||
});
|
||||
|
||||
it('should work for promises', async ({ page }) => {
|
||||
// wrap the promise in an object, otherwise we will await.
|
||||
const wrapperHandle = await page.evaluateHandle(() => ({ b: Promise.resolve(123) }));
|
||||
|
@ -183,7 +183,7 @@ it('should use object previews for arrays and objects', async ({ page, browserNa
|
||||
await page.evaluate(() => console.log([1, 2, 3], { a: 1 }, window));
|
||||
|
||||
if (browserName !== 'firefox')
|
||||
expect(text).toEqual('[1,2,3] {a: 1} Window');
|
||||
expect(text).toEqual('[1, 2, 3] {a: 1} Window');
|
||||
else
|
||||
expect(text).toEqual('Array JSHandle@object JSHandle@object');
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user