Modern QA2026Figma API Integration — tiles
Log inJoin
66 / 74 · 10 Visual & Accessibility Testing · Design System Verification← prev⊞ allnext →☰ Read as one page

12.4Figma API Integration

# scripts/figma_design_drift.py
"""
Compare Figma component specifications with live implementation.
Detects drift between design and code.
"""
import requests
import json

FIGMA_TOKEN = "your-figma-api-token"
FIGMA_FILE_ID = "your-file-id"

def get_figma_component_styles(component_name: str):
    """Extract style properties from a Figma component."""
    url = f"https://api.figma.com/v1/files/{FIGMA_FILE_ID}/components"
    headers = {"X-Figma-Token": FIGMA_TOKEN}
    response = requests.get(url, headers=headers)
    components = response.json()

    for component in components.get("meta", {}).get("components", []):
        if component["name"] == component_name:
            # Get component node details
            node_url = f"https://api.figma.com/v1/files/{FIGMA_FILE_ID}/nodes?ids={component['node_id']}"
            node_response = requests.get(node_url, headers=headers)
            node_data = node_response.json()

            # Extract visual properties
            node = list(node_data["nodes"].values())[0]["document"]
            return {
                "fills": node.get("fills", []),
                "strokes": node.get("strokes", []),
                "cornerRadius": node.get("cornerRadius"),
                "padding": {
                    "top": node.get("paddingTop"),
                    "right": node.get("paddingRight"),
                    "bottom": node.get("paddingBottom"),
                    "left": node.get("paddingLeft"),
                },
                "width": node.get("absoluteBoundingBox", {}).get("width"),
                "height": node.get("absoluteBoundingBox", {}).get("height"),
            }
    return None

def compare_with_implementation(figma_styles: dict, computed_styles: dict):
    """Compare Figma specs with browser computed styles."""
    drift_report = []

    if figma_styles.get("cornerRadius"):
        figma_radius = f"{figma_styles['cornerRadius']}px"
        if computed_styles.get("borderRadius") != figma_radius:
            drift_report.append({
                "property": "border-radius",
                "figma": figma_radius,
                "implementation": computed_styles.get("borderRadius"),
            })

    # Compare padding
    for side in ["top", "right", "bottom", "left"]:
        figma_padding = figma_styles.get("padding", {}).get(side)
        if figma_padding is not None:
            figma_px = f"{figma_padding}px"
            impl_key = f"padding{side.capitalize()}"
            if computed_styles.get(impl_key) != figma_px:
                drift_report.append({
                    "property": f"padding-{side}",
                    "figma": figma_px,
                    "implementation": computed_styles.get(impl_key),
                })

    return drift_report