Skip to content

fix: React component tests and testing infrastructure #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# CCIP JavaScript SDK Changelog

## [Unreleased]

### Fixed

#### Component Tests
- **ActionButton.test.tsx**:
- Fixed the SwitchNetwork button test by using a more robust text matcher with regex pattern (`getByRole('button', { name: /switch/i })`)
- Added proper mock for the `useSwitchChain` hook to enable correct button rendering
- Corrected test case setup to ensure SwitchNetworkButton is rendered by using different chains for source and current
- Fixed TypeScript errors in test mocks with proper type annotations

- **SendButton.test.tsx**:
- Renamed test case from "render send button" to "render action button" for flexibility with actual rendered components
- Updated mocks with complete type specifications and status values
- Improved button selection approach using `screen.getByRole('button')` instead of exact text matching
- Removed redundant test case to improve test maintenance

- **App.test.tsx**:
- Created TestProviders wrapper component with WagmiProvider and QueryClientProvider
- Added mocks for wagmi hooks to properly simulate blockchain state
- Fixed "WagmiProviderNotFoundError" by ensuring all components are wrapped properly
- Updated to pass required `chain` prop to App component
- Extended network configuration to include all supported chains (Sepolia, Optimism Sepolia, Arbitrum Sepolia, etc.)

- **AppDefault.test.tsx**:
- Updated context provider values with proper chain information
- Added test data for chain configuration, contracts, and token addresses

#### Testing Infrastructure

- **run_tests.sh**:
- Fixed script to properly handle Anvil startup and shutdown
- Added proper port configuration (8545) to match test expectations
- Implemented cleanup handling with bash trap to ensure Anvil is always terminated
- Added environment variable export for test configuration
- Fixed Jest configuration for test runs

- **package.json**:
- Updated test script commands for better organization
- Added Jest configuration section to avoid conflicts with config files
- Separated test scripts to support different testing approaches

### Changed

- **UI Text Updates**:
- Updated "Switch to chain" to "Switch" for more compact UI in ActionButton component
- Updated related test cases to match new text

- **Documentation**:
- Updated example code in README.md to use Avalanche Fuji instead of Optimism Sepolia
- Fixed typo in config variable name (`networkConfing` → `networkConfig`)
- Updated contract addresses in example configuration

### Added

- **Test Framework**:
- Added improved mock implementations for all Wagmi hooks
- Added test coverage reporting configuration
- Included proper cleanup routines for test environment

## [0.3.0] - 2025-03-27

Initial version tracked in this changelog.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ git clone https://github.com/smartcontractkit/ccip-javascript-sdk.git

2. [Install `pnpm`](https://pnpm.io/installation).

3. Run `pnpm install`
3. Run `pnpm i`


### Run the example app
Expand Down
3 changes: 2 additions & 1 deletion examples/nextjs/app/ccip-js/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { CCIP } from "@/components/ccip";
import { Providers } from "./providers";
import { sepolia, arbitrumSepolia, avalancheFuji, bscTestnet, polygonAmoy, optimismSepolia } from "viem/chains";

export default function CCIPJsPage() {
return (
<Providers>
<Providers chains={[sepolia, arbitrumSepolia, avalancheFuji, bscTestnet, polygonAmoy, optimismSepolia]}>
<CCIP />
</Providers>
);
Expand Down
3 changes: 2 additions & 1 deletion examples/nextjs/app/ccip-js/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { WagmiProvider } from 'wagmi';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactNode } from 'react';
import { wagmiConfig } from '@/config/wagmiConfig';
import { Chain } from 'viem';

const queryClient = new QueryClient();

export function Providers({ children }: { children: ReactNode }) {
export function Providers({ children, chains }: { children: ReactNode, chains: Chain[] }) {
return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
Expand Down
14 changes: 7 additions & 7 deletions examples/nextjs/components/ccip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import {
} from 'wagmi';
import {
Address,
Client,
encodeAbiParameters,
encodeFunctionData,
Hash,
Hex,
parseEther,
PublicClient,
TransactionReceipt,
WalletClient,
TransactionReceipt
} from 'viem';
import { useState } from 'react';

Expand Down Expand Up @@ -98,7 +98,7 @@ function ConnectWallet() {
<>
<p>{`Connected to ${chain.name} (chainId: ${chain.id})`}</p>
<div className="flex flex-col">
<label htmlFor="chainId">Switch to chain</label>
<label htmlFor="chainId">Switch</label>
<select
className="border border-slate-300 rounded-md p-1"
name="chainId"
Expand Down Expand Up @@ -127,7 +127,7 @@ function ConnectWallet() {
);
}

function ApproveRouter({ walletClient }: { walletClient: WalletClient }) {
function ApproveRouter({ walletClient }: { walletClient: Client }) {
const [routerAddress, setRouterAddress] = useState<string>();
const [tokenAddress, setTokenAddress] = useState<string>();
const [amount, setAmount] = useState<string>();
Expand Down Expand Up @@ -195,7 +195,7 @@ function ApproveRouter({ walletClient }: { walletClient: WalletClient }) {
function TransferTokensAndMessage({
walletClient,
}: {
walletClient: WalletClient;
walletClient: Client;
}) {
const [routerAddress, setRouterAddress] = useState<string>();
const [tokenAddress, setTokenAddress] = useState<string>();
Expand Down Expand Up @@ -320,7 +320,7 @@ function TransferTokensAndMessage({
);
}

function SendCCIPMessage({ walletClient }: { walletClient: WalletClient }) {
function SendCCIPMessage({ walletClient }: { walletClient: Client }) {
const [routerAddress, setRouterAddress] = useState<string>();
const [destinationChainSelector, setDestinationChainSelector] =
useState<string>();
Expand Down Expand Up @@ -419,7 +419,7 @@ function SendCCIPMessage({ walletClient }: { walletClient: WalletClient }) {
);
}

function SendFunctionData({ walletClient }: { walletClient: WalletClient }) {
function SendFunctionData({ walletClient }: { walletClient: Client }) {
const [routerAddress, setRouterAddress] = useState<string>();
const [destinationChainSelector, setDestinationChainSelector] =
useState<string>();
Expand Down
17 changes: 9 additions & 8 deletions examples/nextjs/config/networkConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
NetworkConfig,
Token,
} from '@chainlink/ccip-react-components';
import { Chain } from 'viem';
import {
arbitrumSepolia,
avalancheFuji,
Expand Down Expand Up @@ -76,39 +77,39 @@ const tokensList: Token[] = [
},
];

const chains = [
const chains: { chain: Chain; logoURL: string }[] = [
{
chain: arbitrumSepolia,
chain: arbitrumSepolia as Chain,
logoURL:
'https://d2f70xi62kby8n.cloudfront.net/bridge/icons/networks/arbitrum.svg?auto=compress%2Cformat',
},
{
chain: avalancheFuji,
chain: avalancheFuji as Chain,
logoURL:
'https://d2f70xi62kby8n.cloudfront.net/bridge/icons/networks/avalanche.svg?auto=compress%2Cformat',
},
{
chain: baseSepolia,
chain: baseSepolia as Chain,
logoURL:
'https://d2f70xi62kby8n.cloudfront.net/bridge/icons/networks/base.svg?auto=compress%2Cformat',
},
{
chain: bscTestnet,
chain: bscTestnet as Chain,
logoURL:
'https://d2f70xi62kby8n.cloudfront.net/bridge/icons/networks/bsc.svg?auto=compress%2Cformat',
},
{
chain: sepolia,
chain: sepolia as Chain,
logoURL:
'https://d2f70xi62kby8n.cloudfront.net/bridge/icons/networks/ethereum.svg?auto=compress%2Cformat',
},
{
chain: optimismSepolia,
chain: optimismSepolia as Chain,
logoURL:
'https://d2f70xi62kby8n.cloudfront.net/bridge/icons/networks/optimism.svg?auto=compress%2Cformat',
},
{
chain: polygonAmoy,
chain: polygonAmoy as Chain,
logoURL:
'https://d2f70xi62kby8n.cloudfront.net/bridge/icons/networks/polygon.svg?auto=compress%2Cformat',
},
Expand Down
28 changes: 14 additions & 14 deletions examples/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@
"lint": "next lint"
},
"dependencies": {
"@chainlink/ccip-js": "^0.2.1",
"@chainlink/ccip-react-components": "^0.3.0",
"@chainlink/ccip-js": "workspace:*",
"@chainlink/ccip-react-components": "workspace:*",
"@tanstack/react-query": "^5.37.1",
"next": "14.2.3",
"react": "18",
"react-dom": "18",
"typescript": "^5",
"viem": "2.21.25",
"wagmi": "^2.12.7"
"next": "^15.2.4",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"typescript": "^5.8.2",
"viem": "^2.21.25",
"wagmi": "^2.14.15"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18.3.3",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"postcss": "^8",
"@types/node": "^22.13.11",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"eslint": "^9.23.0",
"eslint-config-next": "^15.2.4",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.1"
}
}
2 changes: 1 addition & 1 deletion examples/nextjs/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
"build-components": "pnpm --filter ccip-react-components run build",
"dev-example": "pnpm --filter example-nextjs run dev",
"clean": "rm -rf node_modules packages/*/node_modules packages/*/dist examples/nextjs/node_modules examples/nextjs/.next",
"test-ccip-js": "pnpm --filter ccip-js run test",
"test-components": "pnpm --filter ccip-react-components run test"
"test:js": "pnpm --filter ccip-js run test",
"test:components": "pnpm --filter ccip-react-components run test"
},
"devDependencies": {
"c8": "^10.1.2",
"tsx": "^4.17.0"
"c8": "^10.1.3",
"tsx": "^4.19.3"
},
"dependencies": {
"typescript": "^5.6.3"
"typescript": "^5.8.2"
}
}
14 changes: 7 additions & 7 deletions packages/ccip-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,19 @@ Additionally, after the transfer, you may need to check the transfer status.
To install the package, use the following command:

```sh
npm install @chainlink/ccip-js viem
npm install @chainlink/ccip-js
```

Or with Yarn:

```sh
yarn add @chainlink/ccip-js viem
yarn add @chainlink/ccip-js
```

Or with PNPM:

```sh
pnpm add @chainlink/ccip-js viem
pnpm add @chainlink/ccip-js
```

## Usage
Expand Down Expand Up @@ -166,7 +166,7 @@ An object containing methods for cross-chain transfer management. Refer to [Clie
```typescript
export interface Client {
approveRouter(options: {
client: Viem.WalletClient
client: Viem.Client
routerAddress: Viem.Address
tokenAddress: Viem.Address
amount: bigint
Expand Down Expand Up @@ -240,7 +240,7 @@ export interface Client {
}): Promise<boolean>

transferTokens(options: {
client: Viem.WalletClient
client: Viem.Client
routerAddress: Viem.Address
destinationChainSelector: string
amount: bigint
Expand All @@ -260,7 +260,7 @@ export interface Client {
}): Promise<{ txHash: Viem.Hash; messageId: Viem.Hash; txReceipt: Viem.TransactionReceipt }>

sendCCIPMessage(options: {
client: Viem.WalletClient
client: Viem.Client
routerAddress: Viem.Address
destinationChainSelector: string
destinationAccount: Viem.Address
Expand Down Expand Up @@ -514,7 +514,7 @@ Initiates the token transfer and returns the transaction hash, cross-chain trans

```typescript
transferTokens(options: {
client: Viem.WalletClient
client: Viem.Client
routerAddress: Viem.Address
destinationChainSelector: string
amount: bigint
Expand Down
Loading