Co oznacza to kryterium
Zmiana opcji lub wpisanie danych powinny mieć przewidywalny skutek. Jeśli sama zmiana wartości przenosi użytkownika do innego widoku, okna lub miejsca pracy, trzeba go o tym uprzedzić przed użyciem kontrolki. Można też pozostawić wybór w formularzu i przejść dalej osobnym, jasno nazwanym przyciskiem. Uprzedzenie dopuszczone tutaj nie usprawiedliwia zmiany kontekstu po samym otrzymaniu fokusu.
| ID / potrzeba | Bariera i korzyść |
|---|---|
blindness / Niewidzenie |
Po wyborze opcji użytkownik może stracić pole i miejsce odczytu, zanim dowie się o nowym ekranie. Stabilny formularz lub uprzedzenie pozwalają przewidzieć skutek. |
low-vision / Słabowidzenie |
Przy powiększeniu widoczny jest fragment ekranu; samoczynna wymiana widoku utrudnia odnalezienie pozycji i poprawienie wartości. |
motor / Ograniczenia ruchowe |
Przypadkowa zmiana opcji albo przechodzenie po opcjach klawiaturą mogą uruchomić nawigację przed korektą. Osobna aktywacja daje kontrolę nad momentem przejścia. |
cognitive / Pamięć i koncentracja |
Niespodziewane przejście przerywa edycję i może ukryć związek między wpisywaniem a skutkiem. Wyjaśnienie z wyprzedzeniem lub świadome zatwierdzenie zmniejsza tę barierę. |
Nie dodajemy automatycznie słuchu ani rozróżniania barw. Tagi opisują potrzeby w tych scenariuszach, nie diagnozy ani oficjalną klasyfikację WCAG.
Przykłady błędów i poprawek
Pracownia pokazuje syntetyczne P-104, ul. Ogrodowa 8, piątek 10:00–18:00. Obie pary zaczynają z wyłączonym odbiorem i pustym kodem; wpisywany kod to 104. Good i bad mają te same etykiety, dane i funkcje. Różnica dotyczy automatycznego przejścia po zmianie wartości, zamiast oczekiwania na osobną aktywację.
Problem: włączenie odbioru lub wpisanie trzeciej cyfry w bad zastępuje formularz podsumowaniem bez wcześniejszej informacji. Skutek: edycja kończy się przed świadomym zatwierdzeniem, użytkownik traci możliwość bieżącej korekty. Poprawka: onChanged aktualizuje dane, a onPressed osobnego przycisku przechodzi do podsumowania. Wariant warned pokazuje drugą dopuszczoną drogę — konkretną instrukcję przed zmianą. Late informuje dopiero po przejściu i pozostaje błędny.
| Scenariusz / wariant | Wejście i stan | Problem lub poprawka | Ocena warunku demonstracji, poza wejściem walidatora |
|---|---|---|---|
Odbiór / good |
Tab na switch; Space zmienia false → true | Formularz i fokus zostają; osobny przycisk otwiera podsumowanie | PASS tego warunku |
Odbiór / bad |
Ta sama zmiana false → true | Formularz znika, fokus trafia na nagłówek podsumowania bez uprzedzenia | FAIL 3.2.2 |
Kod / good |
Dotknięcie pola kodu; kolejne 1, 0, 4 w końcowym XCTest |
Po 104 formularz nadal pozwala poprawić kod i opuścić pole Tab; podsumowanie po przycisku |
PASS tego warunku |
Kod / bad |
Te same trzy cyfry | Trzecia cyfra kończy edycję i wymienia widok bez uprzedzenia | FAIL 3.2.2 |
Oba / warned |
Przed kontrolką wyjaśnienie automatycznego przejścia | Ten sam automatyczny skutek co bad, ale wcześniej zapowiedziany; instrukcja także w hint | PASS badanego warunku uprzedzenia; doświadczenie czytnika NOT-RUN |
Odbiór / control |
Ta sama zmiana switcha | Jedynie koszt dostawy 14,90 → 0,00 zł w stałym miejscu; widok i fokus zostają | PASS lokalnego warunku |
Oba / late |
Brak uprzedzenia przed zmianą | Informacja pojawia się dopiero w podsumowaniu; nie naprawia wcześniejszego zaskoczenia | FAIL 3.2.2 |
Wybór odbioru
- Pierwszy Tab ustawia fokus bez zmiany wartości i widoku we wszystkich pięciu wariantach pickup.
- Space zmienia false → true. Good zachowuje formularz i fokus; bad przechodzi bez uprzedzenia. Dotknięcie switcha zbadano osobno w obu wariantach.
- W good Tab na przycisk i Space otwierają ten sam widok docelowy co bad, z inną przyczyną i w wybranym momencie.
- Control zmienia tylko cenę 14,90 → 0,00 zł w stałym miejscu; odwrócenie i ponowny wybór nie przechodzą dalej.

