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:
@ -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()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ -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({
|
||||||
|
Reference in New Issue
Block a user