jan/tests/e2e/pageobjects/settings.page.js
dinhlongviolin1 5d76a1d138 add e2e test
2025-09-09 08:44:11 -07:00

125 lines
4.5 KiB
JavaScript

import BasePage from './base.page.js'
/**
* Settings page object
*/
class SettingsPage extends BasePage {
// Selectors - Exact selectors from Jan app codebase
get settingsButton() { return '[data-test-id="menu-common:settings"]' }
get settingsButtonFallback() { return 'a[href="/settings/general"] svg.tabler-icon-settings-filled' }
get appearanceTab() { return 'a[href*="appearance"]' }
get themeSelector() { return 'span[title="Edit theme"].flex.cursor-pointer.items-center.gap-1.px-2.py-1.rounded-sm.bg-main-view-fg\\/15.text-sm' }
get themeDropdownContent() { return 'div[role="menu"].w-24' }
get themeOption() { return 'div[role="menuitem"].cursor-pointer.my-0\\.5' }
get darkThemeOption() { return 'div[role="menuitem"]:contains("Dark")' }
get lightThemeOption() { return 'div[role="menuitem"]:contains("Light")' }
get systemThemeOption() { return 'div[role="menuitem"]:contains("System")' }
get resetButton() { return 'button:contains("Reset")' }
/**
* Navigate to settings
*/
async navigateToSettings() {
// Try primary selector first, then fallback
if (await this.elementExists(this.settingsButton)) {
await this.clickElement(this.settingsButton)
} else if (await this.elementExists(this.settingsButtonFallback)) {
await this.clickElement(this.settingsButtonFallback)
}
await browser.pause(1000) // Wait for settings to load
}
/**
* Navigate to appearance settings
*/
async navigateToAppearance() {
await this.navigateToSettings()
if (await this.elementExists(this.appearanceTab)) {
await this.clickElement(this.appearanceTab)
await browser.pause(500)
}
}
/**
* Change theme
* @param {string} theme - Theme option ('light', 'dark', 'system')
*/
async changeTheme(theme) {
await this.navigateToAppearance()
// Try different approaches to change theme
const themeSelectors = [
this.themeSelector,
`[data-value="${theme}"]`,
`button:contains("${theme}")`,
`input[value="${theme}"]`
]
for (const selector of themeSelectors) {
if (await this.elementExists(selector)) {
await this.clickElement(selector)
break
}
}
// If there's a save button, click it
if (await this.elementExists(this.saveButton)) {
await this.clickElement(this.saveButton)
}
await browser.pause(1000) // Wait for theme to apply
}
/**
* Get current theme from UI elements
*/
async getCurrentTheme() {
// Check body/html classes or data attributes for theme
const body = await $('body')
const bodyClass = await body.getAttribute('class') || ''
const dataTheme = await body.getAttribute('data-theme') || ''
if (bodyClass.includes('dark') || dataTheme.includes('dark')) return 'dark'
if (bodyClass.includes('light') || dataTheme.includes('light')) return 'light'
// Check for common theme indicators
const html = await $('html')
const htmlClass = await html.getAttribute('class') || ''
if (htmlClass.includes('dark')) return 'dark'
if (htmlClass.includes('light')) return 'light'
return 'unknown'
}
/**
* Verify theme is applied by checking background colors
*/
async verifyThemeApplied(expectedTheme) {
await browser.pause(1000) // Wait for theme to fully apply
// Check background color of main elements
const selectors = ['body', 'html', '[data-testid="main-container"]', '.app', '#root']
for (const selector of selectors) {
if (await this.elementExists(selector)) {
const bgColor = await this.getCSSProperty(selector, 'background-color')
const color = bgColor.value
// Light theme typically has light backgrounds (white, light gray)
// Dark theme typically has dark backgrounds (black, dark gray)
if (expectedTheme === 'light') {
// Light theme: background should be light (high RGB values or white)
return color.includes('255') || color.includes('rgb(255') || color === 'rgba(0,0,0,0)'
} else if (expectedTheme === 'dark') {
// Dark theme: background should be dark (low RGB values)
return color.includes('rgb(0') || color.includes('rgb(1') || color.includes('rgb(2') ||
color.includes('33') || color.includes('51') || color.includes('68')
}
}
}
return false
}
}
export default new SettingsPage()