Co oznacza to kryterium
Przejście fokusem na pole lub przycisk pozwala rozpoznać jego działanie przed uruchomieniem. Sam fokus nie może wysłać formularza, otworzyć okna ani przenieść użytkownika do innego widoku. Taki skutek powinien wynikać z osobnej aktywacji. Lokalna podpowiedź może pojawić się przy fokusie, jeśli zachowuje kontekst zadania.
| ID / potrzeba | Bariera i korzyść |
|---|---|
blindness / Niewidzenie |
Osoba odczytująca kontrolki może zostać przeniesiona, zanim pozna etykietę i podejmie decyzję. Stabilny fokus pozwala poznać akcję. |
low-vision / Słabowidzenie |
Przy powiększeniu widoczny jest fragment ekranu; niespodziewany modal lub zmiana widoku utrudnia odnalezienie pozycji. |
motor / Ograniczenia ruchowe |
Użytkownik klawiatury albo przełączników potrzebuje swobodnie przechodzić między kontrolkami bez przypadkowego uruchamiania funkcji. |
cognitive / Pamięć i koncentracja |
Nieoczekiwana zmiana przerywa plan czynności i utrudnia zrozumienie związku między wyborem elementu a jego działaniem. |
Nie dodajemy automatycznie słuchu ani rozróżniania barw; nie są warunkiem tych scenariuszy. Kategorie są redakcyjnymi tagami potrzeb, nie diagnozami ani oficjalną klasyfikacją WCAG.
Przykłady błędów i poprawek
Własna demonstracja Pracowni pokazuje odbiór syntetycznego P-104 przy ul. Ogrodowej 8, piątek 10:00–18:00. Good i bad mają identyczne dane, kontrolki i funkcje. Bad dodatkowo wywołuje tę samą funkcję w CupertinoButton.onFocusChange przy true; good uruchamia ją tylko z onPressed.
Problem: zwykły Tab otwiera modal pomocy albo wymienia formularz na podsumowanie, zanim użytkownik aktywuje przycisk. Skutek: użytkownik traci miejsce pracy podczas poznawania dostępnych akcji. Poprawka: usuń otwieranie widoku z handlera fokusu i zachowaj je w aktywacji. Nie usuwaj samej funkcji ani widocznego wskaźnika fokusu.
| Scenariusz / wariant | Wejście z początkowego formularza | Skutek i poprawka |
|---|---|---|
| Pomoc / good | Tab na „Pomoc z numerem” | Przycisk zachowuje fokus, formularz pozostaje; dopiero Space otwiera modal i przenosi fokus na zamknięcie |
| Pomoc / bad | Ten sam Tab, bez Space | Modal otwiera się automatycznie, fokus przechodzi na „Zamknij pomoc”. Usunąć wywołanie otwarcia z handlera fokusu |
| Podsumowanie / good | Dwa Tab na „Przejdź do podsumowania” | Formularz pozostaje; Space jawnie zastępuje go podsumowaniem i przenosi fokus na nagłówek |
| Podsumowanie / bad | Te same dwa Tab, bez Space | Formularz zastąpiony podsumowaniem, fokus na nagłówku; bez aktywacji i bez nowej trasy. Usunąć wywołanie przejścia z handlera fokusu |
| Control / oba scenariusze | Tab na właściwy przycisk | Lokalna podpowiedź w zarezerwowanym miejscu; fokus i formularz zachowane. To kontrola warunku 3.2.1, bez deklaracji 1.4.13 |
| Blur / oba scenariusze | Tab na właściwy przycisk | Callback usuwa fokus przez unfocus(). Flutter przenosi primaryFocus do zakresu; pusta lista primary kontrolek nie oznacza braku jakiegokolwiek fokusu w systemie. Analogiczny problem do F55, nie wykonanie DOM blur() |
W adaptacji mobilnej pomoc uruchamia przycisk, a nie pole numeru ze starszej wersji webowej. Tab rozdziela fokus od aktywacji bez otwierania klawiatury ekranowej. Oba przyciski istnieją w obu scenariuszach; w good oba działania zbadano w jednym przebiegu help/good. Kadry review-good-* przedstawiają funkcję podsumowania na rzeczywistej trasie help/good, nie oddzielne przechwycenie review/good. Test widgetu obejmował również review/good. Bad wykonano oddzielnie dla help i review.

