66725a537e
This changes remoteObjectId format from "{injectedScriptId:123,id:456}" to "<isolateId>.<contextId>.<id>". Prepending isolateId fixes the problem that remote object ids clash between processes. This is especially troubling during cross-process navigation in Chromium, see bug. We also stop producing and parsing unnecessary json for object ids. Drive-by: fixed some tests dumping object ids. Most tests avoid dumping unstable values like ids, but there were few that still did. BUG=chromium:1137143 Change-Id: Ia019757fb95704ccb718d3ea6cc54bde1a133382 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2461731 Commit-Queue: Dmitry Gozman <dgozman@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#70592}
136 lines
5.4 KiB
JavaScript
136 lines
5.4 KiB
JavaScript
// Copyright 2018 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
const {session, contextGroup, Protocol} =
|
|
InspectorTest.start('RemoteObject.CustomPreview');
|
|
|
|
(async function test() {
|
|
contextGroup.addScript(`
|
|
var a = {name: 'a'};
|
|
var b = {name: 'b'};
|
|
var c = {name: 'c'};
|
|
a.formattableBy1 = true;
|
|
b.formattableBy2 = true;
|
|
c.formattableBy1 = true;
|
|
c.formattableBy2 = true;
|
|
var formatter1 = {
|
|
header: (x) => x.formattableBy1 ? ['span', {}, 'Header formatted by 1 ', x.name] : null,
|
|
hasBody: () => true,
|
|
body: (x) => ['span', {}, 'Body formatted by 1 ', x.name, ['object', {object: {}}]]
|
|
};
|
|
var formatter2 = {
|
|
header: (x) => x.formattableBy2 ? ['span', {}, 'Header formatted by 2 ', x.name] : null,
|
|
hasBody: (x) => true,
|
|
body: (x) => ['span', {}, 'Body formatted by 2 ', x.name]
|
|
};
|
|
var configTest = {};
|
|
var formatterWithConfig1 = {
|
|
header: function(x, config) {
|
|
if (x !== configTest || config)
|
|
return null;
|
|
return ['span', {}, 'Formatter with config ', ['object', {'object': x, 'config': {'info': 'additional info'}}]];
|
|
},
|
|
hasBody: (x) => false,
|
|
body: (x) => { throw 'Unreachable'; }
|
|
}
|
|
var formatterWithConfig2 = {
|
|
header: function(x, config) {
|
|
if (x !== configTest || !config)
|
|
return null;
|
|
return ['span', {}, 'Header ', 'info: ', config.info];
|
|
},
|
|
hasBody: (x, config) => config && config.info,
|
|
body: (x, config) => ['span', {}, 'body', 'info: ', config.info]
|
|
}
|
|
this.devtoolsFormatters = [formatter1, formatter2, formatterWithConfig1, formatterWithConfig2];
|
|
`);
|
|
|
|
Protocol.Runtime.enable();
|
|
Protocol.Runtime.setCustomObjectFormatterEnabled({enabled: true});
|
|
|
|
Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
|
|
InspectorTest.log('Dump custom previews..');
|
|
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'a'}));
|
|
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'b'}));
|
|
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'c'}));
|
|
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'configTest'}));
|
|
InspectorTest.log('Change formatters order and dump again..');
|
|
await Protocol.Runtime.evaluate({
|
|
expression: 'this.devtoolsFormatters = [formatter2, formatter1, formatterWithConfig1, formatterWithConfig2]'
|
|
});
|
|
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'a'}));
|
|
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'b'}));
|
|
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'c'}));
|
|
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'configTest'}));
|
|
|
|
InspectorTest.log('Test Runtime.getProperties');
|
|
const {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({expression: '({a})'});
|
|
const {result:{result}} = await Protocol.Runtime.getProperties({
|
|
objectId, ownProperties: true, generatePreview: true});
|
|
await dumpCustomPreview(result.find(value => value.name === 'a').value);
|
|
|
|
InspectorTest.log('Try to break custom preview..');
|
|
await Protocol.Runtime.evaluate({
|
|
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
|
|
get: () => { throw 1; },
|
|
configurable: true
|
|
})`
|
|
});
|
|
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
|
|
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
|
|
|
|
await Protocol.Runtime.evaluate({
|
|
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
|
|
get: () => {
|
|
const arr = [1];
|
|
Object.defineProperty(arr, 0, { get: () => { throw 2; }});
|
|
return arr;
|
|
},
|
|
configurable: true
|
|
})`
|
|
});
|
|
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
|
|
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
|
|
|
|
await Protocol.Runtime.evaluate({
|
|
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
|
|
get: () => [{get header() { throw 3; }}],
|
|
configurable: true
|
|
})`
|
|
});
|
|
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
|
|
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
|
|
|
|
await Protocol.Runtime.evaluate({
|
|
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
|
|
get: () => [{header: () => { throw 4; }}],
|
|
configurable: true
|
|
})`
|
|
});
|
|
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
|
|
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
|
|
|
|
InspectorTest.completeTest();
|
|
})()
|
|
|
|
function dumpCustomPreviewForEvaluate(result) {
|
|
return dumpCustomPreview(result.result.result);
|
|
}
|
|
|
|
async function dumpCustomPreview(result) {
|
|
const { objectId, customPreview } = result;
|
|
if (customPreview.header)
|
|
customPreview.header = JSON.parse(customPreview.header);
|
|
InspectorTest.logMessage(customPreview);
|
|
if (customPreview.bodyGetterId) {
|
|
const body = await Protocol.Runtime.callFunctionOn({
|
|
objectId,
|
|
functionDeclaration: 'function(bodyGetter) { return bodyGetter.call(this); }',
|
|
arguments: [ { objectId: customPreview.bodyGetterId } ],
|
|
returnByValue: true
|
|
});
|
|
InspectorTest.logMessage(body);
|
|
}
|
|
}
|