Skip to content

Commit bc122d3

Browse files
committed
wip
1 parent 5842f4f commit bc122d3

File tree

34 files changed

+757
-330
lines changed

34 files changed

+757
-330
lines changed

docs/src/api/class-overlay.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# class: Overlay
2+
* since: v1.59
3+
4+
Interface for managing page overlays that display persistent visual indicators on top of the page.
5+
6+
## async method: Overlay.add
7+
* since: v1.59
8+
- returns: <[Disposable]>
9+
10+
Adds an overlay with the given HTML content. The overlay is displayed on top of the page until removed. Returns a disposable that removes the overlay when disposed.
11+
12+
### param: Overlay.add.html
13+
* since: v1.59
14+
- `html` <[string]>
15+
16+
HTML content for the overlay.
17+
18+
## async method: Overlay.configure
19+
* since: v1.59
20+
21+
Configures overlay behavior.
22+
23+
### option: Overlay.configure.actionDelay
24+
* since: v1.59
25+
- `actionDelay` <[int]>
26+
27+
Delay in milliseconds between actions when overlay is active.
28+
29+
## async method: Overlay.hide
30+
* since: v1.59
31+
32+
Hides all overlays without removing them. Overlays can be shown again with [`method: Overlay.show`].
33+
34+
## async method: Overlay.show
35+
* since: v1.59
36+
37+
Shows previously hidden overlays.

docs/src/api/class-page.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,6 +2759,10 @@ The page's main frame. Page is guaranteed to have a main frame which persists du
27592759
* since: v1.8
27602760
- type: <[Mouse]>
27612761

2762+
## property: Page.overlay
2763+
* since: v1.59
2764+
- type: <[Overlay]>
2765+
27622766
## method: Page.onceDialog
27632767
* since: v1.10
27642768
* langs: java

docs/src/api/class-screencast.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,6 @@ If a screencast is already active (e.g. started by tracing or video recording),
4242

4343
Defaults to 800×800.
4444

45-
### option: Screencast.start.annotate
46-
* since: v1.59
47-
* langs: js
48-
- `annotate` ?<[Object]>
49-
- `delay` ?<[int]> How long each annotation is displayed in milliseconds. Defaults to `500`.
50-
51-
If specified, enables visual annotations on interacted elements during screencast. Interacted elements are highlighted with a semi-transparent blue box and click points are shown as red circles.
52-
5345
## async method: Screencast.stop
5446
* since: v1.59
5547
* langs: js

docs/src/api/class-video.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,6 @@ Path where the video should be saved when the recording is stopped.
144144

145145
Optional dimensions of the recorded video. If not specified the size will be equal to page viewport scaled down to fit into 800x800. Actual picture of the page will be scaled down if necessary to fit the specified size.
146146

147-
### option: Video.start.annotate
148-
* since: v1.59
149-
- `annotate` ?<[Object]>
150-
- `delay` ?<[int]> How long each annotation is displayed in milliseconds. Defaults to `500`.
151-
152-
If specified, enables visual annotations on interacted elements during video recording. Interacted elements are highlighted with a semi-transparent blue box and click points are shown as red circles.
153-
154147
## async method: Video.stop
155148
* since: v1.59
156149

docs/src/api/params.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -810,8 +810,6 @@ When set to `minimal`, only record information necessary for routing from HAR. T
810810
Actual picture of each page will be scaled down if necessary to fit the specified size.
811811
- `width` <[int]> Video frame width.
812812
- `height` <[int]> Video frame height.
813-
- `annotate` ?<[Object]> If specified, enables visual annotations on interacted elements during video recording.
814-
- `delay` ?<[int]> How long each annotation is displayed in milliseconds. Defaults to `500`.
815813

816814
Enables video recording for all pages into `recordVideo.dir` directory. If not specified videos are not recorded. Make
817815
sure to await [`method: BrowserContext.close`] for videos to be saved.

