This commit is contained in:
49lf
2024-11-22 16:09:09 -05:00
parent 249e35f9e0
commit 4c28af615c
12 changed files with 2877 additions and 2675 deletions

View File

@ -9,7 +9,11 @@ import { HomePageFixture } from './fixtures/homePageFixture'
test.setTimeout(120000) test.setTimeout(120000)
async function doBasicSketch(page: Page, homePage: HomePageFixture, openPanes: string[]) { async function doBasicSketch(
page: Page,
homePage: HomePageFixture,
openPanes: string[]
) {
const u = await getUtils(page) const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio const PUR = 400 / 37.5 //pixeltoUnitRatio
@ -139,16 +143,19 @@ async function doBasicSketch(page: Page, homePage: HomePageFixture, openPanes: s
} }
test.describe('Basic sketch', () => { test.describe('Basic sketch', () => {
test('code pane open at start', async ({ page, homePage }) => { // Skip on windows it is being weird. test('code pane open at start', async ({ page, homePage }) => {
// Skip on windows it is being weird.
await doBasicSketch(page, homePage, ['code']) await doBasicSketch(page, homePage, ['code'])
}) })
test('code pane closed at start', async ({ page, homePage }) => { // Load the app with the code panes test('code pane closed at start', async ({ page, homePage }) => {
await page.addInitScript(async (persistModelingContext) => { // Load the app with the code panes
localStorage.setItem( await page.addInitScript(async (persistModelingContext) => {
persistModelingContext, localStorage.setItem(
JSON.stringify({ openPanes: [] }) persistModelingContext,
) JSON.stringify({ openPanes: [] })
}, PERSIST_MODELING_CONTEXT) )
await doBasicSketch(page, homePage, []) }) }, PERSIST_MODELING_CONTEXT)
await doBasicSketch(page, homePage, [])
})
}) })

View File

