HeapProfilerTestRunner.createHeapSnapshotMockFactories=function(){HeapProfilerTestRunner.createJSHeapSnapshotMockObject=function(){return{_rootNodeIndex:0,_nodeTypeOffset:0,_nodeNameOffset:1,_nodeEdgeCountOffset:2,_nodeFieldCount:3,_edgeFieldsCount:3,_edgeTypeOffset:0,_edgeNameOffset:1,_edgeToNodeOffset:2,_nodeTypes:['hidden','object'],_edgeTypes:['element','property','shortcut'],_edgeShortcutType:-1,_edgeHiddenType:-1,_edgeElementType:0,_realNodesLength:18,nodes:new Uint32Array([0,0,2,1,1,2,1,2,2,1,3,1,1,4,0,1,5,0]),containmentEdges:new Uint32Array([2,6,3,1,7,6,0,1,6,1,8,9,1,9,9,1,10,12,1,11,15]),strings:['','A','B','C','D','E','a','b','ac','bc','bd','ce'],_firstEdgeIndexes:new Uint32Array([0,6,12,18,21,21,21]),createNode:HeapSnapshotWorker.JSHeapSnapshot.prototype.createNode,createEdge:HeapSnapshotWorker.JSHeapSnapshot.prototype.createEdge,createRetainingEdge:HeapSnapshotWorker.JSHeapSnapshot.prototype.createRetainingEdge};};HeapProfilerTestRunner.createHeapSnapshotMockRaw=function(){return{snapshot:{meta:{node_fields:['type','name','id','self_size','retained_size','dominator','edge_count'],node_types:[['hidden','object'],'','','','','',''],edge_fields:['type','name_or_index','to_node'],edge_types:[['element','property','shortcut'],'',''],location_fields:['object_index','script_id','line','column'],trace_function_info_fields:['function_id','name','script_name','script_id','line','column'],trace_node_fields:['id','function_info_index','count','size','children']},node_count:6,edge_count:7},nodes:[0,0,1,0,20,0,2,1,1,2,2,2,0,2,1,2,3,3,8,0,2,1,3,4,4,10,0,1,1,4,5,5,5,14,0,1,5,6,6,6,21,0],edges:[1,6,7,1,7,14,0,1,14,1,8,21,1,9,21,1,10,28,1,11,35],trace_function_infos:[0,2,1,0,0,0],trace_tree:[1,0,0,0,[]],locations:[0,1,2,3,18,2,3,4],strings:['','A','B','C','D','E','a','b','ac','bc','bd','ce']};};HeapProfilerTestRunner._postprocessHeapSnapshotMock=function(mock){mock.nodes=new Uint32Array(mock.nodes);mock.edges=new Uint32Array(mock.edges);return mock;};HeapProfilerTestRunner.createHeapSnapshotMock=function(){return HeapProfilerTestRunner._postprocessHeapSnapshotMock(HeapProfilerTestRunner.createHeapSnapshotMockRaw());};HeapProfilerTestRunner.createHeapSnapshotMockWithDOM=function(){return HeapProfilerTestRunner._postprocessHeapSnapshotMock({snapshot:{meta:{node_fields:['type','name','id','edge_count'],node_types:[['hidden','object','synthetic'],'','',''],edge_fields:['type','name_or_index','to_node'],edge_types:[['element','hidden','internal'],'',''],location_fields:['object_index','script_id','line','column']},node_count:13,edge_count:13},nodes:[2,0,1,4,1,11,2,2,1,11,3,3,2,5,4,0,2,6,5,1,1,1,6,0,1,2,7,1,1,4,8,2,1,8,9,0,1,7,10,0,1,3,11,0,1,10,12,0,1,9,13,0],edges:[0,1,4,0,2,8,0,3,12,0,4,16,0,1,20,0,2,24,0,1,24,0,2,28,1,3,32,0,1,36,0,1,40,2,12,44,2,1,48],locations:[0,2,1,1,6,2,2,2],strings:['','A','B','C','D','E','F','G','H','M','N','Window','native']});};HeapProfilerTestRunner.HeapNode=function(name,selfSize,type,id){this._type=type||HeapProfilerTestRunner.HeapNode.Type.object;this._name=name;this._selfSize=selfSize||0;this._builder=null;this._edges={};this._edgesCount=0;this._id=id;};HeapProfilerTestRunner.HeapNode.Type={'hidden':'hidden','array':'array','string':'string','object':'object','code':'code','closure':'closure','regexp':'regexp','number':'number','native':'native','synthetic':'synthetic','bigint':'bigint'};HeapProfilerTestRunner.HeapNode.prototype={linkNode:function(node,type,nameOrIndex){if(!this._builder){throw new Error('parent node is not connected to a snapshot');}
if(!node._builder){node._setBuilder(this._builder);}
if(nameOrIndex===undefined){nameOrIndex=this._edgesCount;}
++this._edgesCount;if(nameOrIndex in this._edges){throw new Error('Can\'t add edge with the same nameOrIndex. nameOrIndex: '+nameOrIndex+' oldNodeName: '+this._edges[nameOrIndex]._name+' newNodeName: '+node._name);}
this._edges[nameOrIndex]=new HeapProfilerTestRunner.HeapEdge(node,type,nameOrIndex);},_setBuilder:function(builder){if(this._builder){throw new Error('node reusing is prohibited');}
this._builder=builder;this._ordinal=this._builder._registerNode(this);},_serialize:function(rawSnapshot){rawSnapshot.nodes.push(this._builder.lookupNodeType(this._type));rawSnapshot.nodes.push(this._builder.lookupOrAddString(this._name));rawSnapshot.nodes.push(this._id||this._ordinal*2+1);rawSnapshot.nodes.push(this._selfSize);rawSnapshot.nodes.push(0);rawSnapshot.nodes.push(0);rawSnapshot.nodes.push(Object.keys(this._edges).length);for(const i in this._edges){this._edges[i]._serialize(rawSnapshot);}}};HeapProfilerTestRunner.HeapEdge=function(targetNode,type,nameOrIndex){this._targetNode=targetNode;this._type=type;this._nameOrIndex=nameOrIndex;};HeapProfilerTestRunner.HeapEdge.prototype={_serialize:function(rawSnapshot){if(!this._targetNode._builder){throw new Error('Inconsistent state of node: '+this._name+' no builder assigned');}
const builder=this._targetNode._builder;rawSnapshot.edges.push(builder.lookupEdgeType(this._type));rawSnapshot.edges.push((typeof this._nameOrIndex==='string'?builder.lookupOrAddString(this._nameOrIndex):this._nameOrIndex));rawSnapshot.edges.push(this._targetNode._ordinal*builder.nodeFieldsCount);}};HeapProfilerTestRunner.HeapEdge.Type={'context':'context','element':'element','property':'property','internal':'internal','hidden':'hidden','shortcut':'shortcut','weak':'weak'};HeapProfilerTestRunner.HeapSnapshotBuilder=function(){this._nodes=[];this._string2id={};this._strings=[];this.nodeFieldsCount=7;this._nodeTypesMap={};this._nodeTypesArray=[];for(const nodeType in HeapProfilerTestRunner.HeapNode.Type){this._nodeTypesMap[nodeType]=this._nodeTypesArray.length;this._nodeTypesArray.push(nodeType);}
this._edgeTypesMap={};this._edgeTypesArray=[];for(const edgeType in HeapProfilerTestRunner.HeapEdge.Type){this._edgeTypesMap[edgeType]=this._edgeTypesArray.length;this._edgeTypesArray.push(edgeType);}
this.rootNode=new HeapProfilerTestRunner.HeapNode('root',0,'object');this.rootNode._setBuilder(this);};HeapProfilerTestRunner.HeapSnapshotBuilder.prototype={generateSnapshot:function(){const rawSnapshot={'snapshot':{'meta':{'node_fields':['type','name','id','self_size','retained_size','dominator','edge_count'],'node_types':[this._nodeTypesArray,'string','number','number','number','number','number'],'edge_fields':['type','name_or_index','to_node'],'edge_types':[this._edgeTypesArray,'string_or_number','node']}},'nodes':[],'edges':[],'locations':[],'strings':[]};for(let i=0;i<this._nodes.length;++i){this._nodes[i]._serialize(rawSnapshot);}
rawSnapshot.strings=this._strings.slice();const meta=rawSnapshot.snapshot.meta;rawSnapshot.snapshot.edge_count=rawSnapshot.edges.length/meta.edge_fields.length;rawSnapshot.snapshot.node_count=rawSnapshot.nodes.length/meta.node_fields.length;return rawSnapshot;},createJSHeapSnapshot:function(){const parsedSnapshot=HeapProfilerTestRunner._postprocessHeapSnapshotMock(this.generateSnapshot());return new HeapSnapshotWorker.JSHeapSnapshot(parsedSnapshot,new HeapSnapshotWorker.HeapSnapshotProgress());},_registerNode:function(node){this._nodes.push(node);return this._nodes.length-1;},lookupNodeType:function(typeName){if(typeName===undefined){throw new Error('wrong node type: '+typeName);}
if(!(typeName in this._nodeTypesMap)){throw new Error('wrong node type name: '+typeName);}
return this._nodeTypesMap[typeName];},lookupEdgeType:function(typeName){if(!(typeName in this._edgeTypesMap)){throw new Error('wrong edge type name: '+typeName);}
return this._edgeTypesMap[typeName];},lookupOrAddString:function(string){if(string in this._string2id){return this._string2id[string];}
this._string2id[string]=this._strings.length;this._strings.push(string);return this._strings.length-1;}};HeapProfilerTestRunner.createHeapSnapshot=function(instanceCount,firstId){let seed=881669;function pseudoRandom(limit){seed=seed*355109+153763>>2&65535;return seed%limit;}
const builder=new HeapProfilerTestRunner.HeapSnapshotBuilder();const rootNode=builder.rootNode;const gcRootsNode=new HeapProfilerTestRunner.HeapNode('(GC roots)',0,HeapProfilerTestRunner.HeapNode.Type.synthetic);rootNode.linkNode(gcRootsNode,HeapProfilerTestRunner.HeapEdge.Type.element);const windowNode=new HeapProfilerTestRunner.HeapNode('Window',20);rootNode.linkNode(windowNode,HeapProfilerTestRunner.HeapEdge.Type.shortcut);gcRootsNode.linkNode(windowNode,HeapProfilerTestRunner.HeapEdge.Type.element);for(let i=0;i<instanceCount;++i){const sizeOfB=pseudoRandom(20)+1;const nodeB=new HeapProfilerTestRunner.HeapNode('B',sizeOfB,undefined,firstId++);windowNode.linkNode(nodeB,HeapProfilerTestRunner.HeapEdge.Type.element);const sizeOfA=pseudoRandom(50)+1;const nodeA=new HeapProfilerTestRunner.HeapNode('A',sizeOfA,undefined,firstId++);nodeB.linkNode(nodeA,HeapProfilerTestRunner.HeapEdge.Type.property,'a');nodeA.linkNode(nodeA,HeapProfilerTestRunner.HeapEdge.Type.property,'a');}
return builder.generateSnapshot();};};HeapProfilerTestRunner.createHeapSnapshotMockFactories();HeapProfilerTestRunner.startProfilerTest=function(callback){TestRunner.addResult('Profiler was enabled.');HeapProfilerTestRunner._panelReset=TestRunner.override(UI.panels.heap_profiler,'_reset',function(){},true);TestRunner.addSniffer(UI.panels.heap_profiler,'_addProfileHeader',HeapProfilerTestRunner._profileHeaderAdded,true);TestRunner.addSniffer(Profiler.ProfileView.prototype,'refresh',HeapProfilerTestRunner._profileViewRefresh,true);TestRunner.addSniffer(Profiler.HeapSnapshotView.prototype,'show',HeapProfilerTestRunner._snapshotViewShown,true);Profiler.HeapSnapshotContainmentDataGrid.prototype.defaultPopulateCount=function(){return 10;};Profiler.HeapSnapshotConstructorsDataGrid.prototype.defaultPopulateCount=function(){return 10;};Profiler.HeapSnapshotDiffDataGrid.prototype.defaultPopulateCount=function(){return 5;};TestRunner.addResult('Detailed heap profiles were enabled.');TestRunner.safeWrap(callback)();};HeapProfilerTestRunner.completeProfilerTest=function(){TestRunner.addResult('');TestRunner.addResult('Profiler was disabled.');TestRunner.completeTest();};HeapProfilerTestRunner.runHeapSnapshotTestSuite=function(testSuite){const testSuiteTests=testSuite.slice();let completeTestStack;function runner(){if(!testSuiteTests.length){if(completeTestStack){TestRunner.addResult('FAIL: test already completed at '+completeTestStack);}
HeapProfilerTestRunner.completeProfilerTest();completeTestStack=new Error().stack;return;}
const nextTest=testSuiteTests.shift();TestRunner.addResult('');TestRunner.addResult('Running: '+/function\s([^(]*)/.exec(nextTest)[1]);HeapProfilerTestRunner._panelReset.call(UI.panels.heap_profiler);TestRunner.safeWrap(nextTest)(runner,runner);}
HeapProfilerTestRunner.startProfilerTest(runner);};HeapProfilerTestRunner.assertColumnContentsEqual=function(reference,actual){const length=Math.min(reference.length,actual.length);for(let i=0;i<length;++i){TestRunner.assertEquals(reference[i],actual[i],'row '+i);}
if(reference.length>length){TestRunner.addResult('extra rows in reference array:\n'+reference.slice(length).join('\n'));}else if(actual.length>length){TestRunner.addResult('extra rows in actual array:\n'+actual.slice(length).join('\n'));}};HeapProfilerTestRunner.checkArrayIsSorted=function(contents,sortType,sortOrder){function simpleComparator(a,b){return(a<b?-1:(a>b?1:0));}
function parseSize(size){return parseInt(size.replace(/[\xa0,]/g,''),10);}
const extractor={text:function(data){data;},number:function(data){return parseInt(data,10);},size:parseSize,name:function(data){return data;},id:function(data){return parseInt(data,10);}}[sortType];if(!extractor){TestRunner.addResult('Invalid sort type: '+sortType);return;}
let acceptableComparisonResult;if(sortOrder===DataGrid.DataGrid.Order.Ascending){acceptableComparisonResult=-1;}else if(sortOrder===DataGrid.DataGrid.Order.Descending){acceptableComparisonResult=1;}else{TestRunner.addResult('Invalid sort order: '+sortOrder);return;}
for(let i=0;i<contents.length-1;++i){const a=extractor(contents[i]);const b=extractor(contents[i+1]);const result=simpleComparator(a,b);if(result!==0&&result!==acceptableComparisonResult){TestRunner.addResult('Elements '+i+' and '+(i+1)+' are out of order: '+a+' '+b+' ('+sortOrder+')');}}};HeapProfilerTestRunner.clickColumn=function(column,callback){callback=TestRunner.safeWrap(callback);const cell=this._currentGrid()._headerTableHeaders[column.id];const event={target:{enclosingNodeOrSelfWithNodeName:function(){return cell;}}};function sortingComplete(){HeapProfilerTestRunner._currentGrid().removeEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete,sortingComplete,this);TestRunner.assertEquals(column.id,this._currentGrid().sortColumnId(),'unexpected sorting');column.sort=this._currentGrid().sortOrder();function callCallback(){callback(column);}
setTimeout(callCallback,0);}
HeapProfilerTestRunner._currentGrid().addEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete,sortingComplete,this);this._currentGrid()._clickInHeaderCell(event);};HeapProfilerTestRunner.clickRowAndGetRetainers=function(row,callback){callback=TestRunner.safeWrap(callback);const event={target:{enclosingNodeOrSelfWithNodeName:function(){return row._element;},selectedNode:row}};this._currentGrid()._mouseDownInDataTable(event);const rootNode=HeapProfilerTestRunner.currentProfileView()._retainmentDataGrid.rootNode();rootNode.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(()=>callback(rootNode));};HeapProfilerTestRunner.clickShowMoreButton=function(buttonName,row,callback){callback=TestRunner.safeWrap(callback);const parent=row.parent;parent.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(()=>setTimeout(()=>callback(parent),0));row[buttonName].click();};HeapProfilerTestRunner.columnContents=function(column,row){this._currentGrid().updateVisibleNodes();const columnOrdinal=HeapProfilerTestRunner.viewColumns().indexOf(column);const result=[];const parent=row||this._currentGrid().rootNode();for(let node=parent.children[0];node;node=node.traverseNextNode(true,parent,true)){if(!node.selectable){continue;}
let content=node.element().children[columnOrdinal];if(content.firstElementChild){content=content.firstElementChild;}
result.push(content.textContent);}
return result;};HeapProfilerTestRunner.countDataRows=function(row,filter){let result=0;filter=filter||function(node){return node.selectable;};for(let node=row.children[0];node;node=node.traverseNextNode(true,row,true)){if(filter(node)){++result;}}
return result;};HeapProfilerTestRunner.expandRow=function(row,callback){callback=TestRunner.safeWrap(callback);row.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(()=>setTimeout(()=>callback(row),0));(function expand(){if(row.hasChildren()){row.expand();}else{setTimeout(expand,0);}})();};HeapProfilerTestRunner.expandRowPromise=function(row){return new Promise(resolve=>HeapProfilerTestRunner.expandRow(row,resolve));};HeapProfilerTestRunner.findAndExpandGCRoots=function(callback){HeapProfilerTestRunner.findAndExpandRow('(GC roots)',callback);};HeapProfilerTestRunner.findAndExpandWindow=function(callback){HeapProfilerTestRunner.findAndExpandRow('Window',callback);};HeapProfilerTestRunner.findAndExpandRow=async function(name,callback){const row=HeapProfilerTestRunner.findRow(name);TestRunner.assertEquals(true,!!row,`"${name}" row`);await HeapProfilerTestRunner.expandRowPromise(row);TestRunner.safeWrap(callback)(row);return row;};HeapProfilerTestRunner.findButtonsNode=function(row,startNode){for(let node=startNode||row.children[0];node;node=node.traverseNextNode(true,row,true)){if(!node.selectable&&node.showNext){return node;}}
return null;};HeapProfilerTestRunner.findRow=function(name,parent){return HeapProfilerTestRunner.findMatchingRow(node=>node._name===name,parent);};HeapProfilerTestRunner.findMatchingRow=function(matcher,parent){parent=parent||this._currentGrid().rootNode();for(let node=parent.children[0];node;node=node.traverseNextNode(true,parent,true)){if(matcher(node)){return node;}}
return null;};HeapProfilerTestRunner.switchToView=function(title,callback){return new Promise(resolve=>{callback=TestRunner.safeWrap(callback);const view=UI.panels.heap_profiler.visibleView;view._changePerspectiveAndWait(title).then(callback).then(resolve);HeapProfilerTestRunner._currentGrid().scrollContainer.style.height='10000px';});};HeapProfilerTestRunner.takeAndOpenSnapshot=async function(generator,callback){callback=TestRunner.safeWrap(callback);const snapshot=generator();const profileType=Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType;function pushGeneratedSnapshot(reportProgress){if(reportProgress){profileType._reportHeapSnapshotProgress({data:{done:50,total:100,finished:false}});profileType._reportHeapSnapshotProgress({data:{done:100,total:100,finished:true}});}
snapshot.snapshot.typeId='HEAP';profileType._addHeapSnapshotChunk({data:JSON.stringify(snapshot)});return Promise.resolve();}
HeapProfilerTestRunner._takeAndOpenSnapshotCallback=callback;TestRunner.override(TestRunner.HeapProfilerAgent,'takeHeapSnapshot',pushGeneratedSnapshot);if(!UI.context.flavor(SDK.HeapProfilerModel)){await new Promise(resolve=>UI.context.addFlavorChangeListener(SDK.HeapProfilerModel,resolve));}
profileType._takeHeapSnapshot();};HeapProfilerTestRunner.takeSnapshotPromise=function(){return new Promise(resolve=>{const heapProfileType=Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType;heapProfileType.addEventListener(Profiler.HeapSnapshotProfileType.SnapshotReceived,finishHeapSnapshot);heapProfileType._takeHeapSnapshot();function finishHeapSnapshot(){const profiles=heapProfileType.getProfiles();if(!profiles.length){throw'FAILED: no profiles found.';}
if(profiles.length>1){throw`FAILED: wrong number of recorded profiles was found. profiles.length = ${profiles.length}`;}
const profile=profiles[0];UI.panels.heap_profiler.showProfile(profile);const dataGrid=HeapProfilerTestRunner.currentProfileView()._dataGrid;dataGrid.addEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete,sortingComplete,null);function sortingComplete(){dataGrid.removeEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete,sortingComplete,null);resolve(profile);}}});};HeapProfilerTestRunner.viewColumns=function(){return HeapProfilerTestRunner._currentGrid()._columnsArray;};HeapProfilerTestRunner.currentProfileView=function(){return UI.panels.heap_profiler.visibleView;};HeapProfilerTestRunner._currentGrid=function(){return this.currentProfileView()._dataGrid;};HeapProfilerTestRunner._snapshotViewShown=function(){if(HeapProfilerTestRunner._takeAndOpenSnapshotCallback){const callback=HeapProfilerTestRunner._takeAndOpenSnapshotCallback;HeapProfilerTestRunner._takeAndOpenSnapshotCallback=null;const dataGrid=this._dataGrid;function sortingComplete(){dataGrid.removeEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete,sortingComplete,null);callback();}
dataGrid.addEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete,sortingComplete,null);}};HeapProfilerTestRunner.showProfileWhenAdded=function(title){HeapProfilerTestRunner._showProfileWhenAdded=title;return new Promise(resolve=>HeapProfilerTestRunner._waitUntilProfileViewIsShown(title,resolve));};HeapProfilerTestRunner._profileHeaderAdded=function(profile){if(HeapProfilerTestRunner._showProfileWhenAdded===profile.title){UI.panels.heap_profiler.showProfile(profile);}};HeapProfilerTestRunner._waitUntilProfileViewIsShown=function(title,callback){callback=TestRunner.safeWrap(callback);const profilesPanel=UI.panels.heap_profiler;if(profilesPanel.visibleView&&profilesPanel.visibleView.profile&&profilesPanel.visibleView._profileHeader.title===title){callback(profilesPanel.visibleView);}else{HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback={title:title,callback:callback};}};HeapProfilerTestRunner._profileViewRefresh=function(){if(HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback&&HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback.title===this._profileHeader.title){const callback=HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback;delete HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback;callback.callback(this);}};HeapProfilerTestRunner.startSamplingHeapProfiler=async function(){if(!UI.context.flavor(SDK.HeapProfilerModel)){await new Promise(resolve=>UI.context.addFlavorChangeListener(SDK.HeapProfilerModel,resolve));}
Profiler.SamplingHeapProfileType.instance._startRecordingProfile();};HeapProfilerTestRunner.stopSamplingHeapProfiler=function(){Profiler.SamplingHeapProfileType.instance._stopRecordingProfile();};;