diff --git a/auth/tests/behat/loginform.feature b/auth/tests/behat/loginform.feature index 7942678268d..2f6c37d7e2b 100644 --- a/auth/tests/behat/loginform.feature +++ b/auth/tests/behat/loginform.feature @@ -96,13 +96,15 @@ Feature: Test if the login form provides the correct feedback And I follow "Log in" Then the focused element is "Password" "field" + @accessibility Scenario: Test the login page focus after error feature Given I follow "Log in" And I set the field "Username" to "admin" And I set the field "Password" to "wrongpassword" And I press "Log in" - And I press the tab key + And I wait until the page is ready Then the focused element is "Username" "field" + And the page should meet accessibility standards with "best-practice" extra tests Scenario: Display the password visibility toggle icon Given the following config values are set as admin: diff --git a/lib/templates/loginform.mustache b/lib/templates/loginform.mustache index 55a8a25e93c..9b2a16e2335 100644 --- a/lib/templates/loginform.mustache +++ b/lib/templates/loginform.mustache @@ -115,16 +115,11 @@ {{/maintenance}} {{#error}} - {{error}} - + {{/error}} {{#info}} - {{info}} - +
{{info}}
{{/info}} - {{#cansignup}} - {{#str}} tocreatenewaccount {{/str}} - {{/cansignup}} {{#showloginform}}
@@ -224,10 +219,11 @@ require(['core_form/events'], function(FormEvent) { function autoFocus() { const userNameField = document.getElementById('username'); - if (userNameField.value.length == 0) { + const passwordField = document.getElementById('password'); + if (userNameField && userNameField.value.length == 0) { userNameField.focus(); - } else { - document.getElementById('password').focus(); + } else if (passwordField) { + passwordField.focus(); } } autoFocus(); @@ -235,9 +231,30 @@ }); {{/autofocusform}} {{/error}} - {{#error}} - document.getElementById('loginerrormessage').focus(); - {{/error}} + require(['core/pending'], function(Pending) { + const errorMessageDiv = document.getElementById('loginerrormessage'); + const infoMessageDiv = document.getElementById('logininfomessage'); + const errorMessage = errorMessageDiv?.textContent.trim(); + const infoMessage = infoMessageDiv?.textContent.trim(); + if (errorMessage || infoMessage) { + const pendingJS = new Pending('login-move-focus'); + const usernameField = document.getElementById('username'); + setTimeout(function() { + // Focus on the username field on error. + if (errorMessage && usernameField) { + usernameField.focus(); + } + // Append a non-breaking space to the error/status message so screen readers will announce them after page load. + if (errorMessage) { + errorMessageDiv.innerHTML += " "; + } + if (infoMessage) { + infoMessageDiv.innerHTML += " "; + } + pendingJS.resolve(); + }, 500); + } + }); {{#togglepassword}} require(['core/togglesensitive'], function(ToggleSensitive) { ToggleSensitive.init("password", {{smallscreensonly}});