chore(snapshot): support aria-owns (#33404)
This commit is contained in:
		
							parent
							
								
									3cd753f6bb
								
							
						
					
					
						commit
						1d4650cea2
					
				|  | @ -50,7 +50,12 @@ export type AriaTemplateRoleNode = AriaProps & { | |||
| export type AriaTemplateNode = AriaTemplateRoleNode | AriaTemplateTextNode; | ||||
| 
 | ||||
| export function generateAriaTree(rootElement: Element): AriaNode { | ||||
|   const visited = new Set<Node>(); | ||||
|   const visit = (ariaNode: AriaNode, node: Node) => { | ||||
|     if (visited.has(node)) | ||||
|       return; | ||||
|     visited.add(node); | ||||
| 
 | ||||
|     if (node.nodeType === Node.TEXT_NODE && node.nodeValue) { | ||||
|       const text = node.nodeValue; | ||||
|       if (text) | ||||
|  | @ -65,13 +70,23 @@ export function generateAriaTree(rootElement: Element): AriaNode { | |||
|     if (roleUtils.isElementHiddenForAria(element)) | ||||
|       return; | ||||
| 
 | ||||
|     const ariaChildren: Element[] = []; | ||||
|     if (element.hasAttribute('aria-owns')) { | ||||
|       const ids = element.getAttribute('aria-owns')!.split(/\s+/); | ||||
|       for (const id of ids) { | ||||
|         const ownedElement = rootElement.ownerDocument.getElementById(id); | ||||
|         if (ownedElement) | ||||
|           ariaChildren.push(ownedElement); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     const childAriaNode = toAriaNode(element); | ||||
|     if (childAriaNode) | ||||
|       ariaNode.children.push(childAriaNode); | ||||
|     processChildNodes(childAriaNode || ariaNode, element); | ||||
|     processElement(childAriaNode || ariaNode, element, ariaChildren); | ||||
|   }; | ||||
| 
 | ||||
|   function processChildNodes(ariaNode: AriaNode, element: Element) { | ||||
|   function processElement(ariaNode: AriaNode, element: Element, ariaChildren: Element[] = []) { | ||||
|     // Surround every element with spaces for the sake of concatenated text nodes.
 | ||||
|     const display = getElementComputedStyle(element)?.display || 'inline'; | ||||
|     const treatAsBlock = (display !== 'inline' || element.nodeName === 'BR') ? ' ' : ''; | ||||
|  | @ -94,6 +109,9 @@ export function generateAriaTree(rootElement: Element): AriaNode { | |||
|       } | ||||
|     } | ||||
| 
 | ||||
|     for (const child of ariaChildren) | ||||
|       visit(ariaNode, child); | ||||
| 
 | ||||
|     ariaNode.children.push(roleUtils.getPseudoContent(element, '::after')); | ||||
| 
 | ||||
|     if (treatAsBlock) | ||||
|  |  | |||
|  | @ -421,3 +421,41 @@ it('should treat input value as text in templates', async ({ page }) => { | |||
|     - textbox: hello world | ||||
|   `);
 | ||||
| }); | ||||
| 
 | ||||
| it('should respect aria-owns', async ({ page }) => { | ||||
|   await page.setContent(` | ||||
|     <a href='about:blank' aria-owns='input p'> | ||||
|       <div role='region'>Link 1</div> | ||||
|     </a> | ||||
|     <a href='about:blank' aria-owns='input p'> | ||||
|       <div role='region'>Link 2</div> | ||||
|     </a> | ||||
|     <input id='input' value='Value'> | ||||
|     <p id='p'>Paragraph</p> | ||||
|   `);
 | ||||
| 
 | ||||
|   // - Different from Chrome DevTools which attributes ownership to the last element.
 | ||||
|   // - CDT also does not include non-owned children in accessible name.
 | ||||
|   // - Disregarding these as aria-owns can't suggest multiple parts by spec.
 | ||||
|   await checkAndMatchSnapshot(page.locator('body'), ` | ||||
|     - link "Link 1 Value Paragraph": | ||||
|       - region: Link 1 | ||||
|       - textbox: Value | ||||
|       - paragraph: Paragraph | ||||
|     - link "Link 2 Value Paragraph": | ||||
|       - region: Link 2 | ||||
|   `);
 | ||||
| }); | ||||
| 
 | ||||
| it('should be ok with circular ownership', async ({ page }) => { | ||||
|   await page.setContent(` | ||||
|     <a href='about:blank' id='parent'> | ||||
|       <div role='region' aria-owns='parent'>Hello</div> | ||||
|     </a> | ||||
|   `);
 | ||||
| 
 | ||||
|   await checkAndMatchSnapshot(page.locator('body'), ` | ||||
|     - link "Hello": | ||||
|       - region: Hello | ||||
|   `);
 | ||||
| }); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue