Disallow users to set theme as a project-level setting (#3312)
* Disallow users to set theme as a project-level setting * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * Fix up tests that assumed theme could be set at project level * Missed two more tests that assumed theme was a project-level setting --------- Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -98,14 +98,16 @@ const extrude001 = extrude(-10, sketch001)`
|
||||
|
||||
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
||||
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||
const themeOption = page.getByRole('option', {
|
||||
name: 'theme',
|
||||
const commandName = 'debug panel'
|
||||
const commandOption = page.getByRole('option', {
|
||||
name: commandName,
|
||||
exact: false,
|
||||
})
|
||||
const commandLevelArgButton = page.getByRole('button', { name: 'level' })
|
||||
const commandThemeArgButton = page.getByRole('button', { name: 'value' })
|
||||
const paneSelector = page.getByRole('button', { name: 'debug panel' })
|
||||
// This selector changes after we set the setting
|
||||
let commandOptionInput = page.getByPlaceholder('Select an option')
|
||||
let commandOptionInput = page.getByPlaceholder('On')
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
@ -127,17 +129,16 @@ const extrude001 = extrude(-10, sketch001)`
|
||||
await expect(cmdSearchBar).toBeFocused()
|
||||
|
||||
// Try typing in the command bar
|
||||
await cmdSearchBar.fill('theme')
|
||||
await expect(themeOption).toBeVisible()
|
||||
await themeOption.click()
|
||||
const themeInput = page.getByPlaceholder('Select an option')
|
||||
await expect(themeInput).toBeVisible()
|
||||
await expect(themeInput).toBeFocused()
|
||||
// Select dark theme
|
||||
await cmdSearchBar.fill(commandName)
|
||||
await expect(commandOption).toBeVisible()
|
||||
await commandOption.click()
|
||||
const toggleInput = page.getByPlaceholder('On')
|
||||
await expect(toggleInput).toBeVisible()
|
||||
await expect(toggleInput).toBeFocused()
|
||||
// Select On
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
|
||||
await expect(page.getByRole('option', { name: 'Off' })).toHaveAttribute(
|
||||
'data-headlessui-state',
|
||||
'active'
|
||||
)
|
||||
@ -145,21 +146,21 @@ const extrude001 = extrude(-10, sketch001)`
|
||||
|
||||
// Check the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "system" for this project`)
|
||||
page.getByText(`Set show debug panel to "false" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
// Check that the visibility changed
|
||||
await expect(paneSelector).not.toBeVisible()
|
||||
|
||||
commandOptionInput = page.getByPlaceholder('system')
|
||||
commandOptionInput = page.getByPlaceholder('off')
|
||||
|
||||
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
|
||||
await commandBarButton.click()
|
||||
await cmdSearchBar.focus()
|
||||
await cmdSearchBar.fill('theme')
|
||||
await themeOption.click()
|
||||
await cmdSearchBar.fill(commandName)
|
||||
await commandOption.click()
|
||||
await expect(commandThemeArgButton).toBeDisabled()
|
||||
await commandOptionInput.focus()
|
||||
await commandOptionInput.fill('lig')
|
||||
await commandOptionInput.fill('on')
|
||||
await commandLevelArgButton.click()
|
||||
await expect(commandLevelArgButton).toBeDisabled()
|
||||
|
||||
@ -197,7 +198,7 @@ const extrude001 = extrude(-10, sketch001)`
|
||||
})
|
||||
await expect(themeOption).toBeVisible()
|
||||
await themeOption.click()
|
||||
const themeInput = page.getByPlaceholder('Select an option')
|
||||
const themeInput = page.getByPlaceholder('dark')
|
||||
await expect(themeInput).toBeVisible()
|
||||
await expect(themeInput).toBeFocused()
|
||||
// Select dark theme
|
||||
@ -212,7 +213,7 @@ const extrude001 = extrude(-10, sketch001)`
|
||||
|
||||
// Check the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "system" for this project`)
|
||||
page.getByText(`Set theme to "system" as a user default`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Binary file not shown.
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
@ -64,95 +64,55 @@ test.describe('Testing settings', () => {
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
|
||||
const paneButtonLocator = page.getByTestId('debug-pane-button')
|
||||
const headingLocator = page.getByRole('heading', {
|
||||
name: 'Settings',
|
||||
exact: true,
|
||||
})
|
||||
const inputLocator = page.locator('input[name="modeling-showDebugPanel"]')
|
||||
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Settings', exact: true })
|
||||
).toBeVisible()
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark')
|
||||
|
||||
// Roll back to default "system" theme
|
||||
await page
|
||||
.getByText(
|
||||
'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
|
||||
)
|
||||
.hover()
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'Roll back theme',
|
||||
})
|
||||
.click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Check that the project setting did not change
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
})
|
||||
|
||||
test('Project settings can be opened with keybinding from the editor', async ({
|
||||
page,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
await expect(headingLocator).toBeVisible()
|
||||
await page.locator('#showDebugPanel').getByText('OffOn').click()
|
||||
|
||||
// Close it and open again with keyboard shortcut, while KCL editor is focused
|
||||
// Put the cursor in the editor
|
||||
await page.locator('.cm-content').click()
|
||||
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Settings', exact: true })
|
||||
).toBeVisible()
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
await test.step('Open settings with keyboard shortcut', async () => {
|
||||
await page.getByTestId('settings-close-button').click()
|
||||
await page.locator('.cm-content').click()
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
await expect(headingLocator).toBeVisible()
|
||||
})
|
||||
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" for this project`)
|
||||
page.getByText(`Set show debug panel to "false" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
await expect(paneButtonLocator).not.toBeVisible()
|
||||
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark')
|
||||
await expect(inputLocator).toBeChecked()
|
||||
|
||||
// Roll back to default "system" theme
|
||||
await page
|
||||
.getByText(
|
||||
'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
|
||||
)
|
||||
// Roll back to default of "off"
|
||||
await await page
|
||||
.getByText('show debug panelRoll back show debug panelRoll back to match')
|
||||
.hover()
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'Roll back theme',
|
||||
name: 'Roll back show debug panel',
|
||||
})
|
||||
.click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
await expect(inputLocator).not.toBeChecked()
|
||||
|
||||
// Check that the project setting did not change
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
await expect(
|
||||
page.locator('input[name="modeling-showDebugPanel"]')
|
||||
).not.toBeChecked()
|
||||
})
|
||||
|
||||
test('Project and user settings can be reset', async ({ page }) => {
|
||||
@ -163,69 +123,67 @@ test.describe('Testing settings', () => {
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
|
||||
// Put the cursor in the editor
|
||||
await page.locator('.cm-content').click()
|
||||
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
const projectSettingsTab = page.getByRole('radio', { name: 'Project' })
|
||||
const userSettingsTab = page.getByRole('radio', { name: 'User' })
|
||||
const resetButton = page.getByRole('button', {
|
||||
name: 'Restore default settings',
|
||||
})
|
||||
const themeColorSetting = page.locator('#themeColor').getByRole('slider')
|
||||
const settingValues = {
|
||||
default: '259',
|
||||
user: '120',
|
||||
project: '50',
|
||||
}
|
||||
|
||||
// Open the settings modal with lower-right button
|
||||
await page.getByRole('link', { name: 'Settings' }).last().click()
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Settings', exact: true })
|
||||
).toBeVisible()
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
await test.step('Set up theme color', async () => {
|
||||
// Verify we're looking at the project-level settings,
|
||||
// and it's set to default value
|
||||
await expect(projectSettingsTab).toBeChecked()
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
// Set project-level value to 50
|
||||
await themeColorSetting.fill(settingValues.project)
|
||||
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
// Set user-level value to 120
|
||||
await userSettingsTab.click()
|
||||
await themeColorSetting.fill(settingValues.user)
|
||||
await projectSettingsTab.click()
|
||||
})
|
||||
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
await test.step('Reset project settings', async () => {
|
||||
// Click the reset settings button.
|
||||
await resetButton.click()
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
// Verify it is now set to the inherited user value
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
// Check that the user setting also rolled back
|
||||
await userSettingsTab.click()
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
await projectSettingsTab.click()
|
||||
|
||||
// Set the user theme to light.
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
// Set project-level value to 50 again to test the user-level reset
|
||||
await themeColorSetting.fill(settingValues.project)
|
||||
await userSettingsTab.click()
|
||||
})
|
||||
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" as a user default`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
await test.step('Reset user settings', async () => {
|
||||
// Change the setting and click the reset settings button.
|
||||
await themeColorSetting.fill(settingValues.user)
|
||||
await resetButton.click()
|
||||
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
// Verify it is now set to the default value
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
// Check that the project setting also changed
|
||||
await projectSettingsTab.click()
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -114,6 +114,7 @@ export function createSettings() {
|
||||
* The overall appearance of the app: light, dark, or system
|
||||
*/
|
||||
theme: new Setting<Themes>({
|
||||
hideOnLevel: 'project',
|
||||
defaultValue: Themes.System,
|
||||
description: 'The overall appearance of the app',
|
||||
validate: (v) => isEnumMember(v, Themes),
|
||||
|
Reference in New Issue
Block a user