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