Add electron test for persisting open panes (#3535)

* 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 <ircsurfer33@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
This commit is contained in:
Jonathan Tran
2024-08-20 22:11:21 -04:00
committed by GitHub
parent 4a14ca38ab
commit d14b8f5443
2 changed files with 113 additions and 23 deletions

View File

@ -1,8 +1,9 @@
import { test, expect } from '@playwright/test' 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 { bracket } from 'lib/exampleKcl'
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates' import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates'
import fsp from 'fs/promises'
test.beforeEach(async ({ context, page }) => { test.beforeEach(async ({ context, page }) => {
await setup(context, page) await setup(context, page)
@ -217,3 +218,89 @@ test.describe('Code pane and errors', () => {
).toBeVisible() ).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()
}
)

View File

@ -105,17 +105,21 @@ async function waitForDefaultPlanesToBeVisible(page: Page) {
) )
} }
async function openKclCodePanel(page: Page) { async function openPane(page: Page, testId: string) {
const paneLocator = page.getByTestId('code-pane-button') const locator = page.getByTestId(testId)
const ariaSelected = await paneLocator?.getAttribute('aria-pressed') await expect(locator).toBeVisible()
const isOpen = ariaSelected === 'true' const isOpen = (await locator?.getAttribute('aria-pressed')) === 'true'
if (!isOpen) { if (!isOpen) {
await paneLocator.click() await locator.click()
await expect(paneLocator).toHaveAttribute('aria-pressed', 'true') await expect(locator).toHaveAttribute('aria-pressed', 'true')
} }
} }
async function openKclCodePanel(page: Page) {
await openPane(page, 'code-pane-button')
}
async function closeKclCodePanel(page: Page) { async function closeKclCodePanel(page: Page) {
const paneLocator = page.getByTestId('code-pane-button') const paneLocator = page.getByTestId('code-pane-button')
const ariaSelected = await paneLocator?.getAttribute('aria-pressed') const ariaSelected = await paneLocator?.getAttribute('aria-pressed')
@ -128,14 +132,7 @@ async function closeKclCodePanel(page: Page) {
} }
async function openDebugPanel(page: Page) { async function openDebugPanel(page: Page) {
const debugLocator = page.getByTestId('debug-pane-button') await openPane(page, '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')
}
} }
async function closeDebugPanel(page: Page) { async function closeDebugPanel(page: Page) {
@ -149,14 +146,7 @@ async function closeDebugPanel(page: Page) {
} }
async function openFilePanel(page: Page) { async function openFilePanel(page: Page) {
const fileLocator = page.getByTestId('files-pane-button') await openPane(page, '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')
}
} }
async function closeFilePanel(page: Page) { 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) { async function waitForCmdReceive(page: Page, commandType: string) {
return page return page
.locator(`[data-receive-command-type="${commandType}"]`) .locator(`[data-receive-command-type="${commandType}"]`)
@ -344,6 +342,8 @@ export async function getUtils(page: Page) {
closeDebugPanel: () => closeDebugPanel(page), closeDebugPanel: () => closeDebugPanel(page),
openFilePanel: () => openFilePanel(page), openFilePanel: () => openFilePanel(page),
closeFilePanel: () => closeFilePanel(page), closeFilePanel: () => closeFilePanel(page),
openVariablesPane: () => openVariablesPane(page),
openLogsPane: () => openLogsPane(page),
openAndClearDebugPanel: async () => { openAndClearDebugPanel: async () => {
await openDebugPanel(page) await openDebugPanel(page)
return clearCommandLogs(page) return clearCommandLogs(page)
@ -679,6 +679,7 @@ export async function tearDown(page: Page, testInfo: TestInfo) {
export async function setup(context: BrowserContext, page: Page) { export async function setup(context: BrowserContext, page: Page) {
await context.addInitScript( await context.addInitScript(
async ({ token, settingsKey, settings, IS_PLAYWRIGHT_KEY }) => { async ({ token, settingsKey, settings, IS_PLAYWRIGHT_KEY }) => {
localStorage.clear()
localStorage.setItem('TOKEN_PERSIST_KEY', token) localStorage.setItem('TOKEN_PERSIST_KEY', token)
localStorage.setItem('persistCode', ``) localStorage.setItem('persistCode', ``)
localStorage.setItem(settingsKey, settings) localStorage.setItem(settingsKey, settings)
@ -714,6 +715,8 @@ export async function setup(context: BrowserContext, page: Page) {
]) ])
// kill animations, speeds up tests and reduced flakiness // kill animations, speeds up tests and reduced flakiness
await page.emulateMedia({ reducedMotion: 'reduce' }) await page.emulateMedia({ reducedMotion: 'reduce' })
await page.reload()
} }
export async function setupElectron({ export async function setupElectron({