Skip to content

Commit a05c12a

Browse files
author
Austin Kelleher
committed
Merge branch 'initial-files'
2 parents 0a3dbc0 + 54df52c commit a05c12a

File tree

8 files changed

+175
-148
lines changed

8 files changed

+175
-148
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "playwright-aws-lambda",
3-
"version": "0.3.2",
3+
"version": "0.4.0",
44
"description": "Support for running Microsoft's Playwrite on AWS Lambda and Google Cloud functions",
55
"main": "./dist/src/",
66
"author": "Austin Kelleher, [email protected]",

src/chromium.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { promises as fsPromises } from 'fs';
2+
import { join } from 'path';
3+
import * as playwright from 'playwright-core';
4+
import isLambdaRuntimeEnvironment from './util/isLambdaRuntimeEnvironment';
5+
import { LaunchOptions } from 'playwright-core/lib/server/browserType';
6+
import isHeadlessModeEnabled from './util/isHeadlessModeEnabled';
7+
import fileExists from './util/fileExists';
8+
import setEnvironmentVariables from './util/setEnvironmentVariables';
9+
import getMemorySize from './util/getMemorySize';
10+
11+
const { inflate } = require('lambdafs');
12+
13+
setEnvironmentVariables();
14+
15+
/**
16+
* Returns a list of recommended additional Chromium flags.
17+
*/
18+
export function getChromiumArgs(headless: boolean) {
19+
const result = [
20+
'--disable-background-timer-throttling',
21+
'--disable-breakpad',
22+
'--disable-client-side-phishing-detection',
23+
'--disable-cloud-import',
24+
'--disable-default-apps',
25+
'--disable-dev-shm-usage',
26+
'--disable-extensions',
27+
'--disable-gesture-typing',
28+
'--disable-hang-monitor',
29+
'--disable-infobars',
30+
'--disable-notifications',
31+
'--disable-offer-store-unmasked-wallet-cards',
32+
'--disable-offer-upload-credit-cards',
33+
'--disable-popup-blocking',
34+
'--disable-print-preview',
35+
'--disable-prompt-on-repost',
36+
'--disable-setuid-sandbox',
37+
'--disable-speech-api',
38+
'--disable-sync',
39+
'--disable-tab-for-desktop-share',
40+
'--disable-translate',
41+
'--disable-voice-input',
42+
'--disable-wake-on-wifi',
43+
'--disk-cache-size=33554432',
44+
'--enable-async-dns',
45+
'--enable-simple-cache-backend',
46+
'--enable-tcp-fast-open',
47+
'--enable-webgl',
48+
'--hide-scrollbars',
49+
'--ignore-gpu-blacklist',
50+
'--media-cache-size=33554432',
51+
'--metrics-recording-only',
52+
'--mute-audio',
53+
'--no-default-browser-check',
54+
'--no-first-run',
55+
'--no-pings',
56+
'--no-sandbox',
57+
'--no-zygote',
58+
'--password-store=basic',
59+
'--prerender-from-omnibox=disabled',
60+
'--use-gl=swiftshader',
61+
'--use-mock-keychain',
62+
];
63+
64+
if (getMemorySize() >= 1024) {
65+
result.push('--memory-pressure-off');
66+
}
67+
68+
if (headless === true) {
69+
result.push('--single-process');
70+
} else {
71+
result.push('--start-maximized');
72+
}
73+
74+
return result;
75+
}
76+
77+
async function getChromiumExecutablePath(
78+
headless: boolean
79+
): Promise<string | undefined> {
80+
if (headless !== true) {
81+
return undefined;
82+
}
83+
84+
if ((await fileExists('/tmp/chromium')) === true) {
85+
for (const file of await fsPromises.readdir('/tmp')) {
86+
if (file.startsWith('core.chromium') === true) {
87+
await fsPromises.unlink(`/tmp/${file}`);
88+
}
89+
}
90+
91+
return '/tmp/chromium';
92+
}
93+
94+
const input = join(__dirname, 'bin');
95+
const promises = [
96+
inflate(`${input}/chromium.br`),
97+
inflate(`${input}/swiftshader.tar.br`),
98+
];
99+
100+
if (isLambdaRuntimeEnvironment()) {
101+
promises.push(inflate(`${input}/aws.tar.br`));
102+
}
103+
104+
const result = await Promise.all(promises);
105+
return result.shift();
106+
}
107+
108+
export async function launchChromium(launchOptions?: Partial<LaunchOptions>) {
109+
const headless = isHeadlessModeEnabled();
110+
const args = getChromiumArgs(headless);
111+
const executablePath = await getChromiumExecutablePath(headless);
112+
113+
const browser = await playwright.chromium.launch({
114+
args,
115+
executablePath,
116+
headless,
117+
...launchOptions,
118+
});
119+
120+
return browser;
121+
}

