Back to template gallery

Playwright + Chrome Test Runner

Example of using the Playwright Test project to run automated website tests in the cloud and display their results. Usable as an API.

Language

typescript

Tools

nodejs

playwright

chrome

Use cases

Web scraping

src/main.ts

src/runCodegen.ts

src/transform.ts

1import { execSync } from 'node:child_process';
2import fs from 'node:fs';
3import path from 'node:path';
4
5import { Actor, log } from 'apify';
6import type { Dictionary } from 'apify-client';
7
8import { collectAttachmentPaths, transformToTabular } from './transform.js';
9
10function ensureFolder(pathname: string) {
11 if (!fs.existsSync(pathname)) {
12 fs.mkdirSync(pathname, { recursive: true });
13 }
14}
15
16function getConfigPath() {
17 return `${import.meta.dirname}/../playwright.config.ts`;
18}
19
20function getResultDir() {
21 return `${import.meta.dirname}/../playwright-report`;
22}
23
24const getConfig = (options: {
25 screen: { width: number; height: number };
26 headful: boolean;
27 timeout: number;
28 locale: string;
29 darkMode: boolean;
30 ignoreHTTPSErrors: boolean;
31 video: string;
32}) => {
33 const { screen, headful, timeout, ignoreHTTPSErrors, darkMode, locale, video } = options;
34
35 return `
36// Watch out! This file gets regenerated on every run of the actor.
37// Any changes you make will be lost.
38
39// Tweak your configuration through the Actor's input through the Apify console or directly in the \`input.json\` file.
40import { defineConfig } from '@playwright/test';
41export default defineConfig({
42 timeout: ${timeout},
43 use: {
44 headless: ${!headful},
45 viewport: { width: ${screen.width}, height: ${screen.height} },
46 ignoreHTTPSErrors: ${ignoreHTTPSErrors},
47 colorScheme: '${darkMode ? 'dark' : 'light'}',
48 locale: '${locale}',
49 video: '${video}',
50 launchOptions: {
51 args: [
52 '--disable-gpu', // Mitigates the "crashing GPU process" issue in Docker containers
53 ]
54 },
55 },
56 reporter: [
57 ['html', { outputFolder: '${getResultDir()}', open: 'never' }],
58 ['json', { outputFile: '${getResultDir()}/test-results.json' }]
59 ],
60});`;
61};
62function runTests() {
63 try {
64 execSync(`npx playwright test --config=${getConfigPath()}`, {
65 cwd: import.meta.dirname,
66 encoding: 'utf8',
67 stdio: 'inherit',
68 });
69 } catch {
70 // suppress error, the report will be generated anyway
71 }
72}
73
74function updateConfig(args: {
75 screenWidth?: number;
76 screenHeight?: number;
77 headful?: boolean;
78 timeout?: number;
79 darkMode?: boolean;
80 locale?: string;
81 ignoreHTTPSErrors?: boolean;
82 video?: string;
83}) {
84 const {
85 screenWidth = 1280,
86 screenHeight = 720,
87 headful = false,
88 timeout = 60,
89 darkMode = false,
90 locale = 'en-US',
91 ignoreHTTPSErrors = true,
92 video = 'off',
93 } = args;
94
95 const config = getConfig({
96 screen: { width: screenWidth, height: screenHeight },
97 headful,
98 timeout: timeout * 1000,
99 locale,
100 darkMode,
101 ignoreHTTPSErrors,
102 video,
103 });
104 fs.writeFileSync(getConfigPath(), config, { encoding: 'utf-8' });
105}
106
107await Actor.init();
108const input = ((await Actor.getInput()) ?? {}) as Dictionary;
109
110ensureFolder(getResultDir());
111updateConfig(input);
112
113runTests();
114
115const kvs = await Actor.openKeyValueStore();
116await kvs.setValue('report', fs.readFileSync(path.join(getResultDir(), 'index.html'), { encoding: 'utf-8' }), {
117 contentType: 'text/html',
118});
119const jsonReport = JSON.parse(fs.readFileSync(path.join(getResultDir(), 'test-results.json'), { encoding: 'utf-8' }));
120const attachmentPaths = collectAttachmentPaths(jsonReport);
121
122const attachmentLinks = await Promise.all(
123 attachmentPaths.map(async (x) => {
124 const attachment = fs.readFileSync(x.path);
125 await kvs.setValue(x.key, attachment, { contentType: x.type ?? 'application/octet' });
126 return { ...x, url: kvs.getPublicUrl(x.key) };
127 }),
128);
129
130await Actor.pushData(transformToTabular(jsonReport, attachmentLinks));
131
132const reportURL = kvs.getPublicUrl('report');
133log.info('The test run has finished! The report is available in the Output tab or at the link below:');
134log.info(reportURL);
135
136await Actor.exit();

Playwright test template

Run your Playwright tests on the Apify platform effectively and easily. Just set up your test environment using a user-friendly UI and let the platform do the rest.

Note: This is a custom version of Playwright Test Runner Actor. Unlike the original Actor, this version reads test suite files from the tests folder and does not allow you to pass the test files via Apify input.

Features

Run your Playwright tests on the Apify platform

No more pre-commit hooks or CI/CD pipelines. Integrate your tests with the Apify Platform using a user-friendly UI and forget about the hassle of setting up your test environment.

Test configuration with comprehensive UI

Collect and analyze your test results online

After running the tests, the Apify platform stores the results in comprehensive datasets. You can view the results directly on the platform or download them to your local machine using a REST API.

Analyzing understandable test reports

No more problems with incompatible browser versions

Playwright Test toolkit automatically downloads the latest versions of Chromium, Firefox, and WebKit browsers and installs them in the Apify platform.

This way, you can test your websites using all the popular browsers without worrying about compatibility issues.

Testing with multiple browser versions at once

How to use

Just provide your test suite files in the tests folder and run the Actor. The Actor will automatically run all the tests in the tests folder and store the results in the KVS/dataset fields.

You can also customize the test run by specifying other options in the input, e.g. the screen size, headful/headless execution or the maximum run time.

Test Generator

You can also use the Playwright Codegen to compose your test suites even faster. Just run npm run codegen in your project folder and record your workflow.

The code generator will automatically create a test suite file for you and save it in the tests folder.

Resources

Already have a solution in mind?

Sign up for a free Apify account and deploy your code to the platform in just a few minutes! If you want a head start without coding it yourself, browse our Store of existing solutions.