| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { test as it, expect } from './pageTest'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  | function snapshotForAI(page: any): Promise<string> { | 
					
						
							|  |  |  |   return page._snapshotForAI(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | it('should generate refs', async ({ page }) => { | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <button>One</button> | 
					
						
							|  |  |  |     <button>Two</button> | 
					
						
							|  |  |  |     <button>Three</button> | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot1 = await snapshotForAI(page); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |   expect(snapshot1).toContainYaml(`
 | 
					
						
							|  |  |  |     - generic [ref=e1]: | 
					
						
							|  |  |  |       - button "One" [ref=e2] | 
					
						
							|  |  |  |       - button "Two" [ref=e3] | 
					
						
							|  |  |  |       - button "Three" [ref=e4] | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  |   await expect(page.locator('aria-ref=e2')).toHaveText('One'); | 
					
						
							|  |  |  |   await expect(page.locator('aria-ref=e3')).toHaveText('Two'); | 
					
						
							|  |  |  |   await expect(page.locator('aria-ref=e4')).toHaveText('Three'); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |   await page.locator('aria-ref=e3').evaluate((e: HTMLElement) => { | 
					
						
							|  |  |  |     e.textContent = 'Not Two'; | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot2 = await snapshotForAI(page); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |   expect(snapshot2).toContainYaml(`
 | 
					
						
							|  |  |  |     - generic [ref=e1]: | 
					
						
							|  |  |  |       - button "One" [ref=e2] | 
					
						
							|  |  |  |       - button "Not Two" [ref=e5] | 
					
						
							|  |  |  |       - button "Three" [ref=e4] | 
					
						
							|  |  |  |   `);
 | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | it('should list iframes', async ({ page }) => { | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <h1>Hello</h1> | 
					
						
							|  |  |  |     <iframe name="foo" src="data:text/html,<h1>World</h1>"> | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot1 = await snapshotForAI(page); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   expect(snapshot1).toContain('- iframe'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const frameSnapshot = await page.frameLocator(`iframe`).locator('body').ariaSnapshot(); | 
					
						
							|  |  |  |   expect(frameSnapshot).toEqual('- heading "World" [level=1]'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  | it('should stitch all frame snapshots', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   await page.goto(server.PREFIX + '/frames/nested-frames.html'); | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot = await snapshotForAI(page); | 
					
						
							|  |  |  |   expect(snapshot).toContainYaml(`
 | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |     - generic [ref=e1]: | 
					
						
							|  |  |  |       - iframe [ref=e2]: | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |         - generic [ref=f1e1]: | 
					
						
							|  |  |  |           - iframe [ref=f1e2]: | 
					
						
							|  |  |  |             - generic [ref=f2e2]: Hi, I'm frame | 
					
						
							|  |  |  |           - iframe [ref=f1e3]: | 
					
						
							|  |  |  |             - generic [ref=f3e2]: Hi, I'm frame | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |       - iframe [ref=e3]: | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |         - generic [ref=f4e2]: Hi, I'm frame | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   `);
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const href = await page.locator('aria-ref=e1').evaluate(e => e.ownerDocument.defaultView.location.href); | 
					
						
							|  |  |  |   expect(href).toBe(server.PREFIX + '/frames/nested-frames.html'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const href2 = await page.locator('aria-ref=f1e2').evaluate(e => e.ownerDocument.defaultView.location.href); | 
					
						
							|  |  |  |   expect(href2).toBe(server.PREFIX + '/frames/two-frames.html'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const href3 = await page.locator('aria-ref=f3e2').evaluate(e => e.ownerDocument.defaultView.location.href); | 
					
						
							|  |  |  |   expect(href3).toBe(server.PREFIX + '/frames/frame.html'); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | it('should not generate refs for hidden elements', async ({ page }) => { | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <button>One</button> | 
					
						
							|  |  |  |     <button style="width: 0; height: 0; appearance: none; border: 0; padding: 0;">Two</button> | 
					
						
							|  |  |  |     <button>Three</button> | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot = await snapshotForAI(page); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   expect(snapshot).toContainYaml(`
 | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |     - generic [ref=e1]: | 
					
						
							|  |  |  |       - button "One" [ref=e2] | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |       - button "Two" | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |       - button "Three" [ref=e4] | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   `);
 | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | it('should not generate refs for elements with pointer-events:none', async ({ page }) => { | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <button style="pointer-events: none">no-ref</button> | 
					
						
							|  |  |  |     <div style="pointer-events: none"> | 
					
						
							|  |  |  |       <button style="pointer-events: auto">with-ref</button> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <div style="pointer-events: none"> | 
					
						
							|  |  |  |       <div style="pointer-events: initial"> | 
					
						
							|  |  |  |         <button>with-ref</button> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <div style="pointer-events: none"> | 
					
						
							|  |  |  |       <div style="pointer-events: auto"> | 
					
						
							|  |  |  |         <button>with-ref</button> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <div style="pointer-events: auto"> | 
					
						
							|  |  |  |       <div style="pointer-events: none"> | 
					
						
							|  |  |  |         <button>no-ref</button> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot = await snapshotForAI(page); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   expect(snapshot).toContainYaml(`
 | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |     - generic [ref=e1]: | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |       - button "no-ref" | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |       - button "with-ref" [ref=e4] | 
					
						
							|  |  |  |       - button "with-ref" [ref=e7] | 
					
						
							|  |  |  |       - button "with-ref" [ref=e10] | 
					
						
							|  |  |  |       - generic [ref=e11]: | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |         - generic: | 
					
						
							|  |  |  |           - button "no-ref" | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | it('emit generic roles for nodes w/o roles', async ({ page }) => { | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <style> | 
					
						
							|  |  |  |     input { | 
					
						
							|  |  |  |       width: 0; | 
					
						
							|  |  |  |       height: 0; | 
					
						
							|  |  |  |       opacity: 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     </style> | 
					
						
							|  |  |  |     <div> | 
					
						
							|  |  |  |       <label> | 
					
						
							|  |  |  |         <span> | 
					
						
							|  |  |  |           <input type="radio" value="Apple" checked=""> | 
					
						
							|  |  |  |         </span> | 
					
						
							|  |  |  |         <span>Apple</span> | 
					
						
							|  |  |  |       </label> | 
					
						
							|  |  |  |       <label> | 
					
						
							|  |  |  |         <span> | 
					
						
							|  |  |  |           <input type="radio" value="Pear"> | 
					
						
							|  |  |  |         </span> | 
					
						
							|  |  |  |         <span>Pear</span> | 
					
						
							|  |  |  |       </label> | 
					
						
							|  |  |  |       <label> | 
					
						
							|  |  |  |         <span> | 
					
						
							|  |  |  |           <input type="radio" value="Orange"> | 
					
						
							|  |  |  |         </span> | 
					
						
							|  |  |  |         <span>Orange</span> | 
					
						
							|  |  |  |       </label> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot = await snapshotForAI(page); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   expect(snapshot).toContainYaml(`
 | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |     - generic [ref=e2]: | 
					
						
							|  |  |  |       - generic [ref=e3]: | 
					
						
							|  |  |  |         - generic [ref=e4]: | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |           - radio "Apple" [checked] | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |         - generic [ref=e6]: Apple | 
					
						
							|  |  |  |       - generic [ref=e7]: | 
					
						
							|  |  |  |         - generic [ref=e8]: | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |           - radio "Pear" | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |         - generic [ref=e10]: Pear | 
					
						
							|  |  |  |       - generic [ref=e11]: | 
					
						
							|  |  |  |         - generic [ref=e12]: | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |           - radio "Orange" | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |         - generic [ref=e14]: Orange | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   `);
 | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | it('should collapse generic nodes', async ({ page }) => { | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <div> | 
					
						
							|  |  |  |       <div> | 
					
						
							|  |  |  |         <div> | 
					
						
							|  |  |  |           <button>Button</button> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot = await snapshotForAI(page); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   expect(snapshot).toContainYaml(`
 | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |     - button \"Button\" [ref=e5] | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   `);
 | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | it('should include cursor pointer hint', async ({ page }) => { | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <button style="cursor: pointer">Button</button> | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 16:15:16 -07:00
										 |  |  |   const snapshot = await snapshotForAI(page); | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   expect(snapshot).toContainYaml(`
 | 
					
						
							| 
									
										
										
										
											2025-05-08 13:25:39 -07:00
										 |  |  |     - button \"Button\" [ref=e2] [cursor=pointer] | 
					
						
							| 
									
										
										
										
											2025-05-08 13:04:15 -07:00
										 |  |  |   `);
 | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2025-05-14 17:38:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | it('should gracefully fallback when child frame cant be captured', async ({ page, server }) => { | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <p>Test</p> | 
					
						
							|  |  |  |     <iframe src="${server.PREFIX}/redirectloop1.html#depth=100000"></iframe> | 
					
						
							|  |  |  |   `, { waitUntil: 'domcontentloaded' });
 | 
					
						
							|  |  |  |   const snapshot = await snapshotForAI(page); | 
					
						
							|  |  |  |   expect(snapshot).toContainYaml(`
 | 
					
						
							|  |  |  |     - generic [ref=e1]: | 
					
						
							|  |  |  |       - paragraph [ref=e2]: Test | 
					
						
							|  |  |  |       - iframe [ref=e3] | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | }); |