🎨 Figma Golden

Pub Version Dart SDK Version License: MIT

A Dart package that automatically downloads PNG images of Figma components for use in Flutter golden tests. Supports zone-based configuration for scoped settings and flexible API architecture for easy testing.

πŸ”„ How It Works

  1. Add Download Call: Add downloadFigmaComponent() before your golden test
  2. Run Tests: Execute flutter test with Figma API token
  3. Get Results: Receive both PNG from Figma and your golden test comparison
test('Button golden test', () async {
  // 1️⃣ Download component from Figma (with smart logging)
  await downloadFigmaComponent(
    nodeData: FigmaNodeData.fromUrl('https://www.figma.com/design/FILE_ID?node-id=11-3359'),
    fileName: 'primary_button',
  );
  
  // 2️⃣ Run your golden test
  await tester.pumpWidget(MyApp());
  expect(find.byType(PrimaryButton), 
         matchesGoldenFile('golden/primary_button.png'));
});

Console output with smart logging:

[FIGMA_GOLDEN] ⏳ PROGRESS: Starting download of component 11:3359 from file nLDpIUh4gksHkJxWpdx5Jq  
[FIGMA_GOLDEN] πŸš€ DOWNLOAD COMPLETED: primary_button (1250ms)

✨ Features

  • πŸš€ Automatic PNG Downloads - Download Figma components as PNG files
  • 🌐 Zone-based Configuration - Scoped configurations using Dart zones
  • πŸ“ Smart File Management - Skip existing files, force downloads when needed
  • πŸ”§ Flexible Configuration - Per-test and global settings
  • πŸ“Š Comprehensive Logging - Detailed operation logging
  • 🎯 URL Support - Parse Figma URLs automatically
  • πŸ›‘οΈ Error Handling - Graceful error handling with detailed messages

πŸš€ Getting Started

Installation

Add to your pubspec.yaml:

dev_dependencies:
  figma_golden: ^2.1.0

Setup

  1. Get your Figma API token:

  2. Set the API token:

    # Via environment variable
    export FIGMA_API_TOKEN=your_token_here
       
    # Or via dart-define (recommended for CI/CD)
    flutter test --dart-define=FIGMA_API_TOKEN=your_token_here
    
  3. Basic usage:

    import 'package:figma_golden/figma_golden.dart';
    
    void main() {
      testWidgets('button golden test', (tester) async {
        // Download component before test
        await downloadFigmaComponent(
          nodeData: FigmaNodeData(
            fileId: 'your-figma-file-id',
            nodeId: '11:3359',
          ),
          fileName: 'primary_button',
        );
    
        // Your golden test code here
        await expectLater(
          find.byType(PrimaryButton),
          matchesGoldenFile('golden/primary_button.png'),
        );
      });
    }
    

πŸ“– Documentation

Zone-based Configuration

Use zones to apply configuration scopes:

import 'package:figma_golden/figma_golden.dart';

// Method 1: Direct zone configuration
await FigmaGolden.runWithConfigurationAsync(() async {
  await downloadFigmaComponent(
    nodeData: FigmaNodeData.fromUrl('https://www.figma.com/design/...'),
    fileName: 'component', // Will use zone config
  );
}, config: FigmaGoldenConfig()
  ..setDefaultFileNamePrefix('ui_')
  ..setDefaultRelativePath('widgets/golden/')
  ..setDefaultTimeout(Duration(seconds: 60)));

URL Support

Parse Figma URLs automatically:

// From URL
final nodeData = FigmaNodeData.fromUrl(
  'https://www.figma.com/design/fileId/Design?node-id=11-3359&m=dev'
);

// Safe parsing (returns null if invalid)
final nodeData = FigmaNodeData.tryFromUrl(url);
if (nodeData != null) {
  await downloadFigmaComponent(
    nodeData: nodeData,
    fileName: 'parsed_component',
  );
}

Configuration Options

final config = FigmaGoldenConfig()
  .setDefaultFileNamePrefix('figma_')      // Prefix for all files
  .setDefaultRelativePath('assets/golden/') // Default download path  
  .setDefaultTimeout(Duration(seconds: 30)) // API timeout
  .reset();                                 // Reset to defaults

// Method chaining supported
final chainedConfig = FigmaGoldenConfig()
  .setDefaultFileNamePrefix('ui_')
  .setDefaultRelativePath('components/');

// Copy with modifications
final modifiedConfig = originalConfig.copyWith(
  defaultFileNamePrefix: 'new_prefix_',
  defaultTimeout: Duration(seconds: 60),
);

// Apply filename prefix
final prefixedName = config.applyPrefix('button'); // 'figma_button'

πŸ”§ Configuration

Environment Variables

# API Token (required)
export FIGMA_API_TOKEN=your_token_here

# Force download existing files
export FORCE_DOWNLOAD=true

# Or via Flutter test args
flutter test --dart-define=FIGMA_API_TOKEN=your_token --dart-define=FORCE_DOWNLOAD=true

File Structure

By default, files are saved to:

test/
  golden/
    component_name.png

Customize with configuration:

FigmaGoldenConfig()
  .setDefaultRelativePath('assets/images/') // -> test/assets/images/
  .setDefaultFileNamePrefix('figma_');       // -> figma_component_name.png

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Run tests: flutter test --dart-define=FIGMA_API_TOKEN=test-token
  5. Submit a pull request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Libraries

figma_golden
Figma Golden - Download PNG components from Figma for Flutter golden tests