src/index.ts

Lines changed: 3 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,149 +1,5 @@
1-
require('playwright-core').default = require('playwright-core');
1+
import setEnvironmentVariables from './util/setEnvironmentVariables';
22

3-
import { promises as fsPromises } from 'fs';
4-
import { join } from 'path';
5-
import playwright from 'playwright-core';
6-
import isLambdaRuntimeEnvironment from './isLambdaRuntimeEnvironment';
7-
import { LaunchOptions } from 'playwright-core/lib/server/browserType';
3+
setEnvironmentVariables();
84

9-
const { inflate } = require('lambdafs');
10-
11-
if (isLambdaRuntimeEnvironment()) {
12-
if (process.env.FONTCONFIG_PATH === undefined) {
13-
process.env.FONTCONFIG_PATH = '/tmp/aws';
14-
}
15-
16-
if (process.env.LD_LIBRARY_PATH === undefined) {
17-
process.env.LD_LIBRARY_PATH = '/tmp/aws/lib';
18-
} else if (process.env.LD_LIBRARY_PATH.startsWith('/tmp/aws/lib') !== true) {
19-
process.env.LD_LIBRARY_PATH = [
20-
...new Set(['/tmp/aws/lib', ...process.env.LD_LIBRARY_PATH.split(':')]),
21-
].join(':');
22-
}
23-
}
24-
25-
/**
26-
* Returns a list of recommended additional Chromium flags.
27-
*/
28-
function getChromiumArgs(headless: boolean) {
29-
const result = [
30-
'--disable-background-timer-throttling',
31-
'--disable-breakpad',
32-
'--disable-client-side-phishing-detection',
33-
'--disable-cloud-import',
34-
'--disable-default-apps',
35-
'--disable-dev-shm-usage',
36-
'--disable-extensions',
37-
'--disable-gesture-typing',
38-
'--disable-hang-monitor',
39-
'--disable-infobars',
40-
'--disable-notifications',
41-
'--disable-offer-store-unmasked-wallet-cards',
42-
'--disable-offer-upload-credit-cards',
43-
'--disable-popup-blocking',
44-
'--disable-print-preview',
45-
'--disable-prompt-on-repost',
46-
'--disable-setuid-sandbox',
47-
'--disable-speech-api',
48-
'--disable-sync',
49-
'--disable-tab-for-desktop-share',
50-
'--disable-translate',
51-
'--disable-voice-input',
52-
'--disable-wake-on-wifi',
53-
'--disk-cache-size=33554432',
54-
'--enable-async-dns',
55-
'--enable-simple-cache-backend',
56-
'--enable-tcp-fast-open',
57-
'--enable-webgl',
58-
'--hide-scrollbars',
59-
'--ignore-gpu-blacklist',
60-
'--media-cache-size=33554432',
61-
'--metrics-recording-only',
62-
'--mute-audio',
63-
'--no-default-browser-check',
64-
'--no-first-run',
65-
'--no-pings',
66-
'--no-sandbox',
67-
'--no-zygote',
68-
'--password-store=basic',
69-
'--prerender-from-omnibox=disabled',
70-
'--use-gl=swiftshader',
71-
'--use-mock-keychain',
72-
];
73-
if (
74-
parseInt(
75-
process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE ||
76-
process.env.FUNCTION_MEMORY_MB ||
77-
'1024',
78-
10
79-
) >= 1024
80-
) {
81-
result.push('--memory-pressure-off');
82-
}
83-
if (headless === true) {
84-
result.push('--single-process');
85-
} else {
86-
result.push('--start-maximized');
87-
}
88-
return result;
89-
}
90-
async function fileExists(path: string) {
91-
try {
92-
await fsPromises.access(path);
93-
return true;
94-
} catch (err) {
95-
return false;
96-
}
97-
}
98-
function isHeadlessModeEnabled() {
99-
if (process.env.IS_LOCAL !== undefined) {
100-
return false;
101-
}
102-
return ['AWS_LAMBDA_FUNCTION_NAME', 'FUNCTION_NAME', 'FUNCTION_TARGET'].some(
103-
key => process.env[key] !== undefined
104-
);
105-
}
106-
107-
async function getExecutablePath(
108-
headless: boolean
109-
): Promise<string | undefined> {
110-
if (headless !== true) {
111-
return Promise.resolve(undefined);
112-
}
113-
114-
if ((await fileExists('/tmp/chromium')) === true) {
115-
for (const file of await fsPromises.readdir('/tmp')) {
116-
if (file.startsWith('core.chromium') === true) {
117-
await fsPromises.unlink(`/tmp/${file}`);
118-
}
119-
}
120-
121-
return Promise.resolve('/tmp/chromium');
122-
}
123-
124-
const input = join(__dirname, 'bin');
125-
const promises = [
126-
inflate(`${input}/chromium.br`),
127-
inflate(`${input}/swiftshader.tar.br`),
128-
];
129-
130-
if (isLambdaRuntimeEnvironment()) {
131-
promises.push(inflate(`${input}/aws.tar.br`));
132-
}
133-
134-
const result = await Promise.all(promises);
135-
return result.shift();
136-
}
137-
138-
export async function launchChromium(launchOptions?: Partial<LaunchOptions>) {
139-
const headless = isHeadlessModeEnabled();
140-
const browser = await playwright.chromium.launch({
141-
args: getChromiumArgs(headless),
142-
// defaultViewport: chromium.defaultViewport,
143-
executablePath: await getExecutablePath(headless),
144-
headless,
145-
// headless: true
146-
...launchOptions,
147-
});
148-
return browser;
149-
}
5+
export * from './chromium';

