Skip to content

Instantly share code, notes, and snippets.

@GeorgDangl
Last active June 28, 2022 01:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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: https://blog.dangl.me/archive/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
ADD docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
RUN dos2unix /docker-entrypoint.sh
EXPOSE 9515
ENV ELECTRON_ENABLE_STACK_DUMPING=true
ENV ELECTRON_ENABLE_LOGGING=true
ENTRYPOINT [ "/docker-entrypoint.sh" ]
#!/bin/bash
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 () {
commonSetup.apply(this);
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 this.electronApp.windows();
expect(windows.length).to.equal(1);
});
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 \
--network="e2e7e965ac9ae_default"\
--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"
@toddwprice
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.

@GeorgDangl
Copy link
Author

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.

@toddwprice
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