/** * ds-figma-live-compare.js * Side-by-side Figma and Live Application comparison for QA validation * QA Team Tool #1 */ import { createComparisonView, setupComparisonHandlers } from '../../utils/tool-templates.js'; import { ComponentHelpers } from '../../utils/component-helpers.js'; import contextStore from '../../stores/context-store.js'; import apiClient from '../../services/api-client.js'; class DSFigmaLiveCompare extends HTMLElement { constructor() { super(); this.figmaUrl = ''; this.liveUrl = ''; } async connectedCallback() { await this.loadProjectConfig(); this.render(); this.setupEventListeners(); } async loadProjectConfig() { try { const context = contextStore.getMCPContext(); if (!context.project_id) { throw new Error('No project selected'); } const project = await apiClient.getProject(context.project_id); this.figmaUrl = project.figma_qa_file || project.figma_ui_file || ''; this.liveUrl = project.live_url || window.location.origin; } catch (error) { console.error('[DSFigmaLiveCompare] Failed to load project config:', error); } } setupEventListeners() { const figmaInput = this.querySelector('#figma-url-input'); const liveInput = this.querySelector('#live-url-input'); const loadBtn = this.querySelector('#load-comparison-btn'); const screenshotBtn = this.querySelector('#take-screenshot-btn'); if (figmaInput) { figmaInput.value = this.figmaUrl; } if (liveInput) { liveInput.value = this.liveUrl; } if (loadBtn) { loadBtn.addEventListener('click', () => this.loadComparison()); } if (screenshotBtn) { screenshotBtn.addEventListener('click', () => this.takeScreenshots()); } const comparisonContainer = this.querySelector('#comparison-container'); if (comparisonContainer) { setupComparisonHandlers(comparisonContainer, {}); } } loadComparison() { const figmaInput = this.querySelector('#figma-url-input'); const liveInput = this.querySelector('#live-url-input'); this.figmaUrl = figmaInput?.value || ''; this.liveUrl = liveInput?.value || ''; if (!this.figmaUrl || !this.liveUrl) { ComponentHelpers.showToast?.('Please enter both Figma and Live URLs', 'error'); return; } try { new URL(this.figmaUrl); new URL(this.liveUrl); } catch (error) { ComponentHelpers.showToast?.('Invalid URL format', 'error'); return; } const comparisonContainer = this.querySelector('#comparison-container'); if (comparisonContainer) { comparisonContainer.innerHTML = createComparisonView({ leftTitle: 'Figma Design', rightTitle: 'Live Application', leftSrc: this.figmaUrl, rightSrc: this.liveUrl }); setupComparisonHandlers(comparisonContainer, {}); ComponentHelpers.showToast?.('Comparison loaded', 'success'); } } async takeScreenshots() { ComponentHelpers.showToast?.('Taking screenshots...', 'info'); try { // Take screenshot of live application via MCP (using authenticated API client) const context = contextStore.getMCPContext(); await apiClient.request('POST', '/qa/screenshot-compare', { projectId: context.project_id, figmaUrl: this.figmaUrl, liveUrl: this.liveUrl }); ComponentHelpers.showToast?.('Screenshots saved to gallery', 'success'); // Switch to screenshot gallery const panel = document.querySelector('ds-panel'); if (panel) { panel.switchTab('screenshots'); } } catch (error) { console.error('[DSFigmaLiveCompare] Screenshot failed:', error); ComponentHelpers.showToast?.(`Screenshot failed: ${error.message}`, 'error'); } } render() { this.innerHTML = `
Enter Figma design and live application URLs to validate implementation against specifications