mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-03 16:10:21 +00:00
318 lines
12 KiB
JavaScript
318 lines
12 KiB
JavaScript
const { test, expect, navigateToBase } = require('../utils/enhanced-baseFixtures.js');
|
|
const testLogger = require('../utils/test-logger.js');
|
|
const PageManager = require('../../pages/page-manager.js');
|
|
|
|
test.describe("App Theme Default (Light/Dark) testcases", () => {
|
|
test.describe.configure({ mode: 'parallel' });
|
|
let pm;
|
|
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
testLogger.testStart(testInfo.title, testInfo.file);
|
|
pm = new PageManager(page);
|
|
testLogger.info('Theme default test setup completed');
|
|
});
|
|
|
|
test("should default to light mode on a fresh load with no theme key", {
|
|
tag: ['@theme-default', '@theme', '@all', '@P0']
|
|
}, async ({ page }) => {
|
|
testLogger.info('Clearing theme storage for a fresh light-default load');
|
|
|
|
// Seed before navigation: bootstrapTheme() reads localStorage.theme
|
|
// synchronously in main.ts, so a write after navigateToBase has no effect.
|
|
await page.addInitScript(() => {
|
|
localStorage.removeItem('theme');
|
|
localStorage.removeItem('appliedLightThemeName');
|
|
localStorage.removeItem('appliedDarkThemeName');
|
|
localStorage.removeItem('appliedLightTheme');
|
|
localStorage.removeItem('appliedDarkTheme');
|
|
});
|
|
await navigateToBase(page);
|
|
await pm.themePage.expectProfileMenuVisible();
|
|
testLogger.info('Layout shell mounted; asserting default light mode');
|
|
|
|
await pm.themePage.expectLightMode();
|
|
// No persisted theme resolves to light and is written back, so the key is 'light'.
|
|
expect(await pm.themePage.getCurrentThemeFromStorage()).toBe('light');
|
|
testLogger.info('Default light mode verified');
|
|
});
|
|
|
|
test("should boot in dark mode when theme is seeded to 'dark' before app scripts run", {
|
|
tag: ['@theme-default', '@theme', '@all', '@P0']
|
|
}, async ({ page }) => {
|
|
testLogger.info("Seeding theme='dark' before navigation");
|
|
|
|
// Seed the exact literal "dark" before navigation so the first paint is dark.
|
|
await page.addInitScript(() => localStorage.setItem('theme', 'dark'));
|
|
await navigateToBase(page);
|
|
await pm.themePage.waitForDarkModeApplied();
|
|
testLogger.info('Dark class applied on <html>');
|
|
|
|
await pm.themePage.expectDarkMode();
|
|
expect(await pm.themePage.getCurrentThemeFromStorage()).toBe('dark');
|
|
testLogger.info('Dark default on first paint verified');
|
|
});
|
|
|
|
test("should fall back to light mode for a corrupt non-'dark' theme value", {
|
|
tag: ['@theme-default', '@theme', '@all', '@P1']
|
|
}, async ({ page }) => {
|
|
testLogger.info("Seeding a corrupt theme value 'DARK' before navigation");
|
|
|
|
// Strict === "dark" means "DARK" (and "1", "true", "") resolves to light.
|
|
await page.addInitScript(() => localStorage.setItem('theme', 'DARK'));
|
|
await navigateToBase(page);
|
|
await pm.themePage.expectProfileMenuVisible();
|
|
testLogger.info('Layout shell mounted; asserting corrupt value resolved to light');
|
|
|
|
await pm.themePage.expectLightMode();
|
|
testLogger.info('Corrupt theme value resolved to light mode');
|
|
});
|
|
});
|
|
|
|
test.describe("Theme Management Tests", () => {
|
|
test.describe.configure({ mode: 'serial' }); // Serial to avoid theme state conflicts
|
|
let pm; // Page Manager instance
|
|
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
// Initialize test setup
|
|
testLogger.testStart(testInfo.title, testInfo.file);
|
|
|
|
// Navigate to base URL with authentication
|
|
await navigateToBase(page);
|
|
pm = new PageManager(page);
|
|
|
|
// Post-authentication stabilization wait — keyed on the profile button which
|
|
// is the first user-actionable element to mount after layout shell hydrates.
|
|
await page.waitForLoadState('domcontentloaded');
|
|
await expect(pm.themePage.profileMenuBtn).toBeVisible({ timeout: 10000 });
|
|
|
|
testLogger.info('Theme management test setup completed');
|
|
});
|
|
|
|
test.describe("Theme Switcher", () => {
|
|
test("should toggle between light and dark mode and persist after reload", {
|
|
tag: ['@theme', '@themeSwitcher', '@themePersistence', '@P1']
|
|
}, async ({ page }) => {
|
|
testLogger.info('Testing theme mode toggle and persistence functionality');
|
|
|
|
// Get initial theme state
|
|
const initialIsDark = await pm.themePage.isDarkMode();
|
|
testLogger.info(`Initial theme mode: ${initialIsDark ? 'dark' : 'light'}`);
|
|
|
|
// Toggle theme
|
|
await pm.themePage.toggleThemeMode();
|
|
|
|
// Verify theme changed
|
|
const afterToggleIsDark = await pm.themePage.isDarkMode();
|
|
expect(afterToggleIsDark).not.toBe(initialIsDark);
|
|
testLogger.info(`Theme toggled to: ${afterToggleIsDark ? 'dark' : 'light'}`);
|
|
|
|
// Toggle back to original
|
|
await pm.themePage.toggleThemeMode();
|
|
|
|
// Verify theme restored
|
|
const finalIsDark = await pm.themePage.isDarkMode();
|
|
expect(finalIsDark).toBe(initialIsDark);
|
|
testLogger.info('Theme toggle test completed');
|
|
|
|
// Test persistence - switch to dark mode
|
|
await pm.themePage.switchToDarkMode();
|
|
await pm.themePage.expectDarkMode();
|
|
testLogger.info('Switched to dark mode for persistence test');
|
|
|
|
// Reload the page
|
|
await page.reload();
|
|
await page.waitForLoadState('domcontentloaded');
|
|
|
|
// Wait for theme to be restored from storage (Vue needs time to apply it).
|
|
// The dark-mode signal is the `.dark` class on <html> (set by
|
|
// utils/theme.ts); the legacy `body--dark` on <body> was retired.
|
|
await page.waitForFunction(
|
|
(darkClass) => document.documentElement.classList.contains(darkClass),
|
|
'dark',
|
|
{ timeout: 10000 }
|
|
);
|
|
|
|
// Verify dark mode persisted
|
|
await pm.themePage.expectDarkMode();
|
|
testLogger.info('Dark mode persisted after reload');
|
|
|
|
// Switch back to light mode for cleanup
|
|
await pm.themePage.switchToLightMode();
|
|
testLogger.info('Theme toggle and persistence test completed');
|
|
});
|
|
});
|
|
|
|
test.describe("Predefined Themes", () => {
|
|
test("should open dialog, display tabs and theme options, then close", {
|
|
tag: ['@theme', '@predefinedThemes', '@P1']
|
|
}, async ({ page }) => {
|
|
testLogger.info('Testing predefined themes dialog functionality');
|
|
|
|
// Open predefined themes dialog
|
|
await pm.themePage.openPredefinedThemesDialog();
|
|
await pm.themePage.expectPredefinedThemesDialogVisible();
|
|
testLogger.info('Predefined themes dialog opened');
|
|
|
|
// Verify light mode tab is visible
|
|
await pm.themePage.expectLightModeTabVisible();
|
|
testLogger.info('Light Mode tab visible');
|
|
|
|
// Verify dark mode tab is visible
|
|
await pm.themePage.expectDarkModeTabVisible();
|
|
testLogger.info('Dark Mode tab visible');
|
|
|
|
// Switch between tabs
|
|
await pm.themePage.selectDarkModeTab();
|
|
testLogger.info('Switched to Dark Mode tab');
|
|
|
|
await pm.themePage.selectLightModeTab();
|
|
testLogger.info('Switched back to Light Mode tab');
|
|
|
|
// Verify predefined theme options (Light tab is currently active)
|
|
const expectedThemes = ['O2 Signature', 'O2 Pulse', 'O2 Horizon', 'O2 Beacon'];
|
|
for (const themeName of expectedThemes) {
|
|
await pm.themePage.expectThemeCardVisible(themeName, 'light');
|
|
testLogger.info(`Theme "${themeName}" is visible`);
|
|
}
|
|
|
|
// Verify Custom Color option exists
|
|
await pm.themePage.expectCustomColorCardVisible('light');
|
|
testLogger.info('Custom Color option is visible');
|
|
|
|
// Close dialog
|
|
await pm.themePage.closePredefinedThemesDialog();
|
|
await pm.themePage.expectPredefinedThemesDialogHidden();
|
|
testLogger.info('Predefined themes dialog closed');
|
|
});
|
|
|
|
test("should apply predefined theme, show Applied badge, and reset to default", {
|
|
tag: ['@theme', '@predefinedThemes', '@applyTheme', '@resetTheme', '@P1']
|
|
}, async ({ page }) => {
|
|
testLogger.info('Testing predefined theme application and reset');
|
|
|
|
// Ensure we're in light mode first
|
|
await pm.themePage.switchToLightMode();
|
|
|
|
// Open predefined themes dialog
|
|
await pm.themePage.openPredefinedThemesDialog();
|
|
|
|
// Apply "O2 Pulse" theme
|
|
await pm.themePage.applyThemeByName('O2 Pulse');
|
|
testLogger.info('Applied O2 Pulse theme');
|
|
|
|
// Verify notification
|
|
await pm.themePage.expectNotificationContains('applied');
|
|
testLogger.info('Theme application notification shown');
|
|
|
|
// Verify "Applied" badge appears
|
|
const isApplied = await pm.themePage.isThemeApplied('O2 Pulse');
|
|
expect(isApplied).toBe(true);
|
|
testLogger.info('Applied badge shown for O2 Pulse');
|
|
|
|
// Now test reset - Apply a different theme first
|
|
await pm.themePage.applyThemeByName('O2 Horizon');
|
|
testLogger.info('Applied O2 Horizon theme');
|
|
|
|
// Reset to default
|
|
await pm.themePage.resetToDefaultTheme();
|
|
testLogger.info('Reset theme to default');
|
|
|
|
// Verify reset notification
|
|
try {
|
|
await pm.themePage.expectNotificationContains('reset');
|
|
testLogger.info('Reset notification shown');
|
|
} catch (e) {
|
|
testLogger.info('Reset notification not captured (may have been transient)');
|
|
}
|
|
|
|
// Close dialog
|
|
await pm.themePage.closePredefinedThemesDialog();
|
|
testLogger.info('Apply and reset theme test completed');
|
|
});
|
|
|
|
test("should apply theme in dark mode", {
|
|
tag: ['@theme', '@darkMode', '@P2']
|
|
}, async ({ page }) => {
|
|
testLogger.info('Testing theme application in dark mode');
|
|
|
|
// Switch to dark mode
|
|
await pm.themePage.switchToDarkMode();
|
|
await pm.themePage.expectDarkMode();
|
|
testLogger.info('Switched to dark mode');
|
|
|
|
// Open predefined themes dialog
|
|
await pm.themePage.openPredefinedThemesDialog();
|
|
|
|
// Select dark mode tab
|
|
await pm.themePage.selectDarkModeTab();
|
|
|
|
// Apply "O2 Beacon" theme for dark mode
|
|
await pm.themePage.applyThemeByName('O2 Beacon', 'dark');
|
|
testLogger.info('Applied O2 Beacon theme in dark mode');
|
|
|
|
// Verify notification
|
|
await pm.themePage.expectNotificationContains('applied');
|
|
|
|
// Reset to default
|
|
await pm.themePage.resetToDefaultTheme();
|
|
|
|
// Close dialog and switch back to light mode
|
|
await pm.themePage.closePredefinedThemesDialog();
|
|
await pm.themePage.switchToLightMode();
|
|
testLogger.info('Dark mode theme test completed');
|
|
});
|
|
});
|
|
|
|
test.describe("Custom Color Theme", () => {
|
|
test("should open color picker, close it, and apply custom color theme", {
|
|
tag: ['@theme', '@customColor', '@P2']
|
|
}, async ({ page }) => {
|
|
testLogger.info('Testing custom color theme functionality');
|
|
|
|
// Open predefined themes dialog
|
|
await pm.themePage.openPredefinedThemesDialog();
|
|
|
|
// Open custom color picker
|
|
await pm.themePage.openCustomColorPicker();
|
|
testLogger.info('Custom color picker opened');
|
|
|
|
// Verify color picker is visible
|
|
await pm.themePage.expectColorPickerDialogVisible();
|
|
testLogger.info('Color picker dialog is visible');
|
|
|
|
// Close color picker
|
|
await pm.themePage.closeColorPicker();
|
|
testLogger.info('Color picker closed');
|
|
|
|
// Apply custom color theme
|
|
await pm.themePage.applyCustomColor();
|
|
testLogger.info('Applied custom color theme');
|
|
|
|
// Verify notification
|
|
try {
|
|
await pm.themePage.expectNotificationContains('Custom color applied');
|
|
testLogger.info('Custom color notification shown');
|
|
} catch (e) {
|
|
testLogger.info('Custom color notification not captured (may have been transient)');
|
|
}
|
|
|
|
// Reset to default for cleanup
|
|
await pm.themePage.resetToDefaultTheme();
|
|
|
|
// Close dialog
|
|
await pm.themePage.closePredefinedThemesDialog();
|
|
testLogger.info('Custom color theme test completed');
|
|
});
|
|
});
|
|
|
|
test.afterEach(async () => {
|
|
// Ensure we're back to light mode for next test
|
|
try {
|
|
await pm.themePage.switchToLightMode();
|
|
} catch (e) {
|
|
// Ignore errors in cleanup
|
|
}
|
|
testLogger.info('Theme management test completed');
|
|
});
|
|
});
|