Commit 067930aa authored by Elizabeth Popova's avatar Elizabeth Popova Committed by Commit Bot

[Autofill] Handle a11y announcement of card expirarion error

The card expiration error is now announced the same way as errors in cr-input. Attributes such as role="alert" need to be added again every time for better a11y, see [1].

[1]https://chromium-review.googlesource.com/c/chromium/src/+/2429943

Bug: 1083550
Change-Id: I4dbf22eec455eef659e9aeb18b53f4fd28452474
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2435189Reviewed-by: default avatarChristoph Schwering <schwering@google.com>
Reviewed-by: default avatardpapad <dpapad@chromium.org>
Commit-Queue: Elizabeth Popova <lizapopova@google.com>
Cr-Commit-Position: refs/heads/master@{#811989}
parent 3366f574
...@@ -122,22 +122,23 @@ ...@@ -122,22 +122,23 @@
</label> </label>
<select class="md-select" id="month" value="[[expirationMonth_]]" <select class="md-select" id="month" value="[[expirationMonth_]]"
on-change="onMonthChange_" on-change="onMonthChange_"
aria-label="$i18n{creditCardExpirationMonth}"> aria-label="$i18n{creditCardExpirationMonth}"
aria-invalid$="[[getExpirationAriaInvalid_(expired_)]]">
<template is="dom-repeat" items="[[monthList_]]"> <template is="dom-repeat" items="[[monthList_]]">
<option>[[item]]</option> <option>[[item]]</option>
</template> </template>
</select> </select>
<select class="md-select" id="year" value="[[expirationYear_]]" <select class="md-select" id="year" value="[[expirationYear_]]"
on-change="onYearChange_" on-change="onYearChange_"
aria-label="$i18n{creditCardExpirationYear}"> aria-label="$i18n{creditCardExpirationYear}"
aria-invalid$="[[getExpirationAriaInvalid_(expired_)]]">
<template is="dom-repeat" items="[[yearList_]]"> <template is="dom-repeat" items="[[yearList_]]">
<option>[[item]]</option> <option>[[item]]</option>
</template> </template>
</select> </select>
<!-- Use new error message text under the drop down when nickname <!-- Use new error message text under the drop down when nickname
management is enabled.--> management is enabled.-->
<div id="expired-error" aria-hidden$="[[getAriaHidden_(expired_)]]" <div id="expired-error" hidden="[[!nicknameManagementEnabled_]]">
hidden="[[!nicknameManagementEnabled_]]">
$i18n{creditCardExpired} $i18n{creditCardExpired}
</div> </div>
<!-- Reuse current error message span when nickname management is <!-- Reuse current error message span when nickname management is
......
...@@ -96,6 +96,7 @@ Polymer({ ...@@ -96,6 +96,7 @@ Polymer({
type: Boolean, type: Boolean,
computed: 'computeExpired_(expirationMonth_, expirationYear_)', computed: 'computeExpired_(expirationMonth_, expirationYear_)',
reflectToAttribute: true, reflectToAttribute: true,
observer: 'onExpiredChanged_',
}, },
}, },
...@@ -221,6 +222,26 @@ Polymer({ ...@@ -221,6 +222,26 @@ Polymer({
return !this.nicknameManagementEnabled_ && this.expired_; return !this.nicknameManagementEnabled_ && this.expired_;
}, },
/**
* Handles a11y error announcement the same way as in cr-input.
* @private
*/
onExpiredChanged_() {
const ERROR_ID =
this.nicknameManagementEnabled_ ? 'expired-error' : 'expired';
const errorElement = this.$$(`#${ERROR_ID}`);
// Readding attributes is needed for consistent announcement by VoiceOver
if (this.expired_) {
errorElement.setAttribute('role', 'alert');
this.$$(`#month`).setAttribute('aria-errormessage', ERROR_ID);
this.$$(`#year`).setAttribute('aria-errormessage', ERROR_ID);
} else {
errorElement.removeAttribute('role');
this.$$(`#month`).removeAttribute('aria-errormessage');
this.$$(`#year`).removeAttribute('aria-errormessage');
}
},
/** /**
* Validate no digits are used in nickname. Display error message and disable * Validate no digits are used in nickname. Display error message and disable
* the save button when invalid. * the save button when invalid.
...@@ -241,12 +262,12 @@ Polymer({ ...@@ -241,12 +262,12 @@ Polymer({
}, },
/** /**
* @return {string} 'true' or 'false', indicating whether the expired error * @return {string} 'true' or 'false' for the aria-invalid attribute
* message should be aria-hidden. * of expiration selectors.
* @private * @private
*/ */
getAriaHidden_() { getExpirationAriaInvalid_() {
return this.expired_ ? 'false' : 'true'; return this.expired_ ? 'true' : 'false';
}, },
/** /**
......
...@@ -407,6 +407,12 @@ suite('PaymentsSectionCreditCardEditDialogTest', function() { ...@@ -407,6 +407,12 @@ suite('PaymentsSectionCreditCardEditDialogTest', function() {
// hidden. // hidden.
assertFalse(creditCardDialog.$.expired.hidden); assertFalse(creditCardDialog.$.expired.hidden);
assertTrue(creditCardDialog.$$('#expired-error').hidden); assertTrue(creditCardDialog.$$('#expired-error').hidden);
// Check a11y attributes added for correct error announcement.
assertEquals('alert', creditCardDialog.$.expired.getAttribute('role'));
for (const select of [creditCardDialog.$.month, creditCardDialog.$.year]) {
assertEquals('true', select.getAttribute('aria-invalid'));
assertEquals('expired', select.getAttribute('aria-errormessage'));
}
// Update the expiration year to next year to avoid expired card. // Update the expiration year to next year to avoid expired card.
creditCardDialog.$.year.value = nextYear(); creditCardDialog.$.year.value = nextYear();
...@@ -417,6 +423,12 @@ suite('PaymentsSectionCreditCardEditDialogTest', function() { ...@@ -417,6 +423,12 @@ suite('PaymentsSectionCreditCardEditDialogTest', function() {
assertTrue(creditCardDialog.$.expired.hidden); assertTrue(creditCardDialog.$.expired.hidden);
assertTrue(creditCardDialog.$$('#expired-error').hidden); assertTrue(creditCardDialog.$$('#expired-error').hidden);
assertFalse(creditCardDialog.$.saveButton.disabled); assertFalse(creditCardDialog.$.saveButton.disabled);
// Check a11y attributes for expiration error removed.
assertEquals(null, creditCardDialog.$.expired.getAttribute('role'));
for (const select of [creditCardDialog.$.month, creditCardDialog.$.year]) {
assertEquals('false', select.getAttribute('aria-invalid'));
assertEquals(null, select.getAttribute('aria-errormessage'));
}
}); });
test('expired card when nickname management is enabled', async function() { test('expired card when nickname management is enabled', async function() {
...@@ -436,8 +448,13 @@ suite('PaymentsSectionCreditCardEditDialogTest', function() { ...@@ -436,8 +448,13 @@ suite('PaymentsSectionCreditCardEditDialogTest', function() {
// The new expired error message is shown, the legacy error message is still // The new expired error message is shown, the legacy error message is still
// hidden. // hidden.
assertEquals('visible', getComputedStyle(expiredError).visibility); assertEquals('visible', getComputedStyle(expiredError).visibility);
assertEquals('false', expiredError.getAttribute('aria-hidden'));
assertTrue(creditCardDialog.$.expired.hidden); assertTrue(creditCardDialog.$.expired.hidden);
// Check a11y attributes added for correct error announcement.
assertEquals('alert', expiredError.getAttribute('role'));
for (const select of [creditCardDialog.$.month, creditCardDialog.$.year]) {
assertEquals('true', select.getAttribute('aria-invalid'));
assertEquals('expired-error', select.getAttribute('aria-errormessage'));
}
// Update the expiration year to next year to avoid expired card. // Update the expiration year to next year to avoid expired card.
creditCardDialog.$.year.value = nextYear(); creditCardDialog.$.year.value = nextYear();
...@@ -446,8 +463,13 @@ suite('PaymentsSectionCreditCardEditDialogTest', function() { ...@@ -446,8 +463,13 @@ suite('PaymentsSectionCreditCardEditDialogTest', function() {
// Expired error message is hidden for valid expiration date. // Expired error message is hidden for valid expiration date.
assertEquals('hidden', getComputedStyle(expiredError).visibility); assertEquals('hidden', getComputedStyle(expiredError).visibility);
assertEquals('true', expiredError.getAttribute('aria-hidden'));
assertTrue(creditCardDialog.$.expired.hidden); assertTrue(creditCardDialog.$.expired.hidden);
assertFalse(creditCardDialog.$.saveButton.disabled); assertFalse(creditCardDialog.$.saveButton.disabled);
// Check a11y attributes for expiration error removed.
assertEquals(null, expiredError.getAttribute('role'));
for (const select of [creditCardDialog.$.month, creditCardDialog.$.year]) {
assertEquals('false', select.getAttribute('aria-invalid'));
assertEquals(null, select.getAttribute('aria-errormessage'));
}
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment