A/B Test Plan Documenter

Test Plan Summary

Configure Your Test Plan

Test Details

Variations

Variation A (Control)

Variation B (Variant)

Key Metrics

Secondary Metrics

${abp_escapeHTML(metric_primary) || 'No primary metric defined.'}

${secondaryMetricsHTML}
`; } /** * Reads all values from the config tab and updates the abp_data object */ function abp_updateDataFromConfig() { if (!abp_inputName) return; // Exit if config elements aren't ready abp_data = { name: abp_inputName.value, hypothesis: abp_inputHypothesis.value, duration: abp_inputDuration.value, audience: abp_inputAudience.value, varA_name: abp_inputVarAName.value, varA_details: abp_inputVarADetails.value, varB_name: abp_inputVarBName.value, varB_details: abp_inputVarBDetails.value, metric_primary: abp_inputMetricPrimary.value, metric_secondary: [] }; const metricInputs = document.querySelectorAll('.abp-input-metric-secondary'); metricInputs.forEach(input => { if (input.value) { abp_data.metric_secondary.push(input.value); } }); } /** * Generates and downloads a PDF of the dashboard */ async function abp_downloadPDF() { // Check for required libraries if (typeof jspdf === 'undefined' || typeof html2canvas === 'undefined') { console.error("ABP Tool Error: jsPDF or html2canvas library not loaded."); alert("Error: PDF libraries failed to load. Please check console."); return; } const outputElement = document.getElementById('abp-dashboard-output'); const testName = abp_data.name || 'Test_Plan'; if (!outputElement) { console.error("ABP Tool Error: PDF output element not found."); return; } try { const canvas = await html2canvas(outputElement, { scale: 2, backgroundColor: '#ffffff', useCORS: true }); const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'p', unit: 'px', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgWidth = canvas.width; const imgHeight = canvas.height; const ratio = imgWidth / imgHeight; let newImgWidth = pdfWidth - 40; // 20px margins let newImgHeight = newImgWidth / ratio; if (newImgHeight > pdfHeight - 40) { newImgHeight = pdfHeight - 40; // 20px margins newImgWidth = newImgHeight * ratio; } const x = (pdfWidth - newImgWidth) / 2; const y = 20; pdf.setFontSize(22); pdf.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--abp-primary-color').trim() || '#007bff'); pdf.text(abp_data.name, pdfWidth / 2, y + 10, { align: 'center' }); pdf.addImage(imgData, 'PNG', x, y + 30, newImgWidth, newImgHeight); const safeName = testName.replace(/[^a-z0-9]/gi, '_').toLowerCase(); pdf.save(`AB_Test_Plan_${safeName}.pdf`); } catch (error) { console.error("ABP Tool Error: PDF generation failed.", error); alert("An error occurred while generating the PDF. Please try again."); } } /** * Utility to escape HTML for display * @param {string} str - The string to escape */ function abp_escapeHTML(str) { if (typeof str !== 'string') return ''; return str.replace(/[&<>"']/g, function(m) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[m]; }); } // --- EVENT LISTENERS --- // Tab link clicks abp_tabLinks.forEach((link, index) => { link.addEventListener('click', () => abp_switchTab(index)); }); // Next/Prev button clicks if (abp_prevButton) { abp_prevButton.addEventListener('click', () => { if (abp_currentTab > 0) abp_switchTab(abp_currentTab - 1); }); } if (abp_nextButton) { abp_nextButton.addEventListener('click', () => { if (abp_currentTab < abp_tabLinks.length - 1) abp_switchTab(abp_currentTab + 1); }); } // PDF download if (abp_downloadPdfButton) { abp_downloadPdfButton.addEventListener('click', abp_downloadPDF); } // Add secondary metric button if (abp_addMetricButton) { abp_addMetricButton.addEventListener('click', () => { abp_addMetricInput('', abp_metricCounter++); }); } // Remove metric button (event delegation) if (abp_secondaryMetricsContainer) { abp_secondaryMetricsContainer.addEventListener('click', (e) => { if (e.target.classList.contains('abp-remove-metric')) { const entryDiv = e.target.closest('.abp-metric-entry'); if (entryDiv) { entryDiv.remove(); } } }); } // Auto-update dashboard on config changes if (abp_configTab) { abp_configTab.addEventListener('change', () => { abp_updateDataFromConfig(); // Only re-render dashboard if user is currently on it if (abp_currentTab === 0) { abp_renderDashboard(); } }); } // --- INITIALIZATION --- abp_initSampleData(); abp_renderConfig(); abp_renderDashboard(); });
Scroll to Top