Skip to content
TokenFlight SDK

Testing Guide

The SDK exports a MockWalletAdapter class for testing. It simulates wallet behavior without requiring a real wallet extension:

import { MockWalletAdapter } from '@tokenflight/swap';
const mockAdapter = new MockWalletAdapter();

The mock adapter:

  • Auto-connects when connect() is called
  • Returns a deterministic test address from getAddress()
  • Returns mock transaction hashes from executeWalletAction()
  • Supports the full event system (on, off)
  • Implements all IWalletAdapter methods
import { describe, it, expect, afterEach } from 'vitest';
import { TokenFlightWidget, MockWalletAdapter } from '@tokenflight/swap';
import type { SwapErrorData } from '@tokenflight/swap';
describe('PaymentWidget', () => {
let widget: InstanceType<typeof TokenFlightWidget>;
let container: HTMLDivElement;
afterEach(() => {
widget?.destroy();
container?.remove();
});
it('should initialize without errors', () => {
container = document.createElement('div');
document.body.appendChild(container);
const adapter = new MockWalletAdapter();
widget = new TokenFlightWidget({
container,
config: {
toToken: { chainId: 8453, address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
tradeType: 'EXACT_OUTPUT',
amount: '100',
theme: 'dark',
},
walletAdapter: adapter,
});
expect(() => widget.initialize()).not.toThrow();
});
it('should fire onSwapError callback', async () => {
container = document.createElement('div');
document.body.appendChild(container);
let capturedError: SwapErrorData | null = null;
widget = new TokenFlightWidget({
container,
config: {
toToken: { chainId: 8453, address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
tradeType: 'EXACT_OUTPUT',
amount: '100',
theme: 'dark',
},
walletAdapter: new MockWalletAdapter(),
callbacks: {
onSwapError: (error) => {
capturedError = error;
},
},
});
widget.initialize();
// The callback will fire when an error occurs during widget operation
// Test your error handling logic here
});
});
import { render, screen } from '@testing-library/react';
import { PaymentWidget } from './PaymentWidget';
import { MockWalletAdapter } from '@tokenflight/swap';
it('renders the payment widget container', () => {
const mockAdapter = new MockWalletAdapter();
const { container } = render(
<PaymentWidget walletAdapter={mockAdapter} theme="dark" />
);
// The widget mounts inside a Shadow DOM — use container queries
expect(container.querySelector('div')).toBeTruthy();
});

The SDK’s own E2E tests use Playwright with Chromium. You can follow the same pattern:

import { test, expect } from '@playwright/test';
test('payment widget loads and displays', async ({ page }) => {
await page.goto('/your-page-with-widget');
// Wait for the custom element to be defined
await page.waitForFunction(() =>
customElements.get('tokenflight-widget') !== undefined
);
// Access Shadow DOM content
const widget = page.locator('tokenflight-widget');
const shadow = widget.locator('internal:shadow=.tf-container');
await expect(shadow).toBeVisible();
});

⚠️ Coming soon: A dedicated testnet mode with test tokens is not yet available. Currently, the widget connects to the production Hyperstream API.

For development and testing:

  • Use MockWalletAdapter for automated tests
  • Test with small amounts on supported chains
  • Use the onConnectWallet callback to intercept wallet actions during integration testing

For CI pipelines, use Playwright with MockWalletAdapter injected into your test page:

playwright.config.ts
export default defineConfig({
webServer: {
command: 'pnpm build && pnpm preview',
port: 4173,
},
use: {
browserName: 'chromium',
},
});

Key points for CI:

  • Build the project before running E2E tests
  • Chromium is the primary supported browser for testing
  • Shadow DOM selectors need special handling (use locator('internal:shadow=...') in Playwright)
  • API calls can be mocked with Playwright’s page.route() for deterministic tests