docs/src/test-api/class-testoptions.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,11 @@ export default defineConfig({
625625
- `size` ?<[Object]> Size of the recorded video. Optional.
626626
- `width` <[int]>
627627
- `height` <[int]>
628-
- `annotate` ?<[Object]> If specified, visually annotates actions in the video with element highlights and action title subtitles.
629-
- `delay` ?<[int]> How long each annotation is displayed in milliseconds. Defaults to `500`.
628+
- `annotate` ?<[Object]> If specified, visually annotates the video with test information and action highlights.
629+
- `action` ?<[Object]> Controls visual annotations on interacted elements.
630+
- `delay` ?<[int]> How long each annotation is displayed in milliseconds. Defaults to `500`.
631+
- `test` ?<[Object]> Controls test information displayed as a status overlay in the video.
632+
- `level` ?<[TestAnnotationLevel]<"file"|"test"|"step">> Level of the detail to include about the current test.
630633

631634
Whether to record video for each test. Defaults to `'off'`.
632635
* `'off'`: Do not record video.
@@ -636,7 +639,7 @@ Whether to record video for each test. Defaults to `'off'`.
636639

637640
To control video size, pass an object with `mode` and `size` properties. If video size is not specified, it will be equal to [`property: TestOptions.viewport`] scaled down to fit into 800x800. If `viewport` is not configured explicitly the video size defaults to 800x450. Actual picture of each page will be scaled down if necessary to fit the specified size.
638641

639-
To annotate actions in the video with element highlights and action title subtitles, pass `annotate` with an optional `delay` in milliseconds (defaults to `500`).
642+
To annotate actions in the video, pass `annotate` with `action` and/or `test` sub-options. The `action` option controls visual highlights on interacted elements with an optional `delay` in milliseconds (defaults to `500`). The `test` option controls which test information is displayed as a status overlay.
640643

641644
**Usage**
642645

docs/src/videos.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ await context.close();
3838

3939
You can also specify video size and annotation. The video size defaults to the viewport size scaled down to fit 800x800. The video of the viewport is placed in the top-left corner of the output video, scaled down to fit if necessary. You may need to set the viewport size to match your desired video size.
4040

41-
When `annotate` is specified, each action will be visually highlighted in the video with the element outline and action title subtitle. The optional `delay` property controls how long each annotation is displayed (defaults to `500`ms).
41+
When `action` is specified, each action can be visually highlighted in the video with the element outline and action title subtitle, and test information can be shown as a status overlay. The `action` sub-option controls element highlights with an optional `delay` (defaults to `500`ms). The `test` sub-option controls which test information components are displayed.
4242

4343
```js tab=js-test title="playwright.config.ts"
4444
import { defineConfig } from '@playwright/test';
@@ -47,8 +47,11 @@ export default defineConfig({
4747
video: {
4848
mode: 'on-first-retry',
4949
size: { width: 640, height: 480 },
50-
annotate: { delay: 500 },
51-
}
50+
annotate: {
51+
action: { delay: 500 },
52+
test: { level: 'step' },
53+
},
54+
},
5255
},
5356
});
5457
```
@@ -58,7 +61,6 @@ const context = await browser.newContext({
5861
recordVideo: {
5962
dir: 'videos/',
6063
size: { width: 640, height: 480 },
61-
annotate: { delay: 500 },
6264
}
6365
});
6466
```

examples/todomvc/playwright.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default defineConfig({
4747

4848
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
4949
trace: 'on-first-retry',
50-
video: { mode: 'on', annotate: { delay: 500 } },
50+
video: { mode: 'on', annotate: { action: { delay: 500 }, test: { level: 'step' } } },
5151
},
5252

5353
/* Configure projects for major browsers */

examples/todomvc/tests/todo-creation/add-multiple-todos.spec.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,38 @@ test.describe('Todo Creation', () => {
77
// 1. Navigate to the TodoMVC application
88
// Expect: The page loads with an empty todo list
99
await expect(page.getByRole('textbox', { name: 'What needs to be done?' })).toBeVisible();
10-
11-
// 2. Add first todo 'Buy groceries' by typing and pressing Enter
1210
const newTodoInput = page.getByRole('textbox', { name: 'What needs to be done?' });
13-
await newTodoInput.fill('Buy groceries');
14-
await newTodoInput.press('Enter');
15-
// Expect: The first todo appears in the list
16-
await expect(page.getByText('Buy groceries')).toBeVisible();
11+
12+
await test.step('Add first todo', async () => {
13+
// 2. Add first todo 'Buy groceries' by typing and pressing Enter
14+
await newTodoInput.fill('Buy groceries');
15+
await newTodoInput.press('Enter');
16+
// Expect: The first todo appears in the list
17+
await expect(page.getByText('Buy groceries')).toBeVisible();
18+
});
1719

1820
// 3. Add second todo 'Walk the dog' by typing and pressing Enter
19-
await newTodoInput.fill('Walk the dog');
20-
await newTodoInput.press('Enter');
21-
// Expect: The second todo appears in the list below the first
22-
await expect(page.getByText('Walk the dog')).toBeVisible();
21+
await test.step('Add second todo', async () => {
22+
await newTodoInput.fill('Walk the dog');
23+
await newTodoInput.press('Enter');
24+
// Expect: The second todo appears in the list below the first
25+
await expect(page.getByText('Walk the dog')).toBeVisible();
26+
});
2327

2428
// 4. Add third todo 'Read a book' by typing and pressing Enter
25-
await newTodoInput.fill('Read a book');
26-
await newTodoInput.press('Enter');
27-
// Expect: The third todo appears in the list below the second
28-
await expect(page.getByText('Read a book')).toBeVisible();
29+
await test.step('Add third todo', async () => {
30+
await newTodoInput.fill('Read a book');
31+
await newTodoInput.press('Enter');
32+
// Expect: The third todo appears in the list below the second
33+
await expect(page.getByText('Read a book')).toBeVisible();
34+
});
2935

3036
// Post Conditions: All three todos are visible in the list
31-
await expect(page.getByText('Buy groceries')).toBeVisible();
32-
await expect(page.getByText('Walk the dog')).toBeVisible();
33-
await expect(page.getByText('Read a book')).toBeVisible();
37+
await test.step('Post Conditions: Verify all todos are visible', async () => {
38+
await expect(page.getByText('Buy groceries')).toBeVisible();
39+
await expect(page.getByText('Walk the dog')).toBeVisible();
40+
await expect(page.getByText('Read a book')).toBeVisible();
41+
});
3442

3543
// Post Conditions: The todo counter shows '3 items left'
3644
await expect(page.getByText('3 items left')).toBeVisible();

packages/injected/src/highlight.css

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,23 +107,27 @@ x-pw-action-point {
107107
z-index: 2;
108108
}
109109

110-
x-pw-subtitle {
110+
x-pw-title {
111111
position: absolute;
112-
bottom: 55px;
113-
left: 50%;
114-
transform: translateX(-50%);
112+
top: 6px;
113+
right: 6px;
115114
backdrop-filter: blur(5px);
116-
background-color: rgba(0, 0, 0, 0.7);
115+
background-color: rgba(0, 0, 0, 0.5);
117116
color: white;
118117
border-radius: 6px;
119-
padding: 6px 14px;
120-
font-size: 14px;
118+
padding: 6px;
119+
font-size: 24px;
121120
line-height: 1.4;
122121
white-space: nowrap;
123122
user-select: none;
124123
z-index: 3;
125124
}
126125

126+
x-pw-user-overlays, x-pw-user-overlay {
127+
position: absolute;
128+
inset: 0;
129+
}
130+
127131
@keyframes pw-fade-out {
128132
from { opacity: 1; }
129133
to { opacity: 0; }

0 commit comments

Comments
 (0)