Skip to content

Commit

Permalink
Implement admin GUI testing
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed Oct 25, 2023
1 parent 01bc27f commit be6b68d
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
"@alcalzone/release-script": "^3.6.0",
"@alcalzone/release-script-plugin-iobroker": "^3.6.0",
"@alcalzone/release-script-plugin-license": "^3.5.9",
"@iobroker/legacy-testing": "^1.0.1",
"@types/iobroker": "^5.0.6",
"@types/jsonwebtoken": "^9.0.4",
"@types/node": "^20.8.8",
"puppeteer": "^21.4.1",
"@typescript-eslint/eslint-plugin": "^6.9.0",
"chai": "^4.3.10",
"eslint": "^8.52.0",
Expand Down
104 changes: 104 additions & 0 deletions test/engineHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const fs = require('fs');
const setup = require('@iobroker/legacy-testing');

let rootDir = `${__dirname}/../../../`;
let objects = null;
let states = null;
let onStateChanged = null;

function deleteFoldersRecursive(path) {
if (path.endsWith('/')) {
path = path.substring(0, path.length - 1);
}
if (fs.existsSync(path)) {
const files = fs.readdirSync(path);
for (const file of files) {
const curPath = `${path}/${file}`;
const stat = fs.statSync(curPath);
if (stat.isDirectory()) {
deleteFoldersRecursive(curPath);
fs.rmdirSync(curPath);
} else {
fs.unlinkSync(curPath);
}
}
}
}

function startIoBroker(adapterName, options) {
options = options || {};
if (options.rootDir) {
rootDir = options.rootDir;
}

return new Promise(async resolve => {
// delete the old project
deleteFoldersRecursive(`${rootDir}tmp/screenshots`);

await setup.setOfflineState(`system.adapter.${adapterName}.0.alive`, { val: false });

setup.setupController(null, async systemConfig => {
// disable statistics and set license accepted
systemConfig.common.licenseConfirmed = true;
systemConfig.common.diag = 'none';
await setup.setObject('system.config', systemConfig);

// lets the web adapter start on port 18080
const config = await setup.getAdapterConfig(0, adapterName);
if (config && config.common) {
config.common.enabled = true;
await setup.setAdapterConfig(config.common, config.native, 0, adapterName);
}

setup.startController(
false, // do not start widgets
(/* id, obj */) => {},
(id, state) => onStateChanged && onStateChanged(id, state),
async (_objects, _states) => {
objects = _objects;
states = _states;
setup.startCustomAdapter(adapterName, 0);
await checkIsWelcomeStartedAsync(states);
resolve({ objects, states });
});
});
});
}

async function stopIoBroker(adapterName) {
await setup.stopCustomAdapter(adapterName, 0);

await new Promise(resolve =>
setup.stopController(normalTerminated => {
console.log(`Adapter normal terminated: ${normalTerminated}`);
resolve();
}));
}

function checkIsWelcomeStarted(adapterName, states, cb, counter) {
counter = counter === undefined ? 20 : counter;
if (counter === 0) {
return cb && cb(`Cannot check value Of State system.adapter.${adapterName}.0.alive`);
}

states.getState(`system.adapter.${adapterName}.0.alive`, (err, state) => {
console.log(`[${counter}]Check if ${adapterName} is started "system.adapter.${adapterName}.0.alive" = ${JSON.stringify(state)}`);
err && console.error(err);
if (state && state.val) {
cb && cb();
} else {
setTimeout(() =>
checkIsWelcomeStarted(states, cb, counter - 1), 500);
}
});
}

function checkIsWelcomeStartedAsync(adapterName, states, counter) {
return new Promise(resolve => checkIsWelcomeStarted(adapterName, states, resolve, counter));
}

module.exports = {
startIoBroker,
stopIoBroker,
setOnStateChanged: cb => onStateChanged = cb
};
66 changes: 66 additions & 0 deletions test/guiHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const puppeteer = require('puppeteer');
const { blue, cyan, red, yellow } = require('colorette');
const fs = require('fs');

const rootDir = `${__dirname}/../`;
let gBrowser;
let gPage;

async function startBrowser(adapterName, headless) {
const browser = await puppeteer.launch({
headless: headless === undefined ? false : headless,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const pages = await browser.pages();
const timeout = 5000;
pages[0].setDefaultTimeout(timeout);

await pages[0].setViewport( {
width: 1920,
height: 1080,
deviceScaleFactor: 1
});

gBrowser = browser;
gPage = pages[0];

// LOGGING
gPage
.on('console', message => {
const type = message.type().substr(0, 3).toUpperCase();
const colors = {
LOG: text => text,
ERR: red,
WAR: yellow,
INF: cyan
};

const color = colors[type] || blue;
console.log(color(`[BROWSER] ${type} ${message.text()}`));
})
.on('pageerror', ({ message }) => console.log(red(`[BROWSER] ${message}`)));

await gPage.goto(`http://127.0.0.1:8081/#tab-instances/config/system.adapter.${adapterName}.0`, { waitUntil: 'domcontentloaded' });

// Create directory
!fs.existsSync(`${rootDir}tmp/screenshots`) && fs.mkdirSync(`${rootDir}tmp/screenshots`);
await gPage.screenshot({ path: `${rootDir}tmp/screenshots/00_starting.png` });

return { browser, page: pages[0] };
}

async function stopBrowser(browser) {
browser = browser || gBrowser;
await browser.close();
}

async function screenshot(page, fileName) {
page = page || gPage;
await page.screenshot({ path: `${rootDir}tmp/screenshots/${fileName}.png` });
}

module.exports = {
startBrowser,
stopBrowser,
screenshot
};
28 changes: 28 additions & 0 deletions test/testAdapter.gui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const engineHelper = require('./engineHelper');
const guiHelper = require('./guiHelper');
const adapterName = require('../package.json').name.replace('iobroker.', '');
let gPage;

describe('test-admin-gui', () => {
before(async function (){
this.timeout(240_000);

// install js-controller, web and vis-2-beta
await engineHelper.startIoBroker(adapterName);
const { page } = await guiHelper.startBrowser(adapterName, process.env.CI === 'true');
gPage = page;
});

it('Check web server', async function (){
this.timeout(5_000);
await gPage.waitForSelector('.MuiAvatar-root', { timeout: 5_000 });
});

after(async function () {
this.timeout(5000);
await guiHelper.stopBrowser();
console.log('BROWSER stopped');
await engineHelper.stopIoBroker();
console.log('ioBroker stopped');
});
});

0 comments on commit be6b68d

Please sign in to comment.