import React from 'react';
import { describe, it, expect, vi } from 'vitest';
import { render, fireEvent } from '@testing-library/react';
import { PixelSplitButton } from '../../actions/PixelSplitButton';
const OPTIONS = [
{ value: 'csv', label: 'Export CSV' },
{ value: 'json', label: 'Export JSON' },
];
describe('PixelSplitButton — primary half', () => {
it('renders the label and fires onPrimary when the primary button is clicked', () => {
const onPrimary = vi.fn();
const { getByRole } = render(
,
);
fireEvent.click(getByRole('button', { name: 'Export' }));
expect(onPrimary).toHaveBeenCalledTimes(1);
});
it('clicking the primary button does NOT open the menu', () => {
const { getByRole, queryByRole } = render(
{}} />,
);
fireEvent.click(getByRole('button', { name: 'Export' }));
expect(queryByRole('menu')).toBeNull();
});
});
describe('PixelSplitButton — menu half', () => {
it('chevron trigger has menu a11y wiring and toggles aria-expanded', () => {
const { getByRole, queryByRole } = render(
,
);
const chevron = getByRole('button', { name: 'More options' });
expect(chevron.getAttribute('aria-haspopup')).toBe('menu');
expect(chevron.getAttribute('aria-expanded')).toBe('false');
fireEvent.click(chevron);
expect(chevron.getAttribute('aria-expanded')).toBe('true');
expect(getByRole('menu')).toBeTruthy();
fireEvent.click(chevron);
expect(chevron.getAttribute('aria-expanded')).toBe('false');
expect(queryByRole('menu')).toBeNull();
});
it('renders one menuitem per option and fires onSelect with the value, then closes', () => {
const onSelect = vi.fn();
const { getByRole, getAllByRole, queryByRole } = render(
,
);
fireEvent.click(getByRole('button', { name: 'More options' }));
expect(getAllByRole('menuitem').length).toBe(2);
fireEvent.click(getByRole('menuitem', { name: 'Export JSON' }));
expect(onSelect).toHaveBeenCalledWith('json');
expect(queryByRole('menu')).toBeNull();
});
it('closes when pointer goes down outside the component', () => {
const { getByRole, queryByRole } = render(
,
);
fireEvent.click(getByRole('button', { name: 'More options' }));
expect(getByRole('menu')).toBeTruthy();
fireEvent.pointerDown(document.body);
expect(queryByRole('menu')).toBeNull();
});
});
describe('PixelSplitButton — disabled & ref', () => {
it('disabled disables both halves and blocks opening', () => {
const onPrimary = vi.fn();
const { getByRole, queryByRole } = render(
,
);
const primary = getByRole('button', { name: 'Export' }) as HTMLButtonElement;
const chevron = getByRole('button', { name: 'More options' }) as HTMLButtonElement;
expect(primary.disabled).toBe(true);
expect(chevron.disabled).toBe(true);
fireEvent.click(primary);
fireEvent.click(chevron);
expect(onPrimary).not.toHaveBeenCalled();
expect(queryByRole('menu')).toBeNull();
});
it('forwards ref to the root div', () => {
const ref = React.createRef();
render();
expect(ref.current).toBeInstanceOf(HTMLDivElement);
});
});