BindingsTestRunner.dumpWorkspace=function(previousSnapshot){var uiSourceCodes=Workspace.workspace.uiSourceCodes().slice();var urls=uiSourceCodes.map(code=>code.url());urls=urls.map(url=>{if(!url.startsWith('debugger://'))
return url;return url.replace(/VM\d+/g,'VM[XXX]');});urls.sort(String.caseInsensetiveComparator);var isAdded=new Array(urls.length).fill(false);var removedLines=[];if(previousSnapshot){var diff=Diff.Diff.lineDiff(previousSnapshot,urls);var removedEntries=diff.filter(entry=>entry[0]===Diff.Diff.Operation.Delete).map(entry=>entry[1]);removedLines=[].concat.apply([],removedEntries);var index=0;for(var entry of diff){if(entry[0]===Diff.Diff.Operation.Delete)
continue;if(entry[0]===Diff.Diff.Operation.Equal){index+=entry[1].length;continue;}
for(var line of entry[1])
isAdded[index++]=true;}
var addedEntries=diff.filter(entry=>entry[0]===Diff.Diff.Operation.Insert).map(entry=>entry[1]);addedLines=[].concat.apply([],addedEntries);}
TestRunner.addResult(`Removed: ${removedLines.length} uiSourceCodes`);for(var url of removedLines)
TestRunner.addResult('[-] '+url);TestRunner.addResult(`Workspace: ${urls.length} uiSourceCodes.`);for(var i=0;i<urls.length;++i){var url=urls[i];var prefix=(isAdded[i]?'[+] ':'    ');TestRunner.addResult(prefix+url);}
return urls;};BindingsTestRunner.attachFrame=function(frameId,url,evalSourceURL){var evalSource=`(${attachFrame.toString()})('${frameId}', '${url}')`;if(evalSourceURL)
evalSource+='//# sourceURL='+evalSourceURL;return TestRunner.evaluateInPageAsync(evalSource);function attachFrame(frameId,url){var frame=document.createElement('iframe');frame.src=url;frame.id=frameId;document.body.appendChild(frame);return new Promise(x=>frame.onload=x);}};BindingsTestRunner.detachFrame=function(frameId,evalSourceURL){var evalSource=`(${detachFrame.toString()})('${frameId}')`;if(evalSourceURL)
evalSource+='//# sourceURL='+evalSourceURL;return TestRunner.evaluateInPagePromise(evalSource);function detachFrame(frameId){var frame=document.getElementById(frameId);frame.remove();}};BindingsTestRunner.navigateFrame=function(frameId,navigateURL,evalSourceURL){var evalSource=`(${navigateFrame.toString()})('${frameId}', '${navigateURL}')`;if(evalSourceURL)
evalSource+='//# sourceURL='+evalSourceURL;return TestRunner.evaluateInPageAsync(evalSource);function navigateFrame(frameId,url){var frame=document.getElementById(frameId);frame.src=url;return new Promise(x=>frame.onload=x);}};BindingsTestRunner.attachShadowDOM=function(id,templateSelector,evalSourceURL){var evalSource=`(${createShadowDOM.toString()})('${id}', '${templateSelector}')`;if(evalSourceURL)
evalSource+='//# sourceURL='+evalSourceURL;return TestRunner.evaluateInPagePromise(evalSource);function createShadowDOM(id,templateSelector){var shadowHost=document.createElement('div');shadowHost.setAttribute('id',id);let shadowRoot=shadowHost.attachShadow({mode:'open'});var t=document.querySelector(templateSelector);var instance=t.content.cloneNode(true);shadowRoot.appendChild(instance);document.body.appendChild(shadowHost);}};BindingsTestRunner.detachShadowDOM=function(id,evalSourceURL){var evalSource=`(${removeShadowDOM.toString()})('${id}')`;if(evalSourceURL)
evalSource+='//# sourceURL='+evalSourceURL;return TestRunner.evaluateInPagePromise(evalSource);function removeShadowDOM(id){document.querySelector('#'+id).remove();}};BindingsTestRunner.waitForStyleSheetRemoved=function(urlSuffix){var fulfill;var promise=new Promise(x=>fulfill=x);TestRunner.cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved,onStyleSheetRemoved);return promise;function onStyleSheetRemoved(event){var styleSheetHeader=event.data;if(!styleSheetHeader.resourceURL().endsWith(urlSuffix))
return;TestRunner.cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetRemoved,onStyleSheetRemoved);fulfill();}};TestRunner.addSniffer(Bindings.CompilerScriptMapping.prototype,'_sourceMapAttachedForTest',onSourceMap,true);TestRunner.addSniffer(Bindings.SASSSourceMapping.prototype,'_sourceMapAttachedForTest',onSourceMap,true);var sourceMapCallbacks=new Map();function onSourceMap(sourceMap){for(var urlSuffix of sourceMapCallbacks.keys()){if(sourceMap.url().endsWith(urlSuffix)){var callback=sourceMapCallbacks.get(urlSuffix);callback.call(null);sourceMapCallbacks.delete(urlSuffix);}}}
BindingsTestRunner.waitForSourceMap=function(sourceMapURLSuffix){var fulfill;var promise=new Promise(x=>fulfill=x);sourceMapCallbacks.set(sourceMapURLSuffix,fulfill);return promise;};var locationPool=new Bindings.LiveLocationPool();var nameSymbol=Symbol('LiveLocationNameForTest');var createdSymbol=Symbol('LiveLocationCreated');BindingsTestRunner.createDebuggerLiveLocation=function(name,urlSuffix,lineNumber,columnNumber){var script=TestRunner.debuggerModel.scripts().find(script=>script.sourceURL.endsWith(urlSuffix));var rawLocation=TestRunner.debuggerModel.createRawLocation(script,lineNumber||0,columnNumber||0);return Bindings.debuggerWorkspaceBinding.createLiveLocation(rawLocation,updateDelegate.bind(null,name),locationPool);};BindingsTestRunner.createCSSLiveLocation=function(name,urlSuffix,lineNumber,columnNumber){var header=TestRunner.cssModel.styleSheetHeaders().find(header=>header.resourceURL().endsWith(urlSuffix));var rawLocation=new SDK.CSSLocation(header,lineNumber||0,columnNumber||0);return Bindings.cssWorkspaceBinding.createLiveLocation(rawLocation,updateDelegate.bind(null,name),locationPool);};function updateDelegate(name,liveLocation){liveLocation[nameSymbol]=name;var hint=(liveLocation[createdSymbol]?'[ UPDATE ]':'[ CREATE ]');liveLocation[createdSymbol]=true;BindingsTestRunner.dumpLocation(liveLocation,hint);}
BindingsTestRunner.dumpLocation=function(liveLocation,hint){hint=hint||'[  GET   ]';var prefix=`${hint}  LiveLocation-${liveLocation[nameSymbol]}: `;var uiLocation=liveLocation.uiLocation();if(!uiLocation){TestRunner.addResult(prefix+'null');return;}
TestRunner.addResult(prefix+uiLocation.uiSourceCode.url()+':'+uiLocation.lineNumber+':'+uiLocation.columnNumber);};;InspectorFrontendHost.isolatedFileSystem=function(name){return BindingsTestRunner.TestFileSystem._instances[name];};BindingsTestRunner.TestFileSystem=function(fileSystemPath){this.root=new BindingsTestRunner.TestFileSystem.Entry(this,'',true,null);this.fileSystemPath=fileSystemPath;};BindingsTestRunner.TestFileSystem._instances={};BindingsTestRunner.TestFileSystem.prototype={dumpAsText:function(){var result=[];dfs(this.root,'');result[0]=this.fileSystemPath;return result.join('\n');function dfs(node,indent){result.push(indent+node.name);var newIndent=indent+'    ';for(var child of node._children)
dfs(child,newIndent);}},reportCreatedPromise:function(){return new Promise(fulfill=>this.reportCreated(fulfill));},reportCreated:function(callback){var fileSystemPath=this.fileSystemPath;BindingsTestRunner.TestFileSystem._instances[this.fileSystemPath]=this;InspectorFrontendHost.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemAdded,{fileSystem:{fileSystemPath:this.fileSystemPath,fileSystemName:this.fileSystemPath}});Persistence.isolatedFileSystemManager.addEventListener(Persistence.IsolatedFileSystemManager.Events.FileSystemAdded,created);function created(event){var fileSystem=event.data;if(fileSystem.path()!==fileSystemPath)
return;Persistence.isolatedFileSystemManager.removeEventListener(Persistence.IsolatedFileSystemManager.Events.FileSystemAdded,created);callback(fileSystem);}},reportRemoved:function(){delete BindingsTestRunner.TestFileSystem._instances[this.fileSystemPath];InspectorFrontendHost.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemRemoved,this.fileSystemPath);},addFileMapping:function(urlPrefix,pathPrefix){var fileSystemMapping=new Persistence.FileSystemMapping(Persistence.isolatedFileSystemManager);fileSystemMapping.addFileSystem(this.fileSystemPath);fileSystemMapping.addFileMapping(this.fileSystemPath,urlPrefix,pathPrefix);fileSystemMapping.dispose();Persistence.fileSystemMapping._loadFromSettings();},addFile:function(path,content,lastModified){var pathTokens=path.split('/');var node=this.root;var folders=pathTokens.slice(0,pathTokens.length-1);var fileName=pathTokens.peekLast();for(var folder of folders){var dir=node._childrenMap[folder];if(!dir)
dir=node.mkdir(folder);node=dir;}
var file=node.addFile(fileName,content);if(lastModified)
file._timestamp=lastModified;return file;}};BindingsTestRunner.TestFileSystem.Entry=function(fileSystem,name,isDirectory,parent){this._fileSystem=fileSystem;this.name=name;this._children=[];this._childrenMap={};this.isDirectory=isDirectory;this._timestamp=1000000;this._parent=parent;};BindingsTestRunner.TestFileSystem.Entry.prototype={get fullPath(){return(this.parent?this.parent.fullPath+'/'+this.name:'');},remove:function(success,failure){this._parent._removeChild(this,success,failure);},_removeChild:function(child,success,failure){var index=this._children.indexOf(child);if(index===-1){failure('Failed to remove file: file not found.');return;}
var fullPath=this._fileSystem.fileSystemPath+child.fullPath;this._children.splice(index,1);delete this._childrenMap[child.name];child.parent=null;InspectorFrontendHost.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved,{changed:[],added:[],removed:[fullPath]});success();},mkdir:function(name){var child=new BindingsTestRunner.TestFileSystem.Entry(this._fileSystem,name,true,this);this._childrenMap[name]=child;this._children.push(child);child.parent=this;return child;},addFile:function(name,content){var child=new BindingsTestRunner.TestFileSystem.Entry(this._fileSystem,name,false,this);this._childrenMap[name]=child;this._children.push(child);child.parent=this;child.content=new Blob([content],{type:'text/plain'});var fullPath=this._fileSystem.fileSystemPath+child.fullPath;InspectorFrontendHost.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved,{changed:[],added:[fullPath],removed:[]});return child;},setContent:function(content){this.content=new Blob([content],{type:'text/plain'});this._timestamp+=1000;var fullPath=this._fileSystem.fileSystemPath+this.fullPath;InspectorFrontendHost.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved,{changed:[fullPath],added:[],removed:[]});},createReader:function(){return new BindingsTestRunner.TestFileSystem.Reader(this._children);},createWriter:function(success,failure){success(new BindingsTestRunner.TestFileSystem.Writer(this));},file:function(callback){callback(this.content);},getDirectory:function(path,noop,callback,errorCallback){this.getEntry(path,noop,callback,errorCallback);},getFile:function(path,noop,callback,errorCallback){this.getEntry(path,noop,callback,errorCallback);},_createEntry:function(path,options,callback,errorCallback){var tokens=path.split('/');var name=tokens.pop();var parentEntry=this;for(var token of tokens)
parentEntry=parentEntry._childrenMap[token];var entry=parentEntry._childrenMap[name];if(entry&&options.exclusive){errorCallback(new DOMException('File exists: '+path,'InvalidModificationError'));return;}
if(!entry)
entry=parentEntry.addFile(name,'');callback(entry);},getEntry:function(path,options,callback,errorCallback){if(path.startsWith('/'))
path=path.substring(1);if(options&&options.create){this._createEntry(path,options,callback,errorCallback);return;}
if(!path){callback(this);return;}
var entry=this;for(var token of path.split('/'))
entry=entry._childrenMap[token];(entry?callback(entry):errorCallback(new DOMException('Path not found: '+path,'NotFoundError')));},getMetadata:function(success,failure){success({modificationTime:new Date(this._timestamp),size:(this.isDirectory?0:this.content.size)});},moveTo:function(parent,newName,callback,errorCallback){this._parent._children.remove(this);delete this._parent._childrenMap[this.name];this._parent=parent;this._parent._children.push(this);this.name=newName;this._parent._childrenMap[this.name]=this;callback(this);},getParent:function(callback,errorCallback){callback(this._parent);}};BindingsTestRunner.TestFileSystem.Reader=function(children){this._children=children;};BindingsTestRunner.TestFileSystem.Reader.prototype={readEntries:function(callback){var children=this._children;this._children=[];callback(children);}};BindingsTestRunner.TestFileSystem.Writer=function(entry){this._entry=entry;this._modificationTimesDelta=500;};BindingsTestRunner.TestFileSystem.Writer.prototype={write:function(blob){this._entry._timestamp+=this._modificationTimesDelta;this._entry.content=blob;if(this.onwriteend)
this.onwriteend();},truncate:function(num){this._entry._timestamp+=this._modificationTimesDelta;this._entry.content=this._entry.content.slice(0,num);if(this.onwriteend)
this.onwriteend();}};;BindingsTestRunner.addFiles=function(testFileSystem,files){for(var filePath in files){var file=files[filePath];testFileSystem.addFile(filePath,file.content,(file.time?file.time.getTime():0));}};var timeOverrides;var originalRequestMetadata;BindingsTestRunner.overrideNetworkModificationTime=function(urlToTime){if(!timeOverrides){timeOverrides=new Map();originalRequestMetadata=TestRunner.override(Bindings.ContentProviderBasedProject.prototype,'requestMetadata',overrideTime,true);}
for(var url in urlToTime)
timeOverrides.set(url,urlToTime[url]);function overrideTime(uiSourceCode){if(!timeOverrides.has(uiSourceCode.url()))
return originalRequestMetadata.call(this,uiSourceCode);var override=timeOverrides.get(uiSourceCode.url());return originalRequestMetadata.call(this,uiSourceCode).then(onOriginalMetadata.bind(null,override));}
function onOriginalMetadata(timeOverride,metadata){if(!timeOverride&&!metadata)
return null;return new Workspace.UISourceCodeMetadata(timeOverride,(metadata?metadata.contentSize:null));}};BindingsTestRunner.AutomappingTest=function(workspace){this._workspace=workspace;this._networkProject=new Bindings.ContentProviderBasedProject(this._workspace,'AUTOMAPPING',Workspace.projectTypes.Network,'simple website');if(workspace!==Workspace.workspace)
new Persistence.FileSystemWorkspaceBinding(Persistence.isolatedFileSystemManager,this._workspace);this._failedBindingsCount=0;this._automapping=new Persistence.Automapping(this._workspace,this._onBindingAdded.bind(this),this._onBindingRemoved.bind(this));TestRunner.addSniffer(this._automapping,'_onBindingFailedForTest',this._onBindingFailed.bind(this),true);TestRunner.addSniffer(this._automapping,'_onSweepHappenedForTest',this._onSweepHappened.bind(this),true);};BindingsTestRunner.AutomappingTest.prototype={removeResources:function(urls){for(var url of urls)
this._networkProject.removeFile(url);},addNetworkResources:function(assets){for(var url in assets){var asset=assets[url];var contentType=asset.contentType||Common.resourceTypes.Script;var contentProvider=new Common.StaticContentProvider(url,contentType,Promise.resolve(asset.content));var metadata=(typeof asset.content==='string'||asset.time?new Workspace.UISourceCodeMetadata(asset.time,asset.content.length):null);var uiSourceCode=this._networkProject.createUISourceCode(url,contentType);this._networkProject.addUISourceCodeWithProvider(uiSourceCode,contentProvider,metadata);}},waitUntilMappingIsStabilized:function(){var promise=new Promise(x=>this._stabilizedCallback=x);this._checkStabilized();return promise;},_onSweepHappened:function(){this._failedBindingsCount=0;this._checkStabilized();},_onBindingAdded:function(binding){TestRunner.addResult('Binding created: '+binding);this._checkStabilized();},_onBindingFailed:function(){++this._failedBindingsCount;this._checkStabilized();},_onBindingRemoved:function(binding){TestRunner.addResult('Binding removed: '+binding);this._checkStabilized();},_checkStabilized:function(){if(!this._stabilizedCallback||this._automapping._sweepThrottler._process)
return;var networkUISourceCodes=this._workspace.uiSourceCodesForProjectType(Workspace.projectTypes.Network);var stabilized=this._failedBindingsCount+this._automapping._bindings.size===networkUISourceCodes.length;if(stabilized){TestRunner.addResult('Mapping has stabilized.');var callback=this._stabilizedCallback;delete this._stabilizedCallback;callback.call(null);}}};;Runtime.experiments.enableForTest('persistenceValidation');Persistence.PersistenceBinding.prototype.toString=function(){var lines=['{','       network: '+this.network.url(),'    fileSystem: '+this.fileSystem.url(),'    exactMatch: '+this.exactMatch,'}'];return lines.join('\n');};BindingsTestRunner.waitForBinding=function(fileName){var uiSourceCodes=Workspace.workspace.uiSourceCodes();for(var uiSourceCode of uiSourceCodes){var binding=Persistence.persistence.binding(uiSourceCode);if(!binding)
continue;if(uiSourceCode.name()===fileName)
return Promise.resolve(binding);}
return TestRunner.waitForEvent(Persistence.Persistence.Events.BindingCreated,Persistence.persistence,binding=>binding.network.name()===fileName||binding.fileSystem.name()===fileName);};BindingsTestRunner.addFooJSFile=function(fs){return fs.root.mkdir('inspector').mkdir('persistence').mkdir('resources').addFile('foo.js','\n\nwindow.foo = ()=>\'foo\';');};BindingsTestRunner.forceUseDefaultMapping=function(){Persistence.persistence._setMappingForTest((bindingCreated,bindingRemoved)=>{return new Persistence.DefaultMapping(Workspace.workspace,Persistence.fileSystemMapping,bindingCreated,bindingRemoved);});};BindingsTestRunner.initializeTestMapping=function(){var testMapping;Persistence.persistence._setMappingForTest((bindingCreated,bindingRemoved)=>{testMapping=new TestMapping(bindingCreated,bindingRemoved);return testMapping;});return testMapping;};class TestMapping{constructor(onBindingAdded,onBindingRemoved){this._onBindingAdded=onBindingAdded;this._onBindingRemoved=onBindingRemoved;this._bindings=new Set();}
async addBinding(urlSuffix){if(this._findBinding(urlSuffix)){TestRunner.addResult(`FAILED TO ADD BINDING: binding already exists for ${urlSuffix}`);TestRunner.completeTest();return;}
var networkUISourceCode=await TestRunner.waitForUISourceCode(urlSuffix,Workspace.projectTypes.Network);var fileSystemUISourceCode=await TestRunner.waitForUISourceCode(urlSuffix,Workspace.projectTypes.FileSystem);var binding=new Persistence.PersistenceBinding(networkUISourceCode,fileSystemUISourceCode,false);this._bindings.add(binding);this._onBindingAdded.call(null,binding);}
_findBinding(urlSuffix){for(var binding of this._bindings){if(binding.network.url().endsWith(urlSuffix))
return binding;}
return null;}
async removeBinding(urlSuffix){var binding=this._findBinding(urlSuffix);if(!binding){TestRunner.addResult(`FAILED TO REMOVE BINDING: binding does not exist for ${urlSuffix}`);TestRunner.completeTest();return;}
this._bindings.delete(binding);this._onBindingRemoved.call(null,binding);}
dispose(){for(var binding of this._bindings)
this._onBindingRemoved.call(null,binding);this._bindings.clear();}};