From 369aed369470eb31fe600a066df0c4586ccdfe77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Mon, 1 Jun 2026 13:08:27 +0200 Subject: [PATCH] =?UTF-8?q?fix(tests):=20deterministyczny=20wyb=C3=B3r=20w?= =?UTF-8?q?=20Select2=20helperze=20=E2=80=94=20klik=20pasuj=C4=85cej=20poz?= =?UTF-8?q?ycji=20zamiast=20Enter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit select_select2_autocomplete wciskał Enter wybierając PIERWSZĄ podświetloną pozycję wyników. Pod obciążeniem CI press_sequentially wpisuje znaki wolniej niż debounce Select2, więc dla "Aut2…" w oknie czasowym widoczne bywają jeszcze wyniki dla "Aut…" — zawierające INNEGO autora o wspólnym prefiksie. Enter po cichu wybierał złego autora; błąd ujawniał się dopiero przy zapisie jako UniqueViolation na (rekord_id, autor_id, typ_odpowiedzialnosci_id), bo oba wiersze formsetu wskazywały na ten sam autor_id. Helper klika teraz konkretną pozycję, której widoczny tekst zawiera pełną szukaną wartość; tylko gdy takiej pozycji nie ma (pola, gdzie szukany tekst nie jest podłańcuchem etykiety, np. generowane warianty "zapisany jako") spada do dawnego Enter-na-pierwszej. Weryfikacja lokalna: test_..._dwoch_autorow × 3 parametry × 3 powtórki = 9/9 passed. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/django_bpp/playwright_util.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/django_bpp/playwright_util.py b/src/django_bpp/playwright_util.py index b20c48373..f8170b75e 100644 --- a/src/django_bpp/playwright_util.py +++ b/src/django_bpp/playwright_util.py @@ -153,8 +153,29 @@ def select_select2_autocomplete( timeout=timeout, ) - # Press Enter to select the first/highlighted result - search_input.press("Enter") + # Select the result deterministically. Pressing Enter blindly picks the + # FIRST highlighted option, which under CI timing can be a stale/broader + # intermediate AJAX result: typing "Aut2…" character-by-character may, when + # press_sequentially runs slower than Select2's debounce, momentarily show + # the results for "Aut…" — which also contain a *different* author sharing + # the prefix. Enter then silently selects that wrong author; the mistake + # only surfaces later as a unique-constraint violation on submit (two + # formset rows pointing at the same autor_id). So: prefer clicking the + # specific option whose visible text contains the full search term. Only if + # no such option exists — fields where the search term is not a substring + # of the rendered label, e.g. generated "zapisany jako" name variants — do + # we fall back to Enter-on-first-highlight. + option_selector = ( + ".select2-results__option:not(.loading-results):not(.select2-results__message)" + ) + matching_option = page.locator(option_selector).filter(has_text=value).first + try: + matching_option.wait_for(state="visible", timeout=2000) + matching_option.click() + except Exception: + # No option literally containing the search term — fall back to + # selecting the first/highlighted result via Enter. + search_input.press("Enter") # Wait for the actual signals that selection propagated: # (1) Select2 closes the dropdown after Enter, (2) underlying