@ -79,12 +79,13 @@ test.describe('Can create sketches on all planes and their back sides', () => {
} }
test('XY', async ({ page, homePage }) => { test('XY', async ({ page, homePage }) => {
await sketchOnPlaneAndBackSideTest( await sketchOnPlaneAndBackSideTest(
page, page,
homePage, homePage,
'XY', 'XY',
{ x: 600, y: 388 } // red plane { x: 600, y: 388 } // red plane
// { x: 600, y: 400 }, // red plane // clicks grid helper and that causes problems, should fix so that these coords work too. // { x: 600, y: 400 }, // red plane // clicks grid helper and that causes problems, should fix so that these coords work too.
) }) )
})
test('YZ', async ({ page, homePage }) => { test('YZ', async ({ page, homePage }) => {
await sketchOnPlaneAndBackSideTest(page, homePage, 'YZ', { x: 700, y: 250 }) // green plane await sketchOnPlaneAndBackSideTest(page, homePage, 'YZ', { x: 700, y: 250 }) // green plane
@ -95,11 +96,17 @@ test.describe('Can create sketches on all planes and their back sides', () => {
}) })
test('-XY', async ({ page, homePage }) => { test('-XY', async ({ page, homePage }) => {
await sketchOnPlaneAndBackSideTest(page, homePage, '-XY', { x: 600, y: 118 }) // back of red plane await sketchOnPlaneAndBackSideTest(page, homePage, '-XY', {
x: 600,
y: 118,
}) // back of red plane
}) })
test('-YZ', async ({ page, homePage }) => { test('-YZ', async ({ page, homePage }) => {
await sketchOnPlaneAndBackSideTest(page, homePage, '-YZ', { x: 700, y: 219 }) // back of green plan await sketchOnPlaneAndBackSideTest(page, homePage, '-YZ', {
x: 700,
y: 219,
}) // back of green plan
}) })
test('-XZ', async ({ page, homePage }) => { test('-XZ', async ({ page, homePage }) => {

View File

@ -1,22 +1,23 @@
import { test, expect } from './zoo-test' import { test, expect } from './zoo-test'
import { import { getUtils, executorInputPath } from './test-utils'
getUtils,
executorInputPath,
} from './test-utils'
import { join } from 'path' import { join } from 'path'
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' import fsp from 'fs/promises'
test.describe('Code pane and errors', () => { test.describe('Code pane and errors', () => {
test('Typing KCL errors induces a badge on the code pane button', async ({ page, homePage }) => { const u = await getUtils(page) test('Typing KCL errors induces a badge on the code pane button', async ({
page,
// Load the app with the working starter code homePage,
await page.addInitScript(() => { }) => {
localStorage.setItem( const u = await getUtils(page)
'persistCode',
`// Extruded Triangle // Load the app with the working starter code
await page.addInitScript(() => {
localStorage.setItem(
'persistCode',
`// Extruded Triangle
sketch001 = startSketchOn('XZ') sketch001 = startSketchOn('XZ')
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> line([10, 0], %) |> line([10, 0], %)
@ -24,191 +25,207 @@ test.describe('Code pane and errors', () => {
|> lineTo([profileStartX(%), profileStartY(%)], %) |> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%) |> close(%)
extrude001 = extrude(5, sketch001)` extrude001 = extrude(5, sketch001)`
) )
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Ensure no badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).not.toContainText('notification')
// Delete a character to break the KCL
await u.openKclCodePanel()
await page.getByText('extrude(').click()
await page.keyboard.press('Backspace')
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
}) })
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Ensure no badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).not.toContainText('notification')
// Delete a character to break the KCL
await u.openKclCodePanel()
await page.getByText('extrude(').click()
await page.keyboard.press('Backspace')
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification') })
test('Opening and closing the code pane will consistently show error diagnostics', async ({ page, homePage }) => { test('Opening and closing the code pane will consistently show error diagnostics', async ({
page,
const u = await getUtils(page) homePage,
}) => {
// Load the app with the working starter code const u = await getUtils(page)
await page.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, bracket)
await page.setBodyDimensions({ width: 1200, height: 900 })
await homePage.goToModelingScene()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Ensure we have no errors in the gutter.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Ensure no badge is present
const codePaneButton = page.getByRole('button', { name: 'KCL Code pane' })
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).not.toContainText('notification')
// Delete a character to break the KCL
await u.openKclCodePanel()
await page.getByText('thickness, bracketLeg1Sketch)').click()
await page.keyboard.press('Backspace')
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.locator('.cm-tooltip').first()).toBeVisible()
// Close the code pane
await codePaneButton.click()
await page.waitForTimeout(500)
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Open the code pane
await u.openKclCodePanel()
// Ensure that a badge appears on the button
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.locator('.cm-tooltip').first()).toBeVisible() })
test('When error is not in view you can click the badge to scroll to it', async ({ page, homePage, context }) => { const u = await getUtils(page) // Load the app with the working starter code
await page.addInitScript((code) => {
// Load the app with the working starter code localStorage.setItem('persistCode', code)
await context.addInitScript((code) => { }, bracket)
localStorage.setItem('persistCode', code)
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.waitForTimeout(1000)
// Ensure badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter, since error out of view.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click the badge.
const badge = page.locator('#code-badge')
await expect(badge).toBeVisible()
await badge.click()
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
// Hover over the error to see the error message
await page.hover('.cm-lint-marker-error')
await expect(
page
.getByText(
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
)
.first()
).toBeVisible() })
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({ context, page, homePage }) => { const u = await getUtils(page) await page.setBodyDimensions({ width: 1200, height: 900 })
await homePage.goToModelingScene()
// Load the app with the working starter code
await context.addInitScript((code) => { // wait for execution done
localStorage.setItem('persistCode', code) await u.openDebugPanel()
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW) await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() // Ensure we have no errors in the gutter.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
await page.waitForTimeout(1000)
// Ensure no badge is present
// Ensure badge is present const codePaneButton = page.getByRole('button', { name: 'KCL Code pane' })
const codePaneButtonHolder = page.locator('#code-button-holder') const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).toContainText('notification') await expect(codePaneButtonHolder).not.toContainText('notification')
// Ensure we have no errors in the gutter, since error out of view. // Delete a character to break the KCL
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible() await u.openKclCodePanel()
await page.getByText('thickness, bracketLeg1Sketch)').click()
// click in the editor to focus it await page.keyboard.press('Backspace')
await page.locator('.cm-content').click()
// Ensure that a badge appears on the button
await page.waitForTimeout(500) await expect(codePaneButtonHolder).toContainText('notification')
// go to the start of the editor and enter more text which will trigger // Ensure we have an error diagnostic.
// a lint error. await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// GO to the start of the editor.
await page.keyboard.press('ArrowUp') // error text on hover
await page.keyboard.press('ArrowUp') await page.hover('.cm-lint-marker-error')
await page.keyboard.press('ArrowUp') await expect(page.locator('.cm-tooltip').first()).toBeVisible()
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp') // Close the code pane
await page.keyboard.press('ArrowUp') await codePaneButton.click()
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp') await page.waitForTimeout(500)
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp') // Ensure that a badge appears on the button
await page.keyboard.press('Home') await expect(codePaneButtonHolder).toContainText('notification')
await page.keyboard.type('foo_bar = 1') // Ensure we have no errors in the gutter.
await page.waitForTimeout(500) await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
await page.keyboard.press('Enter')
// Open the code pane
// ensure we have a lint error await u.openKclCodePanel()
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
// Ensure that a badge appears on the button
// Click the badge. await expect(codePaneButtonHolder).toContainText('notification')
const badge = page.locator('#code-badge')
await expect(badge).toBeVisible() // Ensure we have an error diagnostic.
await badge.click() await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
// Ensure we have an error diagnostic. // error text on hover
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible() await page.hover('.cm-lint-marker-error')
await expect(page.locator('.cm-tooltip').first()).toBeVisible()
// Hover over the error to see the error message })
await page.hover('.cm-lint-marker-error')
await expect( test('When error is not in view you can click the badge to scroll to it', async ({
page page,
.getByText( homePage,
'sketch profile must lie entirely on one side of the revolution axis' context,
) }) => {
.first() const u = await getUtils(page)
).toBeVisible() })
// Load the app with the working starter code
await context.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.waitForTimeout(1000)
// Ensure badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter, since error out of view.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// Click the badge.
const badge = page.locator('#code-badge')
await expect(badge).toBeVisible()
await badge.click()
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
// Hover over the error to see the error message
await page.hover('.cm-lint-marker-error')
await expect(
page
.getByText(
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
)
.first()
).toBeVisible()
})
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
context,
page,
homePage,
}) => {
const u = await getUtils(page)
// Load the app with the working starter code
await context.addInitScript((code) => {
localStorage.setItem('persistCode', code)
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.waitForTimeout(1000)
// Ensure badge is present
const codePaneButtonHolder = page.locator('#code-button-holder')
await expect(codePaneButtonHolder).toContainText('notification')
// Ensure we have no errors in the gutter, since error out of view.
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// click in the editor to focus it
await page.locator('.cm-content').click()
await page.waitForTimeout(500)
// go to the start of the editor and enter more text which will trigger
// a lint error.
// GO to the start of the editor.
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.press('Home')
await page.keyboard.type('foo_bar = 1')
await page.waitForTimeout(500)
await page.keyboard.press('Enter')
// ensure we have a lint error
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
// Click the badge.
const badge = page.locator('#code-badge')
await expect(badge).toBeVisible()
await badge.click()
// Ensure we have an error diagnostic.
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
// Hover over the error to see the error message
await page.hover('.cm-lint-marker-error')
await expect(
page
.getByText(
'sketch profile must lie entirely on one side of the revolution axis'
)
.first()
).toBeVisible()
})
}) })
test( test(
@ -287,7 +304,7 @@ test(
{ tag: '@electron' }, { tag: '@electron' },
async ({ context, browserName, page }, testInfo) => { async ({ context, browserName, page }, testInfo) => {
const PROJECT_DIR_NAME = 'lee-was-here' const PROJECT_DIR_NAME = 'lee-was-here'
const { dir: projectsDir, } = await context.folderSetupFn(async (dir) => { const { dir: projectsDir } = await context.folderSetupFn(async (dir) => {
const aProjectDir = join(dir, PROJECT_DIR_NAME) const aProjectDir = join(dir, PROJECT_DIR_NAME)
await fsp.mkdir(aProjectDir, { recursive: true }) await fsp.mkdir(aProjectDir, { recursive: true })
}) })

View File

@ -5,46 +5,52 @@ import { KCL_DEFAULT_LENGTH } from 'lib/constants'
import { normalizeLineEndings } from 'lib/codeEditor' import { normalizeLineEndings } from 'lib/codeEditor'
test.describe('Command bar tests', () => { test.describe('Command bar tests', () => {
test('Extrude from command bar selects extrude line after', async ({ page, homePage }) => { await page.addInitScript(async () => { test('Extrude from command bar selects extrude line after', async ({
localStorage.setItem( page,
'persistCode', homePage,
`sketch001 = startSketchOn('XY') }) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %) |> startProfileAt([-10, -10], %)
|> line([20, 0], %) |> line([20, 0], %)
|> line([0, 20], %) |> line([0, 20], %)
|> xLine(-20, %) |> xLine(-20, %)
|> close(%) |> close(%)
` `
)
})
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Click the line of code for xLine.
await page.getByText(`close(%)`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Extrude' }).click()
await page.waitForTimeout(200)
await page.keyboard.press('Enter')
await page.waitForTimeout(200)
await page.keyboard.press('Enter')
await page.waitForTimeout(200)
await expect(page.locator('.cm-activeLine')).toHaveText(
`extrude001 = extrude(${KCL_DEFAULT_LENGTH}, sketch001)`
) )
}) })
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Click the line of code for xLine.
await page.getByText(`close(%)`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Extrude' }).click()
await page.waitForTimeout(200)
await page.keyboard.press('Enter')
await page.waitForTimeout(200)
await page.keyboard.press('Enter')
await page.waitForTimeout(200)
await expect(page.locator('.cm-activeLine')).toHaveText(
`extrude001 = extrude(${KCL_DEFAULT_LENGTH}, sketch001)`
) })
test('Fillet from command bar', async ({ page, homePage }) => { await page.addInitScript(async () => { test('Fillet from command bar', async ({ page, homePage }) => {
localStorage.setItem( await page.addInitScript(async () => {
'persistCode', localStorage.setItem(
`sketch001 = startSketchOn('XY') 'persistCode',
`sketch001 = startSketchOn('XY')
|> startProfileAt([-5, -5], %) |> startProfileAt([-5, -5], %)
|> line([0, 10], %) |> line([0, 10], %)
|> line([10, 0], %) |> line([10, 0], %)
@ -52,158 +58,170 @@ test.describe('Command bar tests', () => {
|> lineTo([profileStartX(%), profileStartY(%)], %) |> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%) |> close(%)
extrude001 = extrude(-10, sketch001)` extrude001 = extrude(-10, sketch001)`
)
})
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
const selectSegment = () => page.getByText(`line([0, -10], %)`).click()
await selectSegment()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Fillet' }).click()
await page.waitForTimeout(100)
await page.keyboard.press('Enter') // skip selection
await page.waitForTimeout(100)
await page.keyboard.press('Enter') // accept default radius
await page.waitForTimeout(100)
await page.keyboard.press('Enter') // submit
await page.waitForTimeout(100)
await expect(page.locator('.cm-activeLine')).toContainText(
`fillet({ radius: ${KCL_DEFAULT_LENGTH}, tags: [seg01] }, %)`
) )
}) })
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1000, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
const selectSegment = () => page.getByText(`line([0, -10], %)`).click()
await selectSegment()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Fillet' }).click()
await page.waitForTimeout(100)
await page.keyboard.press('Enter') // skip selection
await page.waitForTimeout(100)
await page.keyboard.press('Enter') // accept default radius
await page.waitForTimeout(100)
await page.keyboard.press('Enter') // submit
await page.waitForTimeout(100)
await expect(page.locator('.cm-activeLine')).toContainText(
`fillet({ radius: ${KCL_DEFAULT_LENGTH}, tags: [seg01] }, %)`
) })
test('Command bar can change a setting, and switch back and forth between arguments', async ({ page, homePage }) => { const u = await getUtils(page) test('Command bar can change a setting, and switch back and forth between arguments', async ({
await page.setBodyDimensions({ width: 1200, height: 500 }) page,
await homePage.goToModelingScene() homePage,
}) => {
const commandBarButton = page.getByRole('button', { name: 'Commands' }) const u = await getUtils(page)
const cmdSearchBar = page.getByPlaceholder('Search commands') await page.setBodyDimensions({ width: 1200, height: 500 })
const commandName = 'debug panel' await homePage.goToModelingScene()
const commandOption = page.getByRole('option', {
name: commandName, const commandBarButton = page.getByRole('button', { name: 'Commands' })
exact: false, const cmdSearchBar = page.getByPlaceholder('Search commands')
const commandName = 'debug panel'
const commandOption = page.getByRole('option', {
name: commandName,
exact: false,
})
const commandLevelArgButton = page.getByRole('button', { name: 'level' })
const commandThemeArgButton = page.getByRole('button', { name: 'value' })
const paneSelector = page.getByRole('button', { name: 'debug panel' })
// This selector changes after we set the setting
let commandOptionInput = page.getByPlaceholder('On')
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
// First try opening the command bar and closing it
await page
.getByRole('button', { name: 'Commands', exact: false })
.or(page.getByRole('button', { name: '⌘K' }))
.click()
await expect(cmdSearchBar).toBeVisible()
await page.keyboard.press('Escape')
await expect(cmdSearchBar).not.toBeVisible()
// Now try the same, but with the keyboard shortcut, check focus
await page.keyboard.press('ControlOrMeta+K')
await expect(cmdSearchBar).toBeVisible()
await expect(cmdSearchBar).toBeFocused()
// Try typing in the command bar
await cmdSearchBar.fill(commandName)
await expect(commandOption).toBeVisible()
await commandOption.click()
const toggleInput = page.getByPlaceholder('On')
await expect(toggleInput).toBeVisible()
await expect(toggleInput).toBeFocused()
// Select On
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await expect(page.getByRole('option', { name: 'Off' })).toHaveAttribute(
'data-headlessui-state',
'active'
)
await page.keyboard.press('Enter')
// Check the toast appeared
await expect(
page.getByText(`Set show debug panel to "false" for this project`)
).toBeVisible()
// Check that the visibility changed
await expect(paneSelector).not.toBeVisible()
commandOptionInput = page.locator('[id="option-input"]')
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
await commandBarButton.click()
await cmdSearchBar.focus()
await cmdSearchBar.fill(commandName)
await commandOption.click()
await expect(commandThemeArgButton).toBeDisabled()
await commandOptionInput.focus()
await commandOptionInput.fill('on')
await commandLevelArgButton.click()
await expect(commandLevelArgButton).toBeDisabled()
// Test case for https://github.com/KittyCAD/modeling-app/issues/2881
await commandThemeArgButton.click()
await expect(commandThemeArgButton).toBeDisabled()
await expect(commandLevelArgButton).toHaveText('level: project')
}) })
const commandLevelArgButton = page.getByRole('button', { name: 'level' })
const commandThemeArgButton = page.getByRole('button', { name: 'value' })
const paneSelector = page.getByRole('button', { name: 'debug panel' })
// This selector changes after we set the setting
let commandOptionInput = page.getByPlaceholder('On')
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
// First try opening the command bar and closing it
await page
.getByRole('button', { name: 'Commands', exact: false })
.or(page.getByRole('button', { name: '⌘K' }))
.click()
await expect(cmdSearchBar).toBeVisible()
await page.keyboard.press('Escape')
await expect(cmdSearchBar).not.toBeVisible()
// Now try the same, but with the keyboard shortcut, check focus
await page.keyboard.press('ControlOrMeta+K')
await expect(cmdSearchBar).toBeVisible()
await expect(cmdSearchBar).toBeFocused()
// Try typing in the command bar
await cmdSearchBar.fill(commandName)
await expect(commandOption).toBeVisible()
await commandOption.click()
const toggleInput = page.getByPlaceholder('On')
await expect(toggleInput).toBeVisible()
await expect(toggleInput).toBeFocused()
// Select On
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await expect(page.getByRole('option', { name: 'Off' })).toHaveAttribute(
'data-headlessui-state',
'active'
)
await page.keyboard.press('Enter')
// Check the toast appeared
await expect(
page.getByText(`Set show debug panel to "false" for this project`)
).toBeVisible()
// Check that the visibility changed
await expect(paneSelector).not.toBeVisible()
commandOptionInput = page.locator('[id="option-input"]')
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
await commandBarButton.click()
await cmdSearchBar.focus()
await cmdSearchBar.fill(commandName)
await commandOption.click()
await expect(commandThemeArgButton).toBeDisabled()
await commandOptionInput.focus()
await commandOptionInput.fill('on')
await commandLevelArgButton.click()
await expect(commandLevelArgButton).toBeDisabled()
// Test case for https://github.com/KittyCAD/modeling-app/issues/2881
await commandThemeArgButton.click()
await expect(commandThemeArgButton).toBeDisabled()
await expect(commandLevelArgButton).toHaveText('level: project') })
test('Command bar keybinding works from code editor and can change a setting', async ({ page, homePage }) => { const u = await getUtils(page) test('Command bar keybinding works from code editor and can change a setting', async ({
await page.setBodyDimensions({ width: 1200, height: 500 }) page,
await homePage.goToModelingScene() homePage,
}) => {
await expect( const u = await getUtils(page)
page.getByRole('button', { name: 'Start Sketch' }) await page.setBodyDimensions({ width: 1200, height: 500 })
).not.toBeDisabled() await homePage.goToModelingScene()
// Put the cursor in the code editor await expect(
await page.locator('.cm-content').click() page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
// Now try the same, but with the keyboard shortcut, check focus
await page.keyboard.press('ControlOrMeta+K') // Put the cursor in the code editor
await page.locator('.cm-content').click()
let cmdSearchBar = page.getByPlaceholder('Search commands')
await expect(cmdSearchBar).toBeVisible() // Now try the same, but with the keyboard shortcut, check focus
await expect(cmdSearchBar).toBeFocused() await page.keyboard.press('ControlOrMeta+K')
// Try typing in the command bar let cmdSearchBar = page.getByPlaceholder('Search commands')
await cmdSearchBar.fill('theme') await expect(cmdSearchBar).toBeVisible()
const themeOption = page.getByRole('option', { await expect(cmdSearchBar).toBeFocused()
name: 'Settings · app · theme',
// Try typing in the command bar
await cmdSearchBar.fill('theme')
const themeOption = page.getByRole('option', {
name: 'Settings · app · theme',
})
await expect(themeOption).toBeVisible()
await themeOption.click()
const themeInput = page.getByPlaceholder('dark')
await expect(themeInput).toBeVisible()
await expect(themeInput).toBeFocused()
// Select dark theme
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
'data-headlessui-state',
'active'
)
await page.keyboard.press('Enter')
// Check the toast appeared
await expect(
page.getByText(`Set theme to "system" as a user default`)
).toBeVisible()
// Check that the theme changed
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
}) })
await expect(themeOption).toBeVisible()
await themeOption.click()
const themeInput = page.getByPlaceholder('dark')
await expect(themeInput).toBeVisible()
await expect(themeInput).toBeFocused()
// Select dark theme
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown')
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
'data-headlessui-state',
'active'
)
await page.keyboard.press('Enter')
// Check the toast appeared
await expect(
page.getByText(`Set theme to "system" as a user default`)
).toBeVisible()
// Check that the theme changed
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`) })
test('Can extrude from the command bar', async ({ page, homePage }) => { await page.addInitScript(async () => { test('Can extrude from the command bar', async ({ page, homePage }) => {
localStorage.setItem( await page.addInitScript(async () => {
'persistCode', localStorage.setItem(
`distance = sqrt(20) 'persistCode',
`distance = sqrt(20)
sketch001 = startSketchOn('XZ') sketch001 = startSketchOn('XZ')
|> startProfileAt([-6.95, 10.98], %) |> startProfileAt([-6.95, 10.98], %)
|> line([25.1, 0.41], %) |> line([25.1, 0.41], %)
@ -211,117 +229,123 @@ test.describe('Command bar tests', () => {
|> line([-23.44, 0.52], %) |> line([-23.44, 0.52], %)
|> close(%) |> close(%)
` `
)
})
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// Make sure the stream is up
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await u.clearCommandLogs()
await page.getByRole('button', { name: 'Extrude' }).isEnabled()
let cmdSearchBar = page.getByPlaceholder('Search commands')
await page.keyboard.press('ControlOrMeta+K')
await expect(cmdSearchBar).toBeVisible()
// Search for extrude command and choose it
await page.getByRole('option', { name: 'Extrude' }).click()
// Assert that we're on the selection step
await expect(page.getByRole('button', { name: 'selection' })).toBeDisabled()
// Select a face
await page.mouse.move(700, 200)
await page.mouse.click(700, 200)
// Assert that we're on the distance step
await expect(
page.getByRole('button', { name: 'distance', exact: false })
).toBeDisabled()
// Assert that the an alternative variable name is chosen,
// since the default variable name is already in use (distance)
await page.getByRole('button', { name: 'Create new variable' }).click()
await expect(page.getByPlaceholder('Variable name')).toHaveValue(
'distance001'
)
const continueButton = page.getByRole('button', { name: 'Continue' })
const submitButton = page.getByRole('button', { name: 'Submit command' })
await continueButton.click()
// Review step and argument hotkeys
await expect(submitButton).toBeEnabled()
await expect(submitButton).toBeFocused()
await submitButton.press('Backspace')
// Assert we're back on the distance step
await expect(
page.getByRole('button', { name: 'distance', exact: false })
).toBeDisabled()
await continueButton.click()
await submitButton.click()
await u.waitForCmdReceive('extrude')
await expect(page.locator('.cm-content')).toContainText(
'extrude001 = extrude(distance001, sketch001)'
) )
}) })
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// Make sure the stream is up
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await u.clearCommandLogs()
await page.getByRole('button', { name: 'Extrude' }).isEnabled()
let cmdSearchBar = page.getByPlaceholder('Search commands')
await page.keyboard.press('ControlOrMeta+K')
await expect(cmdSearchBar).toBeVisible()
// Search for extrude command and choose it
await page.getByRole('option', { name: 'Extrude' }).click()
// Assert that we're on the selection step
await expect(page.getByRole('button', { name: 'selection' })).toBeDisabled()
// Select a face
await page.mouse.move(700, 200)
await page.mouse.click(700, 200)
// Assert that we're on the distance step
await expect(
page.getByRole('button', { name: 'distance', exact: false })
).toBeDisabled()
// Assert that the an alternative variable name is chosen,
// since the default variable name is already in use (distance)
await page.getByRole('button', { name: 'Create new variable' }).click()
await expect(page.getByPlaceholder('Variable name')).toHaveValue(
'distance001'
)
const continueButton = page.getByRole('button', { name: 'Continue' })
const submitButton = page.getByRole('button', { name: 'Submit command' })
await continueButton.click()
// Review step and argument hotkeys
await expect(submitButton).toBeEnabled()
await expect(submitButton).toBeFocused()
await submitButton.press('Backspace')
// Assert we're back on the distance step
await expect(
page.getByRole('button', { name: 'distance', exact: false })
).toBeDisabled()
await continueButton.click()
await submitButton.click()
await u.waitForCmdReceive('extrude')
await expect(page.locator('.cm-content')).toContainText('extrude001 = extrude(distance001, sketch001)') test('Can switch between sketch tools via command bar', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
}) const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
const rectangleToolCommand = page.getByRole('option', {
name: 'rectangle',
})
const rectangleToolButton = page.getByRole('button', {
name: 'rectangle Corner rectangle',
})
const lineToolCommand = page.getByRole('option', {
name: 'Line',
})
const lineToolButton = page.getByRole('button', {
name: 'line Line',
exact: true,
})
const arcToolCommand = page.getByRole('option', { name: 'Tangential Arc' })
const arcToolButton = page.getByRole('button', {
name: 'arc Tangential Arc',
})
test('Can switch between sketch tools via command bar', async ({ page, homePage }) => { const u = await getUtils(page) // Start a sketch
await page.setBodyDimensions({ width: 1200, height: 500 }) await sketchButton.click()
await homePage.goToModelingScene() await page.mouse.click(700, 200)
const sketchButton = page.getByRole('button', { name: 'Start Sketch' }) // Switch between sketch tools via the command bar
const cmdBarButton = page.getByRole('button', { name: 'Commands' }) await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
const rectangleToolCommand = page.getByRole('option', { await cmdBarButton.click()
name: 'rectangle', await rectangleToolCommand.click()
await expect(rectangleToolButton).toHaveAttribute('aria-pressed', 'true')
await cmdBarButton.click()
await lineToolCommand.click()
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
// Click in the scene a couple times to draw a line
// so tangential arc is valid
await page.mouse.click(700, 200)
await page.mouse.move(700, 300, { steps: 5 })
await page.mouse.click(700, 300)
// switch to tangential arc via command bar
await cmdBarButton.click()
await arcToolCommand.click()
await expect(arcToolButton).toHaveAttribute('aria-pressed', 'true')
}) })
const rectangleToolButton = page.getByRole('button', {
name: 'rectangle Corner rectangle',
})
const lineToolCommand = page.getByRole('option', {
name: 'Line',
})
const lineToolButton = page.getByRole('button', {
name: 'line Line',
exact: true,
})
const arcToolCommand = page.getByRole('option', { name: 'Tangential Arc' })
const arcToolButton = page.getByRole('button', {
name: 'arc Tangential Arc',
})
// Start a sketch
await sketchButton.click()
await page.mouse.click(700, 200)
// Switch between sketch tools via the command bar
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
await cmdBarButton.click()
await rectangleToolCommand.click()
await expect(rectangleToolButton).toHaveAttribute('aria-pressed', 'true')
await cmdBarButton.click()
await lineToolCommand.click()
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
// Click in the scene a couple times to draw a line
// so tangential arc is valid
await page.mouse.click(700, 200)
await page.mouse.move(700, 300, { steps: 5 })
await page.mouse.click(700, 300)
// switch to tangential arc via command bar
await cmdBarButton.click()
await arcToolCommand.click()
await expect(arcToolButton).toHaveAttribute('aria-pressed', 'true') })
}) })

View File

@ -1,23 +1,16 @@
import { test, expect } from '@playwright/test' import { test, expect } from './zoo-test'
import { getUtils, setup, tearDown } from './test-utils' import { getUtils } from './test-utils'
test.beforeEach(async ({ context, page }, testInfo) => {
await setup(context, page, testInfo)
})
test.afterEach(async ({ page }, testInfo) => {
await tearDown(page, testInfo)
})
test.describe('Copilot ghost text', () => { test.describe('Copilot ghost text', () => {
// eslint-disable-next-line jest/valid-title // eslint-disable-next-line jest/valid-title
test.skip(true, 'Needs to get covered again') test.skip(true, 'Needs to get covered again')
test('completes code in empty file', async ({ page }) => { test('completes code in empty file', async ({ page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -55,9 +48,9 @@ test.describe('Copilot ghost text', () => {
}) => { }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -101,12 +94,13 @@ test.describe('Copilot ghost text', () => {
test('copilot disabled in sketch mode after selecting plane', async ({ test('copilot disabled in sketch mode after selecting plane', async ({
page, page,
homePage,
}) => { }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -184,12 +178,12 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-ghostText')).not.toBeVisible() await expect(page.locator('.cm-ghostText')).not.toBeVisible()
}) })
test('ArrowUp in code rejects the suggestion', async ({ page }) => { test('ArrowUp in code rejects the suggestion', async ({ page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -212,12 +206,15 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
}) })
test('ArrowDown in code rejects the suggestion', async ({ page }) => { test('ArrowDown in code rejects the suggestion', async ({
page,
homePage,
}) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -240,12 +237,15 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
}) })
test('ArrowLeft in code rejects the suggestion', async ({ page }) => { test('ArrowLeft in code rejects the suggestion', async ({
page,
homePage,
}) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -268,12 +268,15 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
}) })
test('ArrowRight in code rejects the suggestion', async ({ page }) => { test('ArrowRight in code rejects the suggestion', async ({
page,
homePage,
}) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -296,12 +299,12 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
}) })
test('Enter in code scoots it down', async ({ page }) => { test('Enter in code scoots it down', async ({ page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -326,12 +329,15 @@ test.describe('Copilot ghost text', () => {
) )
}) })
test('Ctrl+shift+z in code rejects the suggestion', async ({ page }) => { test('Ctrl+shift+z in code rejects the suggestion', async ({
page,
homePage,
}) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
@ -360,12 +366,13 @@ test.describe('Copilot ghost text', () => {
test('Ctrl+z in code rejects the suggestion and undos the last code', async ({ test('Ctrl+z in code rejects the suggestion and undos the last code', async ({
page, page,
homePage,
}) => { }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await page.waitForTimeout(800) await page.waitForTimeout(800)
await u.codeLocator.click() await u.codeLocator.click()
@ -420,98 +427,107 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible() await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
// TODO when we make codemirror a widget, we can test this. // TODO when we make codemirror a widget, we can test this.
//await expect(page.locator('.cm-content')).toHaveText(``) //await expect(page.locator('.cm-content')).toHaveText(``) })
})
test('delete in code rejects the suggestion', async ({ page }) => { test('delete in code rejects the suggestion', async ({
const u = await getUtils(page) page,
// const PUR = 400 / 37.5 //pixeltoUnitRatio homePage,
await page.setViewportSize({ width: 1200, height: 500 }) }) => {
const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
await expect(page.locator('.cm-ghostText')).not.toBeVisible() await expect(page.locator('.cm-ghostText')).not.toBeVisible()
await page.waitForTimeout(500) await page.waitForTimeout(500)
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible() await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText( await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)` `fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
) )
await expect(page.locator('.cm-ghostText').first()).toHaveText( await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {` `fn cube = (pos, scale) => {`
) )
// Going elsewhere in the code should hide the ghost text. // Going elsewhere in the code should hide the ghost text.
await page.keyboard.press('Delete') await page.keyboard.press('Delete')
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible() await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
}) })
test('backspace in code rejects the suggestion', async ({ page }) => { test('backspace in code rejects the suggestion', async ({
const u = await getUtils(page) page,
// const PUR = 400 / 37.5 //pixeltoUnitRatio homePage,
await page.setViewportSize({ width: 1200, height: 500 }) }) => {
const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
await expect(page.locator('.cm-ghostText')).not.toBeVisible() await expect(page.locator('.cm-ghostText')).not.toBeVisible()
await page.waitForTimeout(500) await page.waitForTimeout(500)
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible() await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText( await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)` `fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
) )
await expect(page.locator('.cm-ghostText').first()).toHaveText( await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {` `fn cube = (pos, scale) => {`
) )
// Going elsewhere in the code should hide the ghost text. // Going elsewhere in the code should hide the ghost text.
await page.keyboard.press('Backspace') await page.keyboard.press('Backspace')
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible() await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
}) })
test('focus outside code pane rejects the suggestion', async ({ page }) => { test('focus outside code pane rejects the suggestion', async ({
const u = await getUtils(page) page,
// const PUR = 400 / 37.5 //pixeltoUnitRatio homePage,
await page.setViewportSize({ width: 1200, height: 500 }) }) => {
const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setBodyDimensions({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart() await homePage.goToModelingScene()
await u.codeLocator.click() await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
await expect(page.locator('.cm-ghostText')).not.toBeVisible() await expect(page.locator('.cm-ghostText')).not.toBeVisible()
await page.waitForTimeout(500) await page.waitForTimeout(500)
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
await expect(page.locator('.cm-ghostText').first()).toBeVisible() await expect(page.locator('.cm-ghostText').first()).toBeVisible()
await expect(page.locator('.cm-content')).toHaveText( await expect(page.locator('.cm-content')).toHaveText(
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)` `fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
) )
await expect(page.locator('.cm-ghostText').first()).toHaveText( await expect(page.locator('.cm-ghostText').first()).toHaveText(
`fn cube = (pos, scale) => {` `fn cube = (pos, scale) => {`
) )
// Going outside the editor should hide the ghost text. // Going outside the editor should hide the ghost text.
await page.mouse.move(0, 0) await page.mouse.move(0, 0)
await page await page
.getByRole('button', { name: 'Start Sketch' }) .getByRole('button', { name: 'Start Sketch' })
.waitFor({ state: 'visible' }) .waitFor({ state: 'visible' })
await page.getByRole('button', { name: 'Start Sketch' }).click() await page.getByRole('button', { name: 'Start Sketch' }).click()
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible() await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
await expect(page.locator('.cm-content')).toHaveText(``) await expect(page.locator('.cm-content')).toHaveText(``)
})
}) })
}) })

View File

@ -65,7 +65,7 @@ export class AuthenticatedTronApp {
public readonly testInfo: TestInfo public readonly testInfo: TestInfo
public electronApp?: ElectronApplication public electronApp?: ElectronApplication
public readonly viewPortSize = { width: 1200, height: 500 } public readonly viewPortSize = { width: 1200, height: 500 }
public dir: string = "" public dir: string = ''
constructor(context: BrowserContext, page: Page, testInfo: TestInfo) { constructor(context: BrowserContext, page: Page, testInfo: TestInfo) {
this._page = page this._page = page

File diff suppressed because it is too large Load Diff

View File

@ -418,7 +418,7 @@ export async function getUtils(page: Page, test_?: typeof test) {
codeLocator: page.locator('.cm-content'), codeLocator: page.locator('.cm-content'),
crushKclCodeIntoOneLineAndThenMaybeSome: async () => { crushKclCodeIntoOneLineAndThenMaybeSome: async () => {
const code = await page.locator('.cm-content').innerText() const code = await page.locator('.cm-content').innerText()
return code.replaceAll(' ', '').replaceAll("\n", '') return code.replaceAll(' ', '').replaceAll('\n', '')
}, },
normalisedEditorCode: async () => { normalisedEditorCode: async () => {
const code = await page.locator('.cm-content').innerText() const code = await page.locator('.cm-content').innerText()
@ -687,14 +687,16 @@ const moveDownloadedFileTo = async (page: Page, toLocation: string) => {
const downloadDir = path.resolve( const downloadDir = path.resolve(
page.TEST_SETTINGS_FILE_KEY, page.TEST_SETTINGS_FILE_KEY,
"downloads-during-playwright" 'downloads-during-playwright'
) )
// Expect there to be at least one file // Expect there to be at least one file
expect.poll(async () => { expect
const files = await fsp.readdir(downloadDir) .poll(async () => {
return files.length const files = await fsp.readdir(downloadDir)
}).toBe(1) return files.length
})
.toBe(1)
// Go through the downloads dir and move files to new location // Go through the downloads dir and move files to new location
const files = await fsp.readdir(downloadDir) const files = await fsp.readdir(downloadDir)
@ -832,7 +834,13 @@ export async function setup(
testInfo?: TestInfo testInfo?: TestInfo
) { ) {
await context.addInitScript( await context.addInitScript(
async ({ token, settingsKey, settings, IS_PLAYWRIGHT_KEY, PLAYWRIGHT_TEST_DIR }) => { async ({
token,
settingsKey,
settings,
IS_PLAYWRIGHT_KEY,
PLAYWRIGHT_TEST_DIR,
}) => {
localStorage.clear() localStorage.clear()
localStorage.setItem('TOKEN_PERSIST_KEY', token) localStorage.setItem('TOKEN_PERSIST_KEY', token)
localStorage.setItem('persistCode', ``) localStorage.setItem('persistCode', ``)

File diff suppressed because it is too large Load Diff

View File

@ -4,42 +4,44 @@ import { doExport, getUtils, makeTemplate } from './test-utils'
test.fixme('Units menu', async ({ page, homePage }) => { test.fixme('Units menu', async ({ page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
const unitsMenuButton = page.getByRole('button', { const unitsMenuButton = page.getByRole('button', {
name: 'Current Units', name: 'Current Units',
exact: false, exact: false,
})
await expect(unitsMenuButton).toBeVisible()
await expect(unitsMenuButton).toContainText('in')
await unitsMenuButton.click()
const millimetersButton = page.getByRole('button', { name: 'Millimeters' })
await expect(millimetersButton).toBeVisible()
await millimetersButton.click()
// Look out for the toast message
const toastMessage = page.getByText(
`Set default unit to "mm" for this project`
)
await expect(toastMessage).toBeVisible()
// Verify that the popover has closed
await expect(millimetersButton).not.toBeAttached()
// Verify that the button label has updated
await expect(unitsMenuButton).toContainText('mm')
}) })
await expect(unitsMenuButton).toBeVisible()
await expect(unitsMenuButton).toContainText('in')
await unitsMenuButton.click() test('Successful export shows a success toast', async ({ page, homePage }) => {
const millimetersButton = page.getByRole('button', { name: 'Millimeters' }) // FYI this test doesn't work with only engine running locally
// And you will need to have the KittyCAD CLI installed
await expect(millimetersButton).toBeVisible() const u = await getUtils(page)
await millimetersButton.click() await page.addInitScript(async () => {
;(window as any).playwrightSkipFilePicker = true
// Look out for the toast message localStorage.setItem(
const toastMessage = page.getByText( 'persistCode',
`Set default unit to "mm" for this project` `topAng = 25
)
await expect(toastMessage).toBeVisible()
// Verify that the popover has closed
await expect(millimetersButton).not.toBeAttached()
// Verify that the button label has updated
await expect(unitsMenuButton).toContainText('mm') })
test('Successful export shows a success toast', async ({ page, homePage }) => { // FYI this test doesn't work with only engine running locally
// And you will need to have the KittyCAD CLI installed
const u = await getUtils(page)
await page.addInitScript(async () => {
;(window as any).playwrightSkipFilePicker = true
localStorage.setItem(
'persistCode',
`topAng = 25
bottomAng = 35 bottomAng = 35
baseLen = 3.5 baseLen = 3.5
baseHeight = 1 baseHeight = 1
@ -77,158 +79,172 @@ part001 = startSketchOn('-XZ')
|> xLineTo(ZERO, %) |> xLineTo(ZERO, %)
|> close(%) |> close(%)
|> extrude(4, %)` |> extrude(4, %)`
)
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.waitForCmdReceive('extrude')
await page.waitForTimeout(1000)
await u.clearAndCloseDebugPanel()
await doExport(
{
type: 'gltf',
storage: 'embedded',
presentation: 'pretty',
},
page
) )
}) })
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() test('Paste should not work unless an input is focused', async ({
await u.openDebugPanel() page,
await u.expectCmdLog('[data-message-type="execution-done"]') browserName,
await u.waitForCmdReceive('extrude') homePage,
await page.waitForTimeout(1000) }) => {
await u.clearAndCloseDebugPanel() // To run this test locally, uncomment Firefox in playwright.config.ts
test.skip(
await doExport( browserName !== 'firefox',
{ "This bug is really Firefox-only, which we don't run in CI."
type: 'gltf',
storage: 'embedded',
presentation: 'pretty',
},
page
)
})
test('Paste should not work unless an input is focused', async ({ page, browserName, homePage }) => { // To run this test locally, uncomment Firefox in playwright.config.ts
test.skip(
browserName !== 'firefox',
"This bug is really Firefox-only, which we don't run in CI."
)
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page
.getByRole('button', { name: 'Start Sketch' })
.waitFor({ state: 'visible' })
const codeEditorText = page.locator('.cm-content')
const pasteContent = `// was this pasted?`
const typeContent = `// this should be typed`
// Load text into the clipboard
await page.evaluate((t) => navigator.clipboard.writeText(t), pasteContent)
// Focus the text editor
await codeEditorText.focus()
// Show that we can type into it
await page.keyboard.type(typeContent)
await page.keyboard.press('Enter')
// Paste without the code pane focused
await codeEditorText.blur()
await page.keyboard.press('ControlOrMeta+KeyV')
// Show that the paste didn't work but typing did
await expect(codeEditorText).not.toContainText(pasteContent)
await expect(codeEditorText).toContainText(typeContent)
// Paste with the code editor focused
// Following this guidance: https://github.com/microsoft/playwright/issues/8114
await codeEditorText.focus()
await page.keyboard.press('ControlOrMeta+KeyV')
await expect(
await page.evaluate(
() => document.querySelector('.cm-content')?.textContent
) )
).toContain(pasteContent) }) const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page
.getByRole('button', { name: 'Start Sketch' })
.waitFor({ state: 'visible' })
test('Keyboard shortcuts can be viewed through the help menu', async ({ page, homePage }) => { const u = await getUtils(page) const codeEditorText = page.locator('.cm-content')
await page.setBodyDimensions({ width: 1200, height: 500 }) const pasteContent = `// was this pasted?`
await homePage.goToModelingScene() const typeContent = `// this should be typed`
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' }) // Load text into the clipboard
await page await page.evaluate((t) => navigator.clipboard.writeText(t), pasteContent)
.getByRole('button', { name: 'Start Sketch' })
.waitFor({ state: 'visible' })
// Open the help menu // Focus the text editor
await page.getByRole('button', { name: 'Help and resources' }).click() await codeEditorText.focus()
// Open the keyboard shortcuts // Show that we can type into it
await page.getByRole('button', { name: 'Keyboard Shortcuts' }).click() await page.keyboard.type(typeContent)
await page.keyboard.press('Enter')
// Verify the URL and that you can see a list of shortcuts // Paste without the code pane focused
await expect.poll(() => page.url()).toContain('?tab=keybindings') await codeEditorText.blur()
await expect( await page.keyboard.press('ControlOrMeta+KeyV')
page.getByRole('heading', { name: 'Enter Sketch Mode' })
).toBeAttached() // Show that the paste didn't work but typing did
await expect(codeEditorText).not.toContainText(pasteContent)
await expect(codeEditorText).toContainText(typeContent)
// Paste with the code editor focused
// Following this guidance: https://github.com/microsoft/playwright/issues/8114
await codeEditorText.focus()
await page.keyboard.press('ControlOrMeta+KeyV')
await expect(
await page.evaluate(
() => document.querySelector('.cm-content')?.textContent
)
).toContain(pasteContent)
}) })
test('First escape in tool pops you out of tool, second exits sketch mode', async ({ page, homePage }) => { // Wait for the app to be ready for use test('Keyboard shortcuts can be viewed through the help menu', async ({
const u = await getUtils(page) page,
await page.setBodyDimensions({ width: 1200, height: 500 }) homePage,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await homePage.goToModelingScene() await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
await u.openDebugPanel() await page
await u.expectCmdLog('[data-message-type="execution-done"]') .getByRole('button', { name: 'Start Sketch' })
await u.closeDebugPanel() .waitFor({ state: 'visible' })
const lineButton = page.getByRole('button', { // Open the help menu
name: 'line Line', await page.getByRole('button', { name: 'Help and resources' }).click()
exact: true,
}) // Open the keyboard shortcuts
const arcButton = page.getByRole('button', { await page.getByRole('button', { name: 'Keyboard Shortcuts' }).click()
name: 'arc Tangential Arc',
exact: true, // Verify the URL and that you can see a list of shortcuts
await expect.poll(() => page.url()).toContain('?tab=keybindings')
await expect(
page.getByRole('heading', { name: 'Enter Sketch Mode' })
).toBeAttached()
}) })
// Test these hotkeys perform actions when test('First escape in tool pops you out of tool, second exits sketch mode', async ({
// focus is on the canvas page,
await page.mouse.move(600, 250) homePage,
await page.mouse.click(600, 250) }) => {
// Wait for the app to be ready for use
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
// Start a sketch await homePage.goToModelingScene()
await page.keyboard.press('s') await u.openDebugPanel()
await page.mouse.move(800, 300) await u.expectCmdLog('[data-message-type="execution-done"]')
await page.mouse.click(800, 300) await u.closeDebugPanel()
await page.waitForTimeout(1000)
await expect(lineButton).toBeVisible()
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
// Draw a line const lineButton = page.getByRole('button', {
await page.mouse.move(700, 200, { steps: 5 }) name: 'line Line',
await page.mouse.click(700, 200) exact: true,
await page.mouse.move(800, 250, { steps: 5 }) })
await page.mouse.click(800, 250) const arcButton = page.getByRole('button', {
// Unequip line tool name: 'arc Tangential Arc',
await page.keyboard.press('Escape') exact: true,
// Make sure we didn't pop out of sketch mode. })
await expect(page.getByRole('button', { name: 'Exit Sketch' })).toBeVisible()
await expect(lineButton).not.toHaveAttribute('aria-pressed', 'true')
// Equip arc tool
await page.keyboard.press('a')
await expect(arcButton).toHaveAttribute('aria-pressed', 'true')
await page.mouse.move(1000, 100, { steps: 5 })
await page.mouse.click(1000, 100)
await page.keyboard.press('Escape')
await page.keyboard.press('l')
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
// Do not close the sketch. // Test these hotkeys perform actions when
// On close it will exit sketch mode. // focus is on the canvas
await page.mouse.move(600, 250)
await page.mouse.click(600, 250)
// Unequip line tool // Start a sketch
await page.keyboard.press('Escape') await page.keyboard.press('s')
await expect(lineButton).toHaveAttribute('aria-pressed', 'false') await page.mouse.move(800, 300)
await expect(arcButton).toHaveAttribute('aria-pressed', 'false') await page.mouse.click(800, 300)
// Make sure we didn't pop out of sketch mode. await page.waitForTimeout(1000)
await expect(page.getByRole('button', { name: 'Exit Sketch' })).toBeVisible() await expect(lineButton).toBeVisible()
// Exit sketch await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
await page.keyboard.press('Escape')
await expect( // Draw a line
page.getByRole('button', { name: 'Exit Sketch' }) await page.mouse.move(700, 200, { steps: 5 })
).not.toBeVisible() }) await page.mouse.click(700, 200)
await page.mouse.move(800, 250, { steps: 5 })
await page.mouse.click(800, 250)
// Unequip line tool
await page.keyboard.press('Escape')
// Make sure we didn't pop out of sketch mode.
await expect(page.getByRole('button', { name: 'Exit Sketch' })).toBeVisible()
await expect(lineButton).not.toHaveAttribute('aria-pressed', 'true')
// Equip arc tool
await page.keyboard.press('a')
await expect(arcButton).toHaveAttribute('aria-pressed', 'true')
await page.mouse.move(1000, 100, { steps: 5 })
await page.mouse.click(1000, 100)
await page.keyboard.press('Escape')
await page.keyboard.press('l')
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
// Do not close the sketch.
// On close it will exit sketch mode.
// Unequip line tool
await page.keyboard.press('Escape')
await expect(lineButton).toHaveAttribute('aria-pressed', 'false')
await expect(arcButton).toHaveAttribute('aria-pressed', 'false')
// Make sure we didn't pop out of sketch mode.
await expect(page.getByRole('button', { name: 'Exit Sketch' })).toBeVisible()
// Exit sketch
await page.keyboard.press('Escape')
await expect(
page.getByRole('button', { name: 'Exit Sketch' })
).not.toBeVisible()
})
test.fixme( test.fixme(
'Basic default modeling and sketch hotkeys work', 'Basic default modeling and sketch hotkeys work',
@ -412,37 +428,38 @@ test.fixme(
) )
test('Delete key does not navigate back', async ({ page, homePage }) => { test('Delete key does not navigate back', async ({ page, homePage }) => {
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
await homePage.goToModelingScene();
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' }) const settingsButton = page.getByRole('link', {
name: 'Settings',
exact: false,
})
const settingsCloseButton = page.getByTestId('settings-close-button')
const settingsButton = page.getByRole('link', { await settingsButton.click()
name: 'Settings', await expect.poll(() => page.url()).toContain('/settings')
exact: false,
// Make sure that delete doesn't go back from settings
await page.keyboard.press('Delete')
await expect.poll(() => page.url()).toContain('/settings')
// Now close the settings and try delete again,
// make sure it doesn't go back to settings
await settingsCloseButton.click()
await page.keyboard.press('Delete')
await expect.poll(() => page.url()).not.toContain('/settings')
}) })
const settingsCloseButton = page.getByTestId('settings-close-button')
await settingsButton.click() test('Sketch on face', async ({ page, homePage }) => {
await expect.poll(() => page.url()).toContain('/settings') test.setTimeout(90_000)
const u = await getUtils(page)
// Make sure that delete doesn't go back from settings await page.addInitScript(async () => {
await page.keyboard.press('Delete') localStorage.setItem(
await expect.poll(() => page.url()).toContain('/settings') 'persistCode',
`sketch001 = startSketchOn('XZ')
// Now close the settings and try delete again,
// make sure it doesn't go back to settings
await settingsCloseButton.click()
await page.keyboard.press('Delete')
await expect.poll(() => page.url()).not.toContain('/settings') })
test('Sketch on face', async ({ page, homePage }) => { test.setTimeout(90_000)
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XZ')
|> startProfileAt([3.29, 7.86], %) |> startProfileAt([3.29, 7.86], %)
|> line([2.48, 2.44], %) |> line([2.48, 2.44], %)
|> line([2.66, 1.17], %) |> line([2.66, 1.17], %)
@ -456,126 +473,127 @@ await page.addInitScript(async () => {
|> line([-17.67, 0.85], %) |> line([-17.67, 0.85], %)
|> close(%) |> close(%)
extrude001 = extrude(5 + 7, sketch001)` extrude001 = extrude(5 + 7, sketch001)`
)
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.waitForTimeout(300)
let previousCodeContent = await page.locator('.cm-content').innerText()
await u.openAndClearDebugPanel()
await u.doAndWaitForCmd(
() => page.mouse.click(625, 165),
'default_camera_get_settings',
true
) )
}) await page.waitForTimeout(150)
await u.closeDebugPanel()
await page.setBodyDimensions({ width: 1200, height: 500 }) const firstClickPosition = [612, 238]
const secondClickPosition = [661, 242]
const thirdClickPosition = [609, 267]
await homePage.goToModelingScene() await page.mouse.click(firstClickPosition[0], firstClickPosition[1])
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText()
// wait for execution done await page.waitForTimeout(100)
await u.openDebugPanel() await page.mouse.click(secondClickPosition[0], secondClickPosition[1])
await u.expectCmdLog('[data-message-type="execution-done"]') await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
await u.closeDebugPanel() previousCodeContent = await page.locator('.cm-content').innerText()
await expect( await page.waitForTimeout(100)
page.getByRole('button', { name: 'Start Sketch' }) await page.mouse.click(thirdClickPosition[0], thirdClickPosition[1])
).not.toBeDisabled() await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText()
await page.getByRole('button', { name: 'Start Sketch' }).click() await page.waitForTimeout(100)
await page.waitForTimeout(300) await page.mouse.click(firstClickPosition[0], firstClickPosition[1])
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText()
let previousCodeContent = await page.locator('.cm-content').innerText() await expect.poll(u.normalisedEditorCode).toContain(
u.normalisedCode(`sketch002 = startSketchOn(extrude001, seg01)
await u.openAndClearDebugPanel()
await u.doAndWaitForCmd(
() => page.mouse.click(625, 165),
'default_camera_get_settings',
true
)
await page.waitForTimeout(150)
await u.closeDebugPanel()
const firstClickPosition = [612, 238]
const secondClickPosition = [661, 242]
const thirdClickPosition = [609, 267]
await page.mouse.click(firstClickPosition[0], firstClickPosition[1])
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText()
await page.waitForTimeout(100)
await page.mouse.click(secondClickPosition[0], secondClickPosition[1])
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText()
await page.waitForTimeout(100)
await page.mouse.click(thirdClickPosition[0], thirdClickPosition[1])
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText()
await page.waitForTimeout(100)
await page.mouse.click(firstClickPosition[0], firstClickPosition[1])
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText()
await expect.poll(u.normalisedEditorCode).toContain(
u.normalisedCode(`sketch002 = startSketchOn(extrude001, seg01)
|> startProfileAt([-12.94, 6.6], %) |> startProfileAt([-12.94, 6.6], %)
|> line([2.45, -0.2], %) |> line([2.45, -0.2], %)
|> line([-2.6, -1.25], %) |> line([-2.6, -1.25], %)
|> lineTo([profileStartX(%), profileStartY(%)], %) |> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%) |> close(%)
`) `)
) )
await u.openAndClearDebugPanel() await u.openAndClearDebugPanel()
await page.getByRole('button', { name: 'Exit Sketch' }).click() await page.getByRole('button', { name: 'Exit Sketch' }).click()
await u.expectCmdLog('[data-message-type="execution-done"]') await u.expectCmdLog('[data-message-type="execution-done"]')
await u.updateCamPosition([1049, 239, 686]) await u.updateCamPosition([1049, 239, 686])
await u.closeDebugPanel() await u.closeDebugPanel()
await page.getByText('startProfileAt([-12').click() await page.getByText('startProfileAt([-12').click()
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible() await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400) await page.waitForTimeout(400)
await page.waitForTimeout(150) await page.waitForTimeout(150)
await page.setBodyDimensions({ width: 1200, height: 1200 }) await page.setBodyDimensions({ width: 1200, height: 1200 })
await u.openAndClearDebugPanel() await u.openAndClearDebugPanel()
await u.updateCamPosition([452, -152, 1166]) await u.updateCamPosition([452, -152, 1166])
await u.closeDebugPanel() await u.closeDebugPanel()
await page.waitForTimeout(200) await page.waitForTimeout(200)
const pointToDragFirst = [787, 565] const pointToDragFirst = [787, 565]
await page.mouse.move(pointToDragFirst[0], pointToDragFirst[1]) await page.mouse.move(pointToDragFirst[0], pointToDragFirst[1])
await page.mouse.down() await page.mouse.down()
await page.mouse.move(pointToDragFirst[0] - 20, pointToDragFirst[1], { await page.mouse.move(pointToDragFirst[0] - 20, pointToDragFirst[1], {
steps: 5, steps: 5,
}) })
await page.mouse.up() await page.mouse.up()
await page.waitForTimeout(100) await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent) await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText() previousCodeContent = await page.locator('.cm-content').innerText()
const result = makeTemplate`sketch002 = startSketchOn(extrude001, seg01) const result = makeTemplate`sketch002 = startSketchOn(extrude001, seg01)
|> startProfileAt([-12.83, 6.7], %) |> startProfileAt([-12.83, 6.7], %)
|> line([${[2.28, 2.35]}, -${0.07}], %) |> line([${[2.28, 2.35]}, -${0.07}], %)
|> line([-3.05, -1.47], %) |> line([-3.05, -1.47], %)
|> lineTo([profileStartX(%), profileStartY(%)], %) |> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)` |> close(%)`
await expect(page.locator('.cm-content')).toHaveText(result.regExp) await expect(page.locator('.cm-content')).toHaveText(result.regExp)
// exit sketch // exit sketch
await u.openAndClearDebugPanel() await u.openAndClearDebugPanel()
await page.getByRole('button', { name: 'Exit Sketch' }).click() await page.getByRole('button', { name: 'Exit Sketch' }).click()
await u.expectCmdLog('[data-message-type="execution-done"]') await u.expectCmdLog('[data-message-type="execution-done"]')
await page.getByText('startProfileAt([-12').click() await page.getByText('startProfileAt([-12').click()
await expect(page.getByRole('button', { name: 'Extrude' })).not.toBeDisabled() await expect(page.getByRole('button', { name: 'Extrude' })).not.toBeDisabled()
await page.waitForTimeout(100) await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Extrude' }).click() await page.getByRole('button', { name: 'Extrude' }).click()
await expect(page.getByTestId('command-bar')).toBeVisible() await expect(page.getByTestId('command-bar')).toBeVisible()
await page.waitForTimeout(100) await page.waitForTimeout(100)
await page.getByRole('button', { name: 'arrow right Continue' }).click() await page.getByRole('button', { name: 'arrow right Continue' }).click()
await page.waitForTimeout(100) await page.waitForTimeout(100)
await expect(page.getByText('Confirm Extrude')).toBeVisible() await expect(page.getByText('Confirm Extrude')).toBeVisible()
await page.getByRole('button', { name: 'checkmark Submit command' }).click() await page.getByRole('button', { name: 'checkmark Submit command' }).click()
const result2 = result.genNext` const result2 = result.genNext`
const sketch002 = extrude(${[5, 5]} + 7, sketch002)` const sketch002 = extrude(${[5, 5]} + 7, sketch002)`
await expect(page.locator('.cm-content')).toHaveText(result2.regExp) }) await expect(page.locator('.cm-content')).toHaveText(result2.regExp)
})

View File

@ -10,7 +10,6 @@ export { expect, Page, BrowserContext, TestInfo } from '@playwright/test'
// switch between web and electron if needed. // switch between web and electron if needed.
const pwTestFnWithFixtures = playwrightTestFn.extend<Fixtures>(fixtures) const pwTestFnWithFixtures = playwrightTestFn.extend<Fixtures>(fixtures)
// In JavaScript you cannot replace a function's body only (despite functions // In JavaScript you cannot replace a function's body only (despite functions
// are themselves objects, which you'd expect a body property or something...) // are themselves objects, which you'd expect a body property or something...)
// So we must redefine the function and then re-attach properties. // So we must redefine the function and then re-attach properties.
@ -61,7 +60,7 @@ export function test(desc, objOrFn, fnMaybe) {
// We need to expose this in order for some tests that require folder // We need to expose this in order for some tests that require folder
// creation. Before they used to do this by their own electronSetup({...}) // creation. Before they used to do this by their own electronSetup({...})
// calls. // calls.
tronApp.context.folderSetupFn = function(fn) { tronApp.context.folderSetupFn = function (fn) {
return fn(tronApp.dir).then(() => ({ dir: tronApp.dir })) return fn(tronApp.dir).then(() => ({ dir: tronApp.dir }))
} }

View File

@ -20,7 +20,7 @@ const save_ = async (file: ModelingAppFile, toastId: string) => {
// Skip file picker, save to the test dir downloads directory // Skip file picker, save to the test dir downloads directory
const downloadDir = window.electron.join( const downloadDir = window.electron.join(
window.electron.process.env.TEST_SETTINGS_FILE_KEY, window.electron.process.env.TEST_SETTINGS_FILE_KEY,
"downloads-during-playwright", 'downloads-during-playwright'
) )
await window.electron.mkdir(downloadDir, { recursive: true }) await window.electron.mkdir(downloadDir, { recursive: true })
await window.electron.writeFile( await window.electron.writeFile(