mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(role): update accessible name calculation for native buttons (#22124)
There is a new section in the spec: https://w3c.github.io/html-aam/#button-element-accessible-name-computation Fixes #21808.
This commit is contained in:
parent
fbdafc5fe3
commit
1fbefa694f
@ -463,7 +463,7 @@ function getElementAccessibleNameInternal(element: Element, options: AccessibleN
|
||||
|
||||
// step 2e.
|
||||
if (!['presentation', 'none'].includes(role)) {
|
||||
// https://w3c.github.io/html-aam/#input-type-button-input-type-submit-and-input-type-reset
|
||||
// https://w3c.github.io/html-aam/#input-type-button-input-type-submit-and-input-type-reset-accessible-name-computation
|
||||
if (element.tagName === 'INPUT' && ['button', 'submit', 'reset'].includes((element as HTMLInputElement).type)) {
|
||||
options.visitedElements.add(element);
|
||||
const value = (element as HTMLInputElement).value || '';
|
||||
@ -477,7 +477,7 @@ function getElementAccessibleNameInternal(element: Element, options: AccessibleN
|
||||
return title;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/html-aam/#input-type-image
|
||||
// https://w3c.github.io/html-aam/#input-type-image-accessible-name-computation
|
||||
if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'image') {
|
||||
options.visitedElements.add(element);
|
||||
const alt = element.getAttribute('alt') || '';
|
||||
@ -504,8 +504,24 @@ function getElementAccessibleNameInternal(element: Element, options: AccessibleN
|
||||
return 'Submit';
|
||||
}
|
||||
|
||||
// https://w3c.github.io/html-aam/#input-type-text-input-type-password-input-type-search-input-type-tel-input-type-url-and-textarea-element
|
||||
// https://w3c.github.io/html-aam/#other-form-elements
|
||||
// https://w3c.github.io/html-aam/#button-element-accessible-name-computation
|
||||
if (element.tagName === 'BUTTON') {
|
||||
options.visitedElements.add(element);
|
||||
const labels = (element as HTMLButtonElement).labels || [];
|
||||
if (labels.length) {
|
||||
return [...labels].map(label => getElementAccessibleNameInternal(label, {
|
||||
...options,
|
||||
embeddedInLabel: 'self',
|
||||
embeddedInTextAlternativeElement: false,
|
||||
embeddedInLabelledBy: 'none',
|
||||
embeddedInTargetElement: 'none',
|
||||
})).filter(accessibleName => !!accessibleName).join(' ');
|
||||
}
|
||||
// From here, fallthrough to step 2f.
|
||||
}
|
||||
|
||||
// https://w3c.github.io/html-aam/#input-type-text-input-type-password-input-type-number-input-type-search-input-type-tel-input-type-email-input-type-url-and-textarea-element-accessible-name-computation
|
||||
// https://w3c.github.io/html-aam/#other-form-elements-accessible-name-computation
|
||||
// For "other form elements", we count select and any other input.
|
||||
if (element.tagName === 'TEXTAREA' || element.tagName === 'SELECT' || element.tagName === 'INPUT') {
|
||||
options.visitedElements.add(element);
|
||||
|
@ -240,6 +240,32 @@ test('svg title', async ({ page }) => {
|
||||
expect.soft(await getNameAndRole(page, 'a')).toEqual({ role: 'link', name: 'a link' });
|
||||
});
|
||||
|
||||
test('native controls', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<label for="text1">TEXT1</label><input id="text1" type=text>
|
||||
<input id="text2" type=text title="TEXT2">
|
||||
<input id="text3" type=text placeholder="TEXT3">
|
||||
|
||||
<label for="image1">IMAGE1</label><input id="image1" type=image>
|
||||
<input id="image2" type=image alt="IMAGE2">
|
||||
|
||||
<label for="button1">BUTTON1</label><button id="button1" role="combobox">button</button>
|
||||
<button id="button2" role="combobox">BUTTON2</button>
|
||||
<button id="button3">BUTTON3</button>
|
||||
<button id="button4" title="BUTTON4"></button>
|
||||
`);
|
||||
|
||||
expect.soft(await getNameAndRole(page, '#text1')).toEqual({ role: 'textbox', name: 'TEXT1' });
|
||||
expect.soft(await getNameAndRole(page, '#text2')).toEqual({ role: 'textbox', name: 'TEXT2' });
|
||||
expect.soft(await getNameAndRole(page, '#text3')).toEqual({ role: 'textbox', name: 'TEXT3' });
|
||||
expect.soft(await getNameAndRole(page, '#image1')).toEqual({ role: 'button', name: 'IMAGE1' });
|
||||
expect.soft(await getNameAndRole(page, '#image2')).toEqual({ role: 'button', name: 'IMAGE2' });
|
||||
expect.soft(await getNameAndRole(page, '#button1')).toEqual({ role: 'combobox', name: 'BUTTON1' });
|
||||
expect.soft(await getNameAndRole(page, '#button2')).toEqual({ role: 'combobox', name: '' });
|
||||
expect.soft(await getNameAndRole(page, '#button3')).toEqual({ role: 'button', name: 'BUTTON3' });
|
||||
expect.soft(await getNameAndRole(page, '#button4')).toEqual({ role: 'button', name: 'BUTTON4' });
|
||||
});
|
||||
|
||||
function toArray(x: any): any[] {
|
||||
return Array.isArray(x) ? x : [x];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user