Skip to content

Commit b0bf624

Browse files
committed
full dep list & added some comments
1 parent a367708 commit b0bf624

File tree

1 file changed

+197
-83
lines changed

1 file changed

+197
-83
lines changed

packages/build/src/extensions/playwright.ts

Lines changed: 197 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,173 @@ interface PlaywrightExtensionOptions {
1010
browsers?: PlaywrightBrowser[];
1111

1212
/**
13-
* Whether to support non-headless mode.
13+
* Run the browsers in headless mode (Recommended)
1414
* @default true
1515
*/
1616
headless?: boolean;
1717
}
1818

19+
/**
20+
* This list is from the official playwright registry.
21+
*
22+
* @see https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/registry/nativeDeps.ts
23+
*/
24+
const debian12Deps = {
25+
tools: [
26+
"xvfb",
27+
"fonts-noto-color-emoji",
28+
"fonts-unifont",
29+
"libfontconfig1",
30+
"libfreetype6",
31+
"xfonts-scalable",
32+
"fonts-liberation",
33+
"fonts-ipafont-gothic",
34+
"fonts-wqy-zenhei",
35+
"fonts-tlwg-loma-otf",
36+
"fonts-freefont-ttf",
37+
],
38+
chromium: [
39+
"libasound2",
40+
"libatk-bridge2.0-0",
41+
"libatk1.0-0",
42+
"libatspi2.0-0",
43+
"libcairo2",
44+
"libcups2",
45+
"libdbus-1-3",
46+
"libdrm2",
47+
"libgbm1",
48+
"libglib2.0-0",
49+
"libnspr4",
50+
"libnss3",
51+
"libpango-1.0-0",
52+
"libx11-6",
53+
"libxcb1",
54+
"libxcomposite1",
55+
"libxdamage1",
56+
"libxext6",
57+
"libxfixes3",
58+
"libxkbcommon0",
59+
"libxrandr2",
60+
],
61+
firefox: [
62+
"libasound2",
63+
"libatk1.0-0",
64+
"libcairo-gobject2",
65+
"libcairo2",
66+
"libdbus-1-3",
67+
"libdbus-glib-1-2",
68+
"libfontconfig1",
69+
"libfreetype6",
70+
"libgdk-pixbuf-2.0-0",
71+
"libglib2.0-0",
72+
"libgtk-3-0",
73+
"libharfbuzz0b",
74+
"libpango-1.0-0",
75+
"libpangocairo-1.0-0",
76+
"libx11-6",
77+
"libx11-xcb1",
78+
"libxcb-shm0",
79+
"libxcb1",
80+
"libxcomposite1",
81+
"libxcursor1",
82+
"libxdamage1",
83+
"libxext6",
84+
"libxfixes3",
85+
"libxi6",
86+
"libxrandr2",
87+
"libxrender1",
88+
"libxtst6",
89+
],
90+
webkit: [
91+
"libsoup-3.0-0",
92+
"gstreamer1.0-libav",
93+
"gstreamer1.0-plugins-bad",
94+
"gstreamer1.0-plugins-base",
95+
"gstreamer1.0-plugins-good",
96+
"libatk-bridge2.0-0",
97+
"libatk1.0-0",
98+
"libcairo2",
99+
"libdbus-1-3",
100+
"libdrm2",
101+
"libegl1",
102+
"libenchant-2-2",
103+
"libepoxy0",
104+
"libevdev2",
105+
"libfontconfig1",
106+
"libfreetype6",
107+
"libgbm1",
108+
"libgdk-pixbuf-2.0-0",
109+
"libgles2",
110+
"libglib2.0-0",
111+
"libglx0",
112+
"libgstreamer-gl1.0-0",
113+
"libgstreamer-plugins-base1.0-0",
114+
"libgstreamer1.0-0",
115+
"libgtk-4-1",
116+
"libgudev-1.0-0",
117+
"libharfbuzz-icu0",
118+
"libharfbuzz0b",
119+
"libhyphen0",
120+
"libicu72",
121+
"libjpeg62-turbo",
122+
"liblcms2-2",
123+
"libmanette-0.2-0",
124+
"libnotify4",
125+
"libopengl0",
126+
"libopenjp2-7",
127+
"libopus0",
128+
"libpango-1.0-0",
129+
"libpng16-16",
130+
"libproxy1v5",
131+
"libsecret-1-0",
132+
"libwayland-client0",
133+
"libwayland-egl1",
134+
"libwayland-server0",
135+
"libwebp7",
136+
"libwebpdemux2",
137+
"libwoff1",
138+
"libx11-6",
139+
"libxcomposite1",
140+
"libxdamage1",
141+
"libxkbcommon0",
142+
"libxml2",
143+
"libxslt1.1",
144+
"libatomic1",
145+
"libevent-2.1-7",
146+
"libavif15",
147+
],
148+
lib2package: {
149+
"libavif.so.15": "libavif15",
150+
"libsoup-3.0.so.0": "libsoup-3.0-0",
151+
"libasound.so.2": "libasound2",
152+
"libatk-1.0.so.0": "libatk1.0-0",
153+
"libatk-bridge-2.0.so.0": "libatk-bridge2.0-0",
154+
"libatspi.so.0": "libatspi2.0-0",
155+
"libcairo.so.2": "libcairo2",
156+
"libcups.so.2": "libcups2",
157+
"libdbus-1.so.3": "libdbus-1-3",
158+
"libdrm.so.2": "libdrm2",
159+
"libgbm.so.1": "libgbm1",
160+
"libgio-2.0.so.0": "libglib2.0-0",
161+
"libglib-2.0.so.0": "libglib2.0-0",
162+
"libgobject-2.0.so.0": "libglib2.0-0",
163+
"libnspr4.so": "libnspr4",
164+
"libnss3.so": "libnss3",
165+
"libnssutil3.so": "libnss3",
166+
"libpango-1.0.so.0": "libpango-1.0-0",
167+
"libsmime3.so": "libnss3",
168+
"libX11.so.6": "libx11-6",
169+
"libxcb.so.1": "libxcb1",
170+
"libXcomposite.so.1": "libxcomposite1",
171+
"libXdamage.so.1": "libxdamage1",
172+
"libXext.so.6": "libxext6",
173+
"libXfixes.so.3": "libxfixes3",
174+
"libxkbcommon.so.0": "libxkbcommon0",
175+
"libXrandr.so.2": "libxrandr2",
176+
"libgtk-4.so.1": "libgtk-4-1",
177+
},
178+
};
179+
19180
/**
20181
* Creates a Playwright extension for trigger.dev
21182
* @param options Configuration options
@@ -24,6 +185,23 @@ export function playwright(options: PlaywrightExtensionOptions = {}) {
24185
return new PlaywrightExtension(options);
25186
}
26187

188+
/**
189+
* Background:
190+
*
191+
* Running `npx playwright install --with-deps` normally will install the browsers and the dependencies.
192+
* However, this is not possible in a build context, because we don't have sudo access.
193+
*
194+
* So we need to install the dependencies manually and then download and install the browsers.
195+
* This has a few challenges:
196+
* 1. We don't want to download all browsers, only the ones we need with it's dependencies
197+
* The less dependencies we have to install, the faster the build, and the smaller the image.
198+
* 2. We need to know where to download the browsers from
199+
* while we can hardcode the download url it might change over time (as it has in the past)
200+
* so we need to download the browser info first and then parse the output to get the download url.
201+
*
202+
* Note: While this looks like we are downloading & installing a lot of stuff, it's actually not that bad
203+
* since running `npx playwright install --with-deps` will result in the same amount of downloads.
204+
*/
27205
class PlaywrightExtension implements BuildExtension {
28206
public readonly name = "PlaywrightExtension";
29207
private readonly options: Required<PlaywrightExtensionOptions>;
@@ -43,7 +221,7 @@ class PlaywrightExtension implements BuildExtension {
43221
);
44222

45223
const instructions: string[] = [
46-
// Base dependencies
224+
// Base dependencies, we need these to download the browsers
47225
`RUN apt-get update && apt-get install -y --no-install-recommends \
48226
curl \
49227
unzip \
@@ -57,90 +235,26 @@ class PlaywrightExtension implements BuildExtension {
57235
`RUN npm install -g playwright`,
58236
];
59237

60-
// Browser-specific dependencies
61-
const chromiumDeps = [
62-
"libnspr4",
63-
"libatk1.0-0",
64-
"libatk-bridge2.0-0",
65-
"libatspi2.0-0",
66-
"libasound2",
67-
"libnss3",
68-
"libxcomposite1",
69-
"libxdamage1",
70-
"libxfixes3",
71-
"libxrandr2",
72-
"libgbm1",
73-
"libxkbcommon0",
74-
];
75-
76-
const firefoxDeps = [
77-
"libgtk-3.0",
78-
"libgtk-4-1",
79-
"libgtk-4-common",
80-
"libgtk-4-dev",
81-
"libgtk-4-doc",
82-
"libasound2",
83-
];
84-
85-
const webkitDeps = [
86-
"libenchant-2-2",
87-
"libgl1",
88-
"libgles2",
89-
"libgstreamer-gl1.0-0",
90-
"libgstreamer-plugins-base1.0-0",
91-
"libgstreamer-plugins-bad1.0-0",
92-
"libharfbuzz-icu0",
93-
"libhyphen0",
94-
"libicu72",
95-
"libjpeg-dev",
96-
"libopenjp2-7",
97-
"libopus0",
98-
"libpng-dev",
99-
"libsecret-1-0",
100-
"libvpx7",
101-
"libwebp7",
102-
"libwoff1",
103-
"libx11-6",
104-
"libxcomposite1",
105-
"libxdamage1",
106-
"libxrender1",
107-
"libxt6",
108-
"libgtk-4-1",
109-
"libgraphene-1.0-0",
110-
"libxslt1.1",
111-
"libevent-2.1-7",
112-
"libmanette-0.2-0",
113-
"libwebpdemux2",
114-
"libwebpmux3",
115-
"libatomic1",
116-
"libavif15",
117-
"libx264-dev",
118-
"flite",
119-
"libatk1.0-0",
120-
"libatk-bridge2.0-0",
121-
];
238+
const deps = [...debian12Deps.tools, ...Object.values(debian12Deps.lib2package)];
239+
if (this.options.browsers.includes("chromium")) deps.push(...debian12Deps.chromium);
240+
if (this.options.browsers.includes("firefox")) deps.push(...debian12Deps.firefox);
241+
if (this.options.browsers.includes("webkit")) deps.push(...debian12Deps.webkit);
122242

123-
const deps = [];
124-
if (this.options.browsers.includes("chromium")) deps.push(...chromiumDeps);
125-
if (this.options.browsers.includes("firefox")) deps.push(...firefoxDeps);
126-
if (this.options.browsers.includes("webkit")) deps.push(...webkitDeps);
127-
128-
const uniqueDeps = [...new Set(deps)];
129-
130-
if (uniqueDeps.length > 0) {
131-
instructions.push(
132-
`RUN apt-get update && apt-get install -y --no-install-recommends ${uniqueDeps.join(" ")} \
243+
instructions.push(
244+
`RUN apt-get update && apt-get install -y --no-install-recommends ${deps.join(" ")} \
133245
&& apt-get clean && rm -rf /var/lib/apt/lists/*`
134-
);
135-
}
246+
);
136247

137-
// Setup Playwright browsers
248+
// Setup directory for playwright browsers
138249
instructions.push(`RUN mkdir -p /ms-playwright`);
139-
instructions.push(`RUN npx playwright install --dry-run > /tmp/browser-info.txt`);
140250

251+
/**
252+
* `npx playwright install --dry-run` prints the download urls for the browsers.
253+
* We save this output to a file and then parse it to get the download urls for the browsers.
254+
*/
255+
instructions.push(`RUN npx playwright install --dry-run > /tmp/browser-info.txt`);
141256
this.options.browsers.forEach((browser) => {
142257
const browserType = browser === "chromium" ? "chromium-headless-shell" : browser;
143-
144258
instructions.push(
145259
`RUN grep -A5 "browser: ${browserType}" /tmp/browser-info.txt > /tmp/${browser}-info.txt`,
146260

@@ -160,9 +274,9 @@ class PlaywrightExtension implements BuildExtension {
160274

161275
// Environment variables
162276
const envVars: Record<string, string> = {
163-
PLAYWRIGHT_BROWSERS_PATH: "/ms-playwright",
164-
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1",
165-
PLAYWRIGHT_SKIP_BROWSER_VALIDATION: "1",
277+
PLAYWRIGHT_BROWSERS_PATH: "/ms-playwright", // where playwright will find the browsers
278+
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1", // we already downloaded the browsers
279+
PLAYWRIGHT_SKIP_BROWSER_VALIDATION: "1", // we already downloaded the browsers
166280
};
167281

168282
if (!this.options.headless) {
@@ -173,7 +287,7 @@ class PlaywrightExtension implements BuildExtension {
173287
`RUN chmod +x /usr/local/bin/xvfb-exec`
174288
);
175289

176-
envVars.DISPLAY = ":99";
290+
envVars.DISPLAY = ":99"; // Virtual display for the browsers
177291
}
178292

179293
context.addLayer({

0 commit comments

Comments
 (0)