2026-10-03, iPhone 17 Simulator / iOS 26.5. Good zachowuje formularz po zmianie wartości; osobna aktywacja uruchamia przejście. Kadr pokazuje stan, a wyzwalacz wynika z wejść i callbacków.

Bad wymienia formularz po false → true bez uprzedzenia. Usunięcie przejścia z onChanged i pozostawienie go w przycisku pozwala skorygować wybór przed kontynuacją.

Instrukcja „Zmiana opcji «Odbiór w Pracowni» od razu otworzy podsumowanie odbioru” jest dostępna przed pierwszą zmianą i odpowiada semantycznemu hint. Kolejność i geometria były odczytane; wypowiedź VoiceOver pozostaje NOT-RUN.

Control aktualizuje cenę i zachowuje fokus oraz zadanie; badano również true → false i ponowny wybór. Sam nowy tekst nie oznacza zmiany kontekstu.

Late pokazuje komunikat po skutku. Nie realizuje uprzedzenia, choć test odtworzenia tego wariantu może zakończyć się PASS.
Wpisanie kodu
Końcowy XCTest dotykał pola i wpisywał oddzielnie 1, 0, 4. Good po każdej cyfrze zachowywał edycję; Tab po 104 nie wysyłał formularza. Bad przechodził po trzeciej cyfrze. Trzy cyfry są warunkiem tej demonstracji, nie progiem WCAG. Wcześniejsza nieudana sesja Tab do pola nie jest zaliczeniem końcowej ścieżki; test widgetu badał Tab osobno.

Good po odebranych callbackach 1 → 10 → 104 w końcowej próbie. Opuszczenie pola Tab nie zastępuje jawnego zatwierdzenia.

