2024-08-07 19:27:32 +10:00
|
|
|
import { test, expect } from '@playwright/test'
|
2024-08-19 10:23:43 -04:00
|
|
|
import * as fsp from 'fs/promises'
|
|
|
|
import { getUtils, setup, setupElectron, tearDown } from './test-utils'
|
2024-08-07 19:27:32 +10:00
|
|
|
import { SaveSettingsPayload } from 'lib/settings/settingsTypes'
|
|
|
|
import { TEST_SETTINGS_KEY, TEST_SETTINGS_CORRUPTED } from './storageStates'
|
|
|
|
import * as TOML from '@iarna/toml'
|
|
|
|
|
|
|
|
test.beforeEach(async ({ context, page }) => {
|
|
|
|
await setup(context, page)
|
|
|
|
})
|
|
|
|
|
|
|
|
test.afterEach(async ({ page }, testInfo) => {
|
|
|
|
await tearDown(page, testInfo)
|
|
|
|
})
|
|
|
|
|
|
|
|
test.describe('Testing settings', () => {
|
|
|
|
test('Stored settings are validated and fall back to defaults', async ({
|
|
|
|
page,
|
|
|
|
}) => {
|
|
|
|
const u = await getUtils(page)
|
|
|
|
|
|
|
|
// Override beforeEach test setup
|
|
|
|
// with corrupted settings
|
|
|
|
await page.addInitScript(
|
|
|
|
async ({ settingsKey, settings }) => {
|
|
|
|
localStorage.setItem(settingsKey, settings)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
settingsKey: TEST_SETTINGS_KEY,
|
|
|
|
settings: TOML.stringify({ settings: TEST_SETTINGS_CORRUPTED }),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
|
|
|
|
|
|
|
await u.waitForAuthSkipAppStart()
|
|
|
|
|
|
|
|
// Check the settings were reset
|
|
|
|
const storedSettings = TOML.parse(
|
|
|
|
await page.evaluate(
|
|
|
|
({ settingsKey }) => localStorage.getItem(settingsKey) || '',
|
|
|
|
{ settingsKey: TEST_SETTINGS_KEY }
|
|
|
|
)
|
|
|
|
) as { settings: SaveSettingsPayload }
|
|
|
|
|
|
|
|
expect(storedSettings.settings?.app?.theme).toBe(undefined)
|
|
|
|
|
|
|
|
// Check that the invalid settings were removed
|
|
|
|
expect(storedSettings.settings?.modeling?.defaultUnit).toBe(undefined)
|
|
|
|
expect(storedSettings.settings?.modeling?.mouseControls).toBe(undefined)
|
|
|
|
expect(storedSettings.settings?.app?.projectDirectory).toBe(undefined)
|
|
|
|
expect(storedSettings.settings?.projects?.defaultProjectName).toBe(
|
|
|
|
undefined
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
test('Project settings can be set and override user settings', 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' })
|
|
|
|
|
2024-08-12 15:18:33 -04:00
|
|
|
const paneButtonLocator = page.getByTestId('debug-pane-button')
|
|
|
|
const headingLocator = page.getByRole('heading', {
|
|
|
|
name: 'Settings',
|
|
|
|
exact: true,
|
|
|
|
})
|
|
|
|
const inputLocator = page.locator('input[name="modeling-showDebugPanel"]')
|
|
|
|
|
2024-08-07 19:27:32 +10:00
|
|
|
// Open the settings modal with the browser keyboard shortcut
|
|
|
|
await page.keyboard.press('Meta+Shift+,')
|
|
|
|
|
2024-08-12 15:18:33 -04:00
|
|
|
await expect(headingLocator).toBeVisible()
|
|
|
|
await page.locator('#showDebugPanel').getByText('OffOn').click()
|
2024-08-07 19:27:32 +10:00
|
|
|
|
2024-08-12 15:18:33 -04:00
|
|
|
// Close it and open again with keyboard shortcut, while KCL editor is focused
|
2024-08-07 19:27:32 +10:00
|
|
|
// Put the cursor in the editor
|
2024-08-12 15:18:33 -04:00
|
|
|
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()
|
|
|
|
})
|
2024-08-07 19:27:32 +10:00
|
|
|
|
|
|
|
// Verify the toast appeared
|
|
|
|
await expect(
|
2024-08-12 15:18:33 -04:00
|
|
|
page.getByText(`Set show debug panel to "false" for this project`)
|
2024-08-07 19:27:32 +10:00
|
|
|
).toBeVisible()
|
|
|
|
// Check that the theme changed
|
2024-08-12 15:18:33 -04:00
|
|
|
await expect(paneButtonLocator).not.toBeVisible()
|
2024-08-07 19:27:32 +10:00
|
|
|
|
|
|
|
// Check that the user setting was not changed
|
|
|
|
await page.getByRole('radio', { name: 'User' }).click()
|
2024-08-12 15:18:33 -04:00
|
|
|
await expect(inputLocator).toBeChecked()
|
2024-08-07 19:27:32 +10:00
|
|
|
|
2024-08-12 15:18:33 -04:00
|
|
|
// Roll back to default of "off"
|
|
|
|
await await page
|
|
|
|
.getByText('show debug panelRoll back show debug panelRoll back to match')
|
2024-08-07 19:27:32 +10:00
|
|
|
.hover()
|
|
|
|
await page
|
|
|
|
.getByRole('button', {
|
2024-08-12 15:18:33 -04:00
|
|
|
name: 'Roll back show debug panel',
|
2024-08-07 19:27:32 +10:00
|
|
|
})
|
|
|
|
.click()
|
2024-08-12 15:18:33 -04:00
|
|
|
await expect(inputLocator).not.toBeChecked()
|
2024-08-07 19:27:32 +10:00
|
|
|
|
|
|
|
// Check that the project setting did not change
|
|
|
|
await page.getByRole('radio', { name: 'Project' }).click()
|
2024-08-12 15:18:33 -04:00
|
|
|
await expect(
|
|
|
|
page.locator('input[name="modeling-showDebugPanel"]')
|
|
|
|
).not.toBeChecked()
|
2024-08-07 19:27:32 +10:00
|
|
|
})
|
|
|
|
|
2024-08-16 07:15:42 -04:00
|
|
|
// TODO fixme reset doesn't seem to work for color setting
|
|
|
|
test.fixme('Project and user settings can be reset', async ({ page }) => {
|
2024-08-07 19:27:32 +10:00
|
|
|
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' })
|
|
|
|
|
2024-08-12 15:18:33 -04:00
|
|
|
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()
|
2024-08-07 19:27:32 +10:00
|
|
|
await expect(
|
|
|
|
page.getByRole('heading', { name: 'Settings', exact: true })
|
|
|
|
).toBeVisible()
|
|
|
|
|
2024-08-12 15:18:33 -04:00
|
|
|
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)
|
|
|
|
|
|
|
|
// Set project-level value to 50
|
|
|
|
await themeColorSetting.fill(settingValues.project)
|
|
|
|
|
|
|
|
// Set user-level value to 120
|
|
|
|
await userSettingsTab.click()
|
|
|
|
await themeColorSetting.fill(settingValues.user)
|
|
|
|
await projectSettingsTab.click()
|
|
|
|
})
|
|
|
|
|
|
|
|
await test.step('Reset project settings', async () => {
|
|
|
|
// Click the reset settings button.
|
|
|
|
await resetButton.click()
|
|
|
|
|
|
|
|
// Verify it is now set to the inherited user value
|
|
|
|
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
|
|
|
|
|
|
|
// Check that the user setting also rolled back
|
|
|
|
await userSettingsTab.click()
|
|
|
|
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
|
|
|
await projectSettingsTab.click()
|
|
|
|
|
|
|
|
// Set project-level value to 50 again to test the user-level reset
|
|
|
|
await themeColorSetting.fill(settingValues.project)
|
|
|
|
await userSettingsTab.click()
|
|
|
|
})
|
|
|
|
|
|
|
|
await test.step('Reset user settings', async () => {
|
|
|
|
// Change the setting and click the reset settings button.
|
|
|
|
await themeColorSetting.fill(settingValues.user)
|
|
|
|
await resetButton.click()
|
|
|
|
|
|
|
|
// Verify it is now set to the default value
|
|
|
|
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
|
|
|
|
|
|
|
// Check that the project setting also changed
|
|
|
|
await projectSettingsTab.click()
|
|
|
|
await expect(themeColorSetting).toHaveValue(settingValues.default)
|
|
|
|
})
|
2024-08-07 19:27:32 +10:00
|
|
|
})
|
2024-08-19 10:23:43 -04:00
|
|
|
|
|
|
|
test(
|
|
|
|
`Project settings override user settings on desktop`,
|
|
|
|
{ tag: '@electron' },
|
|
|
|
async ({ browser: _ }, testInfo) => {
|
2024-08-20 16:37:16 +10:00
|
|
|
test.skip(
|
|
|
|
process.platform === 'win32',
|
|
|
|
'TODO: remove this skip https://github.com/KittyCAD/modeling-app/issues/3557'
|
|
|
|
)
|
2024-08-19 10:23:43 -04:00
|
|
|
const { electronApp, page } = await setupElectron({
|
|
|
|
testInfo,
|
|
|
|
folderSetupFn: async (dir) => {
|
|
|
|
await fsp.mkdir(`${dir}/bracket`, { recursive: true })
|
|
|
|
await fsp.copyFile(
|
|
|
|
'src/wasm-lib/tests/executor/inputs/focusrite_scarlett_mounting_braket.kcl',
|
|
|
|
`${dir}/bracket/main.kcl`
|
|
|
|
)
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
|
|
|
|
|
|
|
page.on('console', console.log)
|
|
|
|
|
|
|
|
// Selectors and constants
|
|
|
|
const userThemeColor = '120'
|
|
|
|
const projectThemeColor = '50'
|
|
|
|
const settingsOpenButton = page.getByRole('link', {
|
|
|
|
name: 'settings Settings',
|
|
|
|
})
|
|
|
|
const themeColorSetting = page.locator('#themeColor').getByRole('slider')
|
|
|
|
const projectSettingsTab = page.getByRole('radio', { name: 'Project' })
|
|
|
|
const userSettingsTab = page.getByRole('radio', { name: 'User' })
|
|
|
|
const settingsCloseButton = page.getByTestId('settings-close-button')
|
|
|
|
const projectLink = page.getByText('bracket')
|
|
|
|
const logoLink = page.getByTestId('app-logo')
|
|
|
|
|
|
|
|
// Open the app and set the user theme color
|
|
|
|
await test.step('Set user theme color on home', async () => {
|
|
|
|
await expect(settingsOpenButton).toBeVisible()
|
|
|
|
await settingsOpenButton.click()
|
|
|
|
// The user tab should be selected by default on home
|
|
|
|
await expect(userSettingsTab).toBeChecked()
|
|
|
|
await themeColorSetting.fill(userThemeColor)
|
|
|
|
await expect(logoLink).toHaveCSS('--primary-hue', userThemeColor)
|
|
|
|
await settingsCloseButton.click()
|
|
|
|
})
|
|
|
|
|
|
|
|
await test.step('Set project theme color', async () => {
|
|
|
|
// Open the project
|
|
|
|
await projectLink.click()
|
|
|
|
await settingsOpenButton.click()
|
|
|
|
// The project tab should be selected by default within a project
|
|
|
|
await expect(projectSettingsTab).toBeChecked()
|
|
|
|
await themeColorSetting.fill(projectThemeColor)
|
|
|
|
await expect(logoLink).toHaveCSS('--primary-hue', projectThemeColor)
|
|
|
|
})
|
|
|
|
|
|
|
|
await test.step('Refresh the application and see project setting applied', async () => {
|
|
|
|
await page.reload()
|
|
|
|
|
|
|
|
await expect(logoLink).toHaveCSS('--primary-hue', projectThemeColor)
|
|
|
|
await settingsCloseButton.click()
|
|
|
|
})
|
|
|
|
|
|
|
|
await test.step(`Navigate back to the home view and see user setting applied`, async () => {
|
|
|
|
await logoLink.click()
|
|
|
|
await expect(logoLink).toHaveCSS('--primary-hue', userThemeColor)
|
|
|
|
})
|
|
|
|
|
|
|
|
await electronApp.close()
|
|
|
|
}
|
|
|
|
)
|
2024-08-07 19:27:32 +10:00
|
|
|
})
|