Skip to content

Instantly share code, notes, and snippets.

Last active June 28, 2022 01:36
Show Gist options
  • Save GeorgDangl/f2d65986085da494020edf07a5a6b96f to your computer and use it in GitHub Desktop.
Save GeorgDangl/f2d65986085da494020edf07a5a6b96f to your computer and use it in GitHub Desktop.
Running Fully Automated E2E Tests in Electron in a Docker Container with Playwright:
const path = require('path');
import { _electron } from 'playwright';
export default function setup(): void {
beforeEach(async function () {
this.electronApp = await _electron.launch({
args: ['--disable_splash_screen', path.join(__dirname, '..')]
afterEach(function () {
if (this.electronApp) {
return this.electronApp.close();
FROM node:14 AS node
FROM node AS headless
RUN apt-get update && \
apt-get install -y xvfb \
libgbm1 \
libxss1 \
libnss3 \
libgtk-3-dev \
libasound2-dev \
unzip \
dos2unix \
&& rm -rf /var/lib/apt/lists/*
FROM headless AS final
RUN chmod +x /
RUN dos2unix /
echo "Starting Xvfb"
Xvfb :99 -ac &
sleep 2
export DISPLAY=:99
echo "Executing command $@"
exec "$@"
import { E2eAppConfigService } from './e2e-app-config-service';
import { Page } from 'playwright';
import commonSetup from './common-setup';
import { expect } from 'chai';
describe('my-project-ui App', function () {
let page: Page;
let appConfig: { backendUrl: string };
beforeEach(async function () {
page = await this.electronApp.firstWindow();
appConfig = new E2eAppConfigService().getAppConfig();
it('should display text in header', async function () {
const text = await getText('dangl-header h1');
expect(text).to.contain('header text');
it('creates initial windows', async function () {
const windows = await;
function getText(selector: string): Promise<string> {
return page.textContent(selector);
docker run -v /var/lib/jenkins/workspace/Project/ui/dangl-project-ui:/app/src \
--rm \
--privileged projectname-e2e:dev \
sh -c "cd /app/src/ && \
rm -rf node_modules && \
mkdir node_modules && \
mount -t tmpfs -o rw,size=5G tmpfs node_modules && \
rm -rf dist && \
mkdir dist && \
mount -t tmpfs -o rw,size=1G tmpfs dist && \
npm ci --no-progress && \
npm run e2e:docker"
Copy link

@GeorgDangl thanks for the blog post and for sharing this code. It's immensely helpful. One thing I'm looking for is your "e2e:docker" command in your package.json. I'm assuming it's something like xvfb-run ./node_modules/.bin/playwright test, but I'm curious how that actually looks in your case. Would you mind sharing that bit as well? Thanks.

Copy link

Hey @toddwprice, happy I could help! I’m currently on mobile, so copying it is a bit hard, but it’s not actually calling xvfb or the like, it’s essentially just building the project with a specific configuration (with Hostnames used in e2e etc) and then just starts the tests via mocha.

xvfb is set up in the entry point, and sets the display value. Then, the test code (like in the example above) uses playwright directly to start electron.

Copy link

@GeorgDangl yep I realized my mistake after I went further down the rabbit hole. Your solution already starts Xvfb, so no need to use xvfb-run when kicking off the tests. I'm still have (virtual) screen resolution issues but I think I'm on my way. Thanks for the response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment