Skip to content
This repository has been archived by the owner on Jan 1, 2025. It is now read-only.

Creating End‐to‐End Tests

Sim edited this page Jul 26, 2023 · 15 revisions

This guide will walk you through how to create end-to-end (e2e) tests using the Playwright framework. The examples are based on the existing installer.spec.js test file. Adjust as needed for your tests.

1. Choose a test file

Test files are created by feature. As of the writing of this doc, there is only src/tests/e2e/installer.spec.js, which covers tests for the installer feature of the launcher.

If there is no test file for the feature you want to test, create it. Make sure the name is descriptive of the feature, and try to keep it short and sweet. The name should follow this format: .spec.js

2. Initialize Dependencies

At the start of your test file, import all the necessary dependencies.

const { _electron: electron } = require( 'playwright' );
const { test, expect } = require( '@playwright/test' );
const { findLatestBuild, parseElectronApp, stubDialog } = require( 'electron-playwright-helpers' );
const { promisify } = require( 'util' );

const path = require( 'path' );
const exec = promisify( require( 'child_process' ).exec );
const fs = require( 'fs-extra' );

3. Define Global Variables

Declare your global variables that will be used across multiple tests.

let window;
let electronApp;
let latestBuild;
let appInfo;
let exeDir;
let appData;
let installDir;

4. Set Up Test Hooks

The beforeAll hook runs once before all tests. Here you can initialize global setup operations.

test.beforeAll( () => {
  // Add setup logic here
} );

The beforeEach hook runs before each test. It's typically used to set up test conditions and initialize variables.

test.beforeEach( async () => {
  // Add setup logic here
} );

The afterEach hook is used for cleanup operations that need to be executed after each test.

test.afterEach( async () => {
  // Add cleanup logic here
} );

5. Write Tests

Write your tests within a test() function call. Define a test name and an asynchronous function that contains the test code.

test( 'My Test', async () => {
  // Add test logic here
} );

6. Test Actions

Use the following actions in your tests to interact with the app. Consult the Playwright docs for more ways to interact with the app via tests:

Navigation:

await window.click( '[page-trigger="installer"]' ); // Click a button or link
await window.waitForSelector( '#full-install-button' ); // Wait for an element to be visible

Validate conditions:

expect( await window.isVisible( '.modal-error' ) ).toBeFalsy(); // Assert a condition

Read contents of HTML elements using CSS selectors:

const dl = await window.waitForSelector( '#downloads-page .download' );
const dlTitle = await ( await dl.$( '.progress-title' ) ).textContent();
const dlId = await dl.getAttribute( 'id' );

expect( dlTitle.toLowerCase() ).toContain( 'simitone' );

Stub native Electron dialogs. :

await stubDialog( electronApp, 'showOpenDialog', { filePaths: [ 'C:\\example' ] } );

^ Native dialogs always have to be stubbed, because they are blocking and pause the execution of tests. Since we are not real users running the app, we cannot click on the native dialog and it cannot be simulated

7. Handling Different Platforms

You can handle platform-specific code using the process.platform variable.

if ( process.platform === 'win32' ) {
  // Windows-specific code
} else {
  // MacOS-specific code
}

8. Performing Cleanup Actions

Use an afterEach hook to perform cleanup actions after each test, such as closing the app.

test.afterEach( async () => {
  await electronApp.close();
} );

9. Handling Errors

Add try/catch blocks to handle potential errors during execution that SHOULDN'T cause test failures. ((Which should be RARE))

try {
  // Potentially error-prone code
} catch ( err ) {
  console.error( 'An error occurred:', err );
}

10. Finishing Up

Remember to save your test file with a .spec.js extension, and place it in the src/tests/e2e folder. Playwright's test runner will automatically recognize and run these test files.

Keep adding more tests to your file to cover all the various features and functionalities of the launcher. This way, you'll ensure that everything works as expected and any breaking changes are quickly identified before a release is sent out to end users.