Browse Source
perf(information-sheet): render inline play icon synchronously for answer pace sheet to eliminate late load delay
master
perf(information-sheet): render inline play icon synchronously for answer pace sheet to eliminate late load delay
master
4 changed files with 349 additions and 21 deletions
-
87src/app/questions-list/[slug]/answer-pace-sheet.test.tsx
-
108src/components/Componentes/information-sheet.test.tsx
-
143src/components/Componentes/information-sheet.tsx
-
32src/components/Componentes/ui-icon.tsx
@ -0,0 +1,87 @@ |
|||||
|
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react"; |
||||
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
||||
|
import AnswerPaceSheet, { |
||||
|
isAnswerPaceSheetSeen, |
||||
|
markAnswerPaceSheetSeen, |
||||
|
} from "./answer-pace-sheet"; |
||||
|
|
||||
|
vi.mock("@/translations/provider", () => ({ |
||||
|
useI18n: vi.fn(() => ({ |
||||
|
locale: "fa", |
||||
|
dictionary: { |
||||
|
"Information sheet": "شیت اطلاعات", |
||||
|
Close: "بستن", |
||||
|
}, |
||||
|
})), |
||||
|
})); |
||||
|
|
||||
|
vi.mock("@/lib/first-entry-helper", () => ({ |
||||
|
isFirstEntryCompleted: vi.fn(() => false), |
||||
|
})); |
||||
|
|
||||
|
describe("AnswerPaceSheet", () => { |
||||
|
beforeEach(() => { |
||||
|
window.localStorage.clear(); |
||||
|
}); |
||||
|
|
||||
|
afterEach(() => { |
||||
|
cleanup(); |
||||
|
window.localStorage.clear(); |
||||
|
}); |
||||
|
|
||||
|
it("does not render when activeQuestionIndex is less than 3", () => { |
||||
|
render( |
||||
|
<AnswerPaceSheet |
||||
|
activeQuestionIndex={2} |
||||
|
title="با آرامش پاسخ دهید" |
||||
|
description="میتوانید هر زمان نظرسنجی را متوقف کرده و بعداً ادامه دهید." |
||||
|
continueLabel="متوجه شدم" |
||||
|
/>, |
||||
|
); |
||||
|
|
||||
|
expect(screen.queryByRole("dialog")).toBeNull(); |
||||
|
}); |
||||
|
|
||||
|
it("renders when activeQuestionIndex >= 3 and displays inline play icon synchronously without network img tag", () => { |
||||
|
render( |
||||
|
<AnswerPaceSheet |
||||
|
activeQuestionIndex={3} |
||||
|
title="با آرامش پاسخ دهید" |
||||
|
description="میتوانید هر زمان نظرسنجی را متوقف کرده و بعداً ادامه دهید." |
||||
|
continueLabel="متوجه شدم" |
||||
|
/>, |
||||
|
); |
||||
|
|
||||
|
const dialog = screen.getByRole("dialog"); |
||||
|
expect(dialog).toBeDefined(); |
||||
|
expect(screen.getByText("با آرامش پاسخ دهید")).toBeDefined(); |
||||
|
expect( |
||||
|
screen.getByText( |
||||
|
"میتوانید هر زمان نظرسنجی را متوقف کرده و بعداً ادامه دهید.", |
||||
|
), |
||||
|
).toBeDefined(); |
||||
|
|
||||
|
// Critical: must render inline SVG play icon instantly with NO <img> tag
|
||||
|
expect(dialog.querySelector("img")).toBeNull(); |
||||
|
const playSvg = dialog.querySelector('svg[aria-label="Play"]'); |
||||
|
expect(playSvg).not.toBeNull(); |
||||
|
expect(playSvg?.getAttribute("viewBox")).toBe("0 0 50 50"); |
||||
|
}); |
||||
|
|
||||
|
it("marks sheet as seen and closes on button click", async () => { |
||||
|
render( |
||||
|
<AnswerPaceSheet |
||||
|
activeQuestionIndex={3} |
||||
|
title="با آرامش پاسخ دهید" |
||||
|
description="میتوانید هر زمان نظرسنجی را متوقف کرده و بعداً ادامه دهید." |
||||
|
continueLabel="متوجه شدم" |
||||
|
/>, |
||||
|
); |
||||
|
|
||||
|
const continueBtn = screen.getByRole("button", { name: "متوجه شدم" }); |
||||
|
fireEvent.click(continueBtn); |
||||
|
await waitFor(() => { |
||||
|
expect(isAnswerPaceSheetSeen()).toBe(true); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue