test(quick-260921-ldf): zwei Konstruktionsfehler im Fehler-melden-Test behoben
Beide Befunde sind nicht die Ursache des Wackeltests aus CI-Lauf 395, aber beide haetten die Fehlersuche in die Irre fuehren koennen. Erstens stand ein expect INNERHALB der toPng-Attrappe. Wirft es, landet der Fehler mitten im await von captureScreenshot, und dessen catch liefert still null zurueck. Der Test waere dann nicht an der Stelle durchgefallen, die er prueft, sondern viel spaeter mit der Meldung, es gebe kein Vorschaubild. Die Attrappe haelt die Beobachtung jetzt nur noch fest, geprueft wird sie im Testkoerper. Bewiesen wird dasselbe: zum Zeitpunkt der Aufnahme steht kein role="dialog" im DOM. Zweitens wurden scrollWidth und scrollHeight von document.body per Object.defineProperty ueberschrieben und nie zurueckgesetzt. Die eigene Eigenschaft verdeckt den Getter von Element.prototype, und document.body ueberlebt cleanup() - alle zwoelf folgenden Tests der Datei sahen weiterhin 3200x1000. stubBodyGroesse merkt sich das jetzt, afterEach nimmt es per Reflect.deleteProperty wieder zurueck. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
This commit is contained in:
@@ -91,6 +91,27 @@ beforeEach(() => {
|
|||||||
vi.stubGlobal('fetch', mockFetch);
|
vi.stubGlobal('fetch', mockFetch);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Groesse von `document.body` vortaeuschen. WICHTIG: `Object.defineProperty`
|
||||||
|
* legt eine eigene Eigenschaft auf dem Element an, die den Getter von
|
||||||
|
* `Element.prototype` verdeckt — `document.body` ueberlebt `cleanup()` und
|
||||||
|
* damit die ganze Datei. Ohne Ruecknahme saehen alle folgenden Tests 3200x1000.
|
||||||
|
* Deshalb merken und in `afterEach` wieder loeschen.
|
||||||
|
*/
|
||||||
|
let bodyGroesseVorgetaeuscht = false;
|
||||||
|
function stubBodyGroesse(scrollWidth: number, scrollHeight: number) {
|
||||||
|
Object.defineProperty(document.body, 'scrollWidth', { value: scrollWidth, configurable: true });
|
||||||
|
Object.defineProperty(document.body, 'scrollHeight', { value: scrollHeight, configurable: true });
|
||||||
|
bodyGroesseVorgetaeuscht = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreBodyGroesse() {
|
||||||
|
if (!bodyGroesseVorgetaeuscht) return;
|
||||||
|
Reflect.deleteProperty(document.body, 'scrollWidth');
|
||||||
|
Reflect.deleteProperty(document.body, 'scrollHeight');
|
||||||
|
bodyGroesseVorgetaeuscht = false;
|
||||||
|
}
|
||||||
|
|
||||||
function clearDesktopCookies() {
|
function clearDesktopCookies() {
|
||||||
document.cookie = 'tessera_desktop=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
|
document.cookie = 'tessera_desktop=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
|
||||||
document.cookie = 'tessera_desktop_client=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
|
document.cookie = 'tessera_desktop_client=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
|
||||||
@@ -100,15 +121,21 @@ afterEach(() => {
|
|||||||
cleanup();
|
cleanup();
|
||||||
clearErrorBuffer();
|
clearErrorBuffer();
|
||||||
clearDesktopCookies();
|
clearDesktopCookies();
|
||||||
|
restoreBodyGroesse();
|
||||||
vi.unstubAllGlobals();
|
vi.unstubAllGlobals();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('BugReportButton (quick-260914-m97)', () => {
|
describe('BugReportButton (quick-260914-m97)', () => {
|
||||||
it('Test 1: Bild VOR dem Dialog — toPng laeuft ohne offenen Dialog, mit document.body, pixelRatio 1, skipFonts, 1600-px-Kante; danach Dialog mit Vorschau, Haekchen an, Textfeld leer', async () => {
|
it('Test 1: Bild VOR dem Dialog — toPng laeuft ohne offenen Dialog, mit document.body, pixelRatio 1, skipFonts, 1600-px-Kante; danach Dialog mit Vorschau, Haekchen an, Textfeld leer', async () => {
|
||||||
Object.defineProperty(document.body, 'scrollWidth', { value: 3200, configurable: true });
|
stubBodyGroesse(3200, 1000);
|
||||||
Object.defineProperty(document.body, 'scrollHeight', { value: 1000, configurable: true });
|
// Kein `expect` INNERHALB der Attrappe: ein Fehler daraus landet mitten im
|
||||||
|
// `await` der Komponente und wird von `captureScreenshot` verschluckt
|
||||||
|
// (`catch` liefert `null`) — der Test waere dann an ganz anderer Stelle
|
||||||
|
// mit irrefuehrender Meldung durchgefallen. Also nur festhalten, unten
|
||||||
|
// pruefen (quick-260921-ldf).
|
||||||
|
let dialogWaehrendDerAufnahme: unknown = 'toPng wurde nicht aufgerufen';
|
||||||
mockToPng.mockImplementation(async () => {
|
mockToPng.mockImplementation(async () => {
|
||||||
expect(screen.queryByRole('dialog')).toBeNull();
|
dialogWaehrendDerAufnahme = screen.queryByRole('dialog');
|
||||||
return DATA_URL;
|
return DATA_URL;
|
||||||
});
|
});
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
@@ -117,6 +144,7 @@ describe('BugReportButton (quick-260914-m97)', () => {
|
|||||||
const dialog = await openDialog(user);
|
const dialog = await openDialog(user);
|
||||||
|
|
||||||
expect(mockToPng).toHaveBeenCalledTimes(1);
|
expect(mockToPng).toHaveBeenCalledTimes(1);
|
||||||
|
expect(dialogWaehrendDerAufnahme).toBeNull();
|
||||||
const [node, opts] = mockToPng.mock.calls[0] as [unknown, Record<string, unknown>];
|
const [node, opts] = mockToPng.mock.calls[0] as [unknown, Record<string, unknown>];
|
||||||
expect(node).toBe(document.body);
|
expect(node).toBe(document.body);
|
||||||
expect(opts).toMatchObject({ pixelRatio: 1, skipFonts: true, canvasWidth: 1600, canvasHeight: 500 });
|
expect(opts).toMatchObject({ pixelRatio: 1, skipFonts: true, canvasWidth: 1600, canvasHeight: 500 });
|
||||||
|
|||||||
Reference in New Issue
Block a user