fix: #603 - Dashboards that have fieldsets without entities are hidden (#609)

This commit is contained in:
James Read 2025-06-22 22:09:03 +01:00 committed by GitHub
parent e38361f3d7
commit 433456986d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 195 additions and 12 deletions

View File

@ -0,0 +1,26 @@
logLevel: debug
actions:
- title: Ping
- title: Action 1
- title: Action 2
- title: Action 3
- title: Action 4
dashboards:
- title: Test
contents:
# Uncomment to see the dashboard with the "Ping" action only
- title: Ping
- title: Fieldset 1
type: fieldset
contents:
- title: Action 1
- title: Action 2
- title: Fieldset 2
type: fieldset
contents:
- title: Action 3
- title: Action 4

View File

@ -3,8 +3,12 @@ import fs from 'fs'
import { expect } from 'chai'
import { Condition } from 'selenium-webdriver'
export async function getActionButtons (webdriver) {
return await webdriver.findElement(By.id('contentActions')).findElements(By.tagName('button'))
export async function getActionButtons (dashboardTitle = null) {
if (dashboardTitle == null) {
return await webdriver.findElement(By.id('contentActions')).findElements(By.tagName('button'))
} else {
return await webdriver.findElements(By.css('section[title="' + dashboardTitle + '"] button'))
}
}
export function takeScreenshotOnFailure (test, webdriver) {
@ -41,6 +45,56 @@ export async function getRootAndWait() {
}))
}
export async function closeSidebar() {
await webdriver.findElement(By.id('sidebar-toggler-button')).click()
const sidebar = await webdriver.findElement(By.id('mainnav'))
const neededLeft = '-250px' // Assuming sidebar is closed at this position
let lastLeft = ''
await webdriver.wait(new Condition('wait for sidebar to close', async function() {
const left = await sidebar.getCssValue('left')
if (left !== lastLeft) {
lastLeft = left
console.log('Sidebar left changed to: ', left)
return false
} else {
console.log('Sidebar closed, left is: *' + left, left === neededLeft ? ' (as expected)' : '')
return left === neededLeft
}
}), 10000); // Wait up to 10 seconds for the sidebar to close
}
export async function openSidebar() {
await webdriver.findElement(By.id('sidebar-toggler-button')).click()
const sidebar = await webdriver.findElement(By.id('mainnav'))
let lastLeft = 0
await webdriver.wait(new Condition('wait for sidebar to open', async function() {
const left = await sidebar.getCssValue('left')
if (left !== lastLeft) {
lastLeft = left
console.log('Sidebar left changed to: ', left)
return false
} else {
console.log('Sidebar opened, left is: ', left)
return true
}
}));
}
export async function getNavigationLinks() {
const navigationLinks = await webdriver.findElements(By.css('#navigation-links a'))
return navigationLinks
}
export async function requireExecutionDialogStatus (webdriver, expected) {
// It seems that webdriver will not give us text if domStatus is hidden (which it will be until complete)
await webdriver.executeScript('window.executionDialog.domExecutionDetails.hidden = false')

View File

@ -0,0 +1,50 @@
import { describe, it, before, after } from 'mocha'
import { expect } from 'chai'
import { By, until, Condition } from 'selenium-webdriver'
//import * as waitOn from 'wait-on'
import {
getRootAndWait,
getActionButtons,
openSidebar,
getNavigationLinks,
takeScreenshotOnFailure,
} from '../lib/elements.js'
describe('config: dashboards with basic fieldsets', function () {
before(async function () {
await runner.start('dashboardsWithBasicFieldsets')
})
after(async () => {
await runner.stop()
})
afterEach(function () {
takeScreenshotOnFailure(this.currentTest, webdriver);
});
it('Dashboards with basic fieldsets', async function () {
await getRootAndWait()
const title = await webdriver.getTitle()
expect(title).to.be.equal("OliveTin » Test")
const navigationLinks = await getNavigationLinks()
expect(navigationLinks.length).to.be.equal(2, 'Expected the nav to only have 2 links')
const firstLink = await navigationLinks[0]
expect(await firstLink.getAttribute('id')).to.be.equal('showActions', 'Expected the first link to be the actions link')
expect(await firstLink.isDisplayed()).to.be.false
const secondLink = await navigationLinks[1]
expect(await secondLink.getAttribute('href')).to.be.equal('http://localhost:1337/Test', 'Expected the second link to be the test dashboard with basic fieldsets link')
const actionButtons = await getActionButtons('Test')
expect(actionButtons).to.have.length(5, 'Expected 5 action buttons')
const fieldsets = await webdriver.findElements(By.css('section[title="Test"] fieldset'))
expect(fieldsets).to.have.length(3, 'Expected 3 fieldsets in the Test dashboard')
})
})

View File

@ -4,6 +4,8 @@ import { By, until, Condition } from 'selenium-webdriver'
//import * as waitOn from 'wait-on'
import {
getRootAndWait,
openSidebar,
getNavigationLinks,
takeScreenshotOnFailure,
} from '../lib/elements.js'
@ -26,17 +28,15 @@ describe('config: empty dashboards are hidden', function () {
const title = await webdriver.getTitle()
expect(title).to.be.equal("OliveTin")
await webdriver.findElement(By.id('sidebar-toggler-button')).click()
const navigationLinks = await webdriver.findElements(By.css('#navigation-links a'))
console.log('navigationLinks', navigationLinks)
await openSidebar()
const navigationLinks = await getNavigationLinks()
expect(navigationLinks).to.not.be.empty
expect(navigationLinks.length).to.be.equal(1, 'Expected the nav to only have 1 link')
const firstLinkId = await navigationLinks[0].getAttribute('id')
expect(firstLinkId).to.be.equal('showActions', 'Expected the first link to be the actions link')
})
})

