diff --git a/README.md b/README.md
index b56f4a6..150042a 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,7 @@ OliveTin gives **safe** and **simple** access to predefined shell commands from
[](https://github.com/OliveTin/OliveTin/actions/workflows/build-snapshot.yml)
+More screenshots below
## Use cases
diff --git a/integration-tests/Makefile b/integration-tests/Makefile
index 8aee41b..9952223 100644
--- a/integration-tests/Makefile
+++ b/integration-tests/Makefile
@@ -1,6 +1,10 @@
-default:
+default: test-install test-run
+
+test-install:
npm install --no-fund
- ./node_modules/.bin/mocha -t 5000
+
+test-run:
+ ./node_modules/.bin/mocha -t 10000
nginx:
podman-compose up -d nginx
diff --git a/integration-tests/lib/elements.js b/integration-tests/lib/elements.js
index 6ab8702..ac2b798 100644
--- a/integration-tests/lib/elements.js
+++ b/integration-tests/lib/elements.js
@@ -1,5 +1,6 @@
import { By } from 'selenium-webdriver'
import fs from 'fs'
+import { Condition } from 'selenium-webdriver'
export async function getActionButtons (webdriver) {
return await webdriver.findElement(By.id('contentActions')).findElements(By.tagName('button'))
@@ -10,3 +11,17 @@ export function takeScreenshot (webdriver) {
fs.writeFileSync('out.png', img, 'base64')
})
}
+
+export async function getRootAndWait() {
+ await webdriver.get(runner.baseUrl())
+ await webdriver.wait(new Condition('wait for initial-marshal-complete', async function() {
+ const body = await webdriver.findElement(By.tagName('body'))
+ const attr = await body.getAttribute('initial-marshal-complete')
+
+ if (attr == 'true') {
+ return true
+ } else {
+ return false
+ }
+ }))
+}
diff --git a/integration-tests/runner.mjs b/integration-tests/runner.mjs
index 71d8fef..d1de479 100644
--- a/integration-tests/runner.mjs
+++ b/integration-tests/runner.mjs
@@ -29,40 +29,57 @@ class OliveTinTestRunner {
class OliveTinTestRunnerStartLocalProcess extends OliveTinTestRunner {
async start (cfg) {
+ let stdout = ""
+ let stderr = ""
+
this.ot = spawn('./../OliveTin', ['-configdir', 'configs/' + cfg + '/'])
const logStdout = process.env.OLIVETIN_TEST_RUNNER_LOG_STDOUT === '1'
- if (logStdout) {
- this.ot.stdout.on('data', (data) => {
+ this.ot.stdout.on('data', (data) => {
+ stdout += data
+
+ if (logStdout) {
console.log(`stdout: ${data}`)
- })
-
- this.ot.stderr.on('data', (data) => {
- console.error(`stderr: ${data}`)
- })
- }
-
- this.ot.on('close', (code) => {
- if (code != null) {
- console.log(`child process exited with code ${code}`)
}
})
- /*
- this.server = await startSomeServer({port: process.env.TEST_PORT});
- console.log(`server running on port ${this.server.port}`);
- */
+ this.ot.stderr.on('data', (data) => {
+ stderr += data
- this.BASE_URL = 'http://localhost:1337/'
-
- await waitOn({
- resources: [this.BASE_URL]
+ if (logStdout) {
+ console.log(`stderr: ${data}`)
+ }
})
+
+ this.ot.on('close', (code) => {
+ if (code != null) {
+ console.log(`OliveTin local process exited with code ${code}`)
+ console.log(stdout)
+ console.log(stderr)
+ console.log(this.ot.exitCode)
+ }
+ })
+
+ if (this.ot.exitCode == null) {
+ this.BASE_URL = 'http://localhost:1337/'
+
+ await waitOn({
+ resources: [this.BASE_URL]
+ })
+
+ console.log(" OliveTin local process started and webUI accessible")
+ } else {
+ console.log(" OliveTin local process start FAILED!")
+ console.log(stdout)
+ console.log(stderr)
+ console.log(this.ot.exitCode)
+ }
}
async stop () {
await this.ot.kill()
+ console.log(" OliveTin local process killed")
}
}
diff --git a/integration-tests/test/entities.js b/integration-tests/test/entities.js
index 53c01cf..9ce1c9d 100644
--- a/integration-tests/test/entities.js
+++ b/integration-tests/test/entities.js
@@ -1,7 +1,7 @@
import { describe, it, before, after } from 'mocha'
import { expect } from 'chai'
import { By, until } from 'selenium-webdriver'
-import { takeScreenshot } from '../lib/elements.js'
+import { getRootAndWait, takeScreenshot } from '../lib/elements.js'
describe('config: entities', function () {
before(async function () {
@@ -13,7 +13,7 @@ describe('config: entities', function () {
})
it('Entity buttons are rendered', async function() {
- webdriver.get(runner.baseUrl())
+ await getRootAndWait()
const buttons = await webdriver.findElement(By.id('root-group')).findElements(By.tagName('button'))
expect(buttons).to.not.be.null
diff --git a/integration-tests/test/general.mjs b/integration-tests/test/general.mjs
index ea384d8..46093c3 100644
--- a/integration-tests/test/general.mjs
+++ b/integration-tests/test/general.mjs
@@ -1,7 +1,8 @@
import { describe, it, before, after } from 'mocha'
import { expect } from 'chai'
-import { By } from 'selenium-webdriver'
+import { By, until, Condition } from 'selenium-webdriver'
//import * as waitOn from 'wait-on'
+import { getRootAndWait } from '../lib/elements.js'
describe('config: general', function () {
before(async function () {
@@ -19,6 +20,16 @@ describe('config: general', function () {
expect(title).to.be.equal("OliveTin")
})
+ it('Page title2', async function () {
+ /*
+ await webdriver.get(runner.baseUrl())
+
+ const title = await webdriver.getTitle()
+ expect(title).to.be.equal("OliveTin")
+ */
+ })
+
+
it('Footer contains promo', async function () {
const ftr = await webdriver.findElement(By.tagName('footer')).getText()
@@ -26,7 +37,7 @@ describe('config: general', function () {
})
it('Default buttons are rendered', async function() {
- await webdriver.get(runner.baseUrl())
+ await getRootAndWait()
const buttons = await webdriver.findElement(By.id('root-group')).findElements(By.tagName('button'))
@@ -34,7 +45,7 @@ describe('config: general', function () {
})
it('Start date action (popup)', async function() {
- await webdriver.get(runner.baseUrl())
+ await getRootAndWait()
const buttons = await webdriver.findElements(By.css('[title="date-popup"]'))
diff --git a/integration-tests/test/multipleDropdowns.js b/integration-tests/test/multipleDropdowns.js
index d87efa8..478fce3 100644
--- a/integration-tests/test/multipleDropdowns.js
+++ b/integration-tests/test/multipleDropdowns.js
@@ -1,7 +1,7 @@
import { describe, it, before, after } from 'mocha'
import { expect } from 'chai'
import { By, until } from 'selenium-webdriver'
-import { getActionButtons } from '../lib/elements.js'
+import { getActionButtons, getRootAndWait } from '../lib/elements.js'
describe('config: multipleDropdowns', function () {
before(async function () {
@@ -13,7 +13,7 @@ describe('config: multipleDropdowns', function () {
})
it('Multiple dropdowns are possible', async function() {
- await webdriver.get(runner.baseUrl())
+ await getRootAndWait()
const buttons = await getActionButtons(webdriver)
diff --git a/webui.dev/js/marshaller.js b/webui.dev/js/marshaller.js
index 1866d38..082457c 100644
--- a/webui.dev/js/marshaller.js
+++ b/webui.dev/js/marshaller.js
@@ -20,6 +20,7 @@ export function marshalDashboardComponentsJsonToHtml (json) {
marshalDashboardStructureToHtml(json)
document.getElementById('username').innerText = json.authenticatedUser
+ document.body.setAttribute('initial-marshal-complete', 'true')
changeDirectory(null)
}