Browse Source

More screenshots link (#289)

* More screenshots link

* bugfix: wip

* cicd: Test flakey tests

* cicd: more tests

* cicd: more tests

* cicd: Try a 10s timeout

* cicd: Better debugging of process start / stop

* cicd: Better debugging of process start / stop

* cicd: Possibly unflaky tests
James Read 2 years ago
parent
commit
a3aee3603f

+ 1 - 0
README.md

@@ -12,6 +12,7 @@ OliveTin gives **safe** and **simple** access to predefined shell commands from
 [![Build Snapshot](https://github.com/OliveTin/OliveTin/actions/workflows/build-snapshot.yml/badge.svg)](https://github.com/OliveTin/OliveTin/actions/workflows/build-snapshot.yml)
 
 <img alt = "screenshot" src = "https://github.com/OliveTin/OliveTin/blob/main/var/marketing/screenshotDesktop.png" />
+<a href = "#screenshots">More screenshots below</a>
 
 ## Use cases
 

+ 6 - 2
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

+ 15 - 0
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
+      }
+    }))
+}

+ 33 - 16
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.stderr.on('data', (data) => {
+      stderr += data
+
+      if (logStdout) {
+        console.log(`stderr: ${data}`)
+      }
+    })
 
     this.ot.on('close', (code) => {
       if (code != null) {
-        console.log(`child process exited with code ${code}`)
+        console.log(`OliveTin local process exited with code ${code}`)
+        console.log(stdout)
+        console.log(stderr)
+        console.log(this.ot.exitCode)
       }
     })
 
-    /*
-      this.server = await startSomeServer({port: process.env.TEST_PORT});
-      console.log(`server running on port ${this.server.port}`);
-      */
+    if (this.ot.exitCode == null) {
+      this.BASE_URL = 'http://localhost:1337/'
 
-    this.BASE_URL = 'http://localhost:1337/'
+      await waitOn({
+        resources: [this.BASE_URL]
+      })
 
-    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")
   }
 }
 

+ 2 - 2
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

+ 14 - 3
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"]'))
 

+ 2 - 2
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)
 

+ 1 - 0
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)
 }