Merge pull request 'feat(ui): viewport-aware InfoPopover replaces broken metric tooltips' (#81) from feat/info-popover-tooltip into main
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 5m2s
Stage (build -> staging -> E2E gate) / Build Backend (FastAPI) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Build Frontend (Next.js) (push) Successful in 53s
Stage (build -> staging -> E2E gate) / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Stage (build -> staging -> E2E gate) / Deploy to Staging (push) Successful in 1s
Stage (build -> staging -> E2E gate) / E2E Journeys against Staging (push) Successful in 5m2s
Reviewed-on: #81
This commit was merged in pull request #81.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { InfoPopover } from '@/components/InfoPopover';
|
||||
|
||||
describe('InfoPopover', () => {
|
||||
it('renders nothing when there is no plain content', () => {
|
||||
const { container } = render(<InfoPopover label="X" />);
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
it('renders a labelled, collapsed trigger button', () => {
|
||||
render(<InfoPopover plain="what it means" ariaLabel="Reading score" />);
|
||||
const btn = screen.getByRole('button', { name: 'Reading score' });
|
||||
expect(btn).toHaveAttribute('aria-expanded', 'false');
|
||||
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('opens on click and shows label, plain and detail', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
<InfoPopover
|
||||
label="Reading, Writing & Maths"
|
||||
plain="% reaching the expected standard"
|
||||
detail="National average ~60%"
|
||||
ariaLabel="RWM"
|
||||
/>,
|
||||
);
|
||||
await user.click(screen.getByRole('button', { name: 'RWM' }));
|
||||
const tip = await screen.findByRole('tooltip');
|
||||
expect(tip).toHaveTextContent('Reading, Writing & Maths');
|
||||
expect(tip).toHaveTextContent('% reaching the expected standard');
|
||||
expect(tip).toHaveTextContent('National average ~60%');
|
||||
expect(screen.getByRole('button', { name: 'RWM' })).toHaveAttribute(
|
||||
'aria-expanded',
|
||||
'true',
|
||||
);
|
||||
});
|
||||
|
||||
it('closes again on a second click', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<InfoPopover plain="body" ariaLabel="Info" />);
|
||||
const btn = screen.getByRole('button', { name: 'Info' });
|
||||
await user.click(btn);
|
||||
expect(await screen.findByRole('tooltip')).toBeInTheDocument();
|
||||
await user.click(btn);
|
||||
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('closes on Escape', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<InfoPopover plain="body" ariaLabel="Info" />);
|
||||
await user.click(screen.getByRole('button', { name: 'Info' }));
|
||||
expect(await screen.findByRole('tooltip')).toBeInTheDocument();
|
||||
await user.keyboard('{Escape}');
|
||||
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('defaults the accessible name when no ariaLabel is given', () => {
|
||||
render(<InfoPopover plain="body" />);
|
||||
expect(
|
||||
screen.getByRole('button', { name: 'More information' }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { MetricTooltip } from '@/components/MetricTooltip';
|
||||
import { METRIC_EXPLANATIONS } from '@/lib/metrics';
|
||||
|
||||
describe('MetricTooltip', () => {
|
||||
it('resolves content from a metricKey', async () => {
|
||||
const key = Object.keys(METRIC_EXPLANATIONS)[0];
|
||||
const exp = METRIC_EXPLANATIONS[key];
|
||||
const user = userEvent.setup();
|
||||
render(<MetricTooltip metricKey={key} />);
|
||||
// Collapsed by default — the popover content is not in the DOM until opened
|
||||
// (the old component left an always-present role="tooltip" span behind).
|
||||
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
|
||||
await user.click(screen.getByRole('button', { name: `What does ${exp.label} mean?` }));
|
||||
const tip = await screen.findByRole('tooltip');
|
||||
expect(tip).toHaveTextContent(exp.plain);
|
||||
});
|
||||
|
||||
it('renders nothing for an unknown metricKey with no explicit content', () => {
|
||||
const { container } = render(<MetricTooltip metricKey="__nope__" />);
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
it('lets explicit props override the looked-up explanation', async () => {
|
||||
const key = Object.keys(METRIC_EXPLANATIONS)[0];
|
||||
const user = userEvent.setup();
|
||||
render(<MetricTooltip metricKey={key} plain="custom text" />);
|
||||
await user.click(screen.getByRole('button'));
|
||||
expect(await screen.findByRole('tooltip')).toHaveTextContent('custom text');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { RowLabel } from '@/components/compare/sectionShared';
|
||||
|
||||
describe('RowLabel', () => {
|
||||
it('renders its label text', () => {
|
||||
render(<RowLabel>Attainment 8</RowLabel>);
|
||||
expect(screen.getByText('Attainment 8')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows no help affordance when no tip is given', () => {
|
||||
render(<RowLabel>Attainment 8</RowLabel>);
|
||||
expect(screen.queryByRole('button')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('opens the tip in a popover on click', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<RowLabel tip="Average GCSE score across 8 subjects">Attainment 8</RowLabel>);
|
||||
await user.click(screen.getByRole('button'));
|
||||
expect(await screen.findByRole('tooltip')).toHaveTextContent(
|
||||
'Average GCSE score across 8 subjects',
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user