Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
- v1

jobs:
test:
test-web:
strategy:
matrix:
version: [ 20, 22, 24 ]
Expand All @@ -23,9 +23,30 @@ jobs:
- run: npm run test
- run: npm run install:browsers
- run: npm run test:e2e
- name: junit report
- name: junit report (web)
uses: mikepenz/action-junit-report@v4
if: always()
with:
report_paths: './test-e2e/report.xml'
fail_on_failure: true
test-electron:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- run: npm ci
- run: npm run build
- run: npm run test
- name: setup virtual display
run: |
export DISPLAY=:99
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
- run: xvfb-run --auto-servernum --server-args="-screen 0 1280x720x24" npm run test:e2e:electron
- name: junit report (electron)
uses: mikepenz/action-junit-report@v4
if: always()
with:
report_paths: './test-e2e/report.xml'
fail_on_failure: true
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how

:microscope: - experimental

## [Unreleased]
- :rocket: added step to interact with electron app menu
```gherkin
When I click 'Test > Open Page' electron menu
```

## [2.9.0]
- :rocket: added capability to execute script on electron main process
```gherkin
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
"scripts": {
"build": "tsc",
"test": "vitest --coverage run",
"install:browsers": "playwright install",
"install:browsers": "playwright install chromium",
"test:e2e": "qavajs run --config test-e2e/webui.ts",
"test:e2e:electron": "qavajs run --config test-e2e/webui.ts --profile electron",
"debug:e2e:electron": "qavajs run --config test-e2e/webui.ts --profile electron",
"debug:e2e:electron": "qavajs run --config test-e2e/webui.ts --profile debugElectron",
"debug:e2e": "qavajs run --config test-e2e/webui.ts --profile debug"
},
"repository": {
Expand Down
23 changes: 23 additions & 0 deletions src/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,27 @@ When('I execute {value} function/script on electron app', async function (fn: Me
*/
When('I execute {value} function/script on electron app and save result as {value}', async function (fn: MemoryValue, memoryKey: MemoryValue) {
memoryKey.set(await this.playwright.driver.evaluate(await fn.value()));
});

/**
* Click electron menu
* @param {string} menuPath - menu path
* @example I click 'File > Edit' electron menu
*/
When('I click {value} electron menu', async function (menu: MemoryValue) {
await this.playwright.driver.evaluate(async ({ Menu }: { Menu: any }, { menuPath }: { menuPath: string }) => {
const path = menuPath.split(/\s*>\s*/) as string[];
const menu = Menu.getApplicationMenu();
if (!menu) throw new Error('Menu is not set');
const firstMenu = path.shift() as string;
const findItemPredicate = (item: string) => (menu: any) => menu.label === item || menu.role === item;
let currentMenu = menu.items.find(findItemPredicate(firstMenu));
if (!currentMenu) throw new Error(`Menu '${firstMenu}' is not found`);
for (const pathItem of path) {
if (!currentMenu?.submenu) throw new Error(`Menu '${pathItem}' does not have submenu`);
currentMenu = currentMenu.submenu.items.find(findItemPredicate(pathItem));
if (!currentMenu) throw new Error(`Menu '${pathItem}' is not found`);
}
currentMenu.click()
}, { menuPath: await menu.value() });
});
20 changes: 7 additions & 13 deletions test-e2e/apps/electron/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const { app, BrowserWindow, ipcMain } = require('electron')
const { app, BrowserWindow, ipcMain, Menu } = require('electron')
const path = require('node:path')
const menuTemplate = require('./menuTemplate');
const handleOpenNewWindow = require('./newWindow');

function createWindow () {
const mainWindow = new BrowserWindow({
Expand All @@ -10,20 +12,9 @@ function createWindow () {
}
})

mainWindow.loadFile('index.html')
return mainWindow.loadFile('index.html')
}

function handleOpenNewWindow() {
const newWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

newWindow.loadFile('newWindow.html')
}
app.whenReady().then(() => {
createWindow()

Expand All @@ -38,6 +29,9 @@ app.whenReady().then(() => {
}
event.returnValue = null
})

const menu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(menu);
})

app.on('window-all-closed', function () {
Expand Down
34 changes: 34 additions & 0 deletions test-e2e/apps/electron/menuTemplate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const handleOpenNewWindow = require("./newWindow");

module.exports = [
{
label: 'Default',
submenu: [
{
label: 'Open Page',
click: () => {
handleOpenNewWindow()
}
}
]
},
{
label: 'Test',
submenu: [
{
label: 'Open Page',
click: () => {
handleOpenNewWindow()
}
}
]
},
{
label: 'Help',
submenu: [
{
role: 'about',
}
]
}
];
14 changes: 14 additions & 0 deletions test-e2e/apps/electron/newWindow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const { BrowserWindow } = require('electron')
const path = require('node:path')

module.exports = function handleOpenNewWindow() {
const newWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

newWindow.loadFile('newWindow.html')
}
7 changes: 6 additions & 1 deletion test-e2e/features/electron/electron.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ Feature: electron

Scenario: evaluate script on main process and save result to memory
* I execute '$js(async ({ app }) => app.getAppPath())' script on electron app and save result as 'appPath'
* I expect '$appPath' memory value to contain 'test-e2e/apps/electron'
* I expect '$appPath' memory value to contain 'test-e2e/apps/electron'

Scenario: open menu
* I click 'Test > Open Page' electron menu
* I switch to 'qavajs electron app new window' window
* I click 'Close Current Window Electron Button'
14 changes: 9 additions & 5 deletions test-e2e/webui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const common = {
video: {
event: ['onFail'],
dir: 'video',
size: { width: 800, height: 600 },
size: {width: 800, height: 600},
attach: true
},
screenshot: {
Expand All @@ -34,7 +34,7 @@ const common = {
},
format: [
'@qavajs/console-formatter',
'junit:test-e2e/report.xml',
['junit', 'test-e2e/report.xml'],
['@qavajs/html-formatter', 'test-e2e/report.html']
],
formatOptions: {
Expand Down Expand Up @@ -76,7 +76,7 @@ export const debug = {
video: {
event: ['afterScenario'],
dir: 'video',
size: { width: 800, height: 600 },
size: {width: 800, height: 600},
attach: true
}
},
Expand All @@ -87,17 +87,21 @@ export const electron = {
...common,
paths: ['test-e2e/features/electron/*.feature'],
retry: 0,
// tags: '@debug',
browser: {
logLevel: 'warn',
timeout: {
page: 5000
},
capabilities: {
browserName: 'electron',
args: ['test-e2e/apps/electron/main.js'],
args: ['test-e2e/apps/electron/main.js', '--no-sandbox', '--disable-dev-shm-usage', '--disable-gpu'],
headless: false
}
},
parallel: 1
}

export const debugElectron = {
...electron,
tags: '@debug',
}