diff --git a/e2e/playwright/named-views.spec.ts b/e2e/playwright/named-views.spec.ts index 28e5b192c..a95028bc6 100644 --- a/e2e/playwright/named-views.spec.ts +++ b/e2e/playwright/named-views.spec.ts @@ -6,7 +6,9 @@ import type { NamedView } from '@rust/kcl-lib/bindings/NamedView' import { createProject, - perProjectsettingsToToml, + orRunWhenFullSuiteEnabled, + perProjectSettingsToToml, + runningOnMac, tomlToPerProjectSettings, } from '@e2e/playwright/test-utils' import { expect, test } from '@e2e/playwright/zoo-test' @@ -57,11 +59,13 @@ function tomlStringOverWriteNamedViewUuids(toml: string): string { settings.settings.app.named_views = remappedNamedViews } } - return perProjectsettingsToToml(settings) + return perProjectSettingsToToml(settings) } test.describe('Named view tests', () => { - test.skip() // TODO: Jace is working on these + if (runningOnMac()) { + test.fixme(orRunWhenFullSuiteEnabled()) + } test('Verify project.toml is not created', async ({ page }, testInfo) => { // Create project and load it const projectName = 'named-views' @@ -105,6 +109,9 @@ test.describe('Named view tests', () => { PROJECT_SETTINGS_FILE_NAME ) + const toastMessage = page.getByText('Named view uuid1 created.') + await expect(toastMessage).toBeInViewport() + // Expect project.toml to be generated on disk since a named view was created await expect(async () => { let exists = await fileExists(tempProjectSettingsFilePath) @@ -130,7 +137,6 @@ test.describe('Named view tests', () => { }, testInfo) => { const projectName = 'named-views' const myNamedView1 = 'uuid1' - const myNamedView2 = 'uuid2' // Create project and go into the project await createProject({ name: projectName, page }) @@ -142,6 +148,9 @@ test.describe('Named view tests', () => { await cmdBar.argumentInput.fill(myNamedView1) await cmdBar.progressCmdBar(false) + let toastMessage = page.getByText('Named view uuid1 created.') + await expect(toastMessage).toBeInViewport() + // Generate file paths for project.toml const projectDirName = testInfo.outputPath('electron-test-projects-dir') const tempProjectSettingsFilePath = join( @@ -170,17 +179,20 @@ test.describe('Named view tests', () => { // Delete a named view await cmdBar.openCmdBar() await cmdBar.chooseCommand('delete named view') - cmdBar.selectOption({ name: myNamedView2 }) + cmdBar.selectOption({ name: myNamedView1 }) await cmdBar.progressCmdBar(false) + toastMessage = page.getByText('Named view uuid1 removed.') + await expect(toastMessage).toBeInViewport() + await expect(async () => { // Read project.toml into memory again since we deleted a named view let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8') // Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break tomlString = tomlStringOverWriteNamedViewUuids(tomlString) - // // Write the entire tomlString to a snapshot. - // // There are many key/value pairs to check this is a safer match. + // Write the entire tomlString to a snapshot. + // There are many key/value pairs to check this is a safer match. expect(tomlString).toMatchSnapshot('verify-named-view-gets-deleted') }).toPass() }) @@ -202,6 +214,9 @@ test.describe('Named view tests', () => { await cmdBar.argumentInput.fill(myNamedView) await cmdBar.progressCmdBar(false) + let toastMessage = page.getByText('Named view uuid1 created.') + await expect(toastMessage).toBeInViewport() + // Generate file paths for project.toml const projectDirName = testInfo.outputPath('electron-test-projects-dir') const tempProjectSettingsFilePath = join( @@ -258,26 +273,19 @@ test.describe('Named view tests', () => { await cmdBar.argumentInput.fill(myNamedView1) await cmdBar.progressCmdBar(false) - await page.waitForTimeout(1000) + let toastMessage = page.getByText('Named view uuid1 created.') + await expect(toastMessage).toBeInViewport() - const orbitMouseStart = { x: 800, y: 130 } - const orbitMouseEnd = { x: 0, y: 130 } - await page.mouse.move(orbitMouseStart.x, orbitMouseStart.y) - await page.mouse.down({ button: 'middle' }) - await page.mouse.move(orbitMouseEnd.x, orbitMouseEnd.y, { - steps: 3, - }) - await page.mouse.up({ button: 'middle' }) - - await page.waitForTimeout(1000) + await scene.moveCameraTo({ x: 608, y: 0, z: 0 }, { x: 0, y: 0, z: 0 }) + await page.waitForTimeout(2500) await cmdBar.openCmdBar() await cmdBar.chooseCommand('create named view') await cmdBar.argumentInput.fill(myNamedView2) await cmdBar.progressCmdBar(false) - // Wait a moment for the project.toml to get written to disk with the new view point - await page.waitForTimeout(1000) + toastMessage = page.getByText('Named view uuid2 created.') + await expect(toastMessage).toBeInViewport() // Generate paths for the project.toml const tempProjectSettingsFilePath = join( diff --git a/e2e/playwright/named-views.spec.ts-snapshots/verify-named-view-gets-deleted-chromium-linux b/e2e/playwright/named-views.spec.ts-snapshots/verify-named-view-gets-deleted-chromium-linux index 04d37214a..535bdeed1 100644 --- a/e2e/playwright/named-views.spec.ts-snapshots/verify-named-view-gets-deleted-chromium-linux +++ b/e2e/playwright/named-views.spec.ts-snapshots/verify-named-view-gets-deleted-chromium-linux @@ -1,16 +1,5 @@ [settings] +app = { } modeling = { } text_editor = { } command_bar = { } - -[settings.app.named_views.0656fb1a-9640-473e-b334-591dc70c0138] -name = "uuid1" -eye_offset = 1_378.0059 -fov_y = 45 -is_ortho = false -ortho_scale_enabled = true -ortho_scale_factor = 1.6 -pivot_position = [ 0, 0, 0 ] -pivot_rotation = [ 0.5380994, 0.0, 0.0, 0.8428814 ] -world_coord_system = "right_handed_up_z" -version = 1 diff --git a/e2e/playwright/named-views.spec.ts-snapshots/verify-two-named-view-gets-created-chromium-linux b/e2e/playwright/named-views.spec.ts-snapshots/verify-two-named-view-gets-created-chromium-linux index 555dbad81..5723b4ac9 100644 --- a/e2e/playwright/named-views.spec.ts-snapshots/verify-two-named-view-gets-created-chromium-linux +++ b/e2e/playwright/named-views.spec.ts-snapshots/verify-two-named-view-gets-created-chromium-linux @@ -17,12 +17,12 @@ version = 1 [settings.app.named_views.c810cf04-c6cc-4a4a-8b11-17bf445dcab7] name = "uuid2" -eye_offset = 1_378.0059 +eye_offset = 608 fov_y = 45 is_ortho = false ortho_scale_enabled = true ortho_scale_factor = 1.6 -pivot_position = [ 1_826.5239, 0.0, 0.0 ] -pivot_rotation = [ 0.5380994, 0.0, 0.0, 0.8428814 ] +pivot_position = [ 0, 0, 0 ] +pivot_rotation = [ 0.5, 0.5, 0.5, 0.5 ] world_coord_system = "right_handed_up_z" version = 1 diff --git a/e2e/playwright/test-utils.ts b/e2e/playwright/test-utils.ts index 524dda15d..5b539aec1 100644 --- a/e2e/playwright/test-utils.ts +++ b/e2e/playwright/test-utils.ts @@ -1140,7 +1140,7 @@ export function tomlToPerProjectSettings( return TOML.parse(toml) } -export function perProjectsettingsToToml( +export function perProjectSettingsToToml( settings: DeepPartial ) { // eslint-disable-next-line no-restricted-syntax diff --git a/src/lib/commandBarConfigs/namedViewsConfig.ts b/src/lib/commandBarConfigs/namedViewsConfig.ts index de0822067..997e3cd16 100644 --- a/src/lib/commandBarConfigs/namedViewsConfig.ts +++ b/src/lib/commandBarConfigs/namedViewsConfig.ts @@ -160,10 +160,11 @@ export function createNamedViewsCommand() { data: { level: 'project', value: requestedNamedViews, + toastCallback: () => { + toast.success(`Named view ${requestedView.name} created.`) + }, }, }) - - toast.success(`Named view ${requestedView.name} created.`) } } } @@ -210,9 +211,11 @@ export function createNamedViewsCommand() { data: { level: 'project', value: rest, + toastCallback: () => { + toast.success(`Named view ${viewToDelete.name} removed.`) + }, }, }) - toast.success(`Named view ${viewToDelete.name} removed.`) } else { toast.error(`Unable to delete, could not find the named view`) } @@ -307,6 +310,8 @@ export function createNamedViewsCommand() { type: 'default_camera_get_settings', }, }) + + // We do not have the promise of the engine command for ensuring the camera projection has been completed. toast.success(`Named view ${name} loaded.`) } else { toast.error(`Unable to load named view, could not find named view`) diff --git a/src/machines/settingsMachine.ts b/src/machines/settingsMachine.ts index 5efb6ba96..b51e96c71 100644 --- a/src/machines/settingsMachine.ts +++ b/src/machines/settingsMachine.ts @@ -76,7 +76,14 @@ export const settingsMachine = setup({ level: SettingsLevel } | { type: 'Set all settings'; settings: typeof settings } - | { type: 'set.app.namedViews'; value: NamedView } + | { + type: 'set.app.namedViews' + data: { + value: NamedView + toastCallback: () => void + level: SettingsLevel + } + } | { type: 'load.project'; project?: Project } | { type: 'clear.project' } ) & { doNotPersist?: boolean }, @@ -84,7 +91,11 @@ export const settingsMachine = setup({ actors: { persistSettings: fromPromise< void, - { doNotPersist: boolean; context: SettingsMachineContext } + { + doNotPersist: boolean + context: SettingsMachineContext + toastCallback?: () => void + } >(async ({ input }) => { // Without this, when a user changes the file, it'd // create a detection loop with the file-system watcher. @@ -93,7 +104,12 @@ export const settingsMachine = setup({ codeManager.writeCausedByAppCheckedInFileTreeFileSystemWatcher = true const { currentProject, ...settings } = input.context - return saveSettings(settings, currentProject?.path) + const val = await saveSettings(settings, currentProject?.path) + + if (input.toastCallback) { + input.toastCallback() + } + return val }), loadUserSettings: fromPromise(async () => { const { settings } = await loadAndValidateSettings() @@ -517,6 +533,17 @@ export const settingsMachine = setup({ }, }, input: ({ context, event }) => { + if ( + event.type === 'set.app.namedViews' && + 'toastCallback' in event.data + ) { + return { + doNotPersist: event.doNotPersist ?? false, + context, + toastCallback: event.data.toastCallback, + } + } + return { doNotPersist: event.doNotPersist ?? false, context,