mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	feat(expect): toHaveText/toContainText work with text in shadow dom (#16433)
This commit is contained in:
		
							parent
							
								
									fce45210c1
								
							
						
					
					
						commit
						3dc1920ce8
					
				| @ -21,7 +21,7 @@ import { VueEngine } from './vueSelectorEngine'; | ||||
| import { RoleEngine } from './roleSelectorEngine'; | ||||
| import type { NestedSelectorBody, ParsedSelector, ParsedSelectorPart } from '../isomorphic/selectorParser'; | ||||
| import { allEngineNames, parseSelector, stringifySelector } from '../isomorphic/selectorParser'; | ||||
| import { type TextMatcher, elementMatchesText, createRegexTextMatcher, createStrictTextMatcher, createLaxTextMatcher } from './selectorUtils'; | ||||
| import { type TextMatcher, elementMatchesText, createRegexTextMatcher, createStrictTextMatcher, createLaxTextMatcher, elementText } from './selectorUtils'; | ||||
| import { SelectorEvaluatorImpl } from './selectorEvaluator'; | ||||
| import { isElementVisible, parentElementOrShadowHost } from './domUtils'; | ||||
| import type { CSSComplexSelectorList } from '../isomorphic/cssParser'; | ||||
| @ -1091,7 +1091,7 @@ export class InjectedScript { | ||||
|       } else if (expression === 'to.have.id') { | ||||
|         received = element.id; | ||||
|       } else if (expression === 'to.have.text') { | ||||
|         received = options.useInnerText ? (element as HTMLElement).innerText : element.textContent || ''; | ||||
|         received = options.useInnerText ? (element as HTMLElement).innerText : elementText(new Map(), element).full; | ||||
|       } else if (expression === 'to.have.title') { | ||||
|         received = document.title; | ||||
|       } else if (expression === 'to.have.url') { | ||||
| @ -1124,7 +1124,7 @@ export class InjectedScript { | ||||
|     // List of values.
 | ||||
|     let received: string[] | undefined; | ||||
|     if (expression === 'to.have.text.array' || expression === 'to.contain.text.array') | ||||
|       received = elements.map(e => options.useInnerText ? (e as HTMLElement).innerText : e.textContent || ''); | ||||
|       received = elements.map(e => options.useInnerText ? (e as HTMLElement).innerText : elementText(new Map(), e).full); | ||||
|     else if (expression === 'to.have.class.array') | ||||
|       received = elements.map(e => e.classList.toString()); | ||||
| 
 | ||||
|  | ||||
| @ -107,6 +107,27 @@ test.describe('toHaveText with text', () => { | ||||
|     const locator = page.locator('#node'); | ||||
|     await expect(locator).toHaveText('Text content', { useInnerText: true }); | ||||
|   }); | ||||
| 
 | ||||
|   test('in shadow dom', async ({ page }) => { | ||||
|     await page.setContent(` | ||||
|       <div></div> | ||||
|       <script> | ||||
|         const div = document.querySelector('div'); | ||||
|         const span = document.createElement('span'); | ||||
|         span.textContent = 'some text'; | ||||
|         div.attachShadow({ mode: 'open' }).appendChild(span); | ||||
|       </script> | ||||
|     `);
 | ||||
|     await expect(page.locator('span')).toHaveText('some text'); | ||||
|     await expect(page.locator('span')).toContainText('text'); | ||||
|     await expect(page.locator('div')).toHaveText('some text'); | ||||
|     await expect(page.locator('div')).toContainText('text'); | ||||
|     await expect(page.locator('span')).toHaveText('some text', { useInnerText: true }); | ||||
|     await expect(page.locator('span')).toContainText('text', { useInnerText: true }); | ||||
|     // Playwright intentionally does not perform innerText piercing on shadow dom.
 | ||||
|     await expect(page.locator('div')).not.toHaveText('some text', { useInnerText: true }); | ||||
|     await expect(page.locator('div')).not.toContainText('text', { useInnerText: true }); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| test.describe('not.toHaveText', () => { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dmitry Gozman
						Dmitry Gozman