`;
}
function addTableRow(tableId) {
const table = document.getElementById(tableId);
const newRow = table.tBodies[0].insertRow();
let cellsHtml = '';
for(let i = 0; i < table.tHead.rows[0].cells.length - 1; i++) {
cellsHtml += ` `;
}
newRow.innerHTML = `${cellsHtml} `;
newRow.querySelector('.delete-row-btn').addEventListener('click', (e) => e.target.closest('tr').remove());
}
function filterRuns() {
const filter = document.getElementById('run-search').value.toLowerCase();
document.querySelectorAll('.run-row').forEach(row => {
row.style.display = row.textContent.toLowerCase().includes(filter) ? "" : "none";
});
}
function renderChartsForTab(tabId) {
Object.values(charts).forEach(chart => { if (chart) chart.destroy(); });
if (tabId === 'dashboard-overview') {
const ctx = document.getElementById('trendsChart')?.getContext('2d');
if(ctx) charts.trends = new Chart(ctx, { type: 'line', data: { labels: dashboardData.trends.map(d => d.day), datasets: [
{ label: 'Passed', data: dashboardData.trends.map(d => d.passed), borderColor: '#22c55e', backgroundColor: 'rgba(34, 197, 94, 0.1)', fill: true, tension: 0.3 },
{ label: 'Failed', data: dashboardData.trends.map(d => d.failed), borderColor: '#ef4444', backgroundColor: 'rgba(239, 68, 68, 0.1)', fill: true, tension: 0.3 }
] }, options: { responsive: true, maintainAspectRatio: false, plugins: { title: { display: true, text: 'Daily Test Results' } } } });
}
if (tabId === 'failure-analysis') {
const ctx = document.getElementById('failureBreakdownChart')?.getContext('2d');
if(ctx) charts.failures = new Chart(ctx, { type: 'pie', data: { labels: dashboardData.failureBreakdown.map(f => f.reason), datasets: [{ data: dashboardData.failureBreakdown.map(f => f.count), backgroundColor: ['#ef4444', '#f97316', '#f59e0b', '#eab308', '#84cc16'] }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom' }, title: { display: true, text: 'Failure Reasons Breakdown' } } } });
}
}
function navigateTabs(direction) {
const newIndex = currentTabIndex + direction;
if (newIndex >= 0 && newIndex < tabs.length) showTab(newIndex);
}
function updateNavButtons() {
prevTabBtn.disabled = currentTabIndex === 0;
nextTabBtn.disabled = currentTabIndex === tabs.length - 1;
}
async function generatePDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF('p', 'pt', 'a4');
const activeTab = tabs[currentTabIndex];
const addHeader = (title) => {
doc.setFontSize(18); doc.text('Automated Testing Report', 40, 60);
doc.setFontSize(12); doc.setTextColor(100); doc.text(`Section: ${title}`, 40, 80);
doc.setLineWidth(0.5); doc.line(40, 90, 555, 90);
};
addHeader(activeTab.name);
const tabElement = document.getElementById(activeTab.id);
if (tabElement.querySelector('canvas')) {
const canvas = await html2canvas(tabElement, { backgroundColor: '#ffffff', scale: 2 });
const imgData = canvas.toDataURL('image/png');
const pdfWidth = doc.internal.pageSize.getWidth() - 80;
const pdfHeight = (canvas.height * pdfWidth) / canvas.width;
doc.addImage(imgData, 'PNG', 40, 110, pdfWidth, pdfHeight);
} else {
const table = tabElement.querySelector('table');
if (table) doc.autoTable({ html: table, startY: 110 });
}
doc.save(`Testing_Report_${activeTab.name.replace(/\s/g, '_')}.pdf`);
}
init();
});
