import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import { CarouselComponent } from '../index';
describe('CarouselComponent', () => {
const mockItems = [
Item 1
,
Item 2
,
Item 3
,
Item 4
];
beforeEach(() => {
Element.prototype.scrollTo = jest.fn();
});
it('renders all items', () => {
render();
expect(screen.getByText('Item 1')).toBeInTheDocument();
expect(screen.getByText('Item 2')).toBeInTheDocument();
expect(screen.getByText('Item 3')).toBeInTheDocument();
expect(screen.getByText('Item 4')).toBeInTheDocument();
});
it('renders navigation arrows by default', () => {
render();
const prevButton = screen.getByLabelText('Previous items');
const nextButton = screen.getByLabelText('Next items');
expect(prevButton).toBeInTheDocument();
expect(nextButton).toBeInTheDocument();
});
it('hides navigation arrows when showArrows is false', () => {
render();
const buttons = screen.getAllByRole('button');
expect(buttons.length).toBe(2);
});
it('renders pagination dots by default', () => {
render();
const dots = screen
.getAllByRole('button')
.filter(btn => !btn.querySelector('svg'));
expect(dots.length).toBeGreaterThan(0);
});
it('hides pagination dots when showDots is false', () => {
render(
);
const buttons = screen.queryAllByRole('button');
expect(buttons.length).toBe(0);
});
it('applies custom className', () => {
const { container } = render(
);
expect(container.querySelector('.custom-carousel')).toBeInTheDocument();
});
it('handles itemsPerPage option', () => {
render(
);
const dots = screen
.getAllByRole('button')
.filter(btn => !btn.querySelector('svg'));
expect(dots.length).toBe(4);
});
it('handles empty items array', () => {
const { container } = render();
expect(container.querySelector('[role="button"]')).not.toBeInTheDocument();
});
it('handles single item', () => {
render(Single Item]} />);
expect(screen.getByText('Single Item')).toBeInTheDocument();
});
it('calls onPageChange callback when provided', () => {
const onPageChange = jest.fn();
render();
const nextButton = screen
.getAllByRole('button')
.find(btn => btn.querySelector('svg'));
if (nextButton) {
fireEvent.click(nextButton);
expect(onPageChange).toHaveBeenCalled();
}
});
it('renders with custom arrow component', () => {
const CustomArrow = ({ direction }: { direction: string }) => (
);
render(
);
const customArrows = screen.getAllByText(/Custom/);
expect(customArrows.length).toBe(2);
expect(customArrows[0]).toBeInTheDocument();
});
it('renders with custom dot component', () => {
const CustomDot = ({ index }: { index: number }) => (
);
render(
);
const customDots = screen.getAllByText(/Dot/);
expect(customDots.length).toBe(2);
expect(customDots[0]).toBeInTheDocument();
});
it('navigates to next page when next arrow is clicked', () => {
render(
);
const nextButton = screen.getByLabelText('Next items');
fireEvent.click(nextButton);
expect(Element.prototype.scrollTo).toHaveBeenCalled();
});
it('navigates to previous page when previous arrow is clicked', () => {
render(
);
const nextButton = screen.getByLabelText('Next items');
const prevButton = screen.getByLabelText('Previous items');
fireEvent.click(nextButton);
fireEvent.click(prevButton);
expect(Element.prototype.scrollTo).toHaveBeenCalled();
});
it('handles mouse drag events', () => {
const { container } = render(
);
const carouselRow = container.querySelector('div > div > div');
if (carouselRow) {
fireEvent.mouseDown(carouselRow, { pageX: 100 });
fireEvent.mouseMove(carouselRow, { pageX: 50 });
fireEvent.mouseUp(carouselRow);
}
expect(carouselRow).toBeInTheDocument();
});
it('disables previous arrow on first page', () => {
render(
);
const prevButton = screen.getByLabelText('Previous items');
expect(prevButton).toBeDisabled();
});
it('renders correct number of page dots', () => {
render(
);
const dots = screen
.getAllByRole('button')
.filter(btn => !btn.querySelector('svg'));
expect(dots.length).toBe(2);
});
it('handles page dot click', () => {
render(
);
const dots = screen
.getAllByRole('button')
.filter(btn => !btn.querySelector('svg'));
if (dots[1]) {
fireEvent.click(dots[1]);
expect(Element.prototype.scrollTo).toHaveBeenCalled();
}
});
it('hides dots when there is only one page', () => {
render(
Item 1]}
options={{ itemsPerPage: 2 }}
/>
);
const dots = screen
.queryAllByRole('button')
.filter(btn => !btn.querySelector('svg'));
expect(dots.length).toBe(0);
});
it('handles mouse leave event during drag', () => {
const { container } = render(
);
const carouselRow = container.querySelector('div > div > div');
if (carouselRow) {
fireEvent.mouseDown(carouselRow, { pageX: 100 });
fireEvent.mouseMove(carouselRow, { pageX: 50 });
fireEvent.mouseLeave(carouselRow);
}
expect(carouselRow).toBeInTheDocument();
});
it('applies correct styles to carousel container', () => {
const { container } = render();
const carouselContainer = container.firstChild;
expect(carouselContainer).toBeInTheDocument();
});
});