2026-10-03, iPhone 17 Simulator / iOS 26.5. Przed aktywacją formularz pozostaje; aktualne FocusManager.primaryFocus i hasPrimaryFocus potwierdzają help. Sam kolor przycisku nie dowodzi odbioru Tab.

Bad otwiera pomoc po samym fokusie. Zapis zdarzeń rozdziela Tab → help → context-focus → close bez aktywacji. Kadr ilustruje skutek tego przebiegu.
Space na good otwiera identyczny modal, a Space na „Zamknij pomoc” wraca do inicjatora. Oba warianty pomijają ponowne samoczynne otwarcie przy jednym powrocie z modalu; nie usuwa to początkowego błędu bad. Escape działał w teście widgetu, lecz nie dotarł do Fluttera w XCTest; nie potwierdzono go na iOS.

Funkcja podsumowania przed aktywacją, 2026-10-03. Good zachowuje formularz po samym Tab. Nazwa pliku review-good-focused nie zmienia faktycznej trasy help/good.

Bad przenosi fokus na summary i wymienia formularz bez Space i bez nowej trasy. Zmiana adresu nie jest konieczna do zmiany kontekstu. Good otwiera ten sam widok dopiero po Space.

Control z tej samej próby zachowuje formularz, zadanie i fokus. Badano wejście, wyjście oraz powrót; to kontrola granicy 3.2.1, bez zaliczenia 1.4.13.

