Part of #4600. PR: https://github.com/KittyCAD/modeling-app/pull/4826 # Changes to KCL stdlib - `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)` - `close(sketch, tag?)` is now `close(@sketch, tag?)` - `extrude(length, sketch)` is now `extrude(@sketch, length)` Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this: ``` sketch = startSketchAt([0, 0]) line(sketch, end = [3, 3], tag = $hi) ``` Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as ``` sketch = startSketchAt([0, 0]) |> line(end = [3, 3], tag = $hi) ``` Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are: ``` line\(([^=]*), %\) line(end = $1) line\((.*), %, (.*)\) line(end = $1, tag = $2) lineTo\((.*), %\) line(endAbsolute = $1) lineTo\((.*), %, (.*)\) line(endAbsolute = $1, tag = $2) extrude\((.*), %\) extrude(length = $1) extrude\(([^=]*), ([a-zA-Z0-9]+)\) extrude($2, length = $1) close\(%, (.*)\) close(tag = $1) ``` # Selected notes from commits before I squash them all * Fix test 'yRelative to horizontal distance' Fixes: - Make a lineTo helper - Fix pathToNode to go through the labeled arg .arg property * Fix test by changing lookups into transformMap Parts of the code assumed that `line` is always a relative call. But actually now it might be absolute, if it's got an `endAbsolute` parameter. So, change whether to look up `line` or `lineTo` and the relevant absolute or relative line types based on that parameter. * Stop asserting on exact source ranges When I changed line to kwargs, all the source ranges we assert on became slightly different. I find these assertions to be very very low value. So I'm removing them. * Fix more tests: getConstraintType calls weren't checking if the 'line' fn was absolute or relative. * Fixed another queryAst test There were 2 problems: - Test was looking for the old style of `line` call to choose an offset for pathToNode - Test assumed that the `tag` param was always the third one, but in a kwarg call, you have to look it up by label * Fix test: traverse was not handling CallExpressionKw * Fix another test, addTagKw addTag helper was not aware of kw args. * Convert close from positional to kwargs If the close() call has 0 args, or a single unlabeled arg, the parser interprets it as a CallExpression (positional) not a CallExpressionKw. But then if a codemod wants to add a tag to it, it tries adding a kwarg called 'tag', which fails because the CallExpression doesn't need kwargs inserted into it. The fix is: change the node from CallExpression to CallExpressionKw, and update getNodeFromPath to take a 'replacement' arg, so we can replace the old node with the new node in the AST. * Fix the last test Test was looking for `lineTo` as a substring of the input KCL program. But there's no more lineTo function, so I changed it to look for line() with an endAbsolute arg, which is the new equivalent. Also changed the getConstraintInfo code to look up the lineTo if using line with endAbsolute. * Fix many bad regex find-replaces I wrote a regex find-and-replace which converted `line` calls from positional to keyword calls. But it was accidentally applied to more places than it should be, for example, angledLine, xLine and yLine calls. Fixes this. * Fixes test 'Basic sketch › code pane closed at start' Problem was, the getNodeFromPath call might not actually find a callExpressionKw, it might find a callExpression. So the `giveSketchFnCallTag` thought it was modifying a kwargs call, but it was actually modifying a positional call. This meant it tried to push a labeled argument in, rather than a normal arg, and a lot of other problems. Fixed by doing runtime typechecking. * Fix: Optional args given with wrong type were silently ignored Optional args don't have to be given. But if the user gives them, they should be the right type. Bug: if the KCL interpreter found an optional arg, which was given, but was the wrong type, it would ignore it and pretend the arg was never given at all. This was confusing for users. Fix: Now if you give an optional arg, but it's the wrong type, KCL will emit a type error just like it would for a mandatory argument. --------- Signed-off-by: Nick Cameron <nrc@ncameron.org> Co-authored-by: Nick Cameron <nrc@ncameron.org> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Frank Noirot <frank@kittycad.io> Co-authored-by: Kevin Nadro <kevin@zoo.dev> Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
591 lines
20 KiB
TypeScript
591 lines
20 KiB
TypeScript
import { test, expect } from './zoo-test'
|
|
|
|
import { doExport, getUtils, makeTemplate } from './test-utils'
|
|
|
|
test.fixme('Units menu', async ({ page, homePage }) => {
|
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
await homePage.goToModelingScene()
|
|
|
|
const unitsMenuButton = page.getByRole('button', {
|
|
name: 'Current Units',
|
|
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')
|
|
})
|
|
|
|
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
|
|
baseLen = 3.5
|
|
baseHeight = 1
|
|
totalHeightHalf = 2
|
|
armThick = 0.5
|
|
totalLen = 9.5
|
|
part001 = startSketchOn('-XZ')
|
|
|> startProfileAt([0, 0], %)
|
|
|> yLine(baseHeight, %)
|
|
|> xLine(baseLen, %)
|
|
|> angledLineToY({
|
|
angle = topAng,
|
|
to = totalHeightHalf,
|
|
}, %, $seg04)
|
|
|> xLineTo(totalLen, %, $seg03)
|
|
|> yLine(-armThick, %, $seg01)
|
|
|> angledLineThatIntersects({
|
|
angle = HALF_TURN,
|
|
offset = -armThick,
|
|
intersectTag = seg04
|
|
}, %)
|
|
|> angledLineToY([segAng(seg04) + 180, ZERO], %)
|
|
|> angledLineToY({
|
|
angle = -bottomAng,
|
|
to = -totalHeightHalf - armThick,
|
|
}, %, $seg02)
|
|
|> xLineTo(segEndX(seg03) + 0, %)
|
|
|> yLine(-segLen(seg01), %)
|
|
|> angledLineThatIntersects({
|
|
angle = HALF_TURN,
|
|
offset = -armThick,
|
|
intersectTag = seg02
|
|
}, %)
|
|
|> angledLineToY([segAng(seg02) + 180, -baseHeight], %)
|
|
|> xLineTo(ZERO, %)
|
|
|> close()
|
|
|> extrude(length = 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
|
|
)
|
|
})
|
|
|
|
test('Paste should not work unless an input is focused', async ({
|
|
page,
|
|
homePage,
|
|
}) => {
|
|
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)
|
|
})
|
|
|
|
test('Keyboard shortcuts can be viewed through the help menu', async ({
|
|
page,
|
|
homePage,
|
|
}) => {
|
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
await homePage.goToModelingScene()
|
|
|
|
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 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(
|
|
page.getByRole('heading', { name: 'Enter Sketch Mode' })
|
|
).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 })
|
|
|
|
await homePage.goToModelingScene()
|
|
await u.openDebugPanel()
|
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
await u.closeDebugPanel()
|
|
|
|
const lineButton = page.getByRole('button', {
|
|
name: 'line Line',
|
|
exact: true,
|
|
})
|
|
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)
|
|
|
|
// 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')
|
|
|
|
// 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(
|
|
'Basic default modeling and sketch hotkeys work',
|
|
async ({ page, homePage }) => {
|
|
const u = await getUtils(page)
|
|
|
|
// This test can run long if it takes a little too long to load
|
|
// the engine.
|
|
test.setTimeout(90000)
|
|
// This test has a weird bug on ubuntu
|
|
// Funny, it's flaking on Windows too :). I think there is just something
|
|
// actually wrong.
|
|
test.skip(
|
|
process.platform === 'linux',
|
|
'weird playwright bug on ubuntu https://github.com/KittyCAD/modeling-app/issues/2444'
|
|
)
|
|
// Load the app with the code pane open
|
|
|
|
await test.step(`Set up test`, async () => {
|
|
await page.addInitScript(async () => {
|
|
localStorage.setItem(
|
|
'store',
|
|
JSON.stringify({
|
|
state: {
|
|
openPanes: ['code'],
|
|
},
|
|
version: 0,
|
|
})
|
|
)
|
|
})
|
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
await homePage.goToModelingScene()
|
|
await u.openDebugPanel()
|
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
await u.closeDebugPanel()
|
|
})
|
|
|
|
const codePane = page.locator('.cm-content')
|
|
const lineButton = page.getByRole('button', {
|
|
name: 'line Line',
|
|
exact: true,
|
|
})
|
|
const arcButton = page.getByRole('button', {
|
|
name: 'arc Tangential Arc',
|
|
exact: true,
|
|
})
|
|
const extrudeButton = page.getByRole('button', { name: 'Extrude' })
|
|
const commandBarComboBox = page.getByPlaceholder('Search commands')
|
|
const exitSketchButton = page.getByRole('button', { name: 'Exit Sketch' })
|
|
|
|
await test.step(`Type code with modeling hotkeys, shouldn't fire`, async () => {
|
|
await codePane.click()
|
|
await page.keyboard.type('//')
|
|
await page.keyboard.press('s')
|
|
await expect(commandBarComboBox).not.toBeVisible()
|
|
await page.keyboard.press('e')
|
|
await expect(commandBarComboBox).not.toBeVisible()
|
|
await expect(codePane).toHaveText('//se')
|
|
})
|
|
|
|
// Blur focus from the code editor, use the s command to sketch
|
|
await test.step(`Blur editor focus, enter sketch`, async () => {
|
|
/**
|
|
* TODO: There is a bug somewhere that causes this test to fail
|
|
* if you toggle the codePane closed before your trigger the
|
|
* start of the sketch.
|
|
* and a separate Safari-only bug that causes the test to fail
|
|
* if the pane is open the entire test. The maintainer of CodeMirror
|
|
* has pinpointed this to the unusual browser behavior:
|
|
* https://discuss.codemirror.net/t/how-to-force-unfocus-of-the-codemirror-element-in-safari/8095/3
|
|
*/
|
|
await blurCodeEditor()
|
|
await page.waitForTimeout(1000)
|
|
await page.keyboard.press('s')
|
|
await page.waitForTimeout(1000)
|
|
await page.mouse.move(800, 300, { steps: 5 })
|
|
await page.mouse.click(800, 300)
|
|
await page.waitForTimeout(1000)
|
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'true', {
|
|
timeout: 15_000,
|
|
})
|
|
})
|
|
|
|
// Use some sketch hotkeys to create a sketch (l and a for now)
|
|
await test.step(`Incomplete sketch with hotkeys`, async () => {
|
|
await test.step(`Draw a line`, async () => {
|
|
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)
|
|
})
|
|
|
|
await test.step(`Unequip line tool`, async () => {
|
|
await page.keyboard.press('l')
|
|
await expect(lineButton).not.toHaveAttribute('aria-pressed', 'true')
|
|
})
|
|
|
|
await test.step(`Draw a tangential arc`, async () => {
|
|
await page.keyboard.press('a')
|
|
await expect(arcButton).toHaveAttribute('aria-pressed', 'true', {
|
|
timeout: 10_000,
|
|
})
|
|
await page.mouse.move(1000, 100, { steps: 5 })
|
|
await page.mouse.click(1000, 100)
|
|
})
|
|
|
|
await test.step(`Unequip with escape, equip line tool`, async () => {
|
|
await page.keyboard.press('Escape')
|
|
await page.keyboard.press('l')
|
|
await page.waitForTimeout(50)
|
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
|
})
|
|
})
|
|
|
|
await test.step(`Type code with sketch hotkeys, shouldn't fire`, async () => {
|
|
// Since there's code now, we have to get to the end of the line
|
|
await page.locator('.cm-line').last().click()
|
|
await page.keyboard.down('ControlOrMeta')
|
|
await page.keyboard.press('ArrowRight')
|
|
await page.keyboard.up('ControlOrMeta')
|
|
|
|
await page.keyboard.press('Enter')
|
|
await page.keyboard.type('//')
|
|
await page.keyboard.press('l')
|
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
|
await page.keyboard.press('a')
|
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
|
await expect(codePane).toContainText('//la')
|
|
await page.keyboard.press('Backspace')
|
|
await page.keyboard.press('Backspace')
|
|
await page.keyboard.press('Backspace')
|
|
await page.keyboard.press('Backspace')
|
|
})
|
|
|
|
await test.step(`Close profile and exit sketch`, async () => {
|
|
await blurCodeEditor()
|
|
await page.mouse.move(700, 200, { steps: 5 })
|
|
await page.mouse.click(700, 200)
|
|
// On close it will unequip the line tool.
|
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'false')
|
|
await expect(exitSketchButton).toBeEnabled()
|
|
await page.keyboard.press('Escape')
|
|
await expect(
|
|
page.getByRole('button', { name: 'Exit Sketch' })
|
|
).not.toBeVisible()
|
|
})
|
|
|
|
// Extrude with e
|
|
await test.step(`Extrude the sketch`, async () => {
|
|
await page.mouse.click(750, 150)
|
|
await blurCodeEditor()
|
|
await expect(extrudeButton).toBeEnabled()
|
|
await page.keyboard.press('e')
|
|
await page.waitForTimeout(500)
|
|
await page.mouse.move(800, 200, { steps: 5 })
|
|
await page.mouse.click(800, 200)
|
|
await expect(page.getByRole('button', { name: 'Continue' })).toBeVisible({
|
|
timeout: 20_000,
|
|
})
|
|
await page.getByRole('button', { name: 'Continue' }).click()
|
|
await expect(
|
|
page.getByRole('button', { name: 'Submit command' })
|
|
).toBeVisible()
|
|
await page.getByRole('button', { name: 'Submit command' }).click()
|
|
await expect(page.locator('.cm-content')).toContainText('extrude(')
|
|
})
|
|
|
|
// await codePaneButton.click()
|
|
// await expect(u.codeLocator).not.toBeVisible()
|
|
|
|
/**
|
|
* work-around: to stop `keyboard.press()` from typing in the editor even when it should be blurred
|
|
*/
|
|
async function blurCodeEditor() {
|
|
await page.getByRole('button', { name: 'Commands' }).click()
|
|
await page.waitForTimeout(100)
|
|
await page.keyboard.press('Escape')
|
|
await page.waitForTimeout(100)
|
|
}
|
|
}
|
|
)
|
|
|
|
test('Delete key does not navigate back', async ({ page, homePage }) => {
|
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
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')
|
|
|
|
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 () => {
|
|
localStorage.setItem(
|
|
'persistCode',
|
|
`sketch001 = startSketchOn('XZ')
|
|
|> startProfileAt([3.29, 7.86], %)
|
|
|> line(end = [2.48, 2.44])
|
|
|> line(end = [2.66, 1.17])
|
|
|> line(end = [3.75, 0.46])
|
|
|> line(end = [4.99, -0.46])
|
|
|> line(end = [3.3, -2.12])
|
|
|> line(end = [2.16, -3.33])
|
|
|> line(end = [0.85, -3.08])
|
|
|> line(end = [-0.18, -3.36])
|
|
|> line(end = [-3.86, -2.73])
|
|
|> line(end = [-17.67, 0.85])
|
|
|> close()
|
|
extrude001 = extrude(sketch001, length = 5 + 7)`
|
|
)
|
|
})
|
|
|
|
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()
|
|
|
|
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], %)
|
|
|> line(end = [2.45, -0.2])
|
|
|> line(end = [-2.6, -1.25])
|
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
|> close()
|
|
`)
|
|
)
|
|
|
|
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 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], {
|
|
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()
|
|
|
|
const result = makeTemplate`sketch002 = startSketchOn(extrude001, seg01)
|
|
|> startProfileAt([-12.83, 6.7], %)
|
|
|> line(end = [${[2.28, 2.35]}, -${0.07}])
|
|
|> line(end = [-3.05, -1.47])
|
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
|> close()`
|
|
|
|
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"]')
|
|
|
|
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.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()
|
|
|
|
const result2 = result.genNext`
|
|
const sketch002 = extrude(sketch002, length = ${[5, 5]} + 7)`
|
|
await expect(page.locator('.cm-content')).toHaveText(result2.regExp)
|
|
})
|