test-ts
Run TypeScript tests for Solana frontends and Anchor programs
mkdir -p ~/.claude/commands && curl -fsSL https://raw.githubusercontent.com/solanabr/solana-ai-kit/HEAD/.claude/commands/test-ts.md -o ~/.claude/commands/test-ts.mdtest-ts.md
You are running TypeScript tests. This command covers Anchor program tests, frontend component tests, and integration tests.
## Related Skills
- [testing.md](../skills/testing.md) - Testing strategy details
- [frontend-framework-kit.md](../skills/frontend-framework-kit.md) - React/Next.js patterns
- [programs/anchor.md](../skills/ext/solana-dev/skill/references/programs/anchor.md) - Anchor test patterns
## Step 1: Identify Test Type
```bash
echo "🔍 Detecting TypeScript test configuration..."
# Check for Anchor tests
if [ -f "Anchor.toml" ] && [ -d "tests" ]; then
echo "⚓ Anchor TypeScript tests detected"
fi
# Check for Vitest
if grep -q "vitest" package.json 2>/dev/null; then
echo "⚡ Vitest configured"
fi
# Check for Jest
if grep -q "jest" package.json 2>/dev/null; then
echo "🃏 Jest configured"
fi
# Check for Playwright
if grep -q "playwright" package.json 2>/dev/null; then
echo "🎭 Playwright E2E tests configured"
fi
```
---
## Anchor Program Tests
### Run Anchor Tests
```bash
echo "⚓ Running Anchor TypeScript tests..."
# Build first
anchor build
# Run all tests
anchor test
# Skip rebuild (faster iteration)
anchor test --skip-build
# Run specific test file
anchor test tests/vault.ts
# Run with logs
RUST_LOG=debug anchor test
```
### Anchor Test Pattern
```typescript
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { MyProgram } from "../target/types/my_program";
import { expect } from "chai";
describe("my_program", () => {
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
const program = anchor.workspace.MyProgram as Program<MyProgram>;
it("initializes vault", async () => {
const [vaultPda] = anchor.web3.PublicKey.findProgramAddressSync(
[Buffer.from("vault"), provider.wallet.publicKey.toBuffer()],
program.programId
);
await program.methods
.initialize()
.accounts({
vault: vaultPda,
authority: provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
})
.rpc();
const vault = await program.account.vault.fetch(vaultPda);
expect(vault.authority.toString()).to.equal(
provider.wallet.publicKey.toString()
);
});
it("deposits funds", async () => {
const [vaultPda] = anchor.web3.PublicKey.findProgramAddressSync(
[Buffer.from("vault"), provider.wallet.publicKey.toBuffer()],
program.programId
);
const depositAmount = new anchor.BN(1_000_000_000); // 1 SOL
await program.methods
.deposit(depositAmount)
.accounts({
vault: vaultPda,
authority: provider.wallet.publicKey,
})
.rpc();
const vault = await program.account.vault.fetch(vaultPda);
expect(vault.balance.toNumber()).to.equal(depositAmount.toNumber());
});
it("fails with insufficient funds", async () => {
const [vaultPda] = anchor.web3.PublicKey.findProgramAddressSync(
[Buffer.from("vault"), provider.wallet.publicKey.toBuffer()],
program.programId
);
try {
await program.methods
.withdraw(new anchor.BN(999_000_000_000)) // More than balance
.accounts({
vault: vaultPda,
authority: provider.wallet.publicKey,
})
.rpc();
expect.fail("Should have thrown");
} catch (err) {
expect(err.message).to.include("InsufficientFunds");
}
});
});
```
### LiteSVM TypeScript Tests
For faster tests without validator:
```bash
npm install --save-dev litesvm
```
```typescript
import { LiteSVM } from 'litesvm';
import { PublicKey, Transaction, Keypair } from '@solana/web3.js';
describe("litesvm tests", () => {
let svm: LiteSVM;
const programId = new PublicKey("YourProgramId...");
beforeAll(() => {
svm = new LiteSVM();
svm.addProgramFromFile(programId, "target/deploy/program.so");
});
it("processes instruction", () => {
const payer = Keypair.generate();
svm.airdrop(payer.publicKey, 1_000_000_000);
const tx = new Transaction();
tx.recentBlockhash = svm.latestBlockhash();
tx.add(/* your instruction */);
tx.sign(payer);
const result = svm.sendTransaction(tx);
expect(result.err).toBeNull();
});
});
```
---
## Frontend Component Tests
### Vitest Setup
```bash
echo "⚡ Running Vitest tests..."
npm run test
# or
npx vitest run
```
### React Component Test
```typescript
// components/__tests__/WalletButton.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { WalletButton } from '../WalletButton';
// Mock wallet hooks
vi.mock('@solana/wallet-adapter-react', () => ({
useWallet: () => ({
connected: false,
connect: vi.fn(),
disconnect: vi.fn(),
publicKey: null,
}),
}));
describe('WalletButton', () => {
it('renders connect button when not connected', () => {
render(<WalletButton />);
expect(screen.getByText('Connect Wallet')).toBeInTheDocument();
});
it('calls connect on click', async () => {
const { useWallet } = await import('@solana/wallet-adapter-react');
const mockConnect = vi.fn();
vi.mocked(useWallet).mockReturnValue({
connected: false,
connect: mockConnect,
disconnect: vi.fn(),
publicKey: null,
});
render(<WalletButton />);
fireEvent.click(screen.getByText('Connect Wallet'));
expect(mockConnect).toHaveBeenCalled();
});
});
```
### Hook Testing
```typescript
// hooks/__tests__/useBalance.test.tsx
import { renderHook, waitFor } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { useBalance } from '../useBalance';
describe('useBalance', () => {
it('fetches balance for address', async () => {
const mockAddress = 'So11111111111111111111111111111111111111112';
const { result } = renderHook(() => useBalance(mockAddress));
await waitFor(() => {
expect(result.curreAnchor framework specialist for rapid Solana program development. Use for building programs with Anchor macros, IDL generation, account validation, and standardized patterns. Prioritizes developer experience while maintaining security.\\n\\nUse when: Building new programs quickly, team projects needing standardization, projects requiring IDL for client generation, or when developer experience is prioritized over maximum CU optimization.
DeFi integration specialist for composing with Solana protocols including Jupiter, Drift, Kamino, Raydium, Orca, Meteora, Marginfi, and Sanctum. Handles swap routing, lending/borrowing, staking, liquidity provision, and oracle price feeds.\n\nUse when: Integrating DeFi protocols, building swap interfaces, implementing lending/borrowing, setting up yield strategies, working with Pyth/Switchboard oracles, or composing multi-protocol transactions.
CI/CD, infrastructure, and deployment specialist for Solana projects. Handles GitHub Actions, Docker, monitoring, RPC management, and Cloudflare Workers edge deployment.\n\nUse when: Setting up CI/CD pipelines, containerizing Solana validators or programs, configuring monitoring and alerting, managing RPC infrastructure, deploying edge workers, or automating build and deploy workflows.
Senior Solana game architect for game system design, Unity/C# architecture, on-chain game state, player progression, NFT integration, and PlaySolana ecosystem. Use for high-level game design decisions, architecture reviews, and planning complex game systems.\n\nUse when: Designing new Solana games from scratch, planning game state on-chain, Unity project architecture, integrating with PlaySolana/PSG1, or deciding between implementation approaches.
React Native and Expo specialist for building Solana mobile dApps. Handles mobile wallet adapter integration, transaction signing UX, deep linking, and mobile-specific performance optimization.\n\nUse when: Building React Native or Expo mobile apps with Solana integration, implementing mobile wallet adapter flows, setting up deep links for transaction signing, or optimizing mobile dApp performance.
CU optimization specialist using Pinocchio framework. Use for performance-critical programs requiring 80-95% CU reduction vs Anchor. Specializes in zero-copy access, manual validation, and minimal binary size.\\n\\nUse when: CU limits are being hit, transaction costs are significant at scale, binary size must be minimized, or maximum throughput is required.
Rust backend specialist for building async services that interact with Solana blockchain. Builds APIs, indexing services, and off-chain processing using Axum, Tokio, and modern async patterns.\n\nUse when: Building REST/WebSocket APIs for Solana dApps, implementing transaction indexers, creating webhook services, or any Rust backend that interacts with Solana.
Senior Solana program architect for system design, account structures, PDA schemes, token economics, and cross-program composability. Use for high-level design decisions, architecture reviews, and planning complex multi-program systems.\n\nUse when: Designing new programs from scratch, planning account structures, optimizing PDA schemes, reviewing architecture for security, or deciding between implementation approaches.