test: improved e2e tests

This commit is contained in:
Fabio Di Stasio 2022-04-25 18:26:11 +02:00
parent 8b04a2b7dd
commit daef6f91b0
7 changed files with 73 additions and 56 deletions

View File

@ -19,7 +19,8 @@
"release": "standard-version", "release": "standard-version",
"release:pre": "npm run release -- --prerelease alpha", "release:pre": "npm run release -- --prerelease alpha",
"postinstall": "electron-builder install-app-deps", "postinstall": "electron-builder install-app-deps",
"test": "npm run compile && node tests/app.spec.js", "test": "npm run compile && npm run test:dry",
"test:dry": "xvfb-maybe -- playwright test",
"lint": "eslint . --ext .js,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"", "lint": "eslint . --ext .js,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"",
"lint:fix": "eslint . --ext .js,.vue --fix && stylelint \"./src/**/*.{css,scss,sass,vue}\" --fix", "lint:fix": "eslint . --ext .js,.vue --fix && stylelint \"./src/**/*.{css,scss,sass,vue}\" --fix",
"contributors:add": "all-contributors add", "contributors:add": "all-contributors add",
@ -138,6 +139,7 @@
"@babel/eslint-parser": "^7.15.7", "@babel/eslint-parser": "^7.15.7",
"@babel/preset-env": "^7.15.8", "@babel/preset-env": "^7.15.8",
"@babel/preset-typescript": "^7.16.7", "@babel/preset-typescript": "^7.16.7",
"@playwright/test": "^1.21.1",
"@types/better-sqlite3": "^7.5.0", "@types/better-sqlite3": "^7.5.0",
"@types/node": "^17.0.23", "@types/node": "^17.0.23",
"@types/pg": "^8.6.5", "@types/pg": "^8.6.5",
@ -162,7 +164,8 @@
"html-webpack-plugin": "^5.5.0", "html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "~2.4.5", "mini-css-extract-plugin": "~2.4.5",
"node-loader": "^2.0.0", "node-loader": "^2.0.0",
"playwright": "^1.18.1", "playwright": "^1.21.1",
"playwright-core": "^1.21.1",
"progress-webpack-plugin": "^1.0.12", "progress-webpack-plugin": "^1.0.12",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"sass": "^1.42.1", "sass": "^1.42.1",
@ -179,6 +182,7 @@
"vue-loader": "^16.8.3", "vue-loader": "^16.8.3",
"webpack": "^5.60.0", "webpack": "^5.60.0",
"webpack-cli": "^4.9.1", "webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0" "webpack-dev-server": "^4.4.0",
"xvfb-maybe": "^0.2.1"
} }
} }

View File

@ -50,7 +50,11 @@
<label class="form-label cut-text">{{ $t('word.client') }}</label> <label class="form-label cut-text">{{ $t('word.client') }}</label>
</div> </div>
<div class="column col-8 col-sm-12"> <div class="column col-8 col-sm-12">
<select v-model="connection.client" class="form-select"> <select
id="connection-client"
v-model="connection.client"
class="form-select"
>
<option <option
v-for="client in clients" v-for="client in clients"
:key="client.slug" :key="client.slug"
@ -363,6 +367,7 @@
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button <button
id="connection-test"
class="btn btn-gray mr-2 d-flex" class="btn btn-gray mr-2 d-flex"
:class="{'loading': isTesting}" :class="{'loading': isTesting}"
:disabled="isBusy" :disabled="isBusy"
@ -372,6 +377,7 @@
{{ $t('message.testConnection') }} {{ $t('message.testConnection') }}
</button> </button>
<button <button
id="connection-save"
class="btn btn-primary mr-2 d-flex" class="btn btn-primary mr-2 d-flex"
:disabled="isBusy" :disabled="isBusy"
@click="saveConnection" @click="saveConnection"

View File

@ -355,6 +355,7 @@
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button <button
id="connection-test"
class="btn btn-gray mr-2 d-flex" class="btn btn-gray mr-2 d-flex"
:class="{'loading': isTesting}" :class="{'loading': isTesting}"
:disabled="isBusy" :disabled="isBusy"
@ -364,6 +365,7 @@
{{ $t('message.testConnection') }} {{ $t('message.testConnection') }}
</button> </button>
<button <button
id="connection-save"
class="btn btn-primary mr-2 d-flex" class="btn btn-primary mr-2 d-flex"
:disabled="isBusy || !hasChanges" :disabled="isBusy || !hasChanges"
@click="saveConnection" @click="saveConnection"
@ -372,6 +374,7 @@
{{ $t('word.save') }} {{ $t('word.save') }}
</button> </button>
<button <button
id="connection-connect"
class="btn btn-success d-flex" class="btn btn-success d-flex"
:class="{'loading': isConnecting}" :class="{'loading': isConnecting}"
:disabled="isBusy" :disabled="isBusy"

