Make WordPress Core

Opened 8 days ago

Last modified 7 days ago

#66213 new defect (bug)

Users: Associate profile screen descriptions with their controls

Reported by: johnjamesjacoby Owned by:
Priority: normal Milestone: Awaiting Review
Component: Users Version:
Severity: normal Keywords: good-first-bug has-patch
Cc: Focuses: accessibility, administration

Description

Discovered while reviewing #66205.

The shared user profile/edit screen contains several descriptions that are visually adjacent to their controls but are not programmatically associated with them:

  • The read-only #user_login input and its “Usernames cannot be changed.” description.
  • The #description Biographical Info textarea and its explanatory paragraph.
  • The #generate-reset-link button and the paragraph explaining the effect of sending a password reset link.
  • The session action button and its explanatory paragraph in each conditional state, including the disabled “Log Out Everywhere Else” state and the enabled #destroy-sessions states.

All of these controls are rendered from wp-admin/user-edit.php. The wp-admin/user/profile.php and wp-admin/user/user-edit.php files are wrappers around that shared screen. The same renderer is also used by Site Admin and Network Admin, so the issue affects all three administration contexts.

The required markers for Nickname and Email are already part of their associated labels. The profile picture description is a separate Gravatar link rather than a control description. Other descriptions on the screen, including Email, Repeat New Password, and New Application Password Name, already follow the established pattern of an id on the description and an aria-describedby reference on the control.

Steps to reproduce

  1. Open a user profile or edit-user screen, for example:
    • wp-admin/profile.php
    • wp-admin/network/user-edit.php?user_id=1
    • wp-admin/user/profile.php
  2. Inspect the Username and Biographical Info controls with browser accessibility tools or a screen reader.
  3. When editing another user, inspect the Send Reset Link button.
  4. Inspect the session action button. Its description varies according to the number of sessions and whether the current user or another user is being edited.
  5. Observe that the adjacent descriptions are not exposed as accessible descriptions for these controls.

Expected result

Each control programmatically references its descriptive text, consistent with the existing pattern elsewhere on the same screen.

Suggested change

Add unique IDs to the relevant description elements and matching aria-describedby attributes to the inputs, textarea, and buttons. Each conditional session description should use the same stable ID referenced by its corresponding button.

Change History (2)

This ticket was mentioned in ​PR #13829 on ​WordPress/wordpress-develop by ​@johnjamesjacoby.


8 days ago
#1

  • Keywords has-patch added; needs-patch removed

Associates descriptions on the shared user profile and edit screen with their controls using aria-describedby.

This covers the read-only Username field, Biographical Info field, Send Reset Link button, and all conditional states of the Sessions action. Because wp-admin/user-edit.php is shared, the fix applies to Site Admin, Network Admin, and User Admin.

Testing instructions

  1. Open the following profile and user-edit screens:
    • wp-admin/profile.php
    • wp-admin/network/user-edit.php?user_id=1
    • wp-admin/user/profile.php
  2. Use a browser accessibility inspector or screen reader to confirm the Username and Biographical Info controls expose their adjacent text as accessible descriptions.
  3. When editing another user, confirm the Send Reset Link button exposes its description.
  4. Confirm the session action exposes the correct description in each state:
    • The current user has one session.
    • The current user has multiple sessions.
    • Another user has active sessions.

Local checks:

  • php -l src/wp-admin/user-edit.php
  • PHP_CodeSniffer with the WordPress Core rules
  • git diff --check

Use of AI Tools

AI assistance: Yes
Tool(s): Codex
Model(s): GPT-5
Used for: Auditing the shared renderer and wrappers, implementing the markup associations, checking WordPress Core conventions, and drafting this pull request. The final patch was reviewed and approved by me.

​@therssoftware commented on ​PR #13829:


7 days ago
#2

Test Report: Trac #66213 / PR #13829

Ticket: https://core.trac.wordpress.org/ticket/66213
Pull Request: ​https://github.com/WordPress/wordpress-develop/pull/13829
Tested by: @therssoftware (GitHub: @robelsust)
Patch tested: PR #13829 commit 081615d (johnjamesjacoby:master)

Environment

  • WordPress: 7.2-alpha-63585 / 7.1.2
  • PHP: 8.3.14 & 8.3.33
  • PHPUnit: 9.6.37
  • Browser: Google Chrome (Headless & Full Screen DOM Inspection via Playwright)
  • Database: MariaDB / MySQL
  • OS: macOS (Darwin 24.3.0 arm64)

Summary of Testing

I tested PR #13829 across wp-admin/profile.php and wp-admin/user-edit.php (for both current user and other users), validating all aria-describedby associations, accessible description targets, and conditional session action states.

1. Profile Screen (wp-admin/profile.php - Current User)

  • Username Field: <input id="user_login"> has attribute aria-describedby="user-login-description", referencing <span class="description" id="user-login-description"> ("Usernames cannot be changed.").
  • Biographical Info: <textarea id="description"> has attribute aria-describedby="description-description", referencing <p class="description" id="description-description"> ("Share a little biographical information to fill out your profile. This may be shown publicly.").

2. User Edit Screen (wp-admin/user-edit.php?user_id=X - Another User)

  • Username & Biographical Info: Both controls correctly maintain their respective aria-describedby attributes pointing to their description elements.
  • Send Reset Link Button: <button id="generate-reset-link"> has attribute aria-describedby="generate-reset-link-description", referencing <p class="description" id="generate-reset-link-description"> ("Send {User} a link to reset their password. This will not change their password, nor will it force a change.").

3. Session Action Button (All Conditional States Verified)

  • Current user with multiple sessions: <button id="destroy-sessions"> has attribute aria-describedby="sessions-description", matching "Did you lose your phone or leave your account logged in at a public computer? You can log out everywhere else, and stay logged in here.".
  • Current user with exactly one session: <button disabled class="button"> has attribute aria-describedby="sessions-description", matching "You are only logged in at this location.".
  • Another user with active sessions: <button id="destroy-sessions"> ("Log Out Everywhere") has attribute aria-describedby="sessions-description", matching "Log {User} out of all locations.".
  • Another user without active sessions: The .user-sessions-wrap row is omitted cleanly as expected.

4. Automated Tests & Coding Standards

  • php -l src/wp-admin/user-edit.php: No syntax errors detected.
  • git diff --check: 0 whitespace errors.
  • vendor/bin/phpcs --standard=WordPress-Core src/wp-admin/user-edit.php: 0 errors, 0 warnings.
  • vendor/bin/phpunit tests/phpunit/tests/user.php: OK (122 tests, 416 assertions).
  • vendor/bin/phpunit -c tests/phpunit/multisite.xml tests/phpunit/tests/user.php: OK (120 tests, 417 assertions).

Conclusion

PR #13829 works cleanly as expected. All form controls on the profile and user-edit screens are now programmatically associated with their descriptive text via aria-describedby, ensuring full accessibility for screen readers without any visual regression or PHPCS/PHPUnit issues. Ready to merge.

AI Disclosure

AI assistance: Yes
Tool(s): Gemini
Model(s): Gemini 2.5 Pro
Used for: Automated test execution, DOM verification via Playwright, and test report drafting. All tests and outputs were manually reviewed and verified.

Note: See TracTickets for help on using tickets.