This is an automated email from the ASF dual-hosted git repository. rzo1 pushed a commit to branch bootstrap5-dark-theme in repository https://gitbox.apache.org/repos/asf/storm.git
commit 9fc67a760807f24560b3decf338e2d0b3a9bb02a Author: Richard Zowalla <[email protected]> AuthorDate: Thu Mar 19 09:36:09 2026 +0100 Upgrade Bootstrap to 5.3.8, add dark mode toggle --- storm-webapp/cypress/e2e/dark-theme.cy.js | 110 ++++++++++++++++++++++++++++++ tmp/test-jre21/Dockerfile | 46 ------------- tmp/test-jre21/docker-entrypoint.sh | 22 ------ 3 files changed, 110 insertions(+), 68 deletions(-) diff --git a/storm-webapp/cypress/e2e/dark-theme.cy.js b/storm-webapp/cypress/e2e/dark-theme.cy.js new file mode 100644 index 000000000..6a5d8ca33 --- /dev/null +++ b/storm-webapp/cypress/e2e/dark-theme.cy.js @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +describe('Storm UI - Dark Theme', () => { + + it('applies light theme when cookie is set to light', () => { + cy.setCookie('stormTheme', 'light'); + cy.visit('/'); + cy.document().its('documentElement') + .should('have.attr', 'data-bs-theme', 'light'); + }); + + it('applies dark theme when cookie is set to dark', () => { + cy.setCookie('stormTheme', 'dark'); + cy.visit('/'); + cy.document().its('documentElement') + .should('have.attr', 'data-bs-theme', 'dark'); + }); + + it('dark theme gives body a dark background color', () => { + cy.setCookie('stormTheme', 'dark'); + cy.visit('/'); + cy.get('body').should(($body) => { + const bg = window.getComputedStyle($body[0]).backgroundColor; + // Bootstrap 5.3 dark theme uses #212529 = rgb(33, 37, 41) + expect(bg).to.equal('rgb(33, 37, 41)'); + }); + }); + + it('light theme gives body a white/light background color', () => { + cy.setCookie('stormTheme', 'light'); + cy.visit('/'); + cy.get('body').should(($body) => { + const bg = window.getComputedStyle($body[0]).backgroundColor; + // Bootstrap 5.3 light theme uses #fff = rgb(255, 255, 255) + expect(bg).to.equal('rgb(255, 255, 255)'); + }); + }); + + it('toggle button switches theme from light to dark', () => { + cy.setCookie('stormTheme', 'light'); + cy.visit('/'); + cy.get('#theme-toggle-btn', { timeout: 5000 }) + .should('have.value', 'Dark Mode'); + + cy.get('#theme-toggle-btn').click(); + + cy.document().its('documentElement') + .should('have.attr', 'data-bs-theme', 'dark'); + cy.get('#theme-toggle-btn').should('have.value', 'Light Mode'); + }); + + it('toggle button switches theme from dark to light', () => { + cy.setCookie('stormTheme', 'dark'); + cy.visit('/'); + // Wait for the user template to render and the label to be updated + cy.get('#theme-toggle-btn', { timeout: 5000 }).should('exist'); + // The $(function(){}) handler updates the label after template render + cy.wait(500); + cy.get('#theme-toggle-btn').should('have.value', 'Light Mode'); + + cy.get('#theme-toggle-btn').click(); + + cy.document().its('documentElement') + .should('have.attr', 'data-bs-theme', 'light'); + cy.get('#theme-toggle-btn').should('have.value', 'Dark Mode'); + }); + + it('persists theme preference across page loads', () => { + cy.setCookie('stormTheme', 'light'); + cy.visit('/'); + cy.get('#theme-toggle-btn', { timeout: 5000 }).click(); // → dark + + cy.document().its('documentElement') + .should('have.attr', 'data-bs-theme', 'dark'); + + cy.reload(); + + cy.document().its('documentElement') + .should('have.attr', 'data-bs-theme', 'dark'); + }); + + it('dark theme works on topology page', () => { + cy.setCookie('stormTheme', 'dark'); + cy.visit('/topology.html?id=word-count-1-1234567890'); + cy.document().its('documentElement') + .should('have.attr', 'data-bs-theme', 'dark'); + }); + + it('dark theme works on visualize page', () => { + cy.setCookie('stormTheme', 'dark'); + cy.visit('/visualize.html?id=word-count-1-1234567890&sys=false'); + cy.document().its('documentElement') + .should('have.attr', 'data-bs-theme', 'dark'); + }); +}); diff --git a/tmp/test-jre21/Dockerfile b/tmp/test-jre21/Dockerfile deleted file mode 100644 index 77609b3ca..000000000 --- a/tmp/test-jre21/Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -FROM eclipse-temurin:21-jre - -ENV STORM_CONF_DIR=/conf \ - STORM_DATA_DIR=/data \ - STORM_LOG_DIR=/logs - -# Remove the default user 'ubuntu' and its group -RUN userdel -r ubuntu && \ - groupdel ubuntu || true - -# Add a user with an explicit UID/GID and create necessary directories -RUN set -eux; \ - groupadd -r storm --gid=1000; \ - useradd -r -g storm --uid=1000 storm; \ - mkdir -p "$STORM_CONF_DIR" "$STORM_DATA_DIR" "$STORM_LOG_DIR"; \ - chown -R storm:storm "$STORM_CONF_DIR" "$STORM_DATA_DIR" "$STORM_LOG_DIR" - -# Install required packages -RUN set -eux; \ - apt-get update; \ - DEBIAN_FRONTEND=noninteractive \ - apt-get install -y --no-install-recommends \ - bash \ - ca-certificates \ - gosu \ - python3 \ - procps; \ - rm -rf /var/lib/apt/lists/*; \ - gosu nobody true - -ARG DISTRO_NAME=apache-storm-2.8.5-SNAPSHOT - -# Copy the local tarball and unpack it (skip download and GPG verification) -COPY ${DISTRO_NAME}.tar.gz /tmp/${DISTRO_NAME}.tar.gz -RUN set -eux; \ - tar -xzf /tmp/${DISTRO_NAME}.tar.gz -C /; \ - rm -f /tmp/${DISTRO_NAME}.tar.gz; \ - mv /${DISTRO_NAME} /apache-storm; \ - chown -R storm:storm /apache-storm - -WORKDIR /apache-storm - -ENV PATH $PATH:/apache-storm/bin - -COPY docker-entrypoint.sh / -ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/tmp/test-jre21/docker-entrypoint.sh b/tmp/test-jre21/docker-entrypoint.sh deleted file mode 100755 index 66dff6f6d..000000000 --- a/tmp/test-jre21/docker-entrypoint.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -set -e - -# Allow the container to be started with `--user` -if [ "$1" = 'storm' -a "$(id -u)" = '0' ]; then - chown -R storm:storm "$STORM_CONF_DIR" "$STORM_DATA_DIR" "$STORM_LOG_DIR" - exec gosu storm "$0" "$@" -fi - -# Generate the config only if it doesn't exist -CONFIG="$STORM_CONF_DIR/storm.yaml" -if [ ! -f "$CONFIG" ]; then - cat << EOF > "$CONFIG" -storm.zookeeper.servers: [zookeeper] -nimbus.seeds: [nimbus] -storm.log.dir: "$STORM_LOG_DIR" -storm.local.dir: "$STORM_DATA_DIR" -EOF -fi - -exec "$@"
