profoundjs
Version:
Profound.js Framework and Server
233 lines (194 loc) • 8.03 kB
JavaScript
;
const urlParams = new URLSearchParams(window.location.search);
const run1Id = urlParams.get("run1");
const run2Id = urlParams.get("run2");
const frame1 = document.getElementById("frame1");
const frame2 = document.getElementById("frame2");
function init() {
if (!run1Id || !run2Id) {
document.getElementById("page-title").innerText = "Missing run IDs in URL.";
return;
}
frame1.src = "/auto-testing/work-with-test?runid=" + run1Id;
frame2.src = "/auto-testing/work-with-test?runid=" + run2Id;
setupSync();
}
function formatTimeDifference(diffMs) {
let absDiff = Math.abs(diffMs);
let sign = diffMs > 0 ? "+" : "-";
let formatted;
if (absDiff < 1000) {
formatted = absDiff.toFixed(2) + "ms";
}
else {
formatted = (absDiff / 1000).toFixed(2) + "s";
}
return "(" + sign + formatted + ")";
}
/**
* Update the Performance tab in a frame to show color-coded comparison
* against the other frame's data.
*/
function updatePerformanceComparison(win, otherWin) {
if (!win || !win.pui || !win.pui.autoTesting) return;
if (!otherWin || !otherWin.pui || !otherWin.pui.autoTesting) return;
let at = win.pui.autoTesting;
let otherAt = otherWin.pui.autoTesting;
if (!at.data || !otherAt.data) return;
let tab = at.tabs["Performance"];
if (!tab) return;
let stepIndex = at.data.selectedStepIndex;
if (stepIndex == null) return;
let step = at.data.steps[stepIndex];
let otherStep = otherAt.data.steps[stepIndex];
if (!step) return;
// Get the value cells from the Performance table
let rows = tab.querySelectorAll("tbody tr");
if (rows.length === 0) return;
// Step runtime comparison (first row)
let stepValueCell = rows[0].querySelectorAll("td")[1];
if (stepValueCell && otherStep) {
let myTime = Number(step["runtime"]) || 0;
let otherTime = Number(otherStep["runtime"]) || 0;
let diff = myTime - otherTime;
// Remove previous comparison spans
let existingDiff = stepValueCell.querySelector(".auto-testing-perf-diff");
if (existingDiff) existingDiff.remove();
// Reset classes
stepValueCell.classList.remove("auto-testing-perf-faster", "auto-testing-perf-slower");
if (diff < 0) {
// This run is faster
stepValueCell.classList.add("auto-testing-perf-faster");
var diffSpan = win.document.createElement("span");
diffSpan.className = "auto-testing-perf-diff";
diffSpan.textContent = " " + formatTimeDifference(diff);
stepValueCell.appendChild(diffSpan);
}
else if (diff > 0) {
// This run is slower
stepValueCell.classList.add("auto-testing-perf-slower");
var diffSpan = win.document.createElement("span");
diffSpan.className = "auto-testing-perf-diff";
diffSpan.textContent = " " + formatTimeDifference(diff);
stepValueCell.appendChild(diffSpan);
}
}
// Total runtime comparison (second row, only present on last step)
if (rows.length > 1) {
let totalValueCell = rows[1].querySelectorAll("td")[1];
if (totalValueCell && at.data["run"] && otherAt.data["run"]) {
let myTotal = Number(at.data["run"]["runtime"]) || 0;
let otherTotal = Number(otherAt.data["run"]["runtime"]) || 0;
let totalDiff = myTotal - otherTotal;
let existingTotalDiff = totalValueCell.querySelector(".auto-testing-perf-diff");
if (existingTotalDiff) existingTotalDiff.remove();
totalValueCell.classList.remove("auto-testing-perf-faster", "auto-testing-perf-slower");
if (totalDiff < 0) {
totalValueCell.classList.add("auto-testing-perf-faster");
var diffSpan = win.document.createElement("span");
diffSpan.className = "auto-testing-perf-diff";
diffSpan.textContent = " " + formatTimeDifference(totalDiff);
totalValueCell.appendChild(diffSpan);
}
else if (totalDiff > 0) {
totalValueCell.classList.add("auto-testing-perf-slower");
var diffSpan = win.document.createElement("span");
diffSpan.className = "auto-testing-perf-diff";
diffSpan.textContent = " " + formatTimeDifference(totalDiff);
totalValueCell.appendChild(diffSpan);
}
}
}
}
function setupSync() {
let f1Bound = false;
let f2Bound = false;
let f2SidebarHidden = false;
const timer = setInterval(() => {
try {
const win1 = frame1.contentWindow;
const win2 = frame2.contentWindow;
// Inject CSS to hide sidebar in frame2
if (win2 && win2.document && win2.document.head && !f2SidebarHidden) {
const style = win2.document.createElement("style");
style.innerHTML = ".pui-auto-testing-sidebar { display: none !important; }";
win2.document.head.appendChild(style);
f2SidebarHidden = true;
}
if (!f1Bound && win1 && win1.pui && win1.pui.autoTesting && win1.pui.autoTesting.activateStep) {
const origActivate1 = win1.pui.autoTesting.activateStep;
win1.pui.autoTesting.activateStep = function(stepItem) {
if (win1.pui.autoTesting.data.selectedStepIndex === stepItem.stepIndex) {
return;
}
origActivate1(stepItem);
// Sync frame 2
if (win2 && win2.pui && win2.pui.autoTesting && win2.pui.autoTesting.data && win2.pui.autoTesting.data.steps) {
const stepB = win2.pui.autoTesting.data.steps[stepItem.stepIndex];
if (stepB && stepB.stepItem && win2.pui.autoTesting.data.selectedStepIndex !== stepItem.stepIndex) {
win2.pui.autoTesting.activateStep(stepB.stepItem);
}
}
// Update performance comparison in both frames
updatePerformanceComparison(win1, win2);
updatePerformanceComparison(win2, win1);
};
f1Bound = true;
}
if (!f2Bound && win2 && win2.pui && win2.pui.autoTesting && win2.pui.autoTesting.activateStep) {
const origActivate2 = win2.pui.autoTesting.activateStep;
win2.pui.autoTesting.activateStep = function(stepItem) {
if (win2.pui.autoTesting.data.selectedStepIndex === stepItem.stepIndex) {
return;
}
origActivate2(stepItem);
// Sync frame 1
if (win1 && win1.pui && win1.pui.autoTesting && win1.pui.autoTesting.data && win1.pui.autoTesting.data.steps) {
const stepA = win1.pui.autoTesting.data.steps[stepItem.stepIndex];
if (stepA && stepA.stepItem && win1.pui.autoTesting.data.selectedStepIndex !== stepItem.stepIndex) {
win1.pui.autoTesting.activateStep(stepA.stepItem);
}
}
// Update performance comparison in both frames
updatePerformanceComparison(win1, win2);
updatePerformanceComparison(win2, win1);
};
f2Bound = true;
}
if (f1Bound && f2Bound && f2SidebarHidden) {
// Apply initial performance comparison once both frames are loaded
updatePerformanceComparison(win1, win2);
updatePerformanceComparison(win2, win1);
clearInterval(timer);
}
}
catch (e) {
// Ignore cross-origin errors or errors before full load
}
}, 100);
}
document.getElementById("refresh-button").addEventListener("click", init);
// Basic Resizer
function setupResizer(resizerId, prevColId) {
const resizer = document.getElementById(resizerId);
const prevCol = document.getElementById(prevColId);
let isResizing = false;
resizer.addEventListener("mousedown", (e) => {
isResizing = true;
document.body.style.cursor = "ew-resize";
});
document.addEventListener("mousemove", (e) => {
if (!isResizing) return;
const offsetLeft = prevCol.getBoundingClientRect().left;
let newWidth = e.clientX - offsetLeft;
prevCol.style.flex = `0 0 ${newWidth}px`;
});
document.addEventListener("mouseup", () => {
if (isResizing) {
isResizing = false;
document.body.style.cursor = "default";
}
});
}
setupResizer("resizer", "left-iframe-container");
init();