66 lines
2.5 KiB
TypeScript
66 lines
2.5 KiB
TypeScript
|
|
/**
|
|||
|
|
* Task G5 – Browser-Print: @media print Stylesheet + Print-Service.
|
|||
|
|
*
|
|||
|
|
* printService bereitet den Body auf den Druck vor (print-layout-Klasse,
|
|||
|
|
* Print-Modus ohne UI-Chrome), printLayout() triggert window.print nach
|
|||
|
|
* Vorbereitung und räumt danach ab. Die CSS-Datei muss einen @media print
|
|||
|
|
* Block mit den Kernregeln (UI ausblenden, Canvas füllen, @page)
|
|||
|
|
* enthalten — verifiziert als Datei-Assertion (jsdom kann kein print-CSS
|
|||
|
|
* rendern).
|
|||
|
|
*/
|
|||
|
|
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|||
|
|
import { readFileSync } from 'fs';
|
|||
|
|
import { join } from 'path';
|
|||
|
|
import { preparePrintLayout, cleanupPrintLayout, printLayout } from '../src/services/printService';
|
|||
|
|
|
|||
|
|
describe('G5: printService', () => {
|
|||
|
|
afterEach(() => {
|
|||
|
|
cleanupPrintLayout();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('preparePrintLayout setzt print-layout-Klasse am body', () => {
|
|||
|
|
document.body.classList.remove('print-layout');
|
|||
|
|
preparePrintLayout();
|
|||
|
|
expect(document.body.classList.contains('print-layout')).toBe(true);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('cleanupPrintLayout entfernt die Klasse wieder', () => {
|
|||
|
|
preparePrintLayout();
|
|||
|
|
cleanupPrintLayout();
|
|||
|
|
expect(document.body.classList.contains('print-layout')).toBe(false);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('printLayout ruft window.print nach Vorbereitung und räumt ab (async)', async () => {
|
|||
|
|
const printSpy = vi.spyOn(window, 'print').mockImplementation(() => {});
|
|||
|
|
await printLayout();
|
|||
|
|
expect(printSpy).toHaveBeenCalledTimes(1);
|
|||
|
|
// nach dem Druck ist wieder aufgeräumt
|
|||
|
|
expect(document.body.classList.contains('print-layout')).toBe(false);
|
|||
|
|
printSpy.mockRestore();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
describe('G5: Print-Stylesheet-Regeln (Datei-Assertion)', () => {
|
|||
|
|
const css = readFileSync(join(__dirname, '..', 'src', 'styles.css'), 'utf-8');
|
|||
|
|
const printBlock = css.slice(css.indexOf('@media print'));
|
|||
|
|
|
|||
|
|
it('enthält einen @media print Block mit @page A4 landscape', () => {
|
|||
|
|
expect(css).toContain('@media print');
|
|||
|
|
expect(printBlock).toMatch(/@page\s*\{[^}]*size:\s*A4 landscape/);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('blendet UI-Chrome im Druck aus (screen-only Regel)', () => {
|
|||
|
|
expect(printBlock).toContain('.screen-only');
|
|||
|
|
expect(printBlock).toMatch(/\.screen-only\s*\{[^}]*display:\s*none/);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('Canvas/Druckbereich füllt die Seite (print-area Regel)', () => {
|
|||
|
|
expect(printBlock).toContain('.print-area');
|
|||
|
|
expect(printBlock).toMatch(/\.print-area\s*\{[^}]*width:\s*100%/);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
it('print-layout-Modus erzwingt Farbdruck-Hintergründe (print-color-adjust)', () => {
|
|||
|
|
expect(printBlock).toMatch(/-webkit-print-color-adjust:\s*exact/);
|
|||
|
|
});
|
|||
|
|
});
|