import React from 'react'; import { describe, it, expect } from 'vitest'; import { render } from '@testing-library/react'; import { PixelPricingCard } from '../../cards/PixelPricingCard'; describe('PixelPricingCard', () => { it('renders name as h3', () => { const { getByRole } = render( , ); const h3 = getByRole('heading', { level: 3 }); expect(h3.textContent).toBe('Pro'); }); it('renders price.amount', () => { const { getByTestId } = render( , ); const card = getByTestId('card'); expect(card.textContent).toContain('$29'); }); it('renders price.period when provided', () => { const { getByTestId } = render( , ); const card = getByTestId('card'); expect(card.textContent).toContain('/mo'); }); it('renders price.strikethrough with line-through class on a semantic element', () => { const { container } = render( , ); const strike = container.querySelector('s'); expect(strike).not.toBeNull(); expect(strike!.className).toContain('line-through'); expect(strike!.textContent).toContain('49'); expect(strike!.textContent).toContain('Previous price'); }); it('reserves space for popular ribbon slot when popular not provided', () => { const { getByTestId } = render( , ); const card = getByTestId('card'); const spacer = card.querySelector('[data-pxl-ribbon-slot]'); expect(spacer).not.toBeNull(); expect(spacer!.className).toContain('h-7'); }); it('renders ribbon when popular provided', () => { const { getByText } = render( , ); expect(getByText('BEST VALUE')).toBeInTheDocument(); }); it('renders one li per feature', () => { const { container } = render( , ); const items = container.querySelectorAll('li'); expect(items.length).toBe(3); }); it('features with included=false render with line-through and a sr-only prefix', () => { const { container } = render( , ); const items = container.querySelectorAll('li'); expect(items.length).toBe(2); const excludedSpan = items[1].querySelector('span:not([aria-hidden]):not(.sr-only)'); expect(excludedSpan).not.toBeNull(); expect((excludedSpan as HTMLElement).className).toContain('line-through'); expect(excludedSpan!.textContent).toContain('Not included'); expect(excludedSpan!.textContent).toContain('Excluded thing'); const includedSpan = items[0].querySelector('span:not([aria-hidden]):not(.sr-only)'); expect(includedSpan!.textContent).toContain('Included:'); }); it('highlight=true adds glow class', () => { const { getByTestId } = render( , ); const card = getByTestId('card'); expect(card.className).toContain('shadow-[0_0_24px_-8px_rgba(14,165,233,0.45)]'); }); it('description slot reserves min-h even without description prop', () => { const { getByTestId } = render( , ); const card = getByTestId('card'); const desc = card.querySelector('[data-pxl-description-slot]'); expect(desc).not.toBeNull(); expect(desc!.className).toContain('min-h-[2.5em]'); }); it('descriptionLines="none" drops line-clamp and min-h from the description slot', () => { const { getByTestId } = render( , ); const desc = getByTestId('card').querySelector('[data-pxl-description-slot]'); expect(desc).not.toBeNull(); expect(desc!.className).not.toContain('line-clamp'); expect(desc!.className).not.toContain('min-h-'); }); it('renders priceBadge beside the price', () => { const { getByTestId } = render( -20%} />, ); const slot = getByTestId('card').querySelector('[data-pxl-price-badge-slot]'); expect(slot).not.toBeNull(); expect(slot!.contains(getByTestId('promo'))).toBe(true); }); it('features with highlight=true render the label with the tone text color', () => { const { container } = render( , ); const items = container.querySelectorAll('li'); const plain = items[0].querySelector('span:not([aria-hidden]):not(.sr-only)'); const highlighted = items[1].querySelector('span:not([aria-hidden]):not(.sr-only)'); expect((plain as HTMLElement).className).toContain('text-retro-text'); expect((highlighted as HTMLElement).className).toContain('text-retro-cyan'); expect((highlighted as HTMLElement).className).toContain('font-medium'); }); });