From d14b8f5443bba64c5ab53745d2a169d53e850559 Mon Sep 17 00:00:00 2001 From: Jonathan Tran Date: Tue, 20 Aug 2024 22:11:21 -0400 Subject: [PATCH] Add electron test for persisting open panes (#3535) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add electron test for persisting open panes * Debugging persistence across test runs * Trigger addInitScript for electron * Remove init of PERSIST_MODELING_CONTEXT key * Remove unused code * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) --------- Co-authored-by: 49lf Co-authored-by: github-actions[bot] Co-authored-by: Jess Frazelle --- e2e/playwright/code-pane-and-errors.spec.ts | 89 ++++++++++++++++++++- e2e/playwright/test-utils.ts | 47 ++++++----- 2 files changed, 113 insertions(+), 23 deletions(-) diff --git a/e2e/playwright/code-pane-and-errors.spec.ts b/e2e/playwright/code-pane-and-errors.spec.ts index 2e30d82128..725c677e5e 100644 --- a/e2e/playwright/code-pane-and-errors.spec.ts +++ b/e2e/playwright/code-pane-and-errors.spec.ts @@ -1,8 +1,9 @@ import { test, expect } from '@playwright/test' -import { getUtils, setup, tearDown } from './test-utils' +import { getUtils, setup, setupElectron, tearDown } from './test-utils' import { bracket } from 'lib/exampleKcl' import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates' +import fsp from 'fs/promises' test.beforeEach(async ({ context, page }) => { await setup(context, page) @@ -217,3 +218,89 @@ test.describe('Code pane and errors', () => { ).toBeVisible() }) }) + +test( + 'Opening multiple panes persists when switching projects', + { tag: '@electron' }, + async ({ browserName }, testInfo) => { + // Setup multiple projects. + const { electronApp, page } = await setupElectron({ + testInfo, + folderSetupFn: async (dir) => { + await Promise.all([ + fsp.mkdir(`${dir}/router-template-slate`, { recursive: true }), + fsp.mkdir(`${dir}/bracket`, { recursive: true }), + ]) + await Promise.all([ + fsp.copyFile( + 'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl', + `${dir}/router-template-slate/main.kcl` + ), + fsp.copyFile( + 'src/wasm-lib/tests/executor/inputs/focusrite_scarlett_mounting_braket.kcl', + `${dir}/bracket/main.kcl` + ), + ]) + }, + }) + + const u = await getUtils(page) + await page.setViewportSize({ width: 1200, height: 500 }) + + await test.step('Opening the bracket project should load', async () => { + await expect(page.getByText('bracket')).toBeVisible() + + await page.getByText('bracket').click() + + await expect(page.getByTestId('loading')).toBeAttached() + await expect(page.getByTestId('loading')).not.toBeAttached({ + timeout: 20_000, + }) + }) + + // If they're open by default, we're not actually testing anything. + await test.step('Pre-condition: panes are not already visible', async () => { + await expect(page.locator('#variables-pane')).not.toBeVisible() + await expect(page.locator('#logs-pane')).not.toBeVisible() + }) + + await test.step('Open multiple panes', async () => { + await u.openKclCodePanel() + await u.openVariablesPane() + await u.openLogsPane() + }) + + await test.step('Clicking the logo takes us back to the projects page / home', async () => { + await page.getByTestId('app-logo').click() + + await expect(page.getByRole('link', { name: 'bracket' })).toBeVisible() + await expect(page.getByText('router-template-slate')).toBeVisible() + await expect(page.getByText('New Project')).toBeVisible() + }) + + await test.step('Opening the router-template project should load', async () => { + await expect(page.getByText('router-template-slate')).toBeVisible() + + await page.getByText('router-template-slate').click() + + await expect(page.getByTestId('loading')).toBeAttached() + await expect(page.getByTestId('loading')).not.toBeAttached({ + timeout: 20_000, + }) + + await expect( + page.getByRole('button', { name: 'Start Sketch' }) + ).toBeEnabled({ + timeout: 20_000, + }) + }) + + await test.step('All panes opened before should be visible', async () => { + await expect(page.locator('#code-pane')).toBeVisible() + await expect(page.locator('#variables-pane')).toBeVisible() + await expect(page.locator('#logs-pane')).toBeVisible() + }) + + await electronApp.close() + } +) diff --git a/e2e/playwright/test-utils.ts b/e2e/playwright/test-utils.ts index a90ff2ef9b..e873e65bbc 100644 --- a/e2e/playwright/test-utils.ts +++ b/e2e/playwright/test-utils.ts @@ -105,17 +105,21 @@ async function waitForDefaultPlanesToBeVisible(page: Page) { ) } -async function openKclCodePanel(page: Page) { - const paneLocator = page.getByTestId('code-pane-button') - const ariaSelected = await paneLocator?.getAttribute('aria-pressed') - const isOpen = ariaSelected === 'true' +async function openPane(page: Page, testId: string) { + const locator = page.getByTestId(testId) + await expect(locator).toBeVisible() + const isOpen = (await locator?.getAttribute('aria-pressed')) === 'true' if (!isOpen) { - await paneLocator.click() - await expect(paneLocator).toHaveAttribute('aria-pressed', 'true') + await locator.click() + await expect(locator).toHaveAttribute('aria-pressed', 'true') } } +async function openKclCodePanel(page: Page) { + await openPane(page, 'code-pane-button') +} + async function closeKclCodePanel(page: Page) { const paneLocator = page.getByTestId('code-pane-button') const ariaSelected = await paneLocator?.getAttribute('aria-pressed') @@ -128,14 +132,7 @@ async function closeKclCodePanel(page: Page) { } async function openDebugPanel(page: Page) { - const debugLocator = page.getByTestId('debug-pane-button') - await expect(debugLocator).toBeVisible() - const isOpen = (await debugLocator?.getAttribute('aria-pressed')) === 'true' - - if (!isOpen) { - await debugLocator.click() - await expect(debugLocator).toHaveAttribute('aria-pressed', 'true') - } + await openPane(page, 'debug-pane-button') } async function closeDebugPanel(page: Page) { @@ -149,14 +146,7 @@ async function closeDebugPanel(page: Page) { } async function openFilePanel(page: Page) { - const fileLocator = page.getByTestId('files-pane-button') - await expect(fileLocator).toBeVisible() - const isOpen = (await fileLocator?.getAttribute('aria-pressed')) === 'true' - - if (!isOpen) { - await fileLocator.click() - await expect(fileLocator).toHaveAttribute('aria-pressed', 'true') - } + await openPane(page, 'files-pane-button') } async function closeFilePanel(page: Page) { @@ -169,6 +159,14 @@ async function closeFilePanel(page: Page) { } } +async function openVariablesPane(page: Page) { + await openPane(page, 'variables-pane-button') +} + +async function openLogsPane(page: Page) { + await openPane(page, 'logs-pane-button') +} + async function waitForCmdReceive(page: Page, commandType: string) { return page .locator(`[data-receive-command-type="${commandType}"]`) @@ -344,6 +342,8 @@ export async function getUtils(page: Page) { closeDebugPanel: () => closeDebugPanel(page), openFilePanel: () => openFilePanel(page), closeFilePanel: () => closeFilePanel(page), + openVariablesPane: () => openVariablesPane(page), + openLogsPane: () => openLogsPane(page), openAndClearDebugPanel: async () => { await openDebugPanel(page) return clearCommandLogs(page) @@ -679,6 +679,7 @@ export async function tearDown(page: Page, testInfo: TestInfo) { export async function setup(context: BrowserContext, page: Page) { await context.addInitScript( async ({ token, settingsKey, settings, IS_PLAYWRIGHT_KEY }) => { + localStorage.clear() localStorage.setItem('TOKEN_PERSIST_KEY', token) localStorage.setItem('persistCode', ``) localStorage.setItem(settingsKey, settings) @@ -714,6 +715,8 @@ export async function setup(context: BrowserContext, page: Page) { ]) // kill animations, speeds up tests and reduced flakiness await page.emulateMedia({ reducedMotion: 'reduce' }) + + await page.reload() } export async function setupElectron({