# Playwright PDF Generator Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace the default exam-sprint PDF generator with Playwright Java while keeping the openhtmltopdf implementation and dependencies available for comparison. **Architecture:** Keep `ExamSprintReportPdfGenerator` unchanged. Add a Spring-managed `PlaywrightExamSprintReportPdfGenerator` in the infrastructure PDF package, remove component auto-registration from `OpenHtmlToPdfExamSprintReportPdfGenerator`, and let application/runtime code continue consuming the domain interface. The first version reuses one Chromium browser and serializes Playwright calls to avoid unsafe concurrent access. **Tech Stack:** Java 17, Spring Boot 3.3.5, Maven, Playwright Java, Chromium, JUnit 5, AssertJ, PDFBox test utilities already present transitively through openhtmltopdf tests. --- ## File Structure - Modify `abilities/exam-sprint/infrastructure/pom.xml`: add `com.microsoft.playwright:playwright` and keep existing `com.openhtmltopdf` dependencies. - Modify `abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/OpenHtmlToPdfExamSprintReportPdfGenerator.java`: remove `@Component` so the legacy implementation is not the default Spring bean. - Create `abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGenerator.java`: default PDF generator using Playwright Chromium. - Create `abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGeneratorTest.java`: targeted Playwright generator coverage. - Modify `abilities/exam-sprint/application/src/test/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportWarmupResourceIntegrationTest.java`: exercise Playwright in the existing warmup resource integration path. ## Tasks ### Task 1: Add Playwright Dependency and Default Bean Switch **Files:** - Modify: `abilities/exam-sprint/infrastructure/pom.xml` - Modify: `abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/OpenHtmlToPdfExamSprintReportPdfGenerator.java` - [ ] Add this dependency after the existing `openhtmltopdf-svg-support` dependency: ```xml com.microsoft.playwright playwright 1.58.0 ``` - [ ] Remove `import org.springframework.stereotype.Component;` and `@Component` from `OpenHtmlToPdfExamSprintReportPdfGenerator`. - [ ] Run compile for the infrastructure module: ```bash mvn -pl abilities/exam-sprint/infrastructure -am -DskipTests compile ``` Expected: compile succeeds or fails only because the new Playwright implementation has not been added yet if this task is executed independently. ### Task 2: Implement Playwright PDF Generator **Files:** - Create: `abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGenerator.java` - [ ] Create `PlaywrightExamSprintReportPdfGenerator` with these behaviors: - Implements `ExamSprintReportPdfGenerator`. - Is annotated with `@Component`. - Lazily creates one headless Chromium `Browser` during the first `generate()` call so Spring context startup does not require Chromium to launch. - Serializes Playwright calls using a private lock. - Creates and closes a fresh `BrowserContext` per PDF. - Injects bundled MiSans as `MiSans`, `MiSans VF`, and `ReportFont` through a `file:` URL `@font-face` block when the bundled font is available. - Waits for `document.fonts.ready` before `page.pdf()`. - Uses A4, print media, CSS page size preference, and background printing. - Wraps generation failures in `IllegalStateException("Failed to generate PDF", exception)`. - Closes browser and Playwright from `destroy()`/`close()`. ### Task 3: Add Playwright Generator Tests **Files:** - Create: `abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/pdf/PlaywrightExamSprintReportPdfGeneratorTest.java` - [ ] Add tests that create one generator for the class and close it after all tests. - [ ] Verify simple Chinese HTML returns bytes whose first four ISO-8859-1 chars are `%PDF`. - [ ] Verify inline SVG Chinese text renders without failure. - [ ] Verify full Outlook and Achievement templates generate readable PDFs with at least one page. ### Task 4: Update Warmup Resource Integration Test **Files:** - Modify: `abilities/exam-sprint/application/src/test/java/cn/yunzhixue/ability/center/examsprint/application/report/ExamSprintReportWarmupResourceIntegrationTest.java` - [ ] Replace direct construction of `OpenHtmlToPdfExamSprintReportPdfGenerator` with `PlaywrightExamSprintReportPdfGenerator`. - [ ] Close the generator at the end of the test using try-with-resources. ### Task 5: Verification **Files:** - No source file changes. - [ ] If Chromium is not installed for Playwright, run this command before PDF tests: ```bash mvn -pl abilities/exam-sprint/infrastructure exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install chromium" ``` - [ ] Run targeted infrastructure tests: ```bash mvn -pl abilities/exam-sprint/infrastructure -am -Dtest=PlaywrightExamSprintReportPdfGeneratorTest,OpenHtmlToPdfExamSprintReportPdfGeneratorTest test ``` - [ ] Run the application warmup resource integration test: ```bash mvn -pl abilities/exam-sprint/application -am -Dtest=ExamSprintReportWarmupResourceIntegrationTest test ``` - [ ] Run runtime configuration test to ensure the default Spring wiring still accepts a single PDF generator bean: ```bash mvn -pl ability-center-runtime -am -Dtest=ExamSprintReportRuntimeConfigurationTest test ``` ## Self-Review - Spec coverage: The plan directly implements default Playwright switching, keeps openhtmltopdf code and dependencies, and validates both the new generator and warmup resource path. - Placeholder scan: No task relies on TBD/TODO wording; all files and commands are explicit. - Type consistency: The plan keeps `ExamSprintReportPdfGenerator.generate(String): byte[]` unchanged and introduces only infrastructure-level Playwright classes. - Commit policy: No commit step is included because this session has not received an explicit request to create a git commit.