""" Figma Integration Tests - Real DSS Design File Connection Tests the complete flow: 1. Connect to real Figma file (DSS main design system) 2. Extract design variables (colors, typography, spacing) 3. Extract components 4. Extract styles and assets 5. Generate multiple output formats 6. Verify token consistency Requires environment variables: - FIGMA_API_KEY: Your Figma Personal Access Token - DSS_FIGMA_FILE_KEY: File key for main DSS design file """ import pytest import os import json from pathlib import Path # These imports would come from your DSS package # from figma.figma_tools import FigmaToolSuite # from dss.tokens import DesignToken class TestFigmaIntegration: """Test real Figma file integration""" # Fixtures now defined in conftest.py for shared access # ===== TEST CASES ===== def test_figma_api_key_configured(self, figma_config): """Verify Figma API key is configured""" assert figma_config['api_key'], "FIGMA_API_KEY not set" assert figma_config['api_key'].startswith('figd_'), "Invalid API key format" def test_dss_file_key_configured(self, figma_config): """Verify DSS file key is configured""" assert figma_config['file_key'], "DSS_FIGMA_FILE_KEY not set" assert len(figma_config['file_key']) > 0, "File key is empty" def test_extract_variables_returns_dict(self, figma_client, figma_config): """Test variable extraction returns structured data""" result = figma_client['extract_variables'](figma_config['file_key']) assert isinstance(result, dict) assert 'variables' in result assert result['status'] == 'success' def test_extracted_variables_have_colors(self, figma_client, figma_config): """Test colors are extracted""" result = figma_client['extract_variables'](figma_config['file_key']) variables = result['variables'] assert 'colors' in variables assert len(variables['colors']) > 0 assert 'primary' in variables['colors'] def test_extracted_variables_have_typography(self, figma_client, figma_config): """Test typography tokens are extracted""" result = figma_client['extract_variables'](figma_config['file_key']) variables = result['variables'] assert 'typography' in variables assert len(variables['typography']) > 0 def test_extracted_variables_have_spacing(self, figma_client, figma_config): """Test spacing tokens are extracted""" result = figma_client['extract_variables'](figma_config['file_key']) variables = result['variables'] assert 'spacing' in variables assert len(variables['spacing']) > 0 def test_extract_components(self, figma_client, figma_config): """Test component extraction""" result = figma_client['extract_components'](figma_config['file_key']) assert result['status'] == 'success' assert 'components' in result assert len(result['components']) > 0 def test_components_have_metadata(self, figma_client, figma_config): """Test components have required metadata""" result = figma_client['extract_components'](figma_config['file_key']) components = result['components'] for name, component in components.items(): assert 'description' in component assert 'variants' in component assert 'properties' in component def test_extract_styles(self, figma_client, figma_config): """Test style extraction""" result = figma_client['extract_styles'](figma_config['file_key']) assert result['status'] == 'success' assert 'styles' in result def test_extract_all_assets_if_blank(self, figma_client, figma_config): """Test full extraction: if no cached data, get everything""" # Get all asset types variables = figma_client['extract_variables'](figma_config['file_key']) components = figma_client['extract_components'](figma_config['file_key']) styles = figma_client['extract_styles'](figma_config['file_key']) # Should have data from all categories assert bool(variables.get('variables')) assert bool(components.get('components')) assert bool(styles.get('styles')) def test_tokens_match_dss_structure(self, figma_client, figma_config): """Verify extracted tokens match DSS token structure""" result = figma_client['extract_variables'](figma_config['file_key']) variables = result['variables'] # Should have standard DSS token categories standard_categories = ['colors', 'typography', 'spacing'] for category in standard_categories: assert category in variables, f"Missing {category} category" def test_variable_formats(self, figma_client, figma_config): """Test variables can be exported in different formats""" for fmt in ['json', 'css', 'typescript', 'scss']: result = figma_client['extract_variables']( figma_config['file_key'], format=fmt ) assert result['status'] == 'success' def test_color_values_are_valid_hex(self, figma_client, figma_config): """Test color values are valid hex codes""" result = figma_client['extract_variables'](figma_config['file_key']) colors = result['variables']['colors'] import re hex_pattern = r'^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$' for name, color in colors.items(): assert re.match(hex_pattern, color), f"Invalid hex color: {color}" def test_spacing_values_are_numbers(self, figma_client, figma_config): """Test spacing values are numeric""" result = figma_client['extract_variables'](figma_config['file_key']) spacing = result['variables']['spacing'] for name, value in spacing.items(): assert isinstance(value, (int, float)), f"Non-numeric spacing: {value}" def test_typography_has_required_properties(self, figma_client, figma_config): """Test typography tokens have required properties""" result = figma_client['extract_variables'](figma_config['file_key']) typography = result['variables']['typography'] required = ['fontSize', 'fontWeight'] for name, props in typography.items(): for req in required: assert req in props, f"{name} missing {req}" def test_error_handling_invalid_file(self, figma_client): """Test error handling for invalid file key""" result = figma_client['extract_variables']('invalid-key') # Should still return dict (with error status) assert isinstance(result, dict) def test_error_handling_network_error(self, figma_client): """Test error handling for network issues""" # Would be tested with actual network errors # For now, just verify error handling structure assert True def test_token_count_matches_actual(self, figma_client, figma_config): """Test token count matches extracted tokens""" result = figma_client['extract_variables'](figma_config['file_key']) # Count should match actual tokens token_count = sum(len(tokens) for tokens in result['variables'].values()) assert token_count > 0 def test_components_count_accurate(self, figma_client, figma_config): """Test component count is accurate""" result = figma_client['extract_components'](figma_config['file_key']) actual_count = len(result['components']) assert result['components_count'] == actual_count class TestTokenConsistency: """Test token naming and structure consistency""" def test_token_naming_conventions(self, figma_client, figma_config): """Test tokens follow naming conventions""" result = figma_client['extract_variables'](figma_config['file_key']) variables = result['variables'] # Colors should be kebab-case colors = variables['colors'] for name in colors.keys(): assert name.islower() and '-' in name or name.islower() def test_no_duplicate_token_names(self, figma_client, figma_config): """Test no duplicate token names across categories""" result = figma_client['extract_variables'](figma_config['file_key']) variables = result['variables'] all_names = [] for category_tokens in variables.values(): all_names.extend(category_tokens.keys()) # Check for duplicates assert len(all_names) == len(set(all_names)), "Duplicate token names found" class TestFigmaSync: """Test Figma sync and token database storage""" def test_tokens_can_be_saved(self, figma_client, figma_config, tmp_path): """Test tokens can be saved to file""" result = figma_client['extract_variables'](figma_config['file_key']) # Write to temp file output_file = tmp_path / "tokens.json" with open(output_file, 'w') as f: json.dump(result, f) # Verify file was created assert output_file.exists() assert output_file.stat().st_size > 0 def test_exported_tokens_can_be_read(self, figma_client, figma_config, tmp_path): """Test exported tokens can be read back""" result = figma_client['extract_variables'](figma_config['file_key']) # Write to temp file output_file = tmp_path / "tokens.json" with open(output_file, 'w') as f: json.dump(result, f) # Read back with open(output_file, 'r') as f: loaded = json.load(f) assert loaded['variables'] == result['variables']