feat(app): clearer interactive question card

Fixes #1642
This commit is contained in:
Christoph Leiter
2026-06-30 22:53:12 +02:00
committed by GitHub
parent 20385bdb50
commit 2b46caa20e
2 changed files with 166 additions and 80 deletions
+22 -21
View File
@@ -10,50 +10,51 @@ export async function expectCurrentQuestion(
): Promise<void> {
const card = page.getByTestId("question-form-card").first();
await expect(card.getByTestId("question-form-current-question")).toHaveText(input.question);
await expect(
card.getByRole("button", { name: `Question ${input.index} of ${input.total}` }),
).toHaveAttribute("aria-selected", "true");
// Nav tabs only render for multi-question cards (hidden for a lone question).
if (input.total > 1) {
await expect(questionNavTab(page, input)).toHaveAttribute("aria-selected", "true");
}
}
export async function expectQuestionHidden(page: Page, question: string): Promise<void> {
await expect(page.getByText(question, { exact: true })).toHaveCount(0);
}
export async function chooseQuestionOption(page: Page, option: string): Promise<void> {
await page
// Options render as radios (single-select) or checkboxes (multi-select), so match
// either role by accessible name.
function questionOption(page: Page, option: string) {
const card = page.getByTestId("question-form-card").first();
return card.getByRole("radio", { name: option }).or(card.getByRole("checkbox", { name: option }));
}
// The multi-question nav renders as a tablist; each question is a tab.
function questionNavTab(page: Page, input: { index: number; total: number }) {
return page
.getByTestId("question-form-card")
.first()
.getByRole("button", { name: option })
.click();
.getByRole("tab", { name: `Question ${input.index} of ${input.total}` });
}
export async function chooseQuestionOption(page: Page, option: string): Promise<void> {
await questionOption(page, option).click();
}
export async function expectQuestionOptionSelected(page: Page, option: string): Promise<void> {
await expect(
page.getByTestId("question-form-card").first().getByRole("button", { name: option }),
).toHaveAttribute("aria-selected", "true");
await expect(questionOption(page, option)).toHaveAttribute("aria-checked", "true");
}
export async function openQuestion(
page: Page,
input: { index: number; total: number },
): Promise<void> {
await page
.getByTestId("question-form-card")
.first()
.getByRole("button", { name: `Question ${input.index} of ${input.total}` })
.click();
await questionNavTab(page, input).click();
}
export async function expectQuestionNavigationEnabled(
page: Page,
input: { index: number; total: number },
): Promise<void> {
await expect(
page
.getByTestId("question-form-card")
.first()
.getByRole("button", { name: `Question ${input.index} of ${input.total}` }),
).toBeEnabled();
await expect(questionNavTab(page, input)).toBeEnabled();
}
export async function fillQuestionAnswer(