Bad kończy edycję po 104. Sekwencja odebranych zmian tekstu identyfikuje przyczynę; widoczny kadr podsumowania sam jej nie ustala.
Kiedy obowiązuje i gdzie są wyjątki
- Wymaganie normatywne: zmiana ustawienia dowolnej kontrolki nie powoduje automatycznie zmiany kontekstu, chyba że o zachowaniu uprzedzono przed użyciem kontrolki. Nie ma osobnego wyjątku „niezbędne” ani listy dozwolonych typów aplikacji.
- Zmiana ustawienia: trwała wartość lub stan po zakończeniu interakcji: zaznaczenie checkboxa, przełączenie switcha, wybrana opcja, wpisany tekst. Przycisk przełączający stan lub wyłączający się po użyciu także może zmieniać ustawienie. Nie klasyfikuj wyzwalacza wyłącznie po nazwie typu widgetu.
- Aktywacja: link albo przycisk wysyłający formularz, otwierający modal czy przechodzący dalej uruchamia polecenie. Nie jest automatycznie zmianą ustawienia tylko dlatego, że użytkownik go kliknął. Przy mieszanym działaniu przeanalizuj rzeczywisty stan i przyczynę, zamiast wyłączać wszystkie przyciski.
- Zmiana kontekstu: duży skutek mogący dezorientować osobę niewidzącą całego widoku naraz; dotyczy m.in. odbiornika, obszaru widoku, fokusu i treści zmieniającej znaczenie strony. Nowe okno, przeniesienie fokusu do innej kontrolki, inny albo pozornie nowy ekran i znaczne przeorganizowanie treści są przykładami. Brak zmiany URL nie dowodzi braku zmiany kontekstu.
- Lokalna aktualizacja: zmiana ceny, podpowiedzi lub zależnych pól nie musi zmieniać kontekstu, jeśli pozostaje ten sam formularz, zadanie, znaczenie i fokus. Sam DOM diff, nowy tekst, animacja albo otwarcie klawiatury systemowej nie są wystarczającym dowodem naruszenia autora.
- Uprzedzenie: opisz konkretny skutek przed użyciem, w osiągalnej instrukcji lub wcześniejszym kroku. G13 dopuszcza instrukcję poprzedzającą kontrolkę, wcześniejszy etap procesu, a w określonym intranecie wcześniejsze wymagane szkolenie. Programowe powiązanie instrukcji z kontrolką jest pomocną techniką. Nie ustanawiamy dodatkowego normatywnego obowiązku checkboxa zgody ani ostrzeżenia po każdym ponownym użyciu.
- „Odbiór w Pracowni” samo w sobie nie zapowiada podsumowania. Tekst „wartość zmieniona” jest zbyt ogólny. Komunikat po przejściu, toast znikający przed odczytem lub instrukcja niedostępna przed pierwszą zmianą nie realizują warunku uprzedzenia. Sama obecność tekstu w kodzie nie dowodzi dostępności instrukcji dla użytkownika.
- Granica 3.2.1: samo otrzymanie fokusu jest odrębnym wyzwalaczem. Uprzedzenie dopuszczone w 3.2.2 nie usprawiedliwia zmiany kontekstu przy samym fokusie. Końcowy XCTest potwierdza pierwszy Tab bez zmiany wartości i widoku w pięciu wariantach pickup. Pole kodu otrzymuje fokus przez dotknięcie; próby Tab z wcześniejszej nieudanej sesji nie stanowią końcowego zaliczenia tej ścieżki. Test widgetu sprawdza Tab także dla pola kodu, w osobnym środowisku testowym Fluttera.
- F36/F37: opisane błędy WWW dotyczą automatycznej zmiany kontekstu po uzupełnieniu/opuszczeniu pola oraz nowego okna po zmianie wyboru bez uprzedzenia. Opisane mobilne przejścia są własnymi analogicznymi scenariuszami, nie dosłownym wykonaniem HTML F36/F37 ani testem otwarcia nowego okna.
- Techniki pomocnicze: G80 oddziela zmianę wartości od zatwierdzenia; H32/H84 pokazują rozwiązanie HTML. G13 wyjaśnia uprzedzenie, SCR19 lokalną aktualizację bez zmiany kontekstu. Nie są jedynymi sposobami spełnienia wymagania ani nowymi obowiązkami natywnych API.
- Dopuszczalne uprzedzenie nie potwierdza wszystkich innych kryteriów: np. nawigacja po grupie opcji może wciąż uniemożliwić wybór klawiaturą. 3.2.5 (AAA) obejmuje szerszy zakres zmian kontekstu; 3.3.2 dotyczy instrukcji danych, 3.3.1 błędów, a 4.1.3 komunikatów statusu. Nie oceniono ich zgodności tutaj.
Platformy
Domyślna podstawa to WCAG 2.2. Poza WWW zastosowano Group Note WCAG2ICT z 2025-12-11: 3.2.2 stosuje się bez zmiany brzmienia do dokumentów poza WWW i oprogramowania, z odniesieniem do intencji Understanding. WCAG2ICT jest wskazówką informacyjną, nie osobną normą zgodności ani wyborem podstawy prawnej. Zmianę znaczenia strony odnosimy do kontekstu dokumentu lub oprogramowania.
| ID / środowisko | Podstawa / kryterium | Stan | Warunek, zakres, adaptacja i uzasadnienie | Weryfikacja |
|---|---|---|---|---|
web / WWW |
WCAG 2.2 / 3.2.2 | dotyczy | Kontrolki z wartością lub ustawieniem; bez adaptacji. Przeglądarka telefonu pozostaje środowiskiem webowym. W hybrydzie oddzielić HTML od części natywnej. | AI 2026-10-03; wykonanie WWW NOT-RUN |
mobile / aplikacje mobilne |
WCAG 2.2 + WCAG2ICT 2025-12-11 / 3.2.2 | dotyczy | Przełączniki, wybór opcji, edycja tekstu; bez zmiany wymagania. Nowy ekran lub modal mogą zmienić kontekst bez URL. | AI 2026-10-03; Flutter/iOS wykonane; Android NOT-RUN |
desktop / aplikacje desktopowe |
WCAG 2.2 + WCAG2ICT 2025-12-11 / 3.2.2 | dotyczy | Wartość kontrolki programu, np. lista ustawień; bez zmiany wymagania. Rozpoznać aktywację polecenia i trwałą zmianę ustawienia. | AI 2026-10-03; native NOT-RUN |
document / dokumenty cyfrowe |
WCAG 2.2 + WCAG2ICT 2025-12-11 / 3.2.2 | dotyczy warunkowo | Dokument z edytowalnymi kontrolkami, np. formularz PDF. Bez zmiany wymagania; statyczny tekst bez kontrolek nie uruchamia warunku zmiany wartości. | AI 2026-10-03; odbiornik PDF/Office NOT-RUN |
other / oprogramowanie kiosku lub TV |
WCAG 2.2 + WCAG2ICT 2025-12-11 / 3.2.2 | dotyczy warunkowo | Interfejs z ustawieniami zmienianymi dotykiem, pilotem lub klawiaturą; web jak WWW, native jak oprogramowanie. Ocenić dostępną metodę obsługi, również przy zamkniętej funkcjonalności. Tabela nie bada sprzętu. | AI 2026-10-03; konkretne urządzenie NOT-RUN |
Oddzielne mapowanie EN 301 549
Sprawdzono EN 301 549 V3.2.1 (2021-03), AI 2026-10-03. Nie deklarujemy, że jest najnowszą wersją lub właściwą podstawą prawną konkretnego audytu. Innych wersji EN nie mapowano.
| Środowisko | Podstawa / klauzula | Stan i zakres |
|---|---|---|
web |
EN V3.2.1 / 9.3.2.2 | dotyczy; strona spełnia 3.2.2 WCAG 2.1 |
document |
EN V3.2.1 / 10.3.2.2 | dotyczy warunkowo; dokument poza WWW z kontrolkami objętymi 3.2.2 WCAG 2.1 |
mobile, desktop |
EN V3.2.1 / 11.3.2.2 | dotyczy; oprogramowanie poza WWW udostępniające UI, 3.2.2 WCAG 2.1 |
other / native kiosku lub TV |
EN V3.2.1 / 11.3.2.2 | dotyczy warunkowo; wymaganie dla UI oprogramowania, bez odrębnego wyłączenia 3.2.2 dla closed functionality |
To bezpośrednie klauzule wskazanej EN, odrębne od WCAG2ICT. Żaden wiersz nie oznacza „brak odpowiednika we wskazanej normie”. Nie dotyczy badanego scenariusza: statyczny dokument, kiosk i TV nie występują w demonstracji; nie wyłącza to platform. Nie wykonano pełnego testu EN ani oceny obowiązków prawnych.
Rozwiązania w technologiach
Poniższe fragmenty pokazują zasadę wartość → lokalny stan; przycisk → przejście. Dane i callback podsumowania są własnym kontekstem aplikacji; nie traktujemy ich jako API platform. Minimalny wspólny przykład ma switch, więc nie wymusza czterech dodatkowych aplikacji lub pól kodu.
Flutter / Dart
import 'package:flutter/cupertino.dart';
// W State<StatefulWidget>: bool pickup = false; void openSummary() { ... }
Column(children: [
Row(children: [
const Expanded(child: Text('Odbiór w Pracowni')),
Semantics(label: 'Odbiór w Pracowni', child: CupertinoSwitch(
value: pickup,
onChanged: (value) => setState(() => pickup = value),
)),
]),
CupertinoButton(onPressed: openSummary,
child: const Text('Przejdź do podsumowania')),
]);Fragment edukacyjny jest schematem osadzenia, nie samodzielnym plikiem do kompilacji. Pełna implementacja ma rzeczywiste callbacki, warianty, obserwator, reset i trasy. W wariancie z uprzedzeniem widoczny tekst poprzedza kontrolkę i odpowiada Semantics.hint; nie zastępować instrukcji niewidocznym hintem bez oceny sposobu jej poznania.
Android / Jetpack Compose
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
@Composable
fun Pickup(onReview: (Boolean) -> Unit) {
var pickup by remember { mutableStateOf(false) }
Column {
Text("Odbiór w Pracowni")
Switch(checked = pickup, onCheckedChange = { pickup = it },
modifier = Modifier.semantics {
contentDescription = "Odbiór w Pracowni"
})
Button(onClick = { onReview(pickup) }) {
Text("Przejdź do podsumowania")
}
}
}Nie nawiguj w onCheckedChange bez spełnionego uprzedzenia. Dla tekstu analogicznie aktualizuj stan w onValueChange; decyzję przejścia pozostaw przyciskowi. Materiał opisowy; Android nie był uruchamiany.
iOS / SwiftUI
import SwiftUI
struct Pickup: View {
@State private var pickup = false
let onReview: (Bool) -> Void
var body: some View {
VStack {
Toggle("Odbiór w Pracowni", isOn: $pickup)
Button("Przejdź do podsumowania") { onReview(pickup) }
}
}
}Binding przełącznika aktualizuje wybór; Button uruchamia przejście. Nie dodawaj automatycznej nawigacji w obserwacji wartości tylko dlatego, że binding ją zmienił. Dla uprzedzonej zmiany najpierw udostępnij konkretną instrukcję; zmiana po samym fokusie nadal podlega 3.2.1.
React Native
import React, { useState } from 'react';
import { View, Text, Switch, Pressable } from 'react-native';
export function Pickup({ onReview }: { onReview: (pickup: boolean) => void }) {
const [pickup, setPickup] = useState(false);
return (
<View>
<Text>Odbiór w Pracowni</Text>
<Switch
accessibilityLabel="Odbiór w Pracowni"
value={pickup}
onValueChange={setPickup}
/>
<Pressable accessibilityRole="button" onPress={() => onReview(pickup)}>
<Text>Przejdź do podsumowania</Text>
</Pressable>
</View>
);
}Switch jest kontrolowany przez value; onValueChange zapisuje nową wartość. Dla pola tekstowego onChangeText aktualizuje tekst, a nawigacja jest osobną akcją onPress. Zdarzenie końca edycji nie oznacza automatycznie zamiaru wysłania formularza.
Status dokumentacji i wykonania
| Technologia | Przegląd API, 2026-10-03 | Kompilacja | Działanie |
|---|---|---|---|
flutter |
PASS: oficjalne CupertinoSwitch/value/onChanged/focusNode, CupertinoTextField/onChanged i CupertinoButton/onPressed; lokalne źródło użytego SDK | Pełna demonstracja Flutter 3.44.9 / Dart 3.12.2, build iOS; fragment schematyczny nie jest osobnym buildem | Widgety i natywny XCTest opisane poniżej |
jetpack-compose |
PASS: oficjalne Switch/checked/onCheckedChange, standardowa semantyka i Button | NOT-RUN; brak użytej wersji Compose | NOT-RUN Android |
swiftui |
PASS: dokumentacja oraz deklaracje Toggle/Binding/Button w lokalnym SDK Xcode 27.0; przeglądarka dokumentacji wymagała JS, odczyt Markdown niedostępny | NOT-RUN fragmentu SwiftUI | NOT-RUN aplikacji SwiftUI; Flutter/iOS nie potwierdza tego kodu |
react-native |
PASS: oficjalne Switch/value/onValueChange, TextInput/onChangeText i Pressable/onPress | NOT-RUN; brak użytej wersji RN | NOT-RUN RN |
Brak buildów fragmentów edukacyjnych jest jawnym zakresem materiału, bez obowiązku tworzenia czterech aplikacji. Analiza składni nie potwierdza doświadczenia użytkownika ani czytnika.
Jak sprawdzić
Dobór wykonania: wybrano główną demonstrację mobilną we wspólnej aplikacji Flutter/Cupertino, zgodnie z zakresem zlecenia. Switch i pole kodu pozwalają oddzielić otrzymanie fokusu, zmianę wartości oraz aktywację; wymiana formularza na podsumowanie jest zmianą kontekstu bez udziału adresu strony. Nie zbudowano osobnego HTML, aplikacji Compose, SwiftUI lub React Native ani nie uruchamiano Androida.
- Na świeżej trasie ustal wartości, widok, etykiety, fokus i dostępną instrukcję przed użyciem. Dane startowe i końcowe muszą być takie same w parze.
- Przejdź Tab na switch bez Space. Widok i wartość pozostają; ten krok kontroluje granicę 3.2.1. Dopiero Space zmienia wartość. Osobno wykonaj dotknięcie switcha w obu wariantach.
- Po zmianie wartości w good przejdź Tab na przycisk i aktywuj go Space. Przejście dopiero po aktywacji ma inny wyzwalacz niż automatyczne przejście w bad.
- Przy kodzie dotknij widocznego pola i wpisz osobno
1,0,4. Odczytaj odebrane callbacki, tekst i widok po każdej cyfrze. W good sprawdź opuszczenie pola Tab bez przejścia, potem osobną aktywację przycisku. - Porównaj bad z warned: taka sama automatyczna zmiana po wartości, ale w warned instrukcja istnieje przed użyciem i opisuje dokładny skutek. Sprawdź jej widoczność, kolejność, powiązanie i dostępność. W late instrukcja pojawia się dopiero po przejściu.
- W control zmień opcję w obu kierunkach i ponownie ją wybierz. Lokalna cena zmienia się w zarezerwowanym miejscu, przycisk ma ten sam prostokąt, fokus i zadanie pozostają. Nie opieraj tej oceny tylko na prostokącie.
- Sprawdź powrót, reset danych i trasy, wybór scenariusza/wariantu i bezpieczny fallback. Nie mieszaj ustawień demonstracji z kontrolkami zamówienia.
Wyniki źródłowej próby — 2026-10-03
Flutter 3.44.9 / Dart 3.12.2, Xcode 27.0 / SDK 27.0, macOS 27.0, iPhone 17 Simulator / iOS 26.5. Ramka 402 × 874 pt, PNG 1206 × 2622 px, DPR 3, jasny wygląd i tekst large. Pasek 9:41 jest prezentacyjny; końcowe odczyty obejmują 19:33:13–19:36:05 Europe/Warsaw.
| Sprawdzenie | Wynik i zakres |
|---|---|
flutter analyze --no-pub |
PASS, brak problemów, 3,0 s |
flutter test --no-pub --reporter expanded test/on-input-test.dart |
PASS, 4 testy: uprzedzenie/hint, oba scenariusze, fokus/wartość/aktywacja, lokalna cena/odwrócenie/wybór/reset |
flutter test --no-pub --reporter expanded --name '^(?!.*android).*' test/*-test.dart |
PASS, 30 testów hosta; odfiltrowane warianty Android. Nie jest to uruchomienie 30 scenariuszy na urządzeniu |
flutter build ios --simulator --debug --no-codesign --no-pub oraz instalacja |
PASS, końcowy build 12,6 s; hashe Runner/App/kernel_blob równe w lokalnym buildzie i zainstalowanej aplikacji |
XCTest testCodeCompletionAndActivation |
PASS, 126,242 s; dotknięcie pola, odebrane zmiany 1 → 10 → 104, cztery warianty code, Tab z good i osobna aktywacja |
XCTest testPickupAndBoundaries |
PASS, 81,161 s; pięć wariantów pickup, Tab/Space, osobna aktywacja/powrót, dwa dotknięcia switcha, lokalne odwrócenie, ustawienia/reset/fallback |
| Cała końcowa sesja XCTest | PASS, 2 testy / 0 failures, 207,403 s; czas wykonania testów, nie pomiar czasu reakcji produktu |
| Regresja mobilna 3.2.1 | PASS, rzeczywisty Tab na help/good bez otwarcia pomocy; osobny marker w logu, poza 54 odczytami 3.2.2. Nie powtórzono całego wcześniejszego researchu |
| Kontrola zapisanych danych | PASS, odtworzenie zapisanej demonstracji i integralność dowodów; nie wykonuje UI ani walidatora |
Zachowano 54 odczyty aplikacji, 54 natywne drzewa i 51 żądań: 30 Tab/Space, 12 pojedynczych cyfr, 5 dotknięć kontrolek i 4 środka pola. Są 52 różne nazwy próbek; oba startowe odczyty good/bad pickup zachowano dla osobnego przebiegu dotykowego. Callback potwierdza każdą zmianę kodu. Natychmiastowe zwrócenie tap i aktualizacja AX nie są atomowe, więc fokus potwierdzano późniejszym odczytem. Odebrane klawisze miały właściwe HID i nie były oznaczone jako synthesized.
Wcześniejsze nieudane próby
| Próba | Rzeczywisty wynik | Przyczyna lub granica obserwacji |
|---|---|---|
| A | Pickup PASS, code FAIL odebrania Tab w late; 50 odczytów / 48 wejść / 8 PNG | Częściowe wykonanie nie zalicza code/late. |
| B, TextField.tap | Pickup PASS, code FAIL odczytu fokusu; 33 / 34 | Eksport bezpośrednio po tap był pusty lub nieaktualny. |
| C, środek pola | Code FAIL odczytu fokusu; 1 / 1 | Debug PNG z kursorem i klawiaturą nie dowodzi dostarczenia klawisza ani aktualności eksportu. |
| D, observer u góry scroll | Pickup PASS, code FAIL; 33 / 34 | Przesunięcie observera wewnątrz przewijania nie usunęło problemu. |
| E, oczekiwanie na fokus | Good/bad code odtworzone, FAIL warned; 13 / 11 | Observer mógł znikać z odczytu wskutek przewinięcia po otwarciu klawiatury. |
| F, przypięty observer | Oba końcowe testy PASS | Observer poza przewijanym formularzem, odświeżenie po pointer up i ograniczone oczekiwanie na rzeczywiście odczytany fokus; bez wymuszenia go przez test. |
Pierwsze testy widgetów ujawniły nieaktualny eksport fokusu i dodatkowy przystanek Tab opakowania Focus; poprawiono obserwację oraz skipTraversal. Przy teście semantyki skorygowano moment zwolnienia SemanticsHandle. Nie są to końcowe wyniki ani dowody błędu 3.2.2 w good. Snapshot pierwszego testu zrekonstruowano przez przywrócenie wcześniejszego Tab; nie twierdzono, że hash zebrano podczas pierwszej próby.
Część nieudanych procesów xcodebuild nadal zbierała diagnostykę po starcie następnej próby, więc diagnostyka wcześniejszych xcresult może być niepełna. Końcowa sesja zakończyła się kodem 0; wcześniejsze FAIL zachowano. Łącznie źródło zachowuje 17 PNG: osiem końcowych, osiem historycznych z A i jeden debug po C, oraz odrębne obserwacje, drzewa i metadane.
Weryfikacja i ograniczenia
- Deterministyczne odtworzenie demonstracji: ciąg wejść i odebranych zmian wartości oraz widoku pozwala sprawdzić konkretne pary. Oczekiwania PASS/FAIL znajdują się w testach i checkerze, poza obserwatorem aplikacji. PASS testu reprodukcji bad lub late oznacza odtworzenie usterki; oba warianty nadal mają negatywną ocenę 3.2.2.
- Przybliżenie z drzewa: rola Switch/TextField, wartość, nagłówek, zniknięcie formularza i fokus wskazują zachowanie do interpretacji. Drzewo nie rozstrzyga samo, czy treść zmieniła znaczenie i czy użytkownik mógł wcześniej poznać skutek. Nie wystarczy wykrycie callbacka
onChanged, nowego tekstu lub brak nowego URL. - Dla uprzedzenia potrzeba odczytu przed pierwszym użyciem, konkretnej treści zapowiadającej skutek oraz sposobu jej poznania. Instrukcja widoczna dopiero po zdarzeniu nie może zostać dopisana jako wcześniejsze ostrzeżenie. Tekst w semantycznym hint nie jest dowodem jego wypowiedzenia przez VoiceOver.
- Żądanie XCTest i odczyt aplikacji nie są jedną atomową próbką. Aktualizacja drzewa po dotknięciu pola może być opóźniona; driver czeka na rzeczywiście odczytany fokus. Zdarzenie dotknięcia, świeża próbka oraz callback tekstu mają osobne role. Obrys lub kursor nie zastępują potwierdzenia odbioru.
- Flutter
primaryFocusjest obserwacją frameworka, a nie nagraniem fokusu VoiceOver. Natywne drzewa pokazują nazwę, rolę, wartość i układ, nie doświadczenie czytnika. Wejścia XCTest są rzeczywistymi wejściami systemowymi w Simulatorze, lecz nie fizycznym dotykiem ani klawiaturą człowieka. - Ocena AI obejmuje research, odczyty i oględziny mediów. Ocena człowieka oraz badanie skuteczności walidatora Clearship na niezależnych przypadkach są NOT-RUN. Brak danych, brak wykrycia lub test własnych przykładów nie dowodzą uogólnienia ani zgodności aplikacji.
- Ustawienia demonstracji, trasy, identyfikatory próbek i stopka ujawniają wariant. To ograniczenie przyszłej zaślepionej oceny: wyłączyć konfigurację, nazwy good/bad i oczekiwania z wejścia badanego walidatora, udostępniając wyłącznie neutralne obserwacje produktu. Obecny przebieg nie jest taką oceną. Nie kopiować kompletnego katalogu assetów do wejścia walidatora.
Weryfikacja zapisanych danych zna oczekiwania demonstracji i bada integralność; nie powtarza UI ani nie mierzy skuteczności Clearship. Obserwator rejestruje wartości, fokus, wejścia i instrukcję, ale nie ocenia zgodności. Semantyczny hint i natywne drzewa nie dowodzą wypowiedzi czytnika. Wejście systemowe XCTest nie jest fizycznym dotykiem człowieka.
Przegląd człowieka i zaślepiona ocena walidatora pozostają NOT-RUN. VoiceOver/FKA, przełączniki, fizyczny iPhone, inne odbiorniki i buildy fragmentów edukacyjnych nie są wykonane. Nie przygotowano filmu ani audio, nie badano płynności ani czasu reakcji. Wcześniejsze FAIL pozostają historią, a redakcja nie ponawia tych prób.
Jak sprawdza Clearship
Clearship na Androidzie odczytuje stan przed i po dotknięciu kontrolki ustawienia. Deterministyczna metoda labels-input-change-1 wskazuje przejście do innego ekranu lub zmianę języka treści; AI ocenia, czy przed użyciem była instrukcja zapowiadająca ten skutek. Sam detektor nie zgłasza usterki bez oceny uprzedzenia. Do AI trafia obraz i ograniczone drzewo przed akcją, do 200 węzłów.
Pomiar kontrolny z 8 października 2026 r. pozostał poniżej progu: 4/6 usterek i 2 fałszywe alarmy na 24 poprawnych ekranach. Wynik wymaga człowieka. Brak obserwacji po zmianie, niedotknięta kontrolka, niepewność lub błąd AI nie dają wyniku pozytywnego. Ta sama lokalna aktualizacja tekstu może mieć inny skutek dla zadania i wymaga oceny znaczenia.
Metoda nie wykrywa zmian kontekstu po wpisaniu lub opuszczeniu pola, nowych okien, wyjścia z aplikacji, skutków opóźnionych ani zmiany znaczenia bez zmiany języka. Nie wybiera pozycji pickerów i list rozwijanych. Uprzedzenie dostępne tylko czytnikowi nie jest oceniane osobno; WWW jest poza zakresem.
Na iOS P0 nie dotykało badanych przełączników, a opcje przedstawione jako przyciski nie miały selected przed pierwszym wyborem. Brak kandydatów nie potwierdza poprawności: pomiar kontrolny 3.2.2 jest NOT-RUN, a wynik wymaga człowieka. Końcowe XCTest edukacyjnej demonstracji iOS nie potwierdza tej metody produktu.