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)
async function doBasicSketch(page: Page, homePage: HomePageFixture, openPanes: string[]) {
async function doBasicSketch(
page: Page,
homePage: HomePageFixture,
openPanes: string[]
) {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
const PUR = 400 / 37.5 //pixeltoUnitRatio
@ -139,16 +143,19 @@ async function doBasicSketch(page: Page, homePage: HomePageFixture, openPanes: s
}
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'])
})
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 }) => {
// Load the app with the code panes
await page.addInitScript(async (persistModelingContext) => {
localStorage.setItem(
persistModelingContext,
JSON.stringify({ openPanes: [] })
)
}, PERSIST_MODELING_CONTEXT)
await doBasicSketch(page, homePage, []) })
await doBasicSketch(page, homePage, [])
})
})

View File

@ -84,7 +84,8 @@ test.describe('Can create sketches on all planes and their back sides', () => {
'XY',
{ 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.
) })
)
})
test('YZ', async ({ page, homePage }) => {
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 }) => {
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 }) => {
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 }) => {

View File

@ -1,16 +1,17 @@
import { test, expect } from './zoo-test'
import {
getUtils,
executorInputPath,
} from './test-utils'
import { getUtils, executorInputPath } from './test-utils'
import { join } from 'path'
import { bracket } from 'lib/exampleKcl'
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates'
import fsp from 'fs/promises'
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,
homePage,
}) => {
const u = await getUtils(page)
// Load the app with the working starter code
await page.addInitScript(() => {
@ -45,10 +46,13 @@ test.describe('Code pane and errors', () => {
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 }) => {
await expect(codePaneButtonHolder).toContainText('notification')
})
test('Opening and closing the code pane will consistently show error diagnostics', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
// Load the app with the working starter code
@ -108,9 +112,15 @@ test.describe('Code pane and errors', () => {
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.locator('.cm-tooltip').first()).toBeVisible() })
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)
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 context.addInitScript((code) => {
@ -145,9 +155,15 @@ test.describe('Code pane and errors', () => {
'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() })
).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)
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) => {
@ -208,7 +224,8 @@ test.describe('Code pane and errors', () => {
'sketch profile must lie entirely on one side of the revolution axis'
)
.first()
).toBeVisible() })
).toBeVisible()
})
})
test(
@ -287,7 +304,7 @@ test(
{ tag: '@electron' },
async ({ context, browserName, page }, testInfo) => {
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)
await fsp.mkdir(aProjectDir, { recursive: true })
})

View File