View File

@ -16,9 +16,9 @@ export default {
}, },
getters: { getters: {
getSelected: state => { getSelected: state => {
if (!state.workspaces.length) return 'NEW';
if (state.selected_workspace) return state.selected_workspace; if (state.selected_workspace) return state.selected_workspace;
if (state.workspaces.length) return state.workspaces[0].uid; return state.workspaces[0].uid;
return 'NEW';
}, },
getWorkspace: state => uid => { getWorkspace: state => uid => {
return state.workspaces.find(workspace => workspace.uid === uid); return state.workspaces.find(workspace => workspace.uid === uid);

View File

@ -1,49 +0,0 @@
const { _electron: electron } = require('playwright');
const { strict: assert } = require('assert');
(async () => {
console.log('Starting tests');
// Launch Electron app.
const electronApp = await electron.launch({ args: ['dist/main.js'] });
/**
* App main window state
* @type {{isVisible: boolean; isDevToolsOpened: boolean; isCrashed: boolean}}
*/
const windowState = await electronApp.evaluate(({ BrowserWindow }) => {
const mainWindow = BrowserWindow.getAllWindows()[0];
const getState = () => ({
isVisible: mainWindow.isVisible(),
isDevToolsOpened: mainWindow.webContents.isDevToolsOpened()
});
return new Promise((resolve) => {
if (mainWindow.isVisible())
resolve(getState());
else
mainWindow.once('ready-to-show', () => setTimeout(() => resolve(getState()), 0));
});
});
// Check main window state
assert.ok(windowState.isVisible, 'Main window not visible');
assert.ok(!windowState.isDevToolsOpened, 'DevTools opened');
assert.ok(!windowState.isCrashed, 'Window crashed');
/**
* Rendered Main window web-page
* @type {Page}
*/
const page = await electronApp.firstWindow();
console.log(await page.title());
// Check web-page content
const element = await page.$('#wrapper', { strict: true });
assert.notStrictEqual(element, null, 'Can\'t find root element');
assert.notStrictEqual((await element.innerHTML()).trim(), '', 'Window content is empty');
// Close app
await electronApp.close();
console.log('Tests finished');
})();

49
tests/app.spec.ts Normal file
View File

@ -0,0 +1,49 @@
import { Page, _electron as electron } from 'playwright';
import { ElectronApplication } from 'playwright-core';
import { test, expect } from '@playwright/test';
let appWindow: Page;
let electronApp: ElectronApplication;
test.beforeAll(async () => {
electronApp = await electron.launch({ args: ['dist/main.js'] });
appWindow = await electronApp.firstWindow();
await appWindow.waitForEvent('load');
});
test('launch app', async () => {
const isPackaged = await electronApp.evaluate(async ({ app }) => {
return app.isPackaged;
});
expect(isPackaged, 'expect is unpacked').toBe(false);
});
test('main window elements visibility', async () => {
const visibleSelectors = [
'#titlebar',
'#window-content',
'#settingbar',
'#footer'
];
for (const selector of visibleSelectors)
expect(await appWindow.isVisible(selector), `expect ${selector} visible`).toBe(true);
});
// test('SQLite connection', async () => {// FIXME: not working on GitHub Actions
// await appWindow.selectOption('#connection-client', 'sqlite');// Select connection client
// await appWindow.click('#connection-test');// Press test button
// await new Promise(resolve => setTimeout(resolve, 50)); // Small toast wait
// await appWindow.isVisible('.toast-primary');// If success toast
// await appWindow.click('#connection-save');// Save connection
// await appWindow.isVisible('.settingbar-top-elements .settingbar-element .dbi-sqlite');// If new connection in settingbar
// await appWindow.click('#connection-connect');// Connect
// // TODO: continue test chain
// });
test.afterAll(async () => {
// await new Promise(resolve => setTimeout(resolve, 10000));
await electronApp.close();
});

View File

@ -1,5 +1,9 @@
{ {
"include": ["./src/main/**/*", "src/common/interfaces/antares.ts"], "include": [
"./tests/**/*",
"./src/main/**/*",
"./src/common/interfaces/antares.ts"
],
"compilerOptions": { "compilerOptions": {
"baseUrl": "./", "baseUrl": "./",
"target": "es2021", "target": "es2021",