View File

@ -56,7 +56,7 @@ describe('config: general', function () {
it('Default buttons are rendered', async function() {
await getRootAndWait()
const buttons = await getActionButtons(webdriver)
const buttons = await getActionButtons()
expect(buttons).to.have.length(8)
})

View File

@ -24,7 +24,7 @@ describe('config: multipleDropdowns', function () {
it('Multiple dropdowns are possible', async function() {
await getRootAndWait()
const buttons = await getActionButtons(webdriver)
const buttons = await getActionButtons()
let button = null
for (const b of buttons) {

View File

@ -0,0 +1,51 @@
import { describe, it, before, after } from 'mocha'
import { assert } from 'chai'
import { By } from 'selenium-webdriver'
import {
getRootAndWait,
getActionButtons,
getNavigationLinks,
openSidebar,
closeSidebar,
takeScreenshotOnFailure,
} from '../lib/elements.js'
describe('config: onlyDashboards', function () {
before(async function () {
await runner.start('onlyDashboards')
})
after(async () => {
await runner.stop()
})
afterEach(function () {
takeScreenshotOnFailure(this.currentTest, webdriver);
});
it('When there are only dashboards, actions are hidden', async function () {
await getRootAndWait()
await openSidebar()
const navLinks = await getNavigationLinks()
const actionsLink = navLinks[0];
assert.isNotNull(actionsLink, 'Actions link should not be null')
assert.equal(await actionsLink.getAttribute('title'), 'Actions', 'Actions link should have the title "Actions"')
assert.isFalse(await actionsLink.isDisplayed(), 'Actions link should not be displayed when there are only dashboards')
const firstDashboardLink = await webdriver.findElement(By.css('li[title="My Dashboard"]'), 'The first dashboard link should be present')
assert.isNotNull(firstDashboardLink, 'First dashboard link should not be null')
assert.isTrue(await firstDashboardLink.isDisplayed(), 'First dashboard link should be displayed')
const actionButtons = await getActionButtons()
assert.isArray(actionButtons, 'Action buttons should be an array')
assert.lengthOf(actionButtons, 0, 'Action buttons should be empty when everything is added to the dashboard')
const actionButtonsOnDashboard = await getActionButtons('MyDashboard')
assert.isArray(actionButtonsOnDashboard, 'Action buttons on dashboard should be an array')
assert.lengthOf(actionButtonsOnDashboard, 3, 'Action buttons on dashboard should have 3 buttons')
})
})

View File

@ -60,8 +60,10 @@ func getDashboardComponentContents(dashboard *config.DashboardComponent, rr *Das
}
func buildDashboardComponentSimple(subitem *config.DashboardComponent, rr *DashboardRenderRequest) *apiv1.DashboardComponent {
if !slices.Contains(rr.AllowedActionTitles, subitem.Title) {
return nil
if subitem.Type == "" || subitem.Type == "link" {
if !slices.Contains(rr.AllowedActionTitles, subitem.Title) {
return nil
}
}
newitem := &apiv1.DashboardComponent{