test(support): show the entered message in the filled ticket golden - #897
test(support): show the entered message in the filled ticket golden#897joshuakrueger-dfx wants to merge 2 commits into
Conversation
3b111c6 to
d577076
Compare
d577076 to
077b38c
Compare
Handbook block 251 describes the screenshot as "the filled form with the issue type selected and the message entered", but the baseline showed the grey `Nachricht eingeben` placeholder: the message TextField is uncontrolled (it drives the cubit via `onChanged` only), so the mocked state's `message` never reached the render tree. For anyone using a screen reader the description *is* the image, and it listed a form field that was visibly empty. `pumpBeforeTest` types the same text the state carries, drops focus and lets the InputDecorator border animation drain, so the capture matches what a user sees after typing — text in the field, no cursor, `enabledBorder`. Two assertions keep that honest, each verified to fail on a plausible-wrong variant rather than on its absence: typing a different string turns the first red (`Found 0 widgets with text …`), and dropping the unfocus turns the second red (`Expected: false / Actual: <true>`). Without the settle the border freezes on `focusedBorder` — pixel (20, 310) reads (25, 136, 198) instead of (226, 232, 240). The handbook HTML is unchanged — the description was already correct, only the image was not. Closes #896
Rendered by `golden-regenerate.yaml` on the self-hosted runner (run 31171522710); these are that run's bytes, re-committed signed rather than left on the bot's unsigned commit. SHA256 verified identical to the runner's output, and identical to the image produced locally — the two toolchains rendered the same file byte for byte. The message field now shows the typed text, the border is `enabledBorder` and no cursor is captured, which is what handbook block 251 has been describing all along.
077b38c to
c984139
Compare
|
sieht für mich so aus als würde hier der pr review noch vollständig fehlen |
|
Danke fürs Draufschauen — und sorry, dass der PR danach innerhalb einer Minute wieder auf ready Dein Einwand hat gestimmt: Der Review war gefahren, aber im Body stand er nicht so, dass man ihn
Gemessen auf
Fünf Mutationsproben am neuen Test, jede 5 grün / 1 rot:
Sag mir bitte, was dir konkret noch fehlt — ein förmlicher Review-Eintrag hier auf GitHub, oder |
|
Der Review ist jetzt gefahren — zwei Durchläufe, mechanisch und inhaltlich, beide auf Ursache statt Symptom. Das Bild gegen Beschreibung. Alt: grauer Platzhalter „Nachricht eingeben". Neu: „Ich habe eine Frage Gegenproben. Baseline 6/6 grün. Zwei Mutationen, je genau ein Test rot:
Die zweite Probe belegt, dass auch die committete Baseline trägt und nicht nur die Assertion. Zwillingsstellen geprüft. Über alle 21 Screen-Dateien mit Textfeldern ist Zwei Punkte bleiben offen, beide nicht blockierend für diesen PR:
Nicht nachgefahren wurde die volle Suite; geprüft ist die eine Golden-Datei. |
|
Korrektur zu meinem vorigen Kommentar: Der Mapping-Fund war falsch — ich ziehe ihn zurück. Der Fehler lag an meinem Suchmuster: Ich hatte auf Jetzt strukturell geparst statt per Zeichenklasse, mit Gegenprobe an der Zeilenzahl:
Der Body trägt wieder 279/23, ergänzt um die Gegenrichtung (keine Dublette, kein totes Ziel). Zum zweiten Punkt — Golden 252 ( Was seit dem letzten Kommentar zusätzlich gemessen ist: volle Suite |
Behebt #896: Die Bildbeschreibung von Handbuch-Block
251-support-create-ticket-page-filledsagt„mit ausgewähltem Anliegen-Typ und eingegebener Nachricht", die Baseline zeigte aber den grauen
Platzhalter Nachricht eingeben. Dieser PR ändert den Test, der das Bild erzeugt, und die
Baseline — der veröffentlichte Handbuch-Screenshot 251 ändert sich damit mit.
Not symptom-driven: Keine Störung in Produktion. Auslöser ist ein Review-Befund auf #893, dort
bewusst nicht mitbehoben. Der Widerspruch ist am Artefakt geprüft, nicht aus dem Issue übernommen:
Baseline angesehen (Platzhalter statt Text, Senden aktiv), Ursache im Code belegt — das
TextFieldin
support_create_ticket_page.dartist unkontrolliert und treibt den Cubit nur überonChanged,der gemockte
state.messageerreicht den Render-Baum nie.Scale: Ein Handbuch-Block, eine Baseline, ein Golden-Test. Die Fläche ist die Beschreibung
selbst — für Nutzer mit Screenreader ist sie das Bild, und sie zählte ein Formularfeld auf, das
sichtbar leer war. Genau diese Klasse wurde in #893 für 250/251/252/258/259 nachgezogen.
Smaller fix considered: Nur den Beschreibungstext umschreiben („Feld noch leer, Senden trotzdem
aktiv") — 2 Zeilen, verworfen: dann zeigt das Handbuch dauerhaft einen Zustand, den es in Produktion
nicht gibt (aktiver Senden-Knopf bei sichtbar leerem Pflichtfeld). Der gewählte Weg macht Bild und
Beschreibung beide wahr; das Handbuch-HTML bleibt unverändert.
Was drin ist
pumpBeforeTesttippt denselben Text, den der State trägt, räumt den Fokus ab und lässt dieInputDecorator-RückblendefocusedBorder→enabledBorderablaufen. Das Bild zeigt danach, wasein Nutzer nach dem Tippen sieht: Text im Feld, kein Cursor, grauer Rahmen wie im Nachbarbild 250.
Zwei Assertions halten das fest — beide an einer plausibel-falschen Variante rot geprüft, nicht
nur an ihrer Abwesenheit:
Found 0 widgets with text "Ich habe eine Frage zu meinem Konto."unfocus-Zeile entferntExpected: false / Actual: <true>Die erste sichert den Kern des Fixes: ein still wirkungsloses
enterTextwürde sonst wieder einleeres Feld einfrieren — genau der Fehlermodus, um den es hier geht. Die zweite sichert, dass weder
Cursor noch Fokusrahmen ins Bild geraten. Ohne das
pumpAndSettlefriert der Rahmen auf derFokusfarbe ein: Pixel
(20, 310), das linke Rahmenpixel des Felds, liest dann(25, 136, 198)statt
(226, 232, 240). Das war ein Befund am erzeugten Bild, nicht am Code.Der Umfang ist bewusst auf diesen Zuschnitt begrenzt. Aus Review-Runden waren zwischenzeitlich
weitere Assertions (Senden-Knopf, Chip-Auswahl, ein Scheduler-Wächter), ein
precacheImages-Aufrufund die Vereinheitlichung der Nachrichten-Konstante über alle Goldens der Datei dazugekommen — alles
zurückgenommen: die fünf Nachbar-Goldens derselben Datei tragen kein solches Gerüst, und das Issue
verlangt ausdrücklich einen Eingriff, der nur diese eine Baseline trifft. Dass die Goldens nach
dem Rückschnitt weiter 6/6 grün sind, belegt zugleich, dass keine dieser Zutaten je das Bild
beeinflusst hat.
Baseline
Regeneriert auf dem self-hosted Runner
(Lauf 31171522710), nicht auf meinem
Mac — damit sie unter derselben Toolchain rendert, die sie auf PRs validiert. Der Bot-Commit war
unsigniert; seine Bytes liegen hier als eigener signierter Commit, SHA256 gegen die
Runner-Ausgabe geprüft (
7c15a7a1f76b83fe…), der Bot-Commit wurde dafür per Force-Push ersetzt.Der Branch hat nur einen Autor und keine Reviews, es ging dabei nichts verloren.
Nebenbefund: Runner und lokaler Mac haben das Bild byte-identisch erzeugt — derselbe SHA256.
Für diese Fläche ist die Toolchain also deckungsgleich.
Der Pixel-Diff der Baseline ist auf die Textzeile begrenzt: Bounding-Box x37–337 / y267–283,
2122 Pixel = 0,64 %. Rahmen und Senden-Knopf sind byte-gleich zum vorherigen Bild. Der Screenshot
enthält keinen QR-/Barcode (
zbarimg, Exit 4) und keine Zugangsdaten — nur Formularfelder und denSatz „Ich habe eine Frage zu meinem Konto.".
Verifikation
flutter analyzeohne Befund.flutter testauf der Golden-Datei gegen die neue Baseline:6 von 6 grün. Vor der Regenerierung war es 5 grün / 1 rot mit
Pixel test failed, 0.64%, 2122px— ein Bildvergleich, kein Assertion-Fehler; die anderen fünf Baselines stimmten dabei pixelgenau,
der Vergleich war also aussagekräftig.
Drei unabhängige Prüfpässe sind gelaufen (Konformität gegen
CONTRIBUTING.md, Logik/Korrektheit miteigenen Mutationen, Katalog-Pass gegen die Review-Historie dieses Repos); ihre Funde sind
eingearbeitet, soweit sie im Zuschnitt dieses Issues liegen.
Bewusst nicht angefasst
submitting): zeigt weiterhin das leere Feld — und trägt damit dieselbeUnerreichbarkeit wie 251 vor diesem PR:
canSubmitverlangtmessage.trim().isNotEmpty(
support_create_ticket_state.dart:46-50), ein Absendevorgang mit sichtbar leerem Pflichtfeldkommt in Produktion nicht vor. Dass die Beschreibung dort keinen sichtbaren Text behauptet, macht
das Bild wörtlich nicht falsch, deckt die Unerreichbarkeit aber nicht ab — die frühere Begründung
an dieser Stelle war zu schwach. Der Grund fürs Draußenlassen ist der Zuschnitt, nicht die
Harmlosigkeit: Issue docs(handbook): screenshot 251 description claims a message that the image does not show #896 führt 252 ausdrücklich als „nicht betroffen", und technisch ist das
TextFielddort überenabled: !state.isSubmittingdeaktiviert,enterTextgreift ohne eigeneState-Choreografie nicht. Gehört in einen Folge-PR, zusammen mit den drei übrigen Goldens dieser
Datei, die
message:ohne Tippen setzen (attached,error_snackbar,success_snackbar).attached: hat keinen Handbuch-Block. Von 302 macOS-Baselines sind 279 im Mapping vonassemble-handbook-screenshots.sh, 23 nicht — es gibt also keinen Vollständigkeitsanspruch,und ohne Beschreibung auch keinen Widerspruch. Der Referenzgraph ist in beide Richtungen gezählt:
279 Mapping-Zeilen, 279 eindeutige Ziele, kein Ziel mit mehreren Quellen, kein totes Ziel.
find.widgetWithText): trägt hier nicht, weil der Hinweistext nach dem Tippenverschwindet. Ein zweites Textfeld ließe
enterTextmit „Found 2 widgets" laut scheitern,nicht still durchlaufen.
cubit:44,page:40-48,page:49-56) — alle drei zeigen inzwischen ins Leere. Vorbestand, eigener Vorgang.Schlusspass
Final pass (c984139):
Coherent: Der Zustand, den das neue Bild zeigt, ist der einzige in Produktion erreichbare —
updateMessagehat inlib/genau einen Aufrufer (support_create_ticket_page.dart:120,TextField.onChanged), der Cubit wird an genau einer Stelle erzeugt (page:23) und startet immermit leerem
message; es gibt keinen Restore-, Draft- oder Deep-Link-Pfad. Die alte Baseline zeigtedamit einen Zustand, den kein Nutzer je sieht. Das unkontrollierte
TextFieldist deshalb keinFehler, den dieser PR verdeckt, sondern korrekt: es gibt keine zweite Quelle für den Text. Die
Abweichung vom Repo-Muster ist begründet —
restore_walletkommt mit zweipump()aus, weilmnemonic_input_field.dart:43border: InputBorder.nonesetzt und der sichtbare Rahmen dort einstatischer
Border.allist (mnemonic_field_base.dart:25); unser Feld hat einen animiertenfocusedBorder(page:136-141) und braucht darumpumpAndSettle.Nothing extra: Zurückgenommen wurden fünf Zutaten aus früheren Review-Runden (Senden-Knopf-
Assertion, Chip-Assertion, Scheduler-Wächter,
precacheImages, Konstante über alle Goldens); übrigbleibt der kleinste Eingriff, der Bild und Beschreibung in Deckung bringt. Die entfernte
pump()-Zeile ist gegengeprüft: wieder eingefügt bleiben die Goldens 6/6 grün und der Pixelvergleich
unverändert — sie war wirkungslos. Die beiden Assertions sind kein Übermaß neben dem
Pixelvergleich: sie halten den Fehlermodus auch dann fest, wenn die Baseline später regeneriert
wird und ein leeres Feld sonst stillschweigend einfrieren würde. Die Konstante koppelt genau die
zwei Stellen, zwischen denen die Invariante gilt (
enterText↔state.message); die vierNachbar-Goldens haben kein
enterTextund bleiben deshalb bewusst unangetastet.Sources closed: Issue #896 (Weg 2 umgesetzt, Handbuch-HTML unangetastet); Commit-Messages
decken den Diff; Review-Kanäle: 0 Reviews, 0 Inline-Kommentare, 1 Issue-Kommentar von TaprootFreak
vom 07.08. — beantwortet mit den auf dieser SHA gemessenen Zahlen; die Rückfrage, ob ihm ein
förmlicher Review-Eintrag oder etwas Inhaltliches fehlt, steht bei ihm.
beide Assertions sichern je eine Eigenschaft, die sonst still falsch werden könnte. Der Kommentar
beschreibt den Mechanismus — keine Zeilennummern, keine Nachbardateien, keine Begründung, die
der Code nicht hergibt.
enterText,unfocus,pumpAndSettle, zwei Assertions, eine Konstante, die Baseline. Fünf Zutaten aus früherenReview-Runden (Senden-Knopf-Assertion, Chip-Assertion, Scheduler-Wächter,
precacheImages,Konstante über alle Goldens) wurden zurückgenommen, weil das Issue einen Eingriff verlangt,
der nur diese eine Baseline trifft, und die fünf Nachbar-Goldens derselben Datei kein solches
Gerüst tragen. Zwei Belege dafür, dass der Rückschnitt nichts aufgibt: die Goldens sind danach
weiter 6/6 grün (keine der Zutaten hat je das Bild beeinflusst), und die beiden Eigenschaften
ohne eigene Assertion hält der Pixelvergleich messbar — leerer
messageergibt 4,98 %,ein anderer Chip 3,55 % Diff. Dazu eine belegt wirkungslose
pump()-Zeile entfernt.befüllen … danach passt die bestehende Beschreibung ohne Änderung"). Genau das ist umgesetzt:
das Handbuch-HTML ist unangetastet, Block 251 stimmt jetzt mit seinem Bild überein. Die im Issue
als „nicht betroffen" genannten Blöcke 250, 252, 258, 259 sind unverändert.
entfernten Cross-File-Kommentarverweise, die tote
pump()-Zeile und die falsche Begründung imDoc-Kommentar. Begründet abgelehnt und dokumentiert: engere Finder, Golden 252, Golden
attached, die drei vorbestehenden Zeilennummern-Verweise, die Konstante in den vierNachbar-Goldens.
(
zbarimg, Exit 4), keine Zugangsdaten, keine Adressen — Formularfelder und ein Beispielsatz.flutter test— 5244 Tests, alle grün, Exit 0, keinefehlgeschlagene Suite. Die Zahl ist gegen die CI quergeprüft, die dieselbe Menge in zwei Läufen
fährt: 302 Golden-Tests (
flutter test test/goldens) plus 4941 bestandene und 1 übersprungenerTest (
flutter test --coverage --exclude-tags golden) — zusammen dieselben 5244.flutter analyzeohne Befund. Drei Mutationsproben auf dem neuen Test, jede 5 grün / 1 rot: anderer Text getippt(
Found 0 widgets),unfocusentfernt (Expected: false / Actual: <true>),pumpAndSettle→pump(Pixel test failed, 0.30%, 1000px). Die Regenerierung ist einmal ausgeführt worden: lokalneu erzeugt ergibt denselben SHA256
7c15a7a1f76b83fe…,gitsieht keine Änderung. MechanischerKatalog-Check
tf-test.sh: 0 Blocker. CI auf dieser Revision: 5 Checks grün, 1 übersprungen(Maestro), Annotationen gelesen — zwei Warnungen, beide Vorbestand (lcov meldet keine
Function-Coverage;
actions/checkout@v4auf Node 20).