michael@0: michael@0: michael@0: const nsIFilePicker = Components.interfaces.nsIFilePicker; michael@0: const nsILayoutRegressionTester = Components.interfaces.nsILayoutRegressionTester; michael@0: michael@0: const kTestTypeBaseline = 1; michael@0: const kTestTypeVerify = 2; michael@0: const kTestTypeVerifyAndCompare = 3; michael@0: const kTestTypeCompare = 4; michael@0: michael@0: const kTestSourceSingleFile = 1; michael@0: const kTestSourceDirList = 2; michael@0: michael@0: var gTestcaseDirArray = new Array; // array of nsILocalFiles michael@0: michael@0: var gBaselineOutputDir; // nsIFile michael@0: var gVerifyOutputDir; // nsIFile michael@0: michael@0: var gBaselineFileExtension; // string michael@0: var gVerifyFileExtension; // string michael@0: michael@0: var gTestType; // baseline, verify, compare etc. michael@0: michael@0: var gTestWindow; michael@0: var gTestURLs = new Array; michael@0: var gTestURLsIndex; michael@0: michael@0: function DoOnload() michael@0: { michael@0: netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); michael@0: michael@0: // clear any values that the form manager may have unhelpfully filled in michael@0: document.testForm.singleTestFileInput.value = ""; michael@0: document.testForm.baselineOutputDir.value = ""; michael@0: document.testForm.verifyOutputDir.value = ""; michael@0: michael@0: InitFormFromPrefs(); michael@0: michael@0: UpdateRunTestsButton(); michael@0: } michael@0: michael@0: function InitFormFromPrefs() michael@0: { michael@0: // load prefs michael@0: try { michael@0: var testURL = GetStringPref("nglayout.debug.testcaseURL"); michael@0: document.testForm.singleTestFileInput.value = testURL; michael@0: michael@0: var baselineDirURL = GetStringPref("nglayout.debug.baselineDirURL"); michael@0: gBaselineOutputDir = GetFileFromURISpec(baselineDirURL); michael@0: document.testForm.baselineOutputDir.value = gBaselineOutputDir.path; michael@0: michael@0: var verifyDirURL = GetStringPref("nglayout.debug.verifyDirURL"); michael@0: gVerifyOutputDir = GetFileFromURISpec(verifyDirURL); michael@0: document.testForm.verifyOutputDir.value = gVerifyOutputDir.path; michael@0: michael@0: var dirIndex = 0; michael@0: while (true) // we'll throw when we reach a nonexistent pref michael@0: { michael@0: var curDir = GetStringPref("nglayout.debug.testcaseDir" + dirIndex); michael@0: var dirFileSpec = GetFileFromURISpec(curDir); michael@0: gTestcaseDirArray.push(dirFileSpec); michael@0: dirIndex ++; michael@0: } michael@0: } michael@0: catch(e) michael@0: { michael@0: } michael@0: michael@0: RebuildTestDirsSelect(); michael@0: } michael@0: michael@0: function SaveFormToPrefs() michael@0: { michael@0: SaveStringPref("nglayout.debug.testcaseURL", document.testForm.singleTestFileInput.value); michael@0: michael@0: // save prefs michael@0: if (gBaselineOutputDir) michael@0: { michael@0: var baselineDirURL = GetURISpecFromFile(gBaselineOutputDir); michael@0: SaveStringPref("nglayout.debug.baselineDirURL", baselineDirURL); michael@0: } michael@0: michael@0: if (gVerifyOutputDir) michael@0: { michael@0: var verifyDirURL = GetURISpecFromFile(gVerifyOutputDir); michael@0: SaveStringPref("nglayout.debug.verifyDirURL", verifyDirURL); michael@0: } michael@0: michael@0: var dirIndex; michael@0: for (dirIndex = 0; dirIndex < gTestcaseDirArray.length; dirIndex ++) michael@0: { michael@0: var curURL = GetURISpecFromFile(gTestcaseDirArray[dirIndex]); michael@0: SaveStringPref("nglayout.debug.testcaseDir" + dirIndex, curURL); michael@0: } michael@0: try michael@0: { michael@0: // clear prefs for higher indices until we throw michael@0: while (1) michael@0: { michael@0: ClearPref("nglayout.debug.testcaseDir" + dirIndex); michael@0: } michael@0: } michael@0: catch(e) michael@0: { michael@0: } michael@0: michael@0: } michael@0: michael@0: function GetURISpecFromFile(inFile) michael@0: { michael@0: var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); michael@0: var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); michael@0: return fileHandler.getURLSpecFromFile(inFile); michael@0: } michael@0: michael@0: function GetFileFromURISpec(uriSpec) michael@0: { michael@0: var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); michael@0: var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); michael@0: return fileHandler.getFileFromURLSpec(uriSpec); michael@0: } michael@0: michael@0: function SaveStringPref(inPrefName, inPrefValue) michael@0: { michael@0: var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch); michael@0: prefs.setCharPref(inPrefName, inPrefValue); michael@0: } michael@0: michael@0: function GetStringPref(inPrefName) michael@0: { michael@0: var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch); michael@0: return prefs.getCharPref(inPrefName); michael@0: } michael@0: michael@0: function ClearPref(inPrefName) michael@0: { michael@0: var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch); michael@0: prefs.clearUserPref(inPrefName); michael@0: } michael@0: michael@0: function WriteOutput(aText, aReplace, aColorString) michael@0: { michael@0: var outputDiv = document.getElementById("results"); michael@0: michael@0: if (aReplace) michael@0: ClearOutput(); michael@0: michael@0: var childDiv = document.createElement("div"); michael@0: var textNode = document.createTextNode(aText); michael@0: childDiv.appendChild(textNode); michael@0: childDiv.setAttribute("style", "color: " + aColorString + ";"); michael@0: outputDiv.appendChild(childDiv); michael@0: } michael@0: michael@0: function ClearOutput() michael@0: { michael@0: var outputDiv = document.getElementById("results"); michael@0: var curChild; michael@0: while (curChild = outputDiv.firstChild) michael@0: outputDiv.removeChild(curChild); michael@0: } michael@0: michael@0: // returns an nsIFile michael@0: function PickDirectory() michael@0: { michael@0: netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); michael@0: michael@0: var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); michael@0: fp.init(window, "Pick a directory", nsIFilePicker.modeGetFolder); michael@0: var result = fp.show(); michael@0: if (result == nsIFilePicker.returnCancel) michael@0: throw("User cancelled"); michael@0: michael@0: var chosenDir = fp.file; michael@0: return chosenDir; michael@0: } michael@0: michael@0: michael@0: // returns a url string michael@0: function PickFileURL() michael@0: { michael@0: netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); michael@0: michael@0: var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); michael@0: fp.init(window, "Pick a directory", nsIFilePicker.modeOpen); michael@0: fp.appendFilters(nsIFilePicker.filterHTML + nsIFilePicker.filterText); michael@0: michael@0: var result = fp.show(); michael@0: if (result == nsIFilePicker.returnCancel) michael@0: throw("User cancelled"); michael@0: michael@0: return fp.fileURL.spec; michael@0: } michael@0: michael@0: function RebuildTestDirsSelect() michael@0: { michael@0: netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); michael@0: var dirsSelect = document.getElementById("testDirsSelect"); michael@0: michael@0: // rebuild it from gTestcaseDirArray michael@0: while (dirsSelect.length) michael@0: dirsSelect.remove(0); michael@0: michael@0: var i; michael@0: for (i = 0; i < gTestcaseDirArray.length; i ++) michael@0: { michael@0: var curDir = gTestcaseDirArray[i]; michael@0: michael@0: var optionElement = document.createElement("option"); michael@0: var textNode = document.createTextNode(curDir.leafName); michael@0: michael@0: optionElement.appendChild(textNode); michael@0: dirsSelect.add(optionElement, null); michael@0: } michael@0: michael@0: UpdateRunTestsButton(); michael@0: } michael@0: michael@0: // set the 'single testcase' file michael@0: function ChooseTestcaseFile() michael@0: { michael@0: var dirInput = document.getElementById("singleTestFileInput"); michael@0: dirInput.value = PickFileURL(); michael@0: michael@0: UpdateRunTestsButton(); michael@0: } michael@0: michael@0: function AppendTestcaseDir() michael@0: { michael@0: netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); michael@0: michael@0: var chosenDir = PickDirectory(); michael@0: // does the array already contain this dir? michael@0: var i; michael@0: for (i = 0; i < gTestcaseDirArray.length; i ++) michael@0: { michael@0: var curElement = gTestcaseDirArray[i]; michael@0: if (curElement.equals(chosenDir)) // nsIFile::Equals michael@0: return; michael@0: } michael@0: michael@0: gTestcaseDirArray[gTestcaseDirArray.length] = chosenDir; michael@0: RebuildTestDirsSelect(); michael@0: } michael@0: michael@0: function RemoveTestcaseDir() michael@0: { michael@0: var dirsSelect = document.getElementById("testDirsSelect"); michael@0: if (dirsSelect.selectedIndex != -1) michael@0: { michael@0: gTestcaseDirArray.splice(dirsSelect.selectedIndex, 1); michael@0: RebuildTestDirsSelect(); michael@0: } michael@0: } michael@0: michael@0: function InputOptionsValid() michael@0: { michael@0: if (document.testForm.testType[0].checked) michael@0: { michael@0: // need a test file michael@0: var testcaseURL = document.testForm.singleTestFileInput.value; michael@0: if (testcaseURL.length == 0) return false; michael@0: } michael@0: else if (document.testForm.testType[1].checked) michael@0: { michael@0: // need at least one dir michael@0: if (gTestcaseDirArray.length == 0) return false; michael@0: } michael@0: else michael@0: return false; michael@0: michael@0: return true; michael@0: } michael@0: michael@0: function OutputOptionsValid() michael@0: { michael@0: var testType = GetTestType(); michael@0: michael@0: switch (testType) michael@0: { michael@0: case kTestTypeBaseline: michael@0: if (!gBaselineOutputDir) return false; michael@0: break; michael@0: michael@0: case kTestTypeVerify: michael@0: if (!gVerifyOutputDir) return false; michael@0: break; michael@0: michael@0: case kTestTypeVerifyAndCompare: michael@0: case kTestTypeCompare: michael@0: if (!gBaselineOutputDir || !gVerifyOutputDir) return false; michael@0: break; michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: function UpdateRunTestsButton() michael@0: { michael@0: var testType = GetTestType(); michael@0: var dataValid = OutputOptionsValid(); michael@0: if (testType != kTestTypeCompare) michael@0: dataValid &= InputOptionsValid(); michael@0: document.testForm.runTests.disabled = !dataValid; michael@0: } michael@0: michael@0: // returns nsIFile, sets the input value michael@0: function ChooseOutputDirectory(inputElementID) michael@0: { michael@0: netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); michael@0: var chosenDir = PickDirectory(); michael@0: michael@0: var inputElement = document.getElementById(inputElementID); michael@0: inputElement.value = chosenDir.path; michael@0: michael@0: return chosenDir; michael@0: } michael@0: michael@0: michael@0: function CompareFrameDumps(testFileBasename, baselineDir, baselineExt, verifyDir, verifyExt) michael@0: { michael@0: var debugObject = Components.classes["@mozilla.org/layout-debug/regressiontester;1"].createInstance(nsILayoutRegressionTester); michael@0: michael@0: var baseFile = baselineDir.clone(); michael@0: baseFile.append(testFileBasename + baselineExt); michael@0: michael@0: var verifyFile = verifyDir.clone(); michael@0: verifyFile.append(testFileBasename + verifyExt); michael@0: michael@0: var filesDiffer = debugObject.compareFrameModels(baseFile, verifyFile, nsILayoutRegressionTester.COMPARE_FLAGS_BRIEF); michael@0: if (filesDiffer) michael@0: { michael@0: WriteOutput("Test file '" + baseFile.leafName + "' failed", false, "red"); michael@0: } michael@0: else michael@0: { michael@0: WriteOutput("Test file '" + baseFile.leafName + "' passed", false, "green"); michael@0: } michael@0: } michael@0: michael@0: function DumpFrames(testWindow, testFileName, outputDir, outputFileExtension) michael@0: { michael@0: var debugObject = Components.classes["@mozilla.org/layout-debug/regressiontester;1"].createInstance(nsILayoutRegressionTester); michael@0: michael@0: var outputFile = outputDir.clone(); michael@0: outputFile.append(testFileName.replace(".html", outputFileExtension)); michael@0: michael@0: dump("Dumping frame model for " + testFileName + " to " + outputFile.leafName + "\n"); michael@0: var result = debugObject.dumpFrameModel(testWindow, outputFile, nsILayoutRegressionTester.DUMP_FLAGS_MASK_DEFAULT); michael@0: if (result != 0) michael@0: { michael@0: WriteOutput("dumpFrameModel for " + testFileName + " failed", false, "orange"); michael@0: } michael@0: } michael@0: michael@0: function LoadTestURL(testWindow, theURL) michael@0: { michael@0: dump("Loading test " + theURL + "\n"); michael@0: // we use a 1/2 second delay to give time for async reflows to happen michael@0: testWindow.onload = setTimeout("HandleTestWindowLoad(gTestWindow)", 1000); michael@0: testWindow.location.href = theURL; michael@0: } michael@0: michael@0: function HandleTestWindowLoad(testWindow) michael@0: { michael@0: netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); michael@0: michael@0: var outputDir; michael@0: var outputFileExtension; michael@0: var runCompare = false; michael@0: michael@0: switch (gTestType) michael@0: { michael@0: case kTestTypeBaseline: michael@0: outputDir = gBaselineOutputDir; michael@0: outputFileExtension = gBaselineFileExtension; michael@0: break; michael@0: michael@0: case kTestTypeVerify: michael@0: outputDir = gVerifyOutputDir; michael@0: outputFileExtension = gVerifyFileExtension; michael@0: break; michael@0: michael@0: case kTestTypeVerifyAndCompare: michael@0: outputDir = gVerifyOutputDir; michael@0: outputFileExtension = gVerifyFileExtension; michael@0: runCompare = true; michael@0: break; michael@0: michael@0: case kTestTypeCompare: michael@0: dump("Should never get here"); michael@0: break; michael@0: } michael@0: michael@0: var loadedURL = testWindow.location.href; michael@0: var loadedFile = loadedURL.substring(loadedURL.lastIndexOf('/') + 1); michael@0: michael@0: DumpFrames(testWindow, loadedFile, outputDir, outputFileExtension); michael@0: michael@0: if (runCompare) michael@0: { michael@0: var testFileBasename = loadedFile.replace(".html", ""); michael@0: CompareFrameDumps(testFileBasename, gBaselineOutputDir, gBaselineFileExtension, gVerifyOutputDir, gVerifyFileExtension); michael@0: } michael@0: michael@0: // now fire of the next one, if we have one michael@0: var nextURL = gTestURLs[gTestURLsIndex++]; michael@0: if (nextURL) michael@0: LoadTestURL(testWindow, nextURL); michael@0: else michael@0: testWindow.close(); michael@0: } michael@0: michael@0: michael@0: function AddDirectoryEntriesToTestList(inDirFile, inRequiredExtension) michael@0: { michael@0: var enumerator = inDirFile.directoryEntries; michael@0: michael@0: while (enumerator.hasMoreElements()) michael@0: { michael@0: var curFile = enumerator.getNext(); michael@0: curFile = curFile.QueryInterface(Components.interfaces.nsIFile); michael@0: michael@0: var leafName = curFile.leafName; michael@0: if (leafName.indexOf(inRequiredExtension) != -1) michael@0: { michael@0: var fileURI = GetURISpecFromFile(curFile); michael@0: gTestURLs.push(fileURI); michael@0: } michael@0: } michael@0: } michael@0: michael@0: michael@0: // returns an array of filenames michael@0: function DirectoryEntriesToArray(inDirFile, inRequiredExtension) michael@0: { michael@0: var fileArray = new Array; michael@0: michael@0: var enumerator = inDirFile.directoryEntries; michael@0: while (enumerator.hasMoreElements()) michael@0: { michael@0: var curFile = enumerator.getNext(); michael@0: curFile = curFile.QueryInterface(Components.interfaces.nsIFile); michael@0: var leafName = curFile.leafName; michael@0: if (leafName.indexOf(inRequiredExtension) != -1) michael@0: { michael@0: fileArray.push(leafName); michael@0: } michael@0: } michael@0: michael@0: return fileArray; michael@0: } michael@0: michael@0: michael@0: function BuildTestURLsList(testSourceType) michael@0: { michael@0: // clear the array michael@0: gTestURLs.splice(0, gTestURLs.length); michael@0: gTestURLsIndex = 0; michael@0: michael@0: if (testSourceType == kTestSourceSingleFile) michael@0: { michael@0: var testURL = document.testForm.singleTestFileInput.value; michael@0: if (testURL.substr(-5) != ".html") michael@0: { michael@0: // append /index.html if we have to michael@0: if (testURL.substr(-1) != "/") michael@0: testURL += "/"; michael@0: testURL += "index.html"; michael@0: } michael@0: gTestURLs[0] = testURL; michael@0: } michael@0: else michael@0: { michael@0: for (var i = 0; i < gTestcaseDirArray.length; i++) michael@0: { michael@0: var dirFile = gTestcaseDirArray[i]; // nsIFile for the dir michael@0: AddDirectoryEntriesToTestList(dirFile, ".html"); michael@0: } michael@0: } michael@0: } michael@0: michael@0: function CompareFilesInDir(inBaseDir, inBaseExtension, inVerifyDir, inVerifyExtension) michael@0: { michael@0: var comapareFiles = DirectoryEntriesToArray(inBaseDir, inBaseExtension); michael@0: michael@0: for (var i = 0; i < comapareFiles.length; i ++) michael@0: { michael@0: var curFilename = comapareFiles[i]; michael@0: var testFileBasename = curFilename.replace(inBaseExtension, ""); michael@0: CompareFrameDumps(testFileBasename, inBaseDir, inBaseExtension, inVerifyDir, inVerifyExtension); michael@0: } michael@0: } michael@0: michael@0: function GetTestType() michael@0: { michael@0: if (document.testForm.doWhat[0].checked) michael@0: return kTestTypeBaseline; michael@0: michael@0: if (document.testForm.doWhat[1].checked) michael@0: return kTestTypeVerify; michael@0: michael@0: if (document.testForm.doWhat[2].checked) michael@0: return kTestTypeVerifyAndCompare; michael@0: michael@0: if (document.testForm.doWhat[3].checked) michael@0: return kTestTypeCompare; michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: function RunTests() michael@0: { michael@0: netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); michael@0: michael@0: ClearOutput(); michael@0: SaveFormToPrefs(); michael@0: michael@0: var testSourceType; michael@0: if (document.testForm.testType[0].checked) michael@0: testSourceType = kTestSourceSingleFile; michael@0: else michael@0: testSourceType = kTestSourceDirList; michael@0: michael@0: gTestType = GetTestType(); michael@0: michael@0: gBaselineFileExtension = document.testForm.baselineFileExtension.value; michael@0: gVerifyFileExtension = document.testForm.verifyFileExtension.value; michael@0: michael@0: if (gTestType == kTestTypeCompare) michael@0: { michael@0: // to compare, we'll just run through all the files in the michael@0: // baseline and verify dirs, and compare those that exist in michael@0: // both. michael@0: CompareFilesInDir(gBaselineOutputDir, gBaselineFileExtension, gVerifyOutputDir, gVerifyFileExtension); michael@0: } michael@0: else michael@0: { michael@0: BuildTestURLsList(testSourceType); michael@0: michael@0: gTestWindow = window.open("about:blank", "Test window", michael@0: "width=800,height=600,status=yes,toolbars=no"); michael@0: michael@0: // start the first load michael@0: var testURL = gTestURLs[0]; michael@0: gTestURLsIndex = 1; michael@0: LoadTestURL(gTestWindow, testURL); michael@0: } michael@0: michael@0: } michael@0: michael@0: