Skip to content
Merged
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
187 changes: 187 additions & 0 deletions __tests__/components/analytics-charts.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import { describe, it, expect } from 'vitest'
import { render, screen } from '@testing-library/react'
import { AnalyticsCharts, ChartSkeleton } from '@/components/analytics/charts'
import type { StreamStatus } from '@/types/stream'

const emptySnapshot = {
series: [],
topTokens: [],
tokenShares: [],
totalVolume: 0n,
statusBreakdown: [],
topRecipients: [],
unlockProgress: { unlocked: 0n, deposited: 0n },
}

const populatedSnapshot = {
series: [
{ label: 'Jan', count: 5, volume: 1000 },
{ label: 'Feb', count: 8, volume: 1500 },
{ label: 'Mar', count: 12, volume: 2200 },
],
topTokens: [
{
symbol: 'USDC',
amount: 500_000_000n,
count: 10,
decimals: 6,
},
{
symbol: 'XLM',
amount: 1_000_000_000n,
count: 8,
decimals: 7,
},
],
tokenShares: [
{
symbol: 'USDC',
amount: 500_000_000n,
count: 10,
decimals: 6,
},
{
symbol: 'XLM',
amount: 1_000_000_000n,
count: 8,
decimals: 7,
},
],
totalVolume: 1_500_000_000n,
statusBreakdown: [
{ status: 'streaming' as StreamStatus, count: 5 },
{ status: 'completed' as StreamStatus, count: 10 },
{ status: 'scheduled' as StreamStatus, count: 2 },
{ status: 'cancelled' as StreamStatus, count: 1 },
],
topRecipients: [
{
address: 'GABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890AB',
federationName: null,
count: 5,
totals: [
{ symbol: 'USDC', amount: 100_000_000n, decimals: 6 },
],
},
{
address: 'GXYZABCDEFGHIJKLMNOPQRSTUVW0987654321XY',
federationName: 'alice*stellar.org',
count: 3,
totals: [
{ symbol: 'XLM', amount: 50_000_000n, decimals: 7 },
{ symbol: 'USDC', amount: 25_000_000n, decimals: 6 },
],
},
],
unlockProgress: { unlocked: 300_000_000n, deposited: 1_000_000_000n },
}

describe('AnalyticsCharts', () => {
it('renders with an empty snapshot', () => {
const { container } = render(<AnalyticsCharts {...emptySnapshot} />)

expect(screen.getByText(/streaming volume over time/i)).toBeInTheDocument()
expect(screen.getByText(/token distribution/i)).toBeInTheDocument()

Check failure on line 84 in __tests__/components/analytics-charts.test.tsx

View workflow job for this annotation

GitHub Actions / build

__tests__/components/analytics-charts.test.tsx > AnalyticsCharts > renders with an empty snapshot

TestingLibraryElementError: Found multiple elements with the text: /token distribution/i Here are the matching elements: Ignored nodes: comments, script, style <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Token distribution </div> Ignored nodes: comments, script, style <p class="text-sm text-muted-foreground" > No token distribution data available yet. </p> (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style <body> <div> <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)" data-slot="card-header" > <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Streaming volume over time </div> <div class="text-sm text-muted-foreground" data-slot="card-description" > Total tokens deposited into streams created per day, for the selected window. </div> </div> <div class="px-(--card-spacing)" data-slot="card-content" > <p class="text-sm text-muted-foreground" > No stream activity yet for this period. </p> </div> </div> <div class="grid gap-6 lg:grid-cols-[0.9fr_1.1fr]" > <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)" data-slot="card-header" > <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Token distribution </div> <div class="text-sm text-muted-foreground" data-slot="card-description" > Streams grouped by token across the current dataset. </div> </div> <div class="px-(--card-spacing)" data-slot="card-content" > <p class="text-sm text-muted-foreground" > No token distribution data available yet. </p> </div> </div> <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:las
expect(screen.getByText(/stream status breakdown/i)).toBeInTheDocument()
expect(screen.getByText(/top recipients/i)).toBeInTheDocument()
expect(screen.getByText(/top tokens by volume/i)).toBeInTheDocument()
expect(screen.getByText(/unlock progress/i)).toBeInTheDocument()

// Should show empty state messages
expect(container.textContent).toContain('No streaming activity')
})

it('renders with populated data', () => {
const { container } = render(<AnalyticsCharts {...populatedSnapshot} />)

// Token symbols should be visible
expect(screen.getAllByText('USDC').length).toBeGreaterThan(0)
expect(screen.getAllByText('XLM').length).toBeGreaterThan(0)

// Status breakdown should render
expect(screen.getByText(/streaming/i)).toBeInTheDocument()

// Recipients should render
expect(screen.getByText(/alice\*stellar\.org/i)).toBeInTheDocument()

// Should not show empty state messages
expect(container.textContent).not.toContain('No streaming activity')
})

it('formats token amounts in top tokens list', () => {
render(<AnalyticsCharts {...populatedSnapshot} />)

// USDC with 6 decimals: 500_000_000 = 500
expect(screen.getByText(/500/)).toBeInTheDocument()

Check failure on line 115 in __tests__/components/analytics-charts.test.tsx

View workflow job for this annotation

GitHub Actions / build

__tests__/components/analytics-charts.test.tsx > AnalyticsCharts > formats token amounts in top tokens list

TestingLibraryElementError: Found multiple elements with the text: /500/ Here are the matching elements: Ignored nodes: comments, script, style <span class="font-medium" > 500 </span> Ignored nodes: comments, script, style <span class="group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3! bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80" data-slot="badge" data-variant="secondary" > 500 USDC </span> (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style <body> <div> <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)" data-slot="card-header" > <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Streaming volume over time </div> <div class="text-sm text-muted-foreground" data-slot="card-description" > Total tokens deposited into streams created per day, for the selected window. </div> </div> <div class="px-(--card-spacing)" data-slot="card-content" > <div class="recharts-responsive-container" style="width: 100%; height: 260px; min-width: 0;" > <div style="width: 0px; overflow-x: visible;" /> </div> </div> </div> <div class="grid gap-6 lg:grid-cols-[0.9fr_1.1fr]" > <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)" data-slot="card-header" > <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Token distribution </div> <div class="text-sm text-muted-foreground" data-slot="card-description" > Streams grouped by token across the current dataset. </div> </div> <div class="px-(--card-spacing)" data-slot="card-content" > <div class="flex flex-col items-cent

// XLM with 7 decimals: 1_000_000_000 = 100
expect(screen.getByText(/100/)).toBeInTheDocument()
})

it('shows recipient count labels', () => {
render(<AnalyticsCharts {...populatedSnapshot} />)

expect(screen.getByText(/5 streams/i)).toBeInTheDocument()
expect(screen.getByText(/3 streams/i)).toBeInTheDocument()
})

it('calculates and displays unlock progress percentage', () => {
render(<AnalyticsCharts {...populatedSnapshot} />)

// unlocked: 300_000_000, deposited: 1_000_000_000 = 30%
expect(screen.getByText(/30\.0%/)).toBeInTheDocument()
})

it('displays shortened addresses for recipients without federation names', () => {
render(<AnalyticsCharts {...populatedSnapshot} />)

// First recipient has no federation name, so should show shortened address
expect(screen.getByText(/GABCD…90AB/)).toBeInTheDocument()

Check failure on line 139 in __tests__/components/analytics-charts.test.tsx

View workflow job for this annotation

GitHub Actions / build

__tests__/components/analytics-charts.test.tsx > AnalyticsCharts > displays shortened addresses for recipients without federation names

TestingLibraryElementError: Unable to find an element with the text: /GABCD…90AB/. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible. Ignored nodes: comments, script, style <body> <div> <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)" data-slot="card-header" > <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Streaming volume over time </div> <div class="text-sm text-muted-foreground" data-slot="card-description" > Total tokens deposited into streams created per day, for the selected window. </div> </div> <div class="px-(--card-spacing)" data-slot="card-content" > <div class="recharts-responsive-container" style="width: 100%; height: 260px; min-width: 0;" > <div style="width: 0px; overflow-x: visible;" /> </div> </div> </div> <div class="grid gap-6 lg:grid-cols-[0.9fr_1.1fr]" > <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)" data-slot="card-header" > <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Token distribution </div> <div class="text-sm text-muted-foreground" data-slot="card-description" > Streams grouped by token across the current dataset. </div> </div> <div class="px-(--card-spacing)" data-slot="card-content" > <div class="flex flex-col items-center gap-4 sm:flex-row" > <div class="recharts-responsive-container max-w-[200px]" style="width: 100%; height: 200px; min-width: 0;" > <div style="width: 0px; overflow-x: visible;" /> </div> <div class="w-full space-y-2" > <div class="flex items-center justify-between text-sm" > <span class="flex items-center gap-2" > <span class="size-2.5 shrink-0 rounded-full" style="background: var(--color-chart-1);" /> USDC
})

it('displays federation names when available', () => {
render(<AnalyticsCharts {...populatedSnapshot} />)

expect(screen.getByText(/alice\*stellar\.org/i)).toBeInTheDocument()
})

it('shows empty state for zero unlock progress', () => {
const snapshot = {
...emptySnapshot,
unlockProgress: { unlocked: 0n, deposited: 0n },
}
render(<AnalyticsCharts {...snapshot} />)

expect(screen.getByText(/no streams to track/i)).toBeInTheDocument()

Check failure on line 155 in __tests__/components/analytics-charts.test.tsx

View workflow job for this annotation

GitHub Actions / build

__tests__/components/analytics-charts.test.tsx > AnalyticsCharts > shows empty state for zero unlock progress

TestingLibraryElementError: Unable to find an element with the text: /no streams to track/i. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible. Ignored nodes: comments, script, style <body> <div> <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)" data-slot="card-header" > <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Streaming volume over time </div> <div class="text-sm text-muted-foreground" data-slot="card-description" > Total tokens deposited into streams created per day, for the selected window. </div> </div> <div class="px-(--card-spacing)" data-slot="card-content" > <p class="text-sm text-muted-foreground" > No stream activity yet for this period. </p> </div> </div> <div class="grid gap-6 lg:grid-cols-[0.9fr_1.1fr]" > <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)" data-slot="card-header" > <div class="font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm" data-slot="card-title" > Token distribution </div> <div class="text-sm text-muted-foreground" data-slot="card-description" > Streams grouped by token across the current dataset. </div> </div> <div class="px-(--card-spacing)" data-slot="card-content" > <p class="text-sm text-muted-foreground" > No token distribution data available yet. </p> </div> </div> <div class="group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl" data-size="default" data-slot="card" > <div class="group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto
})
})