src/util/fileExists.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { promises as fsPromises } from 'fs';
2+
3+
export default async function fileExists(path: string) {
4+
try {
5+
await fsPromises.access(path);
6+
return true;
7+
} catch (err) {
8+
return false;
9+
}
10+
}

src/util/getMemorySize.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default function getMemorySize() {
2+
return parseInt(
3+
process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE ||
4+
process.env.FUNCTION_MEMORY_MB ||
5+
'1024',
6+
10
7+
);
8+
}

src/util/isHeadlessModeEnabled.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default function isHeadlessModeEnabled() {
2+
if (process.env.IS_LOCAL !== undefined) {
3+
return false;
4+
}
5+
return ['AWS_LAMBDA_FUNCTION_NAME', 'FUNCTION_NAME', 'FUNCTION_TARGET'].some(
6+
key => process.env[key] !== undefined
7+
);
8+
}

src/util/setEnvironmentVariables.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import isLambdaRuntimeEnvironment from './isLambdaRuntimeEnvironment';
2+
3+
let environmentVariablesSet = false;
4+
5+
export default function setEnvironmentVariables() {
6+
if (environmentVariablesSet || !isLambdaRuntimeEnvironment()) {
7+
environmentVariablesSet = true;
8+
return;
9+
}
10+
11+
if (process.env.FONTCONFIG_PATH === undefined) {
12+
process.env.FONTCONFIG_PATH = '/tmp/aws';
13+
}
14+
15+
if (process.env.LD_LIBRARY_PATH === undefined) {
16+
process.env.LD_LIBRARY_PATH = '/tmp/aws/lib';
17+
} else if (process.env.LD_LIBRARY_PATH.startsWith('/tmp/aws/lib') !== true) {
18+
process.env.LD_LIBRARY_PATH = [
19+
...new Set(['/tmp/aws/lib', ...process.env.LD_LIBRARY_PATH.split(':')]),
20+
].join(':');
21+
}
22+
23+
environmentVariablesSet = true;
24+
}

0 commit comments

Comments
 (0)