@ -5,7 +5,11 @@ import { KCL_DEFAULT_LENGTH } from 'lib/constants'
import { normalizeLineEndings } from 'lib/codeEditor'
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 ({
page,
homePage,
}) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XY')
@ -39,9 +43,11 @@ test.describe('Command bar tests', () => {
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 }) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XY')
@ -76,9 +82,14 @@ test.describe('Command bar tests', () => {
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 ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
@ -153,9 +164,14 @@ test.describe('Command bar tests', () => {
// Test case for https://github.com/KittyCAD/modeling-app/issues/2881
await commandThemeArgButton.click()
await expect(commandThemeArgButton).toBeDisabled()
await expect(commandLevelArgButton).toHaveText('level: project') })
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 ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
@ -198,9 +214,11 @@ test.describe('Command bar tests', () => {
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(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 }) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`distance = sqrt(20)
@ -273,11 +291,16 @@ test.describe('Command bar tests', () => {
await u.waitForCmdReceive('extrude')
await expect(page.locator('.cm-content')).toContainText('extrude001 = extrude(distance001, sketch001)')
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)
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()
@ -323,5 +346,6 @@ test.describe('Command bar tests', () => {
// switch to tangential arc via command bar
await cmdBarButton.click()
await arcToolCommand.click()
await expect(arcToolButton).toHaveAttribute('aria-pressed', 'true') })
await expect(arcToolButton).toHaveAttribute('aria-pressed', 'true')
})
})

View File

@ -1,23 +1,16 @@
import { test, expect } from '@playwright/test'
import { getUtils, setup, tearDown } from './test-utils'
import { test, expect } from './zoo-test'
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', () => {
// eslint-disable-next-line jest/valid-title
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 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -55,9 +48,9 @@ test.describe('Copilot ghost text', () => {
}) => {
const u = await getUtils(page)
// 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 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 ({
page,
homePage,
}) => {
const u = await getUtils(page)
// 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -184,12 +178,12 @@ test.describe('Copilot ghost text', () => {
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 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -212,12 +206,15 @@ test.describe('Copilot ghost text', () => {
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 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -240,12 +237,15 @@ test.describe('Copilot ghost text', () => {
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 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -268,12 +268,15 @@ test.describe('Copilot ghost text', () => {
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 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -296,12 +299,12 @@ test.describe('Copilot ghost text', () => {
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 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 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 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 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 ({
page,
homePage,
}) => {
const u = await getUtils(page)
// 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 u.codeLocator.click()
@ -420,15 +427,17 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
// 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 ({
page,
homePage,
}) => {
const u = await getUtils(page)
// 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -453,12 +462,15 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-content')).toHaveText(``)
})
test('backspace in code rejects the suggestion', async ({ page }) => {
test('backspace in code rejects the suggestion', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
// 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -483,12 +495,15 @@ test.describe('Copilot ghost text', () => {
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 ({
page,
homePage,
}) => {
const u = await getUtils(page)
// 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 expect(page.locator('.cm-content')).toHaveText(``)
@ -514,4 +529,5 @@ test.describe('Copilot ghost text', () => {
await expect(page.locator('.cm-content')).toHaveText(``)
})
})
})

View File

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

View File

@ -12,11 +12,13 @@ import {
} from './test-utils'
import { uuidv4, roundOff } from 'lib/utils'
test.describe('Sketch tests', () => {
test('multi-sketch file shows multiple Edit Sketch buttons', async ({ page, context,
homePage }) => { const u = await getUtils(page)
test('multi-sketch file shows multiple Edit Sketch buttons', async ({
page,
context,
homePage,
}) => {
const u = await getUtils(page)
const selectionsSnippets = {
startProfileAt1:
'|> startProfileAt([-width / 4 + screwRadius, height / 2], %)',
@ -97,9 +99,14 @@ test.describe('Sketch tests', () => {
await expect(page.getByRole('button', { name: 'Extrude' })).toBeDisabled()
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeVisible() })
test('Can delete most of a sketch and the line tool will still work', async ({ page, center,
homePage }) => { const u = await getUtils(page)
).toBeVisible()
})
test('Can delete most of a sketch and the line tool will still work', async ({
page,
center,
homePage,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -140,16 +147,21 @@ test.describe('Sketch tests', () => {
await page.mouse.move(700, 200, { step: 25 })
await page.mouse.click(700, 200)
await expect.poll(u.crushKclCodeIntoOneLineAndThenMaybeSome, { timeout: 1000 })
.toBe(`sketch001 = startSketchOn('XZ')
await expect
.poll(u.crushKclCodeIntoOneLineAndThenMaybeSome, { timeout: 1000 })
.toBe(
`sketch001 = startSketchOn('XZ')
|> startProfileAt([4.61,-14.01], %)
|> yLine(15.95, %)
`.replaceAll(' ', '').replaceAll("\n", ''))
`
.replaceAll(' ', '')
.replaceAll('\n', '')
)
}).toPass({ timeout: 40_000, intervals: [1_000] })
})
test('Can exit selection of face', async ({ page, homePage }) => { // Load the app with the code panes
test('Can exit selection of face', async ({ page, homePage }) => {
// Load the app with the code panes
await page.addInitScript(async () => {
localStorage.setItem('persistCode', ``)
})
@ -169,7 +181,8 @@ test.describe('Sketch tests', () => {
await page.keyboard.press('Escape')
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).toBeVisible() })
).toBeVisible()
})
test.describe('Can edit segments by dragging their handles', () => {
const doEditSegmentsByDraggingHandle = async (
page: Page,
@ -304,7 +317,8 @@ test.describe('Sketch tests', () => {
|> line([1.97, 2.06], %)
|> close(%)`)
}
test('code pane open at start-handles', async ({ page, homePage }) => { // Load the app with the code panes
test('code pane open at start-handles', async ({ page, homePage }) => {
// Load the app with the code panes
await page.addInitScript(async () => {
localStorage.setItem(
'store',
@ -316,19 +330,26 @@ test.describe('Sketch tests', () => {
})
)
})
await doEditSegmentsByDraggingHandle(page, homePage, ['code']) })
await doEditSegmentsByDraggingHandle(page, homePage, ['code'])
})
test('code pane closed at start-handles', async ({ page, homePage }) => { // Load the app with the code panes
test('code pane closed at start-handles', async ({ page, homePage }) => {
// Load the app with the code panes
await page.addInitScript(async (persistModelingContext) => {
localStorage.setItem(
persistModelingContext,
JSON.stringify({ openPanes: [] })
)
}, PERSIST_MODELING_CONTEXT)
await doEditSegmentsByDraggingHandle(page, homePage, []) })
await doEditSegmentsByDraggingHandle(page, homePage, [])
})
})
test('Can edit a circle center and radius by dragging its handles', async ({ page, homePage }) => { const u = await getUtils(page)
test('Can edit a circle center and radius by dragging its handles', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -408,8 +429,13 @@ test.describe('Sketch tests', () => {
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn('XZ')
|> circle({ center: [7.26, -2.37], radius: 11.44 }, %)
`) })
test('Can edit a sketch that has been extruded in the same pipe', async ({ page, homePage }) => { const u = await getUtils(page)
`)
})
test('Can edit a sketch that has been extruded in the same pipe', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -505,9 +531,14 @@ test.describe('Sketch tests', () => {
|> tangentialArcTo([24.89, 0.68], %)
|> close(%)
|> extrude(5, %)
`) })
`)
})
test('Can edit a sketch that has been revolved in the same pipe', async ({ page, homePage }) => { const u = await getUtils(page)
test('Can edit a sketch that has been revolved in the same pipe', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -602,8 +633,10 @@ test.describe('Sketch tests', () => {
|> tangentialArcTo([24.95, -5.38], %)
|> line([1.97, 2.06], %)
|> close(%)
|> revolve({ axis: "X" }, %)`) })
test('Can add multiple sketches', async ({ page, homePage }) => { const u = await getUtils(page)
|> revolve({ axis: "X" }, %)`)
})
test('Can add multiple sketches', async ({ page, homePage }) => {
const u = await getUtils(page)
const viewportSize = { width: 1200, height: 500 }
await page.setBodyDimensions(viewportSize)
@ -694,7 +727,8 @@ test.describe('Sketch tests', () => {
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.updateCamPosition([100, 100, 100])
await u.clearCommandLogs() })
await u.clearCommandLogs()
})
test.describe('Snap to close works (at any scale)', () => {
const doSnapAtDifferentScales = async (
page: any,
@ -785,13 +819,21 @@ test.describe('Sketch tests', () => {
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.removeCurrentCode()
}
test('[0, 100, 100]', async ({ page, homePage }) => { await homePage.goToModelingScene()
await doSnapAtDifferentScales(page, [0, 100, 100], 0.01) })
test('[0, 10000, 10000]', async ({ page, homePage }) => { await homePage.goToModelingScene()
await doSnapAtDifferentScales(page, [0, 10000, 10000]) })
test('[0, 100, 100]', async ({ page, homePage }) => {
await homePage.goToModelingScene()
await doSnapAtDifferentScales(page, [0, 100, 100], 0.01)
})
test('exiting a close extrude, has the extrude button enabled ready to go', async ({ page, homePage }) => { // this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
test('[0, 10000, 10000]', async ({ page, homePage }) => {
await homePage.goToModelingScene()
await doSnapAtDifferentScales(page, [0, 10000, 10000])
})
})
test('exiting a close extrude, has the extrude button enabled ready to go', async ({
page,
homePage,
}) => {
// this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -843,8 +885,13 @@ test.describe('Sketch tests', () => {
page.getByRole('button', { name: 'selection : 1 face', exact: false })
).toBeVisible({
timeout: 10_000,
}) })
test("Existing sketch with bad code delete user's code", async ({ page, homePage }) => { // this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
})
})
test("Existing sketch with bad code delete user's code", async ({
page,
homePage,
}) => {
// this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -899,8 +946,13 @@ test.describe('Sketch tests', () => {
sketch002 = startSketchOn(extrude001, 'END')
|>
`.replace(/\s/g, '')
) })
test('empty-scene default-planes act as expected', async ({ page, homePage }) => { /**
)
})
test('empty-scene default-planes act as expected', async ({
page,
homePage,
}) => {
/**
* Tests the following things
* 1) The the planes are there on load because the scene is empty
* 2) The planes don't changes color when hovered initially
@ -995,9 +1047,11 @@ test.describe('Sketch tests', () => {
// expect there to be no planes on load since there's something in the scene
expect(
await u.getGreatestPixDiff(XYPlanePoint, noPlanesColor)
).toBeLessThan(3) })
).toBeLessThan(3)
})
test('Can attempt to sketch on revolved face', async ({ page, homePage }) => { const u = await getUtils(page)
test('Can attempt to sketch on revolved face', async ({ page, homePage }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await page.addInitScript(async () => {
@ -1050,9 +1104,14 @@ test.describe('Sketch tests', () => {
await expect(
page.getByRole('button', { name: 'line Line', exact: true })
).toHaveAttribute('aria-pressed', 'true')
}).toPass({ timeout: 40_000, intervals: [1_000] }) })
}).toPass({ timeout: 40_000, intervals: [1_000] })
})
test('Can sketch on face when user defined function was used in the sketch', async ({ page, homePage }) => { const u = await getUtils(page)
test('Can sketch on face when user defined function was used in the sketch', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
// Checking for a regression that performs a sketch when a user defined function
@ -1142,7 +1201,8 @@ test.describe('Sketch tests', () => {
// Check execution is done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel() })
await u.closeDebugPanel()
})
})
test.describe('Sketch mode should be toleratant to syntax errors', () => {
@ -1213,9 +1273,14 @@ test.describe('Sketch mode should be toleratant to syntax errors', () => {
})
test.describe(`Sketching with offset planes`, () => {
test(
`Can select an offset plane to sketch on`,
async ({ context, page, scene, toolbar, editor, homePage }) => {
test(`Can select an offset plane to sketch on`, async ({
context,
page,
scene,
toolbar,
editor,
homePage,
}) => {
// We seed the scene with a single offset plane
await context.addInitScript(() => {
localStorage.setItem(
@ -1240,9 +1305,7 @@ test.describe(`Sketching with offset planes`, () => {
})
})
await test.step(
`Clicking should select the plane and enter sketch mode`,
async () => {
await test.step(`Clicking should select the plane and enter sketch mode`, async () => {
await planeClick()
// Have to wait for engine-side animation to finish
await page.waitForTimeout(600)
@ -1253,9 +1316,7 @@ test.describe(`Sketching with offset planes`, () => {
diagnostics: [],
highlightedCode: '',
})
}
)
})
}
)
})
})
})

View File

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

View File

@ -1,13 +1,17 @@
import { test, expect } from './zoo-test'
import { commonPoints, getUtils, } from './test-utils'
import { commonPoints, getUtils } from './test-utils'
import { Coords2d } from 'lang/std/sketch'
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
import { uuidv4 } from 'lib/utils'
test.describe('Testing selections', () => {
test.setTimeout(90_000)
test('Selections work on fresh and edited sketch', { tag: ['@skipWin'] }, async ({ page, homePage }) => { // Skip on windows its being weird.
test(
'Selections work on fresh and edited sketch',
{ tag: ['@skipWin'] },
async ({ page, homePage }) => {
// Skip on windows its being weird.
test.skip(process.platform === 'win32', 'Skip on windows')
// tests mapping works on fresh sketch and edited sketch
@ -248,9 +252,12 @@ test.describe('Testing selections', () => {
await test.step(`Test hovering and selecting on edited sketch`, async () => {
await selectionSequence()
}) })
})
}
)
test('Solids should be select and deletable', async ({ page, homePage }) => { test.setTimeout(90_000)
test('Solids should be select and deletable', async ({ page, homePage }) => {
test.setTimeout(90_000)
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
@ -414,8 +421,13 @@ test.describe('Testing selections', () => {
await page.keyboard.press('Backspace')
await u.expectCmdLog('[data-message-type="execution-done"]', 10_000)
await page.waitForTimeout(200)
await expect(u.codeLocator).not.toContainText(`sketch005 = startSketchOn({`) })
test("Deleting solid that the AST mod can't handle results in a toast message", async ({ page, homePage }) => { const u = await getUtils(page)
await expect(u.codeLocator).not.toContainText(`sketch005 = startSketchOn({`)
})
test("Deleting solid that the AST mod can't handle results in a toast message", async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -474,8 +486,13 @@ test.describe('Testing selections', () => {
await u.clearCommandLogs()
await page.keyboard.press('Backspace')
await expect(page.getByText('Unable to delete part')).toBeVisible() })
test('Hovering over 3d features highlights code, clicking puts the cursor in the right place and sends selection id to engine', async ({ page, homePage }) => { const u = await getUtils(page)
await expect(page.getByText('Unable to delete part')).toBeVisible()
})
test('Hovering over 3d features highlights code, clicking puts the cursor in the right place and sends selection id to engine', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.addInitScript(async (KCL_DEFAULT_LENGTH) => {
localStorage.setItem(
'persistCode',
@ -810,8 +827,13 @@ test.describe('Testing selections', () => {
adjacentChamfer2,
`angledLine([segAng(rectangleSegmentA001),-segLen(rectangleSegmentA001)],%,$yo)chamfer({length:30,tags:[seg01,getNextAdjacentEdge(yo),getNextAdjacentEdge(seg02),getOppositeEdge(seg01)]},%)`,
'}, %)'
) })
test("Extrude button should be disabled if there's no extrudable geometry when nothing is selected", async ({ page, homePage }) => { const u = await getUtils(page)
)
})
test("Extrude button should be disabled if there's no extrudable geometry when nothing is selected", async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -874,9 +896,11 @@ test.describe('Testing selections', () => {
// there's not extrudable geometry, so button should be enabled
await expect(
page.getByRole('button', { name: 'Extrude' })
).not.toBeDisabled() })
).not.toBeDisabled()
})
test('Fillet button states test', async ({ page, homePage }) => { const u = await getUtils(page)
test('Fillet button states test', async ({ page, homePage }) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -916,7 +940,8 @@ test.describe('Testing selections', () => {
await selectClose()
await expect(page.getByRole('button', { name: 'Fillet' })).toBeDisabled()
await clickEmpty()
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled() })
await expect(page.getByRole('button', { name: 'Fillet' })).toBeEnabled()
})
const removeAfterFirstParenthesis = (inputString: string) => {
const index = inputString.indexOf('(')
@ -926,7 +951,11 @@ test.describe('Testing selections', () => {
return inputString // return the original string if '(' is not found
}
test('Testing selections (and hovers) work on sketches when NOT in sketch mode', async ({ page, homePage }) => { const cases = [
test('Testing selections (and hovers) work on sketches when NOT in sketch mode', async ({
page,
homePage,
}) => {
const cases = [
{
pos: [694, 185],
expectedCode: 'line([74.36, 130.4], %, $seg01)',
@ -988,8 +1017,13 @@ test.describe('Testing selections', () => {
await expect(page.locator('.cm-activeLine')).toHaveText(
'|> ' + expectedCode
)
} })
test("Hovering and selection of extruded faces works, and is not overridden shortly after user's click", async ({ page, homePage }) => { await page.addInitScript(async () => {
}
})
test("Hovering and selection of extruded faces works, and is not overridden shortly after user's click", async ({
page,
homePage,
}) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn('XZ')
@ -1084,8 +1118,13 @@ test.describe('Testing selections', () => {
await expect(await u.getGreatestPixDiff(cap, selectColor)).toBeLessThan(15)
await page.waitForTimeout(1000)
// check color stays there, i.e. not overridden (this was a bug previously)
await expect(await u.getGreatestPixDiff(cap, selectColor)).toBeLessThan(15) })
test("Various pipe expressions should and shouldn't allow edit and or extrude", async ({ page, homePage }) => { const u = await getUtils(page)
await expect(await u.getGreatestPixDiff(cap, selectColor)).toBeLessThan(15)
})
test("Various pipe expressions should and shouldn't allow edit and or extrude", async ({
page,
homePage,
}) => {
const u = await getUtils(page)
const selectionsSnippets = {
extrudeAndEditBlocked: '|> startProfileAt([10.81, 32.99], %)',
extrudeAndEditBlockedInFunction: '|> startProfileAt(pos, %)',
@ -1176,9 +1215,14 @@ test.describe('Testing selections', () => {
await expect(page.getByRole('button', { name: 'Extrude' })).toBeDisabled()
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).not.toBeVisible() })
).not.toBeVisible()
})
test('Deselecting line tool should mean nothing happens on click', async ({ page, homePage }) => { /**
test('Deselecting line tool should mean nothing happens on click', async ({
page,
homePage,
}) => {
/**
* If the line tool is clicked when the state is 'No Points' it will exit Sketch mode.
* This is the same exact workflow as pressing ESC.
*
@ -1257,5 +1301,6 @@ test.describe('Testing selections', () => {
await expect(page.locator('.cm-content')).not.toHaveText(
previousCodeContent
)
previousCodeContent = await page.locator('.cm-content').innerText() })
previousCodeContent = await page.locator('.cm-content').innerText()
})
})

View File

@ -4,38 +4,40 @@ import { doExport, getUtils, makeTemplate } from './test-utils'
test.fixme('Units menu', async ({ page, homePage }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
const unitsMenuButton = page.getByRole('button', {
const unitsMenuButton = page.getByRole('button', {
name: 'Current Units',
exact: false,
})
await expect(unitsMenuButton).toBeVisible()
await expect(unitsMenuButton).toContainText('in')
})
await expect(unitsMenuButton).toBeVisible()
await expect(unitsMenuButton).toContainText('in')
await unitsMenuButton.click()
const millimetersButton = page.getByRole('button', { name: 'Millimeters' })
await unitsMenuButton.click()
const millimetersButton = page.getByRole('button', { name: 'Millimeters' })
await expect(millimetersButton).toBeVisible()
await millimetersButton.click()
await expect(millimetersButton).toBeVisible()
await millimetersButton.click()
// Look out for the toast message
const toastMessage = page.getByText(
// Look out for the toast message
const toastMessage = page.getByText(
`Set default unit to "mm" for this project`
)
await expect(toastMessage).toBeVisible()
)
await expect(toastMessage).toBeVisible()
// Verify that the popover has closed
await expect(millimetersButton).not.toBeAttached()
// Verify that the popover has closed
await expect(millimetersButton).not.toBeAttached()
// Verify that the button label has updated
await expect(unitsMenuButton).toContainText('mm') })
// 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 () => {
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',
@ -78,157 +80,171 @@ part001 = startSketchOn('-XZ')
|> close(%)
|> extrude(4, %)`
)
})
await page.setBodyDimensions({ width: 1200, height: 500 })
})
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 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(
await doExport(
{
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(
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
)
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`
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)
// Load text into the clipboard
await page.evaluate((t) => navigator.clipboard.writeText(t), pasteContent)
// Focus the text editor
await codeEditorText.focus()
// Focus the text editor
await codeEditorText.focus()
// Show that we can type into it
await page.keyboard.type(typeContent)
await page.keyboard.press('Enter')
// 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')
// 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)
// 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(
// 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) })
).toContain(pasteContent)
})
test('Keyboard shortcuts can be viewed through the help menu', async ({ page, homePage }) => { const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
test('Keyboard shortcuts can be viewed through the help menu', async ({
page,
homePage,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
await page
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
await page
.getByRole('button', { name: 'Start Sketch' })
.waitFor({ state: 'visible' })
// Open the help menu
await page.getByRole('button', { name: 'Help and resources' }).click()
// Open the help menu
await page.getByRole('button', { name: 'Help and resources' }).click()
// Open the keyboard shortcuts
await page.getByRole('button', { name: 'Keyboard Shortcuts' }).click()
// Open the keyboard shortcuts
await page.getByRole('button', { name: 'Keyboard Shortcuts' }).click()
// Verify the URL and that you can see a list of shortcuts
await expect.poll(() => page.url()).toContain('?tab=keybindings')
await expect(
// 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()
).toBeAttached()
})
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
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 })
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
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()
await homePage.goToModelingScene()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
const lineButton = page.getByRole('button', {
const lineButton = page.getByRole('button', {
name: 'line Line',
exact: true,
})
const arcButton = page.getByRole('button', {
})
const arcButton = page.getByRole('button', {
name: 'arc Tangential Arc',
exact: true,
})
})
// Test these hotkeys perform actions when
// focus is on the canvas
await page.mouse.move(600, 250)
await page.mouse.click(600, 250)
// Test these hotkeys perform actions when
// focus is on the canvas
await page.mouse.move(600, 250)
await page.mouse.click(600, 250)
// Start a sketch
await page.keyboard.press('s')
await page.mouse.move(800, 300)
await page.mouse.click(800, 300)
await page.waitForTimeout(1000)
await expect(lineButton).toBeVisible()
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
// Start a sketch
await page.keyboard.press('s')
await page.mouse.move(800, 300)
await page.mouse.click(800, 300)
await page.waitForTimeout(1000)
await expect(lineButton).toBeVisible()
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
// Draw a line
await page.mouse.move(700, 200, { steps: 5 })
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')
// Draw a line
await page.mouse.move(700, 200, { steps: 5 })
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.
// 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(
// 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() })
).not.toBeVisible()
})
test.fixme(
'Basic default modeling and sketch hotkeys work',
@ -412,34 +428,35 @@ test.fixme(
)
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 homePage.goToModelingScene();
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
const settingsButton = page.getByRole('link', {
const settingsButton = page.getByRole('link', {
name: 'Settings',
exact: false,
})
const settingsCloseButton = page.getByTestId('settings-close-button')
await settingsButton.click()
await expect.poll(() => page.url()).toContain('/settings')
// 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()
await expect.poll(() => page.url()).toContain('/settings')
// 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') })
test('Sketch on face', async ({ page, homePage }) => { test.setTimeout(90_000)
const u = await getUtils(page)
await page.addInitScript(async () => {
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')
@ -457,59 +474,59 @@ await page.addInitScript(async () => {
|> close(%)
extrude001 = extrude(5 + 7, sketch001)`
)
})
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
await homePage.goToModelingScene()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await expect(
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
).not.toBeDisabled()
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.waitForTimeout(300)
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.waitForTimeout(300)
let previousCodeContent = await page.locator('.cm-content').innerText()
let previousCodeContent = await page.locator('.cm-content').innerText()
await u.openAndClearDebugPanel()
await u.doAndWaitForCmd(
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.waitForTimeout(150)
await u.closeDebugPanel()
const firstClickPosition = [612, 238]
const secondClickPosition = [661, 242]
const thirdClickPosition = [609, 267]
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.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(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(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 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(
await expect.poll(u.normalisedEditorCode).toContain(
u.normalisedCode(`sketch002 = startSketchOn(extrude001, seg01)
|> startProfileAt([-12.94, 6.6], %)
|> line([2.45, -0.2], %)
@ -517,65 +534,66 @@ await expect.poll(u.normalisedEditorCode).toContain(
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
`)
)
)
await u.openAndClearDebugPanel()
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.openAndClearDebugPanel()
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.updateCamPosition([1049, 239, 686])
await u.closeDebugPanel()
await u.updateCamPosition([1049, 239, 686])
await u.closeDebugPanel()
await page.getByText('startProfileAt([-12').click()
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400)
await page.waitForTimeout(150)
await page.setBodyDimensions({ width: 1200, height: 1200 })
await u.openAndClearDebugPanel()
await u.updateCamPosition([452, -152, 1166])
await u.closeDebugPanel()
await page.waitForTimeout(200)
await page.getByText('startProfileAt([-12').click()
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400)
await page.waitForTimeout(150)
await page.setBodyDimensions({ width: 1200, height: 1200 })
await u.openAndClearDebugPanel()
await u.updateCamPosition([452, -152, 1166])
await u.closeDebugPanel()
await page.waitForTimeout(200)
const pointToDragFirst = [787, 565]
await page.mouse.move(pointToDragFirst[0], pointToDragFirst[1])
await page.mouse.down()
await page.mouse.move(pointToDragFirst[0] - 20, pointToDragFirst[1], {
const pointToDragFirst = [787, 565]
await page.mouse.move(pointToDragFirst[0], pointToDragFirst[1])
await page.mouse.down()
await page.mouse.move(pointToDragFirst[0] - 20, pointToDragFirst[1], {
steps: 5,
})
await page.mouse.up()
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
previousCodeContent = await page.locator('.cm-content').innerText()
})
await page.mouse.up()
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
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], %)
|> line([${[2.28, 2.35]}, -${0.07}], %)
|> line([-3.05, -1.47], %)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)`
await expect(page.locator('.cm-content')).toHaveText(result.regExp)
await expect(page.locator('.cm-content')).toHaveText(result.regExp)
// exit sketch
await u.openAndClearDebugPanel()
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await u.expectCmdLog('[data-message-type="execution-done"]')
// exit sketch
await u.openAndClearDebugPanel()
await page.getByRole('button', { name: 'Exit Sketch' }).click()
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 page.waitForTimeout(100)
await page.getByRole('button', { name: 'Extrude' }).click()
await expect(page.getByRole('button', { name: 'Extrude' })).not.toBeDisabled()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Extrude' }).click()
await expect(page.getByTestId('command-bar')).toBeVisible()
await page.waitForTimeout(100)
await expect(page.getByTestId('command-bar')).toBeVisible()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'arrow right Continue' }).click()
await page.waitForTimeout(100)
await expect(page.getByText('Confirm Extrude')).toBeVisible()
await page.getByRole('button', { name: 'checkmark Submit command' }).click()
await page.getByRole('button', { name: 'arrow right Continue' }).click()
await page.waitForTimeout(100)
await expect(page.getByText('Confirm Extrude')).toBeVisible()
await page.getByRole('button', { name: 'checkmark Submit command' }).click()
const result2 = result.genNext`
const result2 = result.genNext`
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.
const pwTestFnWithFixtures = playwrightTestFn.extend<Fixtures>(fixtures)
// In JavaScript you cannot replace a function's body only (despite functions
// are themselves objects, which you'd expect a body property or something...)
// 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
// creation. Before they used to do this by their own electronSetup({...})
// calls.
tronApp.context.folderSetupFn = function(fn) {
tronApp.context.folderSetupFn = function (fn) {
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
const downloadDir = window.electron.join(
window.electron.process.env.TEST_SETTINGS_FILE_KEY,
"downloads-during-playwright",
'downloads-during-playwright'
)
await window.electron.mkdir(downloadDir, { recursive: true })
await window.electron.writeFile(