|
|
@@ -32,6 +32,7 @@ import java.util.List;
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
import static org.assertj.core.api.Assertions.assertThatCode;
|
|
|
+import static org.assertj.core.api.Assertions.within;
|
|
|
|
|
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
|
|
class PlaywrightExamSprintReportPdfGeneratorTest {
|
|
|
@@ -488,6 +489,62 @@ class PlaywrightExamSprintReportPdfGeneratorTest {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ void generateUsesHeaderFontSizeForBusinessFooterAndPageNumbers() throws Exception {
|
|
|
+ byte[] pdfBytes = pdfGenerator.generate("""
|
|
|
+ <html>
|
|
|
+ <head>
|
|
|
+ <meta charset=\"UTF-8\"/>
|
|
|
+ <style>
|
|
|
+ @page { size: A4; margin: 0; }
|
|
|
+ body { margin: 0; font-family: MiSans, ReportFont, sans-serif; font-size: 14px; }
|
|
|
+ .report-container { padding: 32px; }
|
|
|
+ .report-header { display: table; width: 100%; table-layout: fixed; border-bottom: 3px solid #111; margin-bottom: 28px; padding-bottom: 10px; }
|
|
|
+ .header-logo, .header-main, .header-generated-at { display: table-cell; vertical-align: top; }
|
|
|
+ .header-logo { width: 180px; }
|
|
|
+ .header-main { text-align: center; color: #68768a; }
|
|
|
+ .header-report-type, .header-student-name { font-size: 13px; line-height: 1.5; }
|
|
|
+ .header-generated-at { width: 260px; color: #68768a; font-size: 12px; line-height: 1.5; text-align: right; white-space: nowrap; }
|
|
|
+ .page { height: 1122px; page-break-after: always; }
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+ <body>
|
|
|
+ <div class=\"report-container\">
|
|
|
+ <header class=\"report-header\">
|
|
|
+ <div class=\"header-logo\"></div>
|
|
|
+ <div class=\"header-main\">
|
|
|
+ <div class=\"header-report-type\">学习成果报告</div>
|
|
|
+ <div class=\"header-student-name\">分页测试学生</div>
|
|
|
+ </div>
|
|
|
+ <div class=\"header-generated-at\">2026-05-13 10:08:54</div>
|
|
|
+ </header>
|
|
|
+ <main>
|
|
|
+ <section class=\"page\">第一页正文内容</section>
|
|
|
+ <section class=\"page\">第二页正文内容</section>
|
|
|
+ </main>
|
|
|
+ </div>
|
|
|
+ <div class=\"report-footer-business\">
|
|
|
+ <div class=\"report-footer-business-line\">张三 Tel:138987484</div>
|
|
|
+ <div class=\"report-footer-business-line\">浙江省杭州市</div>
|
|
|
+ </div>
|
|
|
+ </body>
|
|
|
+ </html>
|
|
|
+ """);
|
|
|
+
|
|
|
+ assertPdfHeader(pdfBytes);
|
|
|
+ List<TextLine> pageTwoLines = textLines(pdfBytes, 2);
|
|
|
+ TextLine headerTimeLine = findLineContaining(pageTwoLines, "2026-05-1310:08:54");
|
|
|
+ TextLine businessLine = findLineContaining(pageTwoLines, "张三Tel:138987484");
|
|
|
+ TextLine pageNumberLine = findLineContaining(pageTwoLines, "2/");
|
|
|
+
|
|
|
+ assertThat(businessLine.height())
|
|
|
+ .as("business footer font height should match header generated-at font height")
|
|
|
+ .isCloseTo(headerTimeLine.height(), within(0.6f));
|
|
|
+ assertThat(pageNumberLine.height())
|
|
|
+ .as("page number font height should match header generated-at font height")
|
|
|
+ .isCloseTo(headerTimeLine.height(), within(0.6f));
|
|
|
+ }
|
|
|
+
|
|
|
private void assertPdfHeader(byte[] pdfBytes) {
|
|
|
assertThat(pdfBytes).isNotEmpty();
|
|
|
assertThat(new String(pdfBytes, 0, 4, StandardCharsets.ISO_8859_1)).isEqualTo("%PDF");
|
|
|
@@ -577,6 +634,10 @@ class PlaywrightExamSprintReportPdfGeneratorTest {
|
|
|
}
|
|
|
|
|
|
private record TextLine(String text, float x, float y, float bottomY) {
|
|
|
+
|
|
|
+ private float height() {
|
|
|
+ return bottomY - y;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private AchievementReportContent sampleAchievementContent() {
|