Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

--- develop ---

* issue#449: Contrast Hollyberry details dots against a neutral badge and darken amber and grey row markers
* issue#447: Improve Deepness green and red row marker contrast on dark surfaces
* issue#444: Brighten Dark theme red row markers while preserving panel header colors
* issue#442: Keep Carrot theme status indicators legible on coral details titlebars and light table rows
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ The Deepness fixture checks contrasting green and red row markers on dark
surfaces. See [Deepness theme validation](docs/deepness-theme.md) for screenshots
and reproduction commands.

![Hollyberry dashboard with seeded measurements and alerts](images/hollyberry-theme-dashboard.png)

The Hollyberry fixture checks readable details dots and row markers. See
[Hollyberry theme validation](docs/hollyberry-theme.md) for screenshots and tests.

## Requirements

- Cacti 1.2.17 or later (the `compat` value in the `INFO` file). The plugin is
Expand Down
18 changes: 16 additions & 2 deletions css/hollyberry.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
}

.color_yellow_bubble {
color: #e08a1e;
color: #9a5700;
}

.color_yellow, .color_yellow i {
Expand All @@ -66,9 +66,23 @@
}

.color_grey_bubble {
color: #a1a1a1;
color: #737373;
}

.color_grey, .color_grey i {
color: black !important;
}

/* A neutral badge separates details dots from the title gradient. */
#overlay_detail .cactiTableButton {
background: #fff;
border-radius: 11px;
}

.inpa_sq.color_yellow {
background: #a45d00 !important;
}

.inpa_sq.color_grey {
background: #737373 !important;
}
47 changes: 47 additions & 0 deletions docs/hollyberry-theme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Hollyberry theme validation

Hollyberry details dots sit on a neutral badge so their colors remain visible
against the core title gradient. Amber and grey row markers use darker colors
on light rows. Panel header backgrounds and text colors retain their palette.

## Populated browser fixtures

The screenshots use actual core and plugin Hollyberry stylesheets with synthetic
devices, response times, poller totals, and warning/error messages. They show
browser fixtures, not a live installation or production monitoring data.

![Hollyberry dashboard with populated monitoring panels](../images/hollyberry-theme-dashboard.png)

The browser test opens the real jQuery UI details dialog, checks its alert data,
and closes it.

![Hollyberry details with synthetic warning and error rows](../images/hollyberry-theme-status.png)

## Reproduce

Use the setup in [Cacti theme validation](cacti-theme.md). Set `CACTI_ROOT` to the
adjacent core checkout and run from the plugin root:

```sh
NODE_PATH="$CACTI_ROOT/tests/e2e/node_modules" mise exec node@22 -- node \
"$CACTI_ROOT/tests/e2e/node_modules/@playwright/test/cli.js" test \
--config tests/e2e/playwright.config.cjs
```

Set `UPDATE_THEME_SCREENSHOTS=1` to regenerate committed screenshots. The tests
check all four severity colors on odd, even, and page surfaces, including alpha
composition and samples at sRGB gradient endpoints and quarter points. Indicators
must meet 3:1 contrast against their backgrounds. Sampling does not prove contrast
at every pixel or against arbitrary background images.

After committing, measure changed CSS line coverage:

```sh
mise exec python@3.12 -- python "$CACTI_ROOT/tests/tools/report_changed_coverage.py" \
--base fix/deepness-theme-status-contrast --language css --minimum 100 \
--browser-root tests/e2e/test-results
```

This PR extends the shared browser and alpha-aware contrast tests above the
Deepness layer. Use `origin/develop` after the lower stack layers merge. The gate
measures executed changed CSS lines, not whole-plugin or branch coverage.
Binary file added images/hollyberry-theme-dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/hollyberry-theme-status.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions tests/e2e/cacti-theme.spec.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ async function installCss(page, file) {
await page.addStyleTag({ url: 'http://cacti-theme.test/' + path });
}

for (const theme of ['cacti', 'carrot', 'dark', 'deepness']) {
for (const theme of ['cacti', 'carrot', 'dark', 'deepness', 'hollyberry']) {
test(`${theme} seeded dashboard displays measurements and opens alert details`, async ({ page }, info) => {
await page.setViewportSize({ width: 1140, height: 520 });
await page.setContent(readFileSync(resolve(root, 'tests/fixtures/Ui/cacti-theme.html'), 'utf8').replaceAll('Cacti theme', `${theme[0].toUpperCase() + theme.slice(1)} theme`));
Expand Down Expand Up @@ -65,7 +65,7 @@ test.afterEach(async ({ page }, info) => {
writeFileSync(info.outputPath('changed-coverage.json'), JSON.stringify(coverage));
});

for (const theme of ['cacti', 'carrot', 'dark', 'deepness']) {
for (const theme of ['cacti', 'carrot', 'dark', 'deepness', 'hollyberry']) {
for (const row of ['odd', 'even', '']) {
test(`${theme} severity indicators contrast with titlebars and ${row || 'white'} rows`, async ({ page }) => {
await page.setContent('<!DOCTYPE html><div id="overlay_detail">' + ['green', 'red', 'yellow', 'grey'].map(color =>
Expand Down Expand Up @@ -97,7 +97,9 @@ for (const theme of ['cacti', 'carrot', 'dark', 'deepness']) {
const image = getComputedStyle(e).backgroundImage;
if (image.startsWith('linear-gradient(')) {
const stops = (image.match(/rgba?\([^)]+\)/g) || []).map(rgba);
surfaces = surfaces.flatMap(bg => stops.map(stop => over(stop, bg)));
const samples = stops.flatMap((stop, index) => index === 0 ? [stop] :
[.25, .5, .75, 1].map(t => stop.map((v, channel) => stops[index - 1][channel] * (1 - t) + v * t)));
surfaces = surfaces.flatMap(bg => samples.map(stop => over(stop, bg)));
}
}
const style = getComputedStyle(element), color = rgba(square ? style.backgroundColor : style.color);
Expand Down
Loading