/
index.ts
80 lines (69 loc) · 1.86 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
* @module @mugshot/playwright
*/
import { Webdriver } from 'mugshot';
import { ElementHandle, Page } from 'playwright';
/**
* Adapter over [Playwright](https://github.com/microsoft/playwright) to be
* used with {@link WebdriverScreenshotter}.
*
* @example
* ```ts
* import { Mugshot } from 'mugshot';
* import { PlaywrightAdapter } from '@mugshot/playwright';
* import playwright from 'playwright';
*
* const browser = await playwright.chromium.launch();
* const context = await browser.newContext();
* const page = await context.newPage();
*
* const mugshot = new Mugshot(
* new PlaywrightAdapter(page),
* './screenshots'
* );
* ```
*/
export class PlaywrightAdapter implements Webdriver {
/**
* @param page The return value of `newPage()`.
*/
constructor(private readonly page: Page) {}
takeViewportScreenshot = async () =>
(await this.page.screenshot()).toString('base64');
execute = <R, A extends any[]>(
func: (...args: A) => R,
...args: A
): Promise<R> =>
this.page.evaluate(
// @ts-expect-error because playwright has a weird conditional type for args
func,
...args
);
getElementRect = async (selector: string) => {
const elements = await this.page.$$(selector);
if (!elements.length) {
return null;
}
if (elements.length === 1) {
return this.getBoundingBox()(elements[0]);
}
return Promise.all(elements.map(this.getBoundingBox()));
};
setViewportSize = (width: number, height: number) =>
this.page.setViewportSize({
width,
height,
});
private getBoundingBox = () => async (element: ElementHandle) => {
const rect = await element.boundingBox();
if (!rect) {
return { x: 0, y: 0, width: 0, height: 0 };
}
return {
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height,
};
};
}