# Physical screen-reader test scripts Run these scripts against the exact release candidate. Do not simulate a screen reader with the accessibility tree, and do not mark a row complete from automated output. Record the operating-system, browser, and screen-reader versions plus the commit/build identifier in the WCAG checklist. ## Test states Use a fresh private window/profile for each state unless the step explicitly requires saved preference state. 1. **Default** — normal motion preference, sound not started. 2. **Audio running** — activate **START THE DRIVE** once. 3. **Static** — choose **Static** from **Quality**. 4. **Reduced motion** — enable the OS reduced-motion preference before load. 5. **Media/scene failure** — use the release test build's documented failure setup; never alter production code or expose a public test hook. 6. **Missing social** — use the approved optional-social build fixture; the email action must remain. For each platform, repeat Tasks 1–3 and Task 7 in all six states. Run Tasks 4–6 in every state where their content is present. If final project media is still awaiting approval, record Tasks 5–6 as **not present in candidate — must re-run when approved media enters the manifest**, not as PASS. ## NVDA + Firefox on Windows Setup: - Start NVDA, then Firefox. Record exact versions from NVDA Help → About and Firefox Help → About. - Use a fresh Firefox private window at 100% zoom for the default pass. - Keep NVDA speech viewer open only if it does not change viewport geometry. - Use `NVDA+F7` for the Elements List, `H`/`Shift+H` for headings, `D`/`Shift+D` for landmarks, `K`/`Shift+K` for links, `B` for buttons, `F` for form fields, `Tab`/`Shift+Tab` for focus order, and `Enter`/`Space` for activation. Run the seven literal tasks below. Record the exact announcement when an oracle fails; do not paraphrase the failure. ## VoiceOver + Safari on macOS Setup: - Record macOS and Safari versions, enable VoiceOver with `Command+F5`, and record the VoiceOver version from VoiceOver Utility → About. - Enable Safari's **Press Tab to highlight each item on a webpage**. - Use `VO` (`Control+Option`) + `U` for the rotor, `VO+Command+H` for the next heading, `VO+Command+L` for the next link, `VO+Command+J` for the next form control, `VO+Right/Left Arrow` for sequential reading, and `VO+Space` to activate. Run the seven literal tasks below in Safari. Note whether Quick Nav is on for each run because it changes key behavior, not page semantics. ## VoiceOver + Safari on iOS Setup: - Record device model, iOS version, and Safari build. Enable VoiceOver in Settings → Accessibility → VoiceOver. - Set the rotor to Headings, Links, Form Controls, and Containers as needed. - Use one-finger right/left swipes for sequential navigation, rotor swipes for category navigation, double-tap to activate, and a four-finger tap near the top/bottom to move to the first/last accessible item. - Test portrait at the 320 CSS px-equivalent supported width and landscape. Run the same seven tasks. Also confirm that touch exploration never lands on the decorative canvas, road signs, speed, particles, or HUD. ## Seven literal tasks and pass oracles ### 1. Load, identity, structure, and scene description 1. Load the page at the top without interacting. 2. Read from the first accessible item through the main navigation. 3. Open the landmarks/headings rotor or Elements List. Pass only when: - the document title identifies Luca Pîslaru and the portfolio role; - **Skip to portfolio content** is the first actionable item; - exactly one H1 announces **Luca Pîslaru**, followed by **System Administrator & Full-Stack Developer**; - the portfolio navigation has a useful name and ordered section links; - one concise description explains the restrained retro-futuristic road journey and portfolio progress; - the canvas, poster, car, road signs, speed, particles, and HUD do not appear as separate accessible objects or repeated live announcements. ### 2. Skip link, section navigation, focus, and passive scrolling 1. Return to the top and focus **Skip to portfolio content** with the keyboard or rotor. 2. Activate it and read the focused item. 3. Navigate back to the section navigation, activate **Infrastructure**, and read the focused item. 4. Move through **Selected Builds**, **Toolkit**, and **Contact** using only the navigation links. 5. Put the reading cursor on a navigation link, then scroll manually without activating it. Use Back/Forward once after an explicit section activation. Pass only when: - skip activation lands on the portfolio main content; - explicit section navigation focuses and announces the correct H2 once; - logical focus order matches the visible document order; - focus is visible and not covered by the fixed HUD or drive controls; - passive scrolling and history restoration do not steal keyboard focus or relocate the screen-reader reading cursor. ### 3. Start the Drive and audio controls 1. Find **START THE DRIVE** by button navigation. 2. Read the button and its adjacent supporting description before activating. 3. Activate it once, then navigate through the newly exposed sound controls. 4. Activate **Mute sound**, verify the name becomes **Unmute sound**, adjust **Sound volume**, and mute again before continuing. Pass only when: - the control is announced as a button and the nearby text explains that it enables the interactive soundtrack; - sound never begins before explicit activation; - **Mute sound**/**Unmute sound** and **Sound volume** have correct role, name, and current value/state; - audio state changes are understandable without repeated or continuous live announcements and do not drown out assistive-technology speech; - audio failure, when tested, announces **Audio unavailable** while all portfolio content remains usable. ### 4. Toolkit labels 1. Navigate to **Toolkit** and enter each technology group. 2. Read at least Linux, Docker, Python, Vue.js, C# / .NET, and the Additional experience group in sequence. Pass only when each technology is announced once from its visible text label; the decorative repeated icon/dot is silent; group headings are announced in the expected hierarchy; and no percentage, rating, or invented expertise claim is exposed. ### 5. Chart descriptions and data tables 1. Navigate to the Opinion Dynamics Simulation chart group, if present in the approved candidate. 2. Read the figure caption, adjacent Variables, Trend, and Conclusion fields. 3. Enter any data table by table navigation and traverse its headers and at least two data cells. Pass only when the purpose, axes/variables, trend, and conclusion are usable without inspecting color or pixels; each table has a useful caption and associated row/column headers; and the image alt does not redundantly recite the full adjacent description. ### 6. Authored video controls and failure fallback 1. Navigate to an approved project video, if present in the candidate. 2. Read its name, caption, structured description, initial status, and authored **Play video** control. 3. Activate Play, verify **Pause video**, pause, then repeat with OS reduced motion enabled. 4. Run the approved media-failure state and revisit the same figure. Pass only when no sound autoplays; reduced motion begins from a poster until explicit Play; the authored button exposes the correct play/pause state; the caption/description remains available; failure exposes **Video unavailable** and explanatory text; and inaccessible user-agent shadow controls are not the only control surface. ### 7. Contact and optional social links 1. Navigate to **Contact** by heading and by the section navigation. 2. Read Luca's name, role, visible email address, CV/contact note, and every optional profile link. 3. Inspect the email link's destination/purpose without sending mail. 4. Repeat in the missing-social state. Pass only when: - the visible email and primary `mailto:` action are announced with an unambiguous purpose; - GitHub, GitLab, and LinkedIn have distinct visible/accessibility names when present; - missing optional social links are omitted rather than announced as empty, disabled, or placeholder controls; - the email action remains reachable and the page exposes no CV download. ## Result template Copy one row per state/platform into the WCAG checklist evidence log: ```text Date/time: Build/commit: OS/device: Browser + version: Screen reader + version: State: Tasks run: 1 2 3 4 5 6 7 Result: PASS / FAIL / NOT PRESENT — RE-RUN REQUIRED Exact failed announcement or interaction: Screenshot/speech-viewer/video evidence location (private): Tester: ``` Never place private hostnames, private project names, credentials, personal account identifiers, or uncleared media in the committed evidence log.