diff --git a/bases/rsptx/assignment_server_api/assignment_builder/e2e/consolidation/a11y-scan.spec.ts b/bases/rsptx/assignment_server_api/assignment_builder/e2e/consolidation/a11y-scan.spec.ts index 5f096a583..f05ff0261 100644 --- a/bases/rsptx/assignment_server_api/assignment_builder/e2e/consolidation/a11y-scan.spec.ts +++ b/bases/rsptx/assignment_server_api/assignment_builder/e2e/consolidation/a11y-scan.spec.ts @@ -1,5 +1,7 @@ import { AxeBuilder } from "@axe-core/playwright"; +import { gotoApp } from "../fixtures/appNav"; +import { findGradableQuestion, gotoSplitView } from "../fixtures/grader"; import { expect, test } from "../fixtures/scratch"; const scan = (page: import("@playwright/test").Page) => @@ -40,7 +42,7 @@ test( "reports assignment list axe violations", { tag: ["@p2", "@a11y", "@assignments"] }, async ({ page }, testInfo) => { - await page.goto("/builder"); + await gotoApp(page, "/builder"); await expect(page.getByRole("heading", { level: 1, name: "Assignments" })).toBeVisible(); const results = await scan(page); @@ -53,11 +55,55 @@ test( "reports grader assignment list axe violations", { tag: ["@p2", "@a11y", "@grader"] }, async ({ page }, testInfo) => { - await page.goto("/grader"); + await gotoApp(page, "/grader"); await expect(page.getByRole("heading", { level: 1, name: "Assignment grader" })).toBeVisible(); await expect(page.getByRole("heading", { level: 2, name: "Assignments" })).toBeAttached(); await expect(page.getByRole("navigation", { name: "Breadcrumb" })).toContainText("Assignments"); - await expect(page.getByRole("region", { name: "Assignments" })).toBeVisible(); + await expect(page.locator('[data-tour="grader-assignment-picker"]')).toBeVisible(); + + const results = await scan(page); + + await reportViolations(testInfo, results); + } +); + +test( + "reports grader question list axe violations", + { tag: ["@p2", "@a11y", "@grader"] }, + async ({ page }, testInfo) => { + const target = await findGradableQuestion(page.request); + + await gotoApp(page, `/grader/${target.assignmentId}`); + await expect(page.getByRole("region", { name: "Questions" })).toBeVisible(); + + const results = await scan(page); + + await reportViolations(testInfo, results); + } +); + +test( + "reports grader split view axe violations", + { tag: ["@p2", "@a11y", "@grader"] }, + async ({ page }, testInfo) => { + const target = await findGradableQuestion(page.request); + + await gotoSplitView(page, target); + await expect(page.getByRole("complementary", { name: "Students" })).toBeVisible(); + await expect(page.locator('[data-tour="grader-grade-panel"]')).toBeVisible(); + + const results = await scan(page); + + await reportViolations(testInfo, results); + } +); + +test( + "reports grader gradebook axe violations", + { tag: ["@p2", "@a11y", "@grader", "@gradebook"] }, + async ({ page }, testInfo) => { + await gotoApp(page, "/gradebook"); + await expect(page.getByRole("heading", { level: 2, name: "Gradebook" })).toBeVisible(); const results = await scan(page); diff --git a/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/Grader.module.css b/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/Grader.module.css index b886eb751..7b91359e0 100644 --- a/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/Grader.module.css +++ b/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/Grader.module.css @@ -879,6 +879,9 @@ color: var(--rs-text-muted); margin-bottom: 4px; } +.historyItem.active .historyMeta { + color: var(--rs-brand-800); +} .historyAnswer { font-size: 11px; color: var(--rs-text-strong); diff --git a/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/DeadlineExceptionDialog.tsx b/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/DeadlineExceptionDialog.tsx index 0977a4c1f..709e2eb3b 100644 --- a/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/DeadlineExceptionDialog.tsx +++ b/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/DeadlineExceptionDialog.tsx @@ -85,16 +85,18 @@ export const DeadlineExceptionDialog: React.FC = (
- setExtraDays(typeof v === "number" ? v : 0)} min={0} />
- setTimeMultiplier(typeof v === "number" ? v : 1)} min={0} diff --git a/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/GradePanel.spec.tsx b/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/GradePanel.spec.tsx new file mode 100644 index 000000000..7538cccb5 --- /dev/null +++ b/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/GradePanel.spec.tsx @@ -0,0 +1,64 @@ +import type { GraderStudentAnswer } from "@store/grader/grader.logic.api"; +import userEvent from "@testing-library/user-event"; +import { vi } from "vitest"; + +import { renderWithMantine, screen } from "@/test/renderWithMantine"; + +import { GradePanel } from "./GradePanel"; + +const student: GraderStudentAnswer = { + sid: "ada", + first_name: "Ada", + last_name: "Lovelace", + answer: "", + attempts: 2, + score: 4, + comment: "Good work", + max_points: 10 +}; + +const renderPanel = () => { + const onAutoAdvanceChange = vi.fn(); + + renderWithMantine( + + ); + + return { onAutoAdvanceChange }; +}; + +describe("GradePanel", () => { + it("associates grading controls with their accessible labels", () => { + renderPanel(); + + expect(screen.getByLabelText("Points (max 10)")).toBeInTheDocument(); + expect(screen.getByLabelText("Comment")).toBeInTheDocument(); + expect(screen.getByRole("status")).toHaveTextContent("Ada Lovelace"); + }); + + it("labels and updates the auto-advance switch", async () => { + const { onAutoAdvanceChange } = renderPanel(); + + await userEvent.click(screen.getByLabelText("Auto-advance after save")); + + expect(onAutoAdvanceChange).toHaveBeenCalledWith(true); + }); +}); diff --git a/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/GradePanel.tsx b/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/GradePanel.tsx index fc7da58f5..b2d3eaccf 100644 --- a/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/GradePanel.tsx +++ b/bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/Grader/components/GradePanel.tsx @@ -77,7 +77,12 @@ export const GradePanel = forwardRef(function GradePane
-
+
{studentName}
{student ? ( @@ -98,7 +103,7 @@ export const GradePanel = forwardRef(function GradePane
{onAutoAdvanceChange && ( - +
)}
@@ -142,10 +151,11 @@ export const GradePanel = forwardRef(function GradePane
-
onScoreChange(typeof v === "number" ? v : 0)} onBlur={onScoreBlur} @@ -153,15 +163,15 @@ export const GradePanel = forwardRef(function GradePane max={maxPoints} clampBehavior="strict" disabled={isDisabled} - classNames={{ input: styles.scoreInput }} />
-