“AI naprawi kruchy test”
Jest 15 lutego. Miesiąc temu w wpisie o agentach odłożyłem temat samonaprawiających się lokatorów na osobny tekst, bo leczenie selektora to inna kategoria narzędzi niż pętla z celem. Od tamtej pory w rozmowach o czerwonym E2E pada to samo zdanie: nie trzeba już pisać stabilnych lokatorów, bo model albo produkt “AI” podmieni selector, kiedy strona się zmieni. Brzmi to jak rozwiązanie na flake, które od października 2021 i listopada 2021 leczyłem izolacją środowiska, a nie magią w runnerze.
Moja teza na luty 2024 jest wąska i będę jej bronił przez cały wpis. Self-healing to stary produkt SaaS i OSS, sprzedawany na nowo jako AI, a nie nowy przycisk w Playwright. Leczenie lokatora nie leczy flake ze środowiska, danych ani wyścigu. Nie zdejmuje recenzji, którą w lipcu zostawiłem przy hipotezach z logu.
Stan warsztatu na dziś, żeby za rok było wiadomo, o czym mówię. Runner to Playwright 1.41.1 z 19 stycznia. W testach nadal piszę getByRole i getByTestId, tak jak przy pierwszym projekcie i przy refaktorze POM. Oficjalnego self-healing GA w Playwright 1.41 nie ma. Auto-waiting i retry asercji to nie naprawa lokatora przez model. Copilot Chat jest od 29 grudnia w stabilnym VS Code i do healingu go nie używam: czat widzi otwarty plik, nie DOM z nocnego przebiegu.
Czego tu nie będzie. Nie będzie twierdzenia, że Playwright dostał healer w rdzeniu. Nie będzie tutoriala Healenium, Testim ani Mabl jako nowości lutego. Nie będzie agenta podpiętego do CI. Będzie jedno syntetyczne demo na moim własnym repozytorium z przykładami do bloga: zmiana id przycisku kontra padający timeout API.
Co jest stare
Fala, o której dziś wszyscy mówią jak o nowości 2024, jest starsza od ChatGPT.
Testim reklamował Smart Locators i “AI locators” przy akwizycji przez Tricentis 9 lutego 2022. To dwa lata przed tym wpisem. Mabl zbiera wiele identyfikatorów elementu i adaptuje krok, kiedy jeden z nich znika; firma istnieje od 2017, a auto-heal jest w blogu produktu, nie w changelogu lutego 2024. Healenium to proxy i wrapper na Selenium: przy NoSuchElement podmienia selector na wariant, który “uzdrowił” poprzedni przebieg. Hub EPAM ma linię 3.x od października 2020 (v3.0.1 = 9 października 2020), repozytorium na GitHubie od 7 października 2021. To jest Selenium-shaped OSS, nie funkcja Playwrighta.
Nie pinuję tu patcha Maven ani NuGet na dziś, bo nie mam URL-a, który by to potwierdził na 15 lutego. Daty, które mam, wystarczą: żaden z tych trzech produktów nie “wyszedł w 2024”. Wyszedł hype, w którym stary mechanizm dostaje nowe słowo “AI” i ląduje w tej samej rozmowie co styczniowi agenci.
Różnica kategorii jest prosta. Agent z pętlą dostaje cel i sam dobiera narzędzia. Healer dostaje padający locator i podmienia go na inny, który tym razem trafia w element. Oba potrafią zrobić zielony wynik bez wiedzy, dlaczego było czerwono. Oba zasługują na recenzję jak diff, nie na zaufanie jak asercja.
Co healing leczy, a czego nie
Healing leczy jedną klasę awarii: zmienił się id, class albo ścieżka w DOM, a element nadal jest na stronie i nadal robi to samo. To jest ten sam problem, który od sierpnia 2021 rozwiązuję getByRole, getByTestId i brakiem statycznego drivera, a nie podmianą selectora w locie.
Nie leczy niczego, co nie jest selectorem.
Nie leczy timeoutu sieci, kiedy API logowania nie wraca w piętnastu sekundach. Nie leczy shared fixture, kiedy dwa workery piszą do tego samego użytkownika. Nie leczy race, kiedy przycisk jest w DOM, ale jeszcze disabled, bo hydracja nie skończyła się przed kliknięciem. Nie leczy fontu i viewportu na agencie CI, których nie ma na moim laptopie. To są te same koszyki, które we wrześniu 2022 rozdzieliłem na bramkę i nightly, i te same, które w lipcu model miał tylko nazwać, a ja miałem odtworzyć.
Pixel z listopada 2022 też tu nie pomaga: screenshot mówi, że wygląd się zmienił, healer mówi, że selector się zmienił. Żadne z nich nie mówi, czy zmienił się produkt.
Pokażę to na syntetycznym teście logowania z repozytorium przykładów, nie z projektu klienta. Dwa warianty tej samej czerwieni, jeden healer, dwa różne werdykty.
Wariant A: w piątek ktoś zmienił id przycisku z login-submit na submit-login. Tekst zostaje “Zaloguj”, rola zostaje button. Test napisany na #login-submit pada na NoSuchElement albo na timeout lokatora.
TimeoutError: locator.click: Timeout 15000ms exceeded.
waiting for locator('#login-submit')Healer, który zbiera kilka atrybutów elementu z poprzedniego zielonego przebiegu, znajduje przycisk po tekście albo po sąsiedztwie pola hasła, podmienia selector i nocny przebieg jest zielony. To jest jedyny przypadek, w którym mechanizm robi to, co obiecuje. Koszt: w raporcie nie ma śladu, że produkt zmienił identyfikator. Jeśli zmiana id była przypadkiem, nikt o niej nie usłyszy. Jeśli była celowa i łamie kontrakt automatyzacji, kontrakt właśnie został cicho przepisany.
Wariant B: id jest ten sam. API /auth na środowisku nightly nie odpowiada, modal zgody albo spinner zostaje nad formularzem, przycisk jest w DOM, ale klik nie kończy logowania. Test pada na timeoutcie asercji “widać dashboard”, nie na NoSuchElement.
TimeoutError: expect(locator.getByRole('heading', { name: 'Pulpit' })).toBeVisible()
waiting for getByRole('heading', { name: 'Pulpit' })Healer nie ma tu czego podmienić, albo, gorzej, ma: znajdzie inny heading na stronie logowania, uzna go za “uzdrowiony” cel asercji i zamaskuje timeout API. Wariant B jest flake ze środowiska. Leczenie lokatora jest tu błędem kategorii, dokładnie takim, jaki w styczniu zrobiła pętla, która wymyśliła data-testid, którego nie było, zamiast sprawdzić flagę w konfiguracji.
Healing “naprawia” wariant A i maskuje wariant B. W nightly, bez recenzji podmiany, nie umiem ich odróżnić.
Playwright bez oficjalnego self-healing
Playwright 1.41.1 czeka na element, retryuje asercje i zapisuje trace. To nie jest self-healing. Gdy selector pada, otwieram trace, czytam, czy element był w DOM, czy był niewidoczny, czy był przykryty, i dopiero potem zmieniam test albo środowisko. Auto-waiting skraca czas, który kiedyś spędzałem na sleep, i nic poza tym. Nie podmienia mi lokatora za plecami.
Nie znalazłem w tagu v1.41.1 oficjalnego Healer agent ani self-healing GA. Nie będę pinował funkcji, której nie ma w release notes. Jeśli ktoś sprzedaje “AI locators for Playwright” jako wtyczkę albo SaaS, to jest osobny produkt, z osobną recenzją i osobnym miejscem w piramidzie, a nie feature runnera, który mam w package.json.
Gdy selector pada, mam trzy pytania i żadne z nich nie brzmi “włącz heal”. Czy ten test w ogóle coś sprawdza, czy tylko czeka na element. Czy zmiana jest w produkcie, czy w środowisku. Czy potrafię odtworzyć awarię, zanim zaproponuję poprawkę. To jest ten sam zestaw, który w styczniu zostawiłem przy pętli agenta i w lipcu przy hipotezach z logu. Healing odpowiada na inne pytanie: “czy istnieje inny selector, przy którym ten krok przejdzie”. To pytanie jest przydatne przy refaktorze POM. Jest szkodliwe jako automat w nightly.
Gdy ktoś i tak wstawi healer
Nie uda mi się zakazać tego narzędzia w cudzym zespole. Mogę powiedzieć, pod jakim warunkiem nie skasuje sygnału.
Każda podmiana selectora musi trafić do raportu jak diff. Stary locator, nowy locator, zrzut elementu, na który nowy trafił, i test, który przez to przeszedł. Recenzuję to tak, jak recenzuję ghost text od czerwca 2022 i jak recenzuję hipotezę z modelu od lipca: najpierw odtwarzam, potem zgadzam się albo skreślam. Cichy heal w nightly jest gorszy niż czerwony test, bo czerwony test zostawia ślad. Cichy heal zostawia zielone i regresję produktu, o której nikt nie usłyszy do momentu, aż selector “uzdrowiony” trafi w zły przycisk.
Kontrast z lipcem jest tu obowiązkowy, bo te dwa tematy się zlewają w rozmowach. W triage flake model dawał trzy hipotezy z logu. Ja odtwarzałem. Żadna hipoteza nie zmieniała testu bez mojego commita. Self-healing działa w drugą stronę: zmienia test albo locator w runtime, a log, jeśli w ogóle powstaje, opisuje sukces, nie przyczynę. To nie jest triage. To jest automatyczna poprawka bez ownera.
W podsumowaniu 2023 zapisałem, po czym poznaję, że narzędzie weszło do zespołu, a nie do hype’u. Dwie z tych rzeczy to nazwane zadanie i człowiek, który odpowiada za wynik. Healer ma pierwsze, jeśli ograniczymy go do “podpowiedz inny locator przy refaktorze”. Nie ma drugiego, jeśli w nocy sam przepisuje suite.
Dla porządku jedno zdanie o dacie: 15 lutego Google ogłosiło Gemini 1.5 Pro w limited preview. Nie mam do tego dostępu jako do codziennego modelu i nie jest to stack tego wpisu.
Podsumowanie
Self-healing jest tematem tego miesiąca, bo słowo “AI” przykleiło się do produktów, które znam od lat. W lutym 2024 nie kupuję go jako zamiennika izolacji i recenzji.
Trzy zdania, które chcę móc przeczytać za rok. Testim, Mabl i Healenium są starsze niż hype lutego; Playwright 1.41.1 nie ma oficjalnego self-healing GA, a auto-waiting nie jest naprawą lokatora. Syntetyczny test logowania pokazuje dwie czerwienie: zmiana id przycisku, którą healer “naprawia”, i timeout API, który healing maskuje albo zostawia nietknięty, w obu wypadkach bez werdyktu, czy zmienił się produkt. Recenzja podmiany jak diff zostaje, dokładnie tak jak recenzja hipotezy z logu w lipcu i recenzja pętli agenta w styczniu.
Czego z tego nie wynika. Nie wynika, że Smart Locators są bez wartości przy masowej zmianie id po restylingu. Nie wynika, że nigdy nie wstawię heurystyki “znajdź ten sam przycisk po roli i nazwie” w helperze POM. Nie wynika też, że to się nie zmieni, jeśli Microsoft wpuści healer do rdzenia Playwrighta: dziś go tam nie ma, więc nie mam o czym pisać poza datą.
Warunek, po którym poznam, że temat dojrzał, formułuję tak: podmiana selectora jest akceptowalna wtedy, kiedy zostawia audytowalny diff, nie ukrywa timeoutu środowiska jako sukcesu lokatora i nie zdejmuje z człowieka pytania, czy czerwony test złapał produkt, czy flake. Do tego czasu suite nie ma autonomicznego uzdrowiciela. Ma izolację, trace i mnie.

