Files
english/.opencode/skills/web-testing/references/shadow-dom-testing.md
2026-04-12 01:06:31 +07:00

71 lines
1.6 KiB
Markdown

# Shadow DOM & Web Components Testing
## Challenges
- CSS encapsulation breaks selectors
- Elements hidden from DOM queries
- XPath doesn't penetrate shadow boundaries
## Tool Support
| Tool | Support | Method |
|------|---------|--------|
| Playwright | Native | `>>` piercing selector |
| Cypress | Good | `.shadow()` command |
| Selenium | Limited | JS execution |
| Axe | v5.7+ | API support |
## Playwright Shadow Piercing
```javascript
const input = page.locator('my-component >> .internal-input');
const button = page.locator('comp-a >> comp-b >> button');
const el = page.locator('custom-element >> button:has-text("Click me")');
```
## Cypress Shadow DOM
```javascript
cy.get('my-component').shadow().find('.internal-button').click();
// Enable globally: { includeShadowDom: true }
```
## Selenium Workaround
```javascript
const shadowHost = driver.findElement(By.css('my-component'));
const shadowRoot = driver.executeScript('return arguments[0].shadowRoot', shadowHost);
const button = shadowRoot.findElement(By.css('button'));
```
## Page Object Pattern
```typescript
export class MyComponentPO {
constructor(private page: Page) {}
async fillEmail(email: string) {
await this.page.locator('my-form >> input[type="email"]').fill(email);
}
async submit() {
await this.page.locator('my-form >> button[type="submit"]').click();
}
}
```
## Best Practices
1. Request `open` shadow roots when possible
2. Encapsulate shadow traversal in page objects
3. Avoid deep nesting (increases complexity)
## Debugging
```javascript
const contents = await page.evaluate(() => {
return document.querySelector('my-component').shadowRoot.innerHTML;
});
```