describe('ChartSkeleton', () => {
it('renders placeholders', () => {
const { container } = render(<ChartSkeleton />)

const placeholders = container.querySelectorAll('.animate-pulse')
expect(placeholders.length).toBeGreaterThan(0)
})

it('renders main chart placeholder', () => {
const { container } = render(<ChartSkeleton />)

const mainChart = container.querySelector('.h-64.animate-pulse')
expect(mainChart).toBeInTheDocument()
})

it('renders grid layout placeholders', () => {
const { container } = render(<ChartSkeleton />)

// Should have multiple grid sections with placeholders
const grids = container.querySelectorAll('.grid')
expect(grids.length).toBeGreaterThan(0)
})

it('does not contain any text content', () => {
const { container } = render(<ChartSkeleton />)

expect(container.textContent).toBe('')
})
})
44 changes: 44 additions & 0 deletions __tests__/components/connect-wallet-button.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,48 @@
fireEvent.click(screen.getByRole('button'))
await waitFor(() => expect(screen.getByText(/copy address/i)).toBeInTheDocument())
})

it('copies the full address to clipboard', async () => {
const writeText = vi.fn().mockResolvedValue(undefined)
Object.assign(navigator, {
clipboard: {
writeText,
},
})

render(<ConnectWalletButton />)
fireEvent.click(screen.getByRole('button'))
await waitFor(() => screen.getByText(/copy address/i))
fireEvent.click(screen.getByText(/copy address/i))

await waitFor(() => {
expect(writeText).toHaveBeenCalledWith(ADDR)
})
})

it('shows confirmation feedback after copying', async () => {

Check failure on line 166 in __tests__/components/connect-wallet-button.test.tsx

View workflow job for this annotation

GitHub Actions / build

__tests__/components/connect-wallet-button.test.tsx > ConnectWalletButton — connected > shows confirmation feedback after copying

Error: Test timed out in 5000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ __tests__/components/connect-wallet-button.test.tsx:166:3
vi.useFakeTimers()
const writeText = vi.fn().mockResolvedValue(undefined)
Object.assign(navigator, {
clipboard: {
writeText,
},
})

render(<ConnectWalletButton />)
fireEvent.click(screen.getByRole('button'))
await waitFor(() => screen.getByText(/copy address/i))

// Initially shows "Copy address"
expect(screen.getByText(/copy address/i)).toBeInTheDocument()

fireEvent.click(screen.getByText(/copy address/i))

// After clicking, should show "Copied"
await waitFor(() => {
expect(screen.getByText(/copied/i)).toBeInTheDocument()
})

vi.useRealTimers()
})
})
33 changes: 33 additions & 0 deletions __tests__/components/dashboard-stats-skeleton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, it, expect } from 'vitest'
import { render, screen } from '@testing-library/react'
import { DashboardStatsSkeleton } from '@/components/streams/dashboard-stats'

describe('DashboardStatsSkeleton', () => {
it('renders the expected number of placeholder cards', () => {
const { container } = render(<DashboardStatsSkeleton />)
const cards = container.querySelectorAll('.rounded-2xl.border')
expect(cards).toHaveLength(4)
})

it('placeholder cards have animate-pulse class', () => {
const { container } = render(<DashboardStatsSkeleton />)
const cards = container.querySelectorAll('.animate-pulse')
expect(cards.length).toBeGreaterThanOrEqual(4)
})

it('placeholders contain loading bars for label, value, and hint', () => {
const { container } = render(<DashboardStatsSkeleton />)
const cards = container.querySelectorAll('.rounded-2xl.border')

cards.forEach(card => {
const loadingBars = card.querySelectorAll('.bg-muted')
expect(loadingBars.length).toBe(3) // label, value, hint
})
})

it('skeleton does not contain text content', () => {
const { container } = render(<DashboardStatsSkeleton />)
const textContent = container.textContent
expect(textContent).toBe('')
})
})
Loading
Loading