Files
AI/참고/playwright-main/tests/library/screencast-actions.spec.ts
2026-05-12 19:40:31 +09:00

202 lines
7.2 KiB
TypeScript

/**
* 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', 'Annotations use an open shadow root only in default mode');
test('should show annotation on click', async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html');
await page.screencast.showActions({ duration: 5000 });
page.click('button').catch(() => {});
await expect(page.locator('x-pw-highlight')).toBeVisible();
await expect(page.locator('x-pw-action-point')).toBeVisible();
await expect(page.locator('x-pw-title')).toBeVisible();
await expect(page.locator('x-pw-title')).toHaveText(/click/i);
await context.close();
});
test('should render annotation styles', async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html');
await page.screencast.showActions({ duration: 5000, fontSize: 32 });
page.click('button').catch(() => {});
// Highlight box: blue overlay with non-zero dimensions.
const highlight = page.locator('x-pw-highlight');
await expect(highlight).toBeVisible();
const highlightStyle = await highlight.evaluate((el: HTMLElement) => ({
backgroundColor: el.style.backgroundColor,
borderColor: el.style.borderColor,
}));
expect(highlightStyle.backgroundColor).toBe('rgba(0, 128, 255, 0.15)');
expect(highlightStyle.borderColor).toBe('rgba(0, 128, 255, 0.6)');
const box = await highlight.boundingBox();
expect(box!.width).toBeGreaterThan(0);
expect(box!.height).toBeGreaterThan(0);
// Action point: 20x20 red circle.
const actionPoint = page.locator('x-pw-action-point');
await expect(actionPoint).toBeVisible();
const apStyle = await actionPoint.evaluate((el: HTMLElement) => {
const cs = getComputedStyle(el);
return { width: cs.width, height: cs.height, background: cs.backgroundColor, borderRadius: cs.borderRadius };
});
expect(apStyle.width).toBe('20px');
expect(apStyle.height).toBe('20px');
expect(apStyle.background).toBe('rgb(255, 0, 0)');
expect(apStyle.borderRadius).toBe('10px');
// Title: white text, dark background, positioned top-right by default, custom fontSize.
const title = page.locator('x-pw-title');
await expect(title).toBeVisible();
const titleStyle = await title.evaluate((el: HTMLElement) => {
const cs = getComputedStyle(el);
return {
color: cs.color, borderRadius: cs.borderRadius, padding: cs.padding,
top: el.style.top, right: el.style.right, fontSize: el.style.fontSize,
};
});
expect(titleStyle.color).toBe('rgb(255, 255, 255)');
expect(titleStyle.borderRadius).toBe('6px');
expect(titleStyle.padding).toBe('6px');
expect(titleStyle.top).toBe('6px');
expect(titleStyle.right).toBe('6px');
expect(titleStyle.fontSize).toBe('32px');
await context.close();
});
for (const { position, expected } of [
{ position: 'top-left' as const, expected: { top: '6px', left: '6px' } },
{ position: 'top' as const, expected: { top: '6px', left: '50%' } },
{ position: 'bottom-left' as const, expected: { bottom: '6px', left: '6px' } },
{ position: 'bottom' as const, expected: { bottom: '6px', left: '50%' } },
{ position: 'bottom-right' as const, expected: { bottom: '6px', right: '6px' } },
] as const) {
test(`should position title at ${position}`, async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html');
await page.screencast.showActions({ duration: 5000, position });
page.click('button').catch(() => {});
const title = page.locator('x-pw-title');
await expect(title).toBeVisible();
const titleStyle = await title.evaluate((el: HTMLElement) => ({
top: el.style.top,
bottom: el.style.bottom,
left: el.style.left,
right: el.style.right,
})) as any;
for (const [key, value] of Object.entries(expected))
expect(titleStyle[key]).toBe(value);
await context.close();
});
}
test('should clear annotation after duration', async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html');
await page.screencast.showActions({ duration: 1000 });
await page.click('button');
await expect(page.locator('x-pw-action-point')).toBeHidden();
await expect(page.locator('x-pw-title')).toBeHidden();
await context.close();
});
test('should annotate fill action', async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/textarea.html');
await page.screencast.showActions({ duration: 5000 });
page.fill('textarea', 'hello').catch(() => {});
const title = page.locator('x-pw-title');
await expect(title).toBeVisible();
await expect(title).toHaveText(/fill/i);
await context.close();
});
test('should stop showing actions after dispose', async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html');
const actions = await page.screencast.showActions({ duration: 1000 });
await page.click('button');
await actions.dispose();
await page.goto(server.PREFIX + '/input/button.html');
await page.click('button');
await expect(page.locator('x-pw-title')).toBeHidden();
await context.close();
});
test('should stop showing actions after hideActions', async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html');
await page.screencast.showActions({ duration: 1000 });
await page.click('button');
await page.screencast.hideActions();
await page.goto(server.PREFIX + '/input/button.html');
await page.click('button');
await expect(page.locator('x-pw-title')).toBeHidden();
await context.close();
});
test('should survive navigation', async ({ browser, server }) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(server.PREFIX + '/input/button.html');
await page.screencast.showActions({ duration: 5000 });
page.click('button').catch(() => {});
await expect(page.locator('x-pw-title')).toBeVisible();
await page.goto(server.PREFIX + '/input/button.html');
page.click('button').catch(() => {});
await expect(page.locator('x-pw-title')).toBeVisible();
await context.close();
});