Blur: focus → remove-focus → unfocus przenosi primaryFocus do zakresu. Pusta lista primary kontrolek nie oznacza braku wszelkiego fokusu w systemie. Naprawa usuwa unfocus z handlera, zamiast ukrywać obrys.
„Wróć do formularza” odtwarza widok; reset przywraca początkowy scenariusz i wariant. To podgląd offline, bez wysłania zamówienia. Oczekiwania pozostają w testach, poza obserwatorem; wariant jest jawny i nie jest zaślepionym wejściem walidatora.
Historyczny przykład WWW
We wcześniejszej próbie 2026-10-03 Tab na pole numeru w help/bad otwierał modal, a trzy Tab na przycisk w review/bad wymieniały widok przy stałym adresie. Ta sama funkcja pozostawała dostępna przez aktywację przycisku w good. Control pokazywał podpowiedź w zarezerwowanym miejscu. Blur wykonywał DOM blur() i pozostawiał aktywny BODY. To wcześniejsze wykonanie desktopowego HTML, a nie wynik native iOS.
| Scenariusz / wariant | Stan początkowy i wejście | Skutek / poprawka | Wynik warunku demonstracji |
|---|---|---|---|
Pomoc / good |
Formularz P-104; Tab na numer zamówienia | Pole zachowuje fokus; pomoc dopiero po aktywacji „Pomoc z numerem” | PASS |
Pomoc / bad |
Ten sam formularz; ten sam Tab | Automatyczny modal przenosi fokus na „Zamknij pomoc”, choć nie było aktywacji | FAIL 3.2.1 |
Podsumowanie / good |
Formularz P-104; trzy Tab na przycisk | Formularz pozostaje; Enter lub Space jawnie otwiera podsumowanie | PASS |
Podsumowanie / bad |
Ten sam formularz i trzy Tab | Formularz znika, fokus trafia na nagłówek podsumowania bez aktywacji i bez zmiany URL | FAIL 3.2.1 |
Pomoc / control |
Formularz P-104; Tab na numer | Lokalna podpowiedź w zarezerwowanym miejscu; fokus, URL i geometria pól/akcji zachowane | PASS tego warunku, bez deklaracji 1.4.13 |
Pomoc / blur |
Formularz P-104; Tab na numer | Pole otrzymuje i zaraz traci fokus; aktywny staje się BODY | FAIL, odtworzenie F55 |
Kiedy obowiązuje i gdzie są wyjątki
- Wymaganie normatywne: każdy komponent, który otrzymuje fokus, nie inicjuje zmiany kontekstu. W 3.2.1 nie ma wyjątku „użytkownik został wcześniej ostrzeżony” ani wyjątku „niezbędne”. Uprzedzenie nie legalizuje nawigacji wyzwalanej samym fokusem.
- Zmiana kontekstu: duża zmiana mogąca dezorientować osobę niewidzącą całej strony naraz. Obejmuje zmianę odbiornika, obszaru widoku, fokusu lub treści zmieniającej znaczenie strony. Nowe okno, przeniesienie fokusu do innego komponentu, nowa strona lub pozornie nowa strona oraz istotne przeorganizowanie treści są przykładami.
- Nie oceniaj tylko adresu: pełna wymiana formularza na podsumowanie w SPA może zmienić kontekst przy tym samym URL. Sam inny URL też nie jest kompletnym dowodem związku z fokusem; trzeba odtworzyć wyzwalacz.
- Wskazówka Understanding: otrzymanie fokusu może wynikać z Tab lub kliknięcia w pole. Sam hover zwykle nie ustawia fokusu; skrypt może jednak go ustawić. Kliknięcie przycisku może jednocześnie ustawić fokus i uruchomić aktywację. Ustal, czy działanie następuje po aktywacji, czy już po samym fokusie; test Tab rozdziela te zdarzenia.
- Technika pomocnicza G107: zmiana kontekstu po aktywacji, np. przycisku, zamiast po fokusie. Technika nie jest jedynym dopuszczalnym rozwiązaniem ani dodatkowym normatywnym zakazem wszystkich aktualizacji.
- Udokumentowany błąd F55: skrypt usuwa fokus zaraz po jego otrzymaniu, np. przez
blur(). Ukrycie obrysu w CSS jest odrębnym problemem widoczności fokusu; nie jest tym samym co usunięcie fokusu. - Zmiana koloru obrysu, drobna informacja pomocnicza albo lokalne rozwinięcie treści nie muszą zmieniać kontekstu. Oceniaj skutek: czy fokus pozostał, zadanie i znaczenie widoku są te same, a treść nie została istotnie przeorganizowana. Nie przyjmuj „brak zmiany fokusu = zawsze PASS”.
- Modal odbierający fokus przy wejściu w pole jest błędny. Modal otwarty świadomą akcją „Pomoc z numerem” może poprawnie przejąć fokus. Zamknięcie po Escape i powrót do inicjatora to zarządzanie fokusem po działaniu użytkownika, a nie samoczynna zmiana przy wejściu na kontrolkę.
- Przewinięcie potrzebne do pokazania elementu wybranego przez użytkownika nie oznacza automatycznie naruszenia; badaj duży, dezorientujący skutek i przyczynę. Nie ustanawiamy progu pikseli ani czasu z definicji 3.2.1.
- Fokus klawiatury i fokus dostępności nie są identycznymi mechanizmami natywnych platform. Sam odczyt etykiety,
onAppear, hover lub uruchomienie aplikacji nie dowodzi otrzymania fokusu. W aplikacji mobilnej trzeba odtworzyć właściwe sterowanie; otwarcie klawiatury do pola nie jest automatycznie dowodem błędu autora. - Granica 3.2.2: zmiana wartości opcji lub pola jest osobnym wyzwalaczem; tam występuje warunek uprzedzenia użytkownika. Nie przenosić go do 3.2.1. Ustawienia iOS działają po aktywacji przycisku; historyczne WWW przeładowuje demonstrację po zmianie opcji, nie po fokusie selecta.
- Granica 3.2.5 (AAA): szersza ocena zmian kontekstu, niezależna od samego otrzymania fokusu. Aktualizacje po zegarze nie stają się automatycznie naruszeniem 3.2.1 bez związku przyczynowego. Podpowiedź na fokusie może wymagać osobnej oceny 1.4.13; wynik 3.2.1 jej nie zastępuje.
Platformy
Domyślna podstawa to WCAG 2.2. Poza WWW zastosowano informacyjną Group Note WCAG2ICT z 2025-12-11, która dla 3.2.1 zachowuje wymaganie bez zmiany. Interpretacja nie jest samodzielną normą zgodności ani wyborem podstawy prawnej audytu. W hybrydzie część HTML i część natywną badać osobno.
| ID / środowisko | Podstawa / kryterium | Stan | Warunek, zakres, adaptacja i uzasadnienie | Weryfikacja |
|---|---|---|---|---|
web / WWW |
WCAG 2.2 / 3.2.1 | dotyczy | Komponent otrzymujący fokus; bez adaptacji. Przeglądarka telefonu też jest środowiskiem webowym. Nawigacja fokusem służy rozpoznaniu elementów. | AI 2026-10-03; desktop WWW wykonane, telefon NOT-RUN |
mobile / aplikacje mobilne |
WCAG 2.2 + WCAG2ICT 2025-12-11 / 3.2.1 | dotyczy | Komponenty oprogramowania; bez zmiany wymagania. Rozpoznać fokus wejścia i dostępności oraz rzeczywisty sposób otrzymania fokusu na platformie. | AI 2026-10-03; Flutter/Cupertino iOS wykonane, Android i VoiceOver NOT-RUN |
desktop / aplikacje desktopowe |
WCAG 2.2 + WCAG2ICT 2025-12-11 / 3.2.1 | dotyczy | Kontrolki programu; bez zmiany wymagania. Sam wybór kontrolki klawiaturą nie powinien otwierać innego okna lub widoku. | AI 2026-10-03; native NOT-RUN |
document / dokumenty cyfrowe |
WCAG 2.2 + WCAG2ICT 2025-12-11 / 3.2.1 | dotyczy warunkowo | Dokument z elementami otrzymującymi fokus, np. pola lub linki; bez zmiany wymagania. Dokument bez takich komponentów nie uruchamia warunku badanego zdarzenia. | AI 2026-10-03; odbiornik PDF/Office NOT-RUN |
other / oprogramowanie kiosku lub TV |
WCAG 2.2 + WCAG2ICT 2025-12-11 / 3.2.1 | dotyczy warunkowo | UI z fokusem, np. obsługiwane pilotem; web jak WWW, native jak oprogramowanie. Zamknięta funkcjonalność wymaga oceny dostępnego sposobu sterowania. Tabela dotyczy oprogramowania, nie sprzętu. | AI 2026-10-03; konkretne urządzenie NOT-RUN |
WCAG2ICT zwraca uwagę na dokumenty złożone, np. prezentację z osadzonym arkuszem. Zmiana narzędzi po jawnej komendzie menu lub specjalnym geście wyboru trybu nie jest skutkiem samego fokusu; nie oznacza to ogólnego wyjątku dla wszystkich dokumentów złożonych. Definicję zmiany kontekstu odnosimy do dokumentu albo oprogramowania, a nie tylko do URL.
Oddzielne mapowanie EN 301 549
Sprawdzono EN 301 549 V3.2.1 (2021-03), AI 2026-10-03. To jawnie określona wersja, a nie deklaracja najnowszej ani obowiązującej prawnie podstawy. Innych wersji EN nie mapowano w tym wpisie; nie przenosić numerów ani wyłączeń do innej wersji.
| Środowisko | Podstawa / klauzula | Stan i zakres |
|---|---|---|
web |
EN V3.2.1 / 9.3.2.1 | dotyczy; strona spełnia 3.2.1 WCAG 2.1 |
document |
EN V3.2.1 / 10.3.2.1 | dotyczy warunkowo; dokument poza WWW z komponentami otrzymującymi fokus, 3.2.1 WCAG 2.1 |
mobile, desktop |
EN V3.2.1 / 11.3.2.1 | dotyczy; oprogramowanie poza WWW udostępniające UI, 3.2.1 WCAG 2.1 |
other / native kiosku lub TV |
EN V3.2.1 / 11.3.2.1 | dotyczy warunkowo; wskazane urządzenie udostępnia UI oprogramowania; bez odrębnego wyłączenia 3.2.1 dla closed functionality |
Uwagi 10.3.2.1 i 11.3.2.1 dotyczą jawnego wejścia w część dokumentu złożonego inną akcją niż samo ustawienie fokusu. Żaden wiersz nie oznacza „brak odpowiednika we wskazanej normie”. Nie dotyczy badanego scenariusza: dokument złożony, zamknięty kiosk i TV nie są częścią wykonanych demonstracji iOS/WWW; nie wyłącza to platform. Test według kompletnej EN i przegląd człowieka NOT-RUN. Klasyfikacja nie ustala obowiązków prawnych.
Rozwiązania w technologiach
Minimalne fragmenty umieszczają zmianę kontekstu w aktywacji. showSummary jest callbackiem aplikacji otwierającym podsumowanie; powinien zarządzać fokusem dopiero w wyniku tej akcji. Nie podłączaj go do odbioru fokusu, onFocusChange, onFocusChanged ani zdarzenia samego odczytania elementu. Obsługa zdarzenia fokusu może aktualizować obrys albo lokalną wskazówkę.
Flutter / Dart
import 'package:flutter/cupertino.dart';
Widget pickupButton(VoidCallback showSummary) => CupertinoButton(
onPressed: showSummary,
child: const Text('Przejdź do podsumowania'),
);Osadzenie: widget w istniejącym CupertinoApp; callback dostarcza właściciel ekranu. Focus.onFocusChange służy informacji o fokusie, nie jest właściwym miejscem automatycznego Navigator.push ani otwierania pomocy. Nie zakładaj równoważności FocusNode i fokusu VoiceOver. Pełna demonstracja korzysta ze wspólnego CupertinoApp. Obserwator rejestruje wejścia i skutki; nie steruje działaniem ani nie wpisuje oceny PASS/FAIL. Minimalny fragment powyżej nie był osobno kompilowany; build i test dotyczą pełnej aplikacji.
HTML / CSS
<button id="review" type="button">Przejdź do podsumowania</button>
<script>
document.getElementById('review').addEventListener('click', showSummary);
// showSummary jest funkcją aplikacji; brak wyzwalania jej przy focus.
</script>Natywny button obsługuje aktywację klawiaturą i wskazaniem. Nie dodawaj równoległego handlera Enter, który mógłby uruchomić akcję dwukrotnie. Pełna demonstracja zawiera również celowo błędne handlery. Pomoc używa natywnego dialog.showModal() po aktywacji; programowe skupienie nagłówka podsumowania ma tabindex="-1".
Android / Jetpack Compose
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun PickupButton(showSummary: () -> Unit) {
Button(onClick = showSummary) { Text("Przejdź do podsumowania") }
}Osadzenie: UI aplikacji Compose. Akcja na onClick; nie uruchamiaj przejścia z onFocusChanged. Żądanie FocusRequester opisuje fokus wejścia, nie potwierdza odczytu TalkBack. Nie wykonywano builda ani uruchomienia Androida.
iOS / SwiftUI
import SwiftUI
struct PickupButton: View {
let showSummary: () -> Void
var body: some View {
Button("Przejdź do podsumowania", action: showSummary)
}
}Osadzenie: widok SwiftUI z callbackiem gospodarza. Prezentację uruchamia akcja Button; obserwacja FocusState albo AccessibilityFocusState nie powinna samoczynnie otwierać następnego widoku. Fokus dostępności i wejścia trzeba ocenić oddzielnie; snippet nie jest próbą VoiceOver. API Button potwierdzono także w lokalnym interfejsie SDK Xcode 27.0, bez typechecku tego fragmentu.
React Native
import React from 'react';
import { Pressable, Text } from 'react-native';
export function PickupButton({ showSummary }: { showSummary: () => void }) {
return (
<Pressable accessibilityRole="button" onPress={showSummary}>
<Text>Przejdź do podsumowania</Text>
</Pressable>
);
}Osadzenie: ekran React Native. onPress uruchamia akcję; nie używaj samego fokusu ani onPressIn jako zamiennika świadomej aktywacji. Dostępność aktywacji klawiaturą i czytnikiem zależy od platformy i wymaga osobnego wykonania. Przykład nie jest gwarancją jednakowego zachowania native i React Native Web.
Stan dokumentacji, kompilacji i działania
| ID / technologia | Dokumentacja 2026-10-03 | Kompilacja / składnia | Działanie |
|---|---|---|---|
html |
PASS: standard HTML, aktywacja, fokus, dialog | PASS: node --check skryptu inline i runnera |
PASS: lokalny HTTP, rzeczywista przeglądarka, zakres poniżej |
flutter |
PASS: oficjalne API onPressed/onFocusChange, FocusManager i unfocus; Context7 pomocniczo | PASS pełnej demonstracji: Flutter 3.44.9 / Dart 3.12.2; snippet osobno NOT-RUN | PASS prób demonstracji Cupertino/iOS; VoiceOver NOT-RUN |
jetpack-compose |
PASS: oficjalny Button i zarządzanie fokusem | NOT-RUN; bez użytej wersji Compose | NOT-RUN Android |
swiftui |
PASS: dokumentacja Button i lokalny interfejs SDK Xcode 27.0 | NOT-RUN fragmentu | NOT-RUN iOS |
react-native |
PASS: oficjalne Pressable/onPress | NOT-RUN; bez użytej wersji RN | NOT-RUN native |
Brak buildów edukacyjnych fragmentów nie zobowiązuje do tworzenia czterech aplikacji. Składnia i build nie potwierdzają działania odbiornika ani technologii asystującej.
Jak sprawdzić
- Na świeżym ekranie zapisz aktywny element, widok, okna i stan zadania przed wejściem. Rozróżnij fokus wejścia i dostępności oraz rzeczywiste sposoby otrzymania fokusu.
- Przejdź Tab i Shift+Tab bez Enter/Space. Po każdym kroku zapisz odebrane wejście, fokus, callbacki i widok. Sprawdź wszystkie osiągalne komponenty, nie tylko pierwszy przycisk.
- W good oczekuj zachowania formularza po fokusie, a modalu lub podsumowania dopiero po aktywacji. W bad samo otrzymanie fokusu wyzwala ten skutek. Sprawdź powrót do inicjatora po zamknięciu.
- Osobno sprawdź kliknięcie pola i aktywację przycisku; kliknięcie przycisku może łączyć oba zdarzenia. Lokalna podpowiedź nie daje automatycznego FAIL, a stały URL nie daje automatycznego PASS. Oceniaj znaczenie zmiany i przyczynę.
- Zbadaj kontrolę usunięcia fokusu oraz późniejsze skutki, jeśli występują. Nie ustanawiaj własnego progu pikseli albo czasu jako WCAG. Odsłuch i sterowanie AT wymagają osobnej próby.
Wyniki źródłowej próby mobilnej
Próba 2026-10-03: Flutter 3.44.9 / Dart 3.12.2, Xcode 27.0 / SDK 27.0, iPhone 17 Simulator / iOS 26.5. Ramka 402 × 874 pt, PNG 1206 × 2622 px, DPR 3, pion i jasny wygląd. Ustawienia systemowego tekstu nie zostały zmienione ani odczytane. Pasek 09:41 jest prezentacyjny. Finalne próbki obejmują 18:44:59–18:46:05 Europe/Warsaw; dwa testy, 0 failures, 72,761 s wykonania, bez pomiaru czasu reakcji produktu.
XCTest dostarczał klawisze przez XCUIApplication.typeKey. Aplikacja odczytywała niesyntetyzowane HardwareKeyboard.KeyDownEvent, aktualny fokus Fluttera, callbacki i zmianę widoku; natywne drzewa potwierdzały modal i podsumowanie. Driver nie ustawiał fokusu i nie zastępował wejścia wywołaniem callbacka. Programowe requestFocus w aplikacji było badanym skutkiem autora.
| Sprawdzenie | Rzeczywisty wynik i zakres |
|---|---|
| Analiza / testy / build | PASS: flutter analyze; 26 testów Flutter (bez testów nazwanych android); build debug iOS Simulator i instalacja na istniejącym urządzeniu. Bez nowych zależności |
| 37 żądań klawiszy | PASS: 28 Tab, w tym 9 Shift+Tab, oraz 9 Space. Każdy ma nowy niesyntetyzowany KeyDownEvent z odpowiednim HID; żądania i odczyty przed/po z zegarem monotonicznym oraz UTC |
| Good: cały formularz | PASS: oba kierunki przez help, review, scenario, variant, reset nie zmieniają widoku. Oba działania sprawdzono w help/good; wybór scenariusza nie zmienia działania good |
| Good: aktywacja | PASS: Space otwiera pomoc lub podsumowanie; Space na zamknięciu wraca na help. Powrót z podsumowania odtwarza formularz |
| Bad: pomoc / podsumowanie | Odtworzone FAIL 3.2.1: otrzymany Tab i fokus właściwego przycisku → context-focus → close lub summary; brak activation. Natywne UI potwierdza modal albo brak przycisku formularza i nagłówek podsumowania |
| Control / oba scenariusze | PASS warunku demonstracji: fokus i formularz zachowane, podpowiedź przy wejściu/powrocie znika po wyjściu. Asercja natywnego prostokąta przycisku review przed/po PASS; nie obejmuje całego układu ani 1.4.13 |
| Blur / oba scenariusze | Odtworzony FAIL: focus → remove-focus → unfocus, pusta lista primary kontrolek, primaryFocus zakresu. Brak deklaracji „system nie ma fokusu” |
| Wybór / reset / fallback | PASS: zmiana wariantu i scenariusza przez Space, reset do początkowej konfiguracji/danych, nieznana trasa do help/good |
| Regresja 3.1.1 | PASS: istniejąca trasa good, English oraz odczyt przez 2 tap XCTest; UIKit collection-info.language=en. Dowody i źródła 3.1.1 zachowane bez zmian względem początku korekty |
| 38 odczytów i 38 drzew UI, 8 PNG | PASS: checker i oględziny AI wszystkich finalnych kadrów; rzeczywiste stany bez splash lub retuszu. Odczyt sekwencyjny nie jest atomowym snapshotem systemu |
| Escape | Próba dostarczenia przez XCTest FAIL: brak zdarzenia Fluttera, modal nie zamknął się. Funkcja na iOS niepotwierdzona; test widgetu Escape PASS, nie zastępuje wykonania systemowego |
| Enter, VoiceOver, FKA, fizyczna klawiatura/iPhone, Android | NOT-RUN. Fokus wejścia Fluttera i drzewa UI nie potwierdzają fokusu dostępności ani mowy czytnika |
| Człowiek / walidator Clearship | NOT-RUN: brak przeglądu człowieka i niezależnej oceny walidatora |
Zachowano wcześniejsze nieudane próby. Pierwsza: 25 odczytów, 22 żądania, 4 PNG; FAIL dostarczenia Escape. Helper miał błędny HID Escape, ale jego korekta nie zapewniła odbioru; końcowa próba użyła działającego Space. Druga: 27 odczytów, 24 żądania, 5 PNG; FAIL selektora StaticText dla nagłówka, który UIKit eksportował jako Other. Test poprawiono na etykietę niezależnie od typu. Aplikacja nie zmieniła się między próbami.
Wyniki wcześniejszej próby WWW
Próba 2026-10-03: Codex IAB na macOS 27.0, 1280 × 720 CSS px / DPR 1, zoom domyślny, JPEG 1280 × 720. Wersji silnika nie ustalono. Finalny przebieg 17:26:49–17:27:03 Europe/Warsaw dotyczył HTML.
| Sprawdzenie | Zaobserwowany wynik / zakres |
|---|---|
| 38 żądań klawiszy + 2 kliknięcia pola | PASS runnera: wejścia publicznym API CUA; 36 zachowanych keydown z isTrusted=true; dwa resety przeładowały dokument przed odczytem keydown, zachowując keyup w nowym dokumencie. Bez DOM dispatchEvent ani ustawiania fokusu przez runner |
| 50 odczytów DOM i AX | PASS: activeElement, otwarcie dialogu, visibility/hidden, adres, treść i dziennik zdarzeń; odczyty sekwencyjne, nie atomowy snapshot |
| Good pomoc | PASS: 6 Tab naprzód i 5 Shift+Tab wstecz zachowują widok; Enter otwiera modal, Escape zamyka i wraca na help |
| Bad pomoc | Odtworzony FAIL: Tab na order → modal i close; brak click. Kliknięcie pola także otwiera modal; test nie jest fizycznym kliknięciem człowieka |
| Good podsumowanie | PASS: Tab na review zachowuje formularz; osobne Enter i Space otwierają summary; Reset przywraca formularz P-104 i nowy dokument |
| Bad podsumowanie | Odtworzony FAIL: trzeci Tab przenosi na summary i usuwa formularz bez click; URL i navigationStart zachowane |
| Control | PASS warunku demonstracji: tip widoczny po fokusie order, brak dialogu/nawigacji/zmiany widoku; pole i przycisk mają identyczne prostokąty przed/po; Tab wychodzi na help |
| Blur / F55 | Odtworzony FAIL: focus order → blur order → BODY; formularz bez zmiany. Sam brak obrysu nie służył jako dowód |
| Nieznana konfiguracja | PASS: fallback do good/help; Tab nie otwiera modalu |
| 6 finalnych obrazów i konsola | PASS oględzin AI: właściwe stany, bez splash/retuszu; brak odnotowanych error/warn; nie jest to ocena człowieka |
| Składnia i kontrola zachowanych dowodów | PASS: inline JS, runner, checker, hashe i linki; checker nie powtarza UI |
| Native / mobile / dokument / TV / inne przeglądarki / fizyczne wejście | NOT-RUN; nie są potwierdzone wykonaniem WWW |
| VoiceOver / TalkBack / przełączniki / odczyt głosowy | NOT-RUN; AX i isTrusted nie są testem czytnika ani dowodem fizycznego wejścia |
| Przegląd merytoryczny człowieka | NOT-RUN |
Pierwsza próba WWW: 31 odczytów, 26 żądań, 5 JPEG, FAIL asercji resetu. Enter przeładował dokument na keydown, a nowy dokument zarejestrował keyup; oczekiwanie pustego dziennika było błędne. Poprawiono wyłącznie asercję. Finalny przebieg i niezmienione oryginały mają odrębne pochodzenie; historyczny FAIL nie jest nową usterką produktu. Powtarzające się nazwy initial/reset należy odróżniać kolejnością i czasem, nie nadpisywać po nazwie próbki.
Weryfikacja i ograniczenia
- Reguła deterministyczna na demonstracji: porównaj ciąg wejść, odebrany fokus i wynik. Tab bez click powodujący modal/fokus innego elementu lub zmianę całego widoku jest konkretnym negatywnym wynikiem. Oczekiwania PASS/FAIL są w runnerze i checkerze, poza obserwatorem aplikacji.
- Mobilny fokus: eksport
FocusNodenie jest niezależnym odczytem systemowego fokusu iOS ani fokusu dostępności. XCTest dostarcza rzeczywiste klawisze i natywne drzewa UI, które potwierdzają skutek widokowy; nie potwierdza to VoiceOver lub Full Keyboard Access. - Przybliżenie z DOM/AX: różne drzewa, URL, focus lub liczba okien wskazują zdarzenie do zbadania. Brak zmiany URL nie dowodzi PASS; lokalne rozwinięcie treści nie dowodzi FAIL. Trzeba też poznać zmianę znaczenia i przyczynę. Sam tekst
onfocusnie jest naruszeniem. - Potrzebny jest odczyt przed/po, typ wejścia, odebrane zdarzenia, aktywny komponent, widok i okna oraz stan zadania.
isTrusted=truemówi o zdarzeniu odbiornika przeglądarki, nie o pochodzeniu od fizycznego człowieka. Sam fokus programowy też może emitować trusted event. - Kliknięcie przycisku miesza fokus z aktywacją; kontrola Tab pomaga je oddzielić. Ukryte lub opóźnione skutki, rozgałęzienia zależne od danych, iframe, nowa karta i błędy czytnika mogą wymagać osobnych testów. Próbki nie są gwarancją braku efektu po dowolnym czasie.
- Ocena AI: interpretacja źródeł, odczyt i oględziny ośmiu nowych PNG i sześciu historycznych JPEG. Nie jest przeglądem merytorycznym człowieka. Człowiek: NOT-RUN. Nie testowano badanego walidatora Clearship ani nie mierzono skuteczności wykrywania na niezależnych przypadkach.
- Demonstracja ma selektor oczekiwanych wariantów dla odtwarzania. Przed przyszłym badaniem walidatora oddziel tę konfigurację i oczekiwania od jego wejścia; UI i eksport zawierają również scenario/good/bad. To test mechaniki własnej demonstracji, bez zaślepionej oceny jakości. Niewykrycie problemu lub brak danych nie oznaczają zgodności.
Bez filmu i audio: sekwencja wejść i trwałe stany opisują wyzwalacz, ale nie potwierdzają płynności, czasu reakcji ani wypowiedzi czytnika. Przegląd człowieka, VoiceOver, FKA, fizyczna klawiatura/iPhone i Android pozostają NOT-RUN. Systemowe Escape na iOS pozostaje FAIL dostarczenia, Enter NOT-RUN; działanie widgetu nie zastępuje tej drogi wejścia.
Jak sprawdza Clearship
Na Androidzie Clearship porównuje obserwacje przed i bezpośrednio po Tab/Shift+Tab, oddzielając je od aktywacji. Deterministyczna metoda focus-order-1 wskazuje wyjście z aplikacji, inny ekran lub nową treść z przeniesionym fokusem oraz próbuje ustalić komponent wyzwalający. Pomiar kontrolny z 7 października 2026 r. spełnił próg 3.2.1: 6/6 usterek, 0 fałszywych alarmów na 80 poprawnych ekranach.
Nieznany wyzwalacz, komponenty bez zbadanego fokusu, brak obserwacji, limit czasu i błąd klawiatury wymagają człowieka. Analiza obserwuje tylko skutek tuż po klawiszu: nie potwierdza braku opóźnionych przejść, fokusu czytnika ani wszystkich istotnych zmian znaczenia treści bez przeniesienia fokusu. Lokalna podpowiedź sama nie oznacza zmiany kontekstu, a procent zachowanych napisów jest parametrem detektora, nie regułą WCAG.
Na iOS przejście klawiaturowe P4 produktu jest niedostępne; kryterium pozostaje niezbadane i bez pomiaru. Edukacyjny XCTest Fluttera z 3 października nie uruchamia tej metody Clearship. Treść WWW i rzeczywiste AT są poza potwierdzonym zakresem.