/** * Copyright Microsoft Corporation. All rights reserved. * * 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 { expect, browserTest as test } from '../config/browserTest'; test.skip(({ mode }) => mode !== 'default', 'Overlay uses an open shadow root only in default mode'); test('should add and remove overlay', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); const disposable = await page.screencast.showOverlay('
Hello Overlay
'); await expect(page.locator('x-pw-user-overlays')).toBeVisible(); await expect(page.locator('.x-pw-user-overlay')).toHaveCount(1); await expect(page.locator('#my-overlay')).toHaveText('Hello Overlay'); await disposable.dispose(); await expect(page.locator('.x-pw-user-overlay')).toHaveCount(0); await context.close(); }); test('should add multiple overlays', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); const d1 = await page.screencast.showOverlay('
First
'); const d2 = await page.screencast.showOverlay('
Second
'); await expect(page.locator('.x-pw-user-overlay')).toHaveCount(2); await expect(page.locator('#overlay-1')).toHaveText('First'); await expect(page.locator('#overlay-2')).toHaveText('Second'); await d1.dispose(); await expect(page.locator('.x-pw-user-overlay')).toHaveCount(1); await expect(page.locator('#overlay-2')).toHaveText('Second'); await d2.dispose(); await expect(page.locator('.x-pw-user-overlay')).toHaveCount(0); await context.close(); }); test('should hide and show overlays', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); await page.screencast.showOverlay('
Visible
'); await expect(page.locator('x-pw-user-overlays')).toBeVisible(); await page.screencast.hideOverlays(); await expect(page.locator('x-pw-user-overlays')).toBeHidden(); await page.screencast.showOverlays(); await expect(page.locator('x-pw-user-overlays')).toBeVisible(); await expect(page.locator('#my-overlay')).toHaveText('Visible'); await context.close(); }); test('should survive navigation', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); await page.screencast.showOverlay('
Survives Reload
'); await expect(page.locator('#persistent')).toHaveText('Survives Reload'); await page.goto(server.EMPTY_PAGE); await expect(page.locator('#persistent')).toHaveText('Survives Reload'); await page.reload(); await expect(page.locator('#persistent')).toHaveText('Survives Reload'); await context.close(); }); test('should remove overlay and not restore after navigation', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); const disposable = await page.screencast.showOverlay('
Temporary
'); await expect(page.locator('#temp')).toHaveText('Temporary'); await disposable.dispose(); await expect(page.locator('.x-pw-user-overlay')).toHaveCount(0); await page.reload(); await expect(page.locator('.x-pw-user-overlay')).toHaveCount(0); await context.close(); }); test('should sanitize scripts from overlay html', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); await page.screencast.showOverlay('
Safe
'); await expect(page.locator('#safe')).toHaveText('Safe'); expect(await page.evaluate(() => (window as any).__injected)).toBeUndefined(); await context.close(); }); test('should strip event handlers from overlay html', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); await page.screencast.showOverlay('
Click me
'); await expect(page.locator('#clean')).toHaveText('Click me'); const hasOnclick = await page.locator('#clean').evaluate(el => el.hasAttribute('onclick')); expect(hasOnclick).toBe(false); await context.close(); }); test('should auto-remove overlay after timeout', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); await page.screencast.showOverlay('
Temporary
', { duration: 1 }); await expect(page.locator('.x-pw-user-overlay')).toHaveCount(0); await context.close(); }); test('should allow styles in overlay html', async ({ browser, server }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(server.EMPTY_PAGE); await page.screencast.showOverlay('
Styled
'); await expect(page.locator('#styled')).toHaveText('Styled'); const color = await page.locator('#styled').evaluate(el => getComputedStyle(el).color); expect(color).toBe('rgb(255, 0, 0)'); await context.close(); });