Merge branch 'main' into ryanrosello-og/playwright-test-coverage

This commit is contained in:
Ryan Rosello
2024-08-13 18:55:42 +10:00
389 changed files with 2720 additions and 2429 deletions

View File

@ -37,7 +37,7 @@ jobs:
playwright-ubuntu: playwright-ubuntu:
timeout-minutes: 30 timeout-minutes: 30
runs-on: ubuntu-latest-8-cores runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -98,14 +98,16 @@ const extrude001 = extrude(-10, sketch001)`
const commandBarButton = page.getByRole('button', { name: 'Commands' }) const commandBarButton = page.getByRole('button', { name: 'Commands' })
const cmdSearchBar = page.getByPlaceholder('Search commands') const cmdSearchBar = page.getByPlaceholder('Search commands')
const themeOption = page.getByRole('option', { const commandName = 'debug panel'
name: 'theme', const commandOption = page.getByRole('option', {
name: commandName,
exact: false, exact: false,
}) })
const commandLevelArgButton = page.getByRole('button', { name: 'level' }) const commandLevelArgButton = page.getByRole('button', { name: 'level' })
const commandThemeArgButton = page.getByRole('button', { name: 'value' }) const commandThemeArgButton = page.getByRole('button', { name: 'value' })
const paneSelector = page.getByRole('button', { name: 'debug panel' })
// This selector changes after we set the setting // This selector changes after we set the setting
let commandOptionInput = page.getByPlaceholder('Select an option') let commandOptionInput = page.getByPlaceholder('On')
await expect( await expect(
page.getByRole('button', { name: 'Start Sketch' }) page.getByRole('button', { name: 'Start Sketch' })
@ -127,17 +129,16 @@ const extrude001 = extrude(-10, sketch001)`
await expect(cmdSearchBar).toBeFocused() await expect(cmdSearchBar).toBeFocused()
// Try typing in the command bar // Try typing in the command bar
await cmdSearchBar.fill('theme') await cmdSearchBar.fill(commandName)
await expect(themeOption).toBeVisible() await expect(commandOption).toBeVisible()
await themeOption.click() await commandOption.click()
const themeInput = page.getByPlaceholder('Select an option') const toggleInput = page.getByPlaceholder('On')
await expect(themeInput).toBeVisible() await expect(toggleInput).toBeVisible()
await expect(themeInput).toBeFocused() await expect(toggleInput).toBeFocused()
// Select dark theme // Select On
await page.keyboard.press('ArrowDown') await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown') await page.keyboard.press('ArrowDown')
await page.keyboard.press('ArrowDown') await expect(page.getByRole('option', { name: 'Off' })).toHaveAttribute(
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
'data-headlessui-state', 'data-headlessui-state',
'active' 'active'
) )
@ -145,21 +146,21 @@ const extrude001 = extrude(-10, sketch001)`
// Check the toast appeared // Check the toast appeared
await expect( await expect(
page.getByText(`Set theme to "system" for this project`) page.getByText(`Set show debug panel to "false" for this project`)
).toBeVisible() ).toBeVisible()
// Check that the theme changed // Check that the visibility changed
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`) await expect(paneSelector).not.toBeVisible()
commandOptionInput = page.getByPlaceholder('system') commandOptionInput = page.getByPlaceholder('off')
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882 // Test case for https://github.com/KittyCAD/modeling-app/issues/2882
await commandBarButton.click() await commandBarButton.click()
await cmdSearchBar.focus() await cmdSearchBar.focus()
await cmdSearchBar.fill('theme') await cmdSearchBar.fill(commandName)
await themeOption.click() await commandOption.click()
await expect(commandThemeArgButton).toBeDisabled() await expect(commandThemeArgButton).toBeDisabled()
await commandOptionInput.focus() await commandOptionInput.focus()
await commandOptionInput.fill('lig') await commandOptionInput.fill('on')
await commandLevelArgButton.click() await commandLevelArgButton.click()
await expect(commandLevelArgButton).toBeDisabled() await expect(commandLevelArgButton).toBeDisabled()
@ -197,7 +198,7 @@ const extrude001 = extrude(-10, sketch001)`
}) })
await expect(themeOption).toBeVisible() await expect(themeOption).toBeVisible()
await themeOption.click() await themeOption.click()
const themeInput = page.getByPlaceholder('Select an option') const themeInput = page.getByPlaceholder('dark')
await expect(themeInput).toBeVisible() await expect(themeInput).toBeVisible()
await expect(themeInput).toBeFocused() await expect(themeInput).toBeFocused()
// Select dark theme // Select dark theme
@ -212,7 +213,7 @@ const extrude001 = extrude(-10, sketch001)`
// Check the toast appeared // Check the toast appeared
await expect( await expect(
page.getByText(`Set theme to "system" for this project`) page.getByText(`Set theme to "system" as a user default`)
).toBeVisible() ).toBeVisible()
// Check that the theme changed // 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`)

View File

@ -1,6 +1,8 @@
import { test, expect } from '@playwright/test' import { test, expect } from '@playwright/test'
import { getUtils, setup, tearDown } from './test-utils' import { getUtils, setup, tearDown } from './test-utils'
import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from './storageStates'
import { bracket } from 'lib/exampleKcl'
test.beforeEach(async ({ context, page }) => { test.beforeEach(async ({ context, page }) => {
await setup(context, page) await setup(context, page)
@ -223,4 +225,210 @@ const sketch001 = startSketchAt([-0, -0])
await expect(page.locator('.cm-lint-marker-error')).toBeVisible() await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
}) })
test('when engine fails export we handle the failure and alert the user', async ({
page,
}) => {
const u = await getUtils(page)
await page.addInitScript(async (code) => {
localStorage.setItem('persistCode', code)
}, TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR)
await page.setViewportSize({ width: 1000, height: 500 })
await u.waitForAuthSkipAppStart()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
// Click the export button
exportButton.click()
// Click the stl.
const stlOption = page.getByText('glTF')
await expect(stlOption).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
const submitButton = page.getByText('Confirm Export')
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
const exportingToastMessage = page.getByText(`Exporting...`)
await expect(exportingToastMessage).toBeVisible()
const errorToastMessage = page.getByText(`Error while exporting`)
await expect(errorToastMessage).toBeVisible()
const engineErrorToastMessage = page.getByText(`Nothing to export`)
await expect(engineErrorToastMessage).toBeVisible()
// Make sure the exporting toast is gone
await expect(exportingToastMessage).not.toBeVisible()
// Click the code editor
page.locator('.cm-content').click()
await page.waitForTimeout(2000)
// Expect the toast to be gone
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
// Now add in code that works.
page.locator('.cm-content').fill(bracket)
page.locator('.cm-content').click()
await page.keyboard.press('End')
await page.keyboard.press('Enter')
// wait for execution done
await u.openDebugPanel()
await u.clearCommandLogs()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Now try exporting
// Click the export button
exportButton.click()
// Click the stl.
await expect(stlOption).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
await expect(exportingToastMessage).toBeVisible()
// Expect it to succeed.
await expect(exportingToastMessage).not.toBeVisible()
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible()
})
test('ensure you can not export while an export is already going', async ({
page,
}) => {
const u = await getUtils(page)
await page.addInitScript(async (code) => {
localStorage.setItem('persistCode', code)
}, bracket)
await page.setViewportSize({ width: 1000, height: 500 })
await u.waitForAuthSkipAppStart()
// wait for execution done
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
// Click the export button
exportButton.click()
// Click the stl.
const stlOption = page.getByText('glTF')
await expect(stlOption).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
const submitButton = page.getByText('Confirm Export')
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
const exportingToastMessage = page.getByText(`Exporting...`)
await expect(exportingToastMessage).toBeVisible()
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
// Try exporting again.
// Click the export button
exportButton.click()
// Click the stl.
await expect(stlOption).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
await expect(exportingToastMessage).toBeVisible()
await expect(alreadyExportingToastMessage).toBeVisible()
// Expect it to succeed.
await expect(exportingToastMessage).not.toBeVisible()
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible()
await expect(alreadyExportingToastMessage).not.toBeVisible()
// Try exporting again.
// Click the export button
exportButton.click()
// Click the stl.
await expect(stlOption).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
await expect(exportingToastMessage).toBeVisible()
// Expect it to succeed.
await expect(exportingToastMessage).not.toBeVisible()
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
await expect(alreadyExportingToastMessage).not.toBeVisible()
await expect(successToastMessage).toBeVisible()
})
}) })

View File

@ -151,11 +151,12 @@ test.describe('Sketch tests', () => {
await page.mouse.click(700, 200) await page.mouse.click(700, 200)
await expect(page.locator('.cm-content')).toHaveText( await expect.poll(u.normalisedEditorCode)
`const sketch001 = startSketchOn('XZ') .toBe(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([4.61, -14.01], %) |> startProfileAt([12.34, -12.34], %)
|> line([0.31, 16.47], %)` |> line([-12.34, 12.34], %)
)
`)
}) })
test('Can exit selection of face', async ({ page }) => { test('Can exit selection of face', async ({ page }) => {
// Load the app with the code panes // Load the app with the code panes

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -368,3 +368,5 @@ startSketchOn(keychain, 'end')
height - (keychainHoleSize + 1.5) height - (keychainHoleSize + 1.5)
], keychainHoleSize, %) ], keychainHoleSize, %)
|> extrude(-thickness, %)` |> extrude(-thickness, %)`
export const TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR = `const thing = 1`

View File

@ -204,19 +204,24 @@ test.describe('Test network and connection issues', () => {
// Ensure we can continue sketching // Ensure we can continue sketching
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20) await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
await expect(page.locator('.cm-content')) await expect.poll(u.normalisedEditorCode)
.toHaveText(`const sketch001 = startSketchOn('XZ') .toBe(`const sketch001 = startSketchOn('XZ')
|> startProfileAt(${commonPoints.startAt}, %) |> startProfileAt([12.34, -12.34], %)
|> line([${commonPoints.num1}, 0], %) |> line([12.34, 0], %)
|> line([-8.84, 8.75], %)`) |> line([-12.34, 12.34], %)
`)
await page.waitForTimeout(100) await page.waitForTimeout(100)
await page.mouse.click(startXPx, 500 - PUR * 20) await page.mouse.click(startXPx, 500 - PUR * 20)
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ') await expect.poll(u.normalisedEditorCode)
|> startProfileAt(${commonPoints.startAt}, %) .toBe(`const sketch001 = startSketchOn('XZ')
|> line([${commonPoints.num1}, 0], %) |> startProfileAt([12.34, -12.34], %)
|> line([-8.84, 8.75], %) |> line([12.34, 0], %)
|> line([-5.6, 0], %)`) |> line([-12.34, 12.34], %)
|> line([-12.34, 0], %)
`)
// Unequip line tool // Unequip line tool
await page.keyboard.press('Escape') await page.keyboard.press('Escape')

View File

@ -271,6 +271,18 @@ async function waitForAuthAndLsp(page: Page) {
return waitForLspPromise return waitForLspPromise
} }
export function normaliseKclNumbers(code: string, ignoreZero = true): string {
const numberRegexp = /(?<!\w)-?\b\d+(\.\d+)?\b(?!\w)/g
const replaceNumber = (number: string) => {
if (ignoreZero && (number === '0' || number === '-0')) return number
const sign = number.startsWith('-') ? '-' : ''
return `${sign}12.34`
}
const replaceNumbers = (text: string) =>
text.replace(numberRegexp, replaceNumber)
return replaceNumbers(code)
}
export async function getUtils(page: Page) { export async function getUtils(page: Page) {
// Chrome devtools protocol session only works in Chromium // Chrome devtools protocol session only works in Chromium
const browserType = page.context().browser()?.browserType().name() const browserType = page.context().browser()?.browserType().name()
@ -333,6 +345,11 @@ export async function getUtils(page: Page) {
.boundingBox() .boundingBox()
.then((box) => ({ ...box, x: box?.x || 0, y: box?.y || 0 })), .then((box) => ({ ...box, x: box?.x || 0, y: box?.y || 0 })),
codeLocator: page.locator('.cm-content'), codeLocator: page.locator('.cm-content'),
normalisedEditorCode: async () => {
const code = await page.locator('.cm-content').innerText()
return normaliseKclNumbers(code)
},
normalisedCode: (code: string) => normaliseKclNumbers(code),
canvasLocator: page.getByTestId('client-side-scene'), canvasLocator: page.getByTestId('client-side-scene'),
doAndWaitForCmd: async ( doAndWaitForCmd: async (
fn: () => Promise<void>, fn: () => Promise<void>,

View File

@ -80,11 +80,11 @@ const part001 = startSketchOn('XZ')
|> line([74.36, 130.4], %, $seg01) |> line([74.36, 130.4], %, $seg01)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> angledLine([segAng(seg01), yo], %) |> angledLine([segAng(seg01), yo], %)
|> line([41.19, 28.97 + 5], %) |> line([41.19, 58.97 + 5], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 120], %)
|> xLine(-425.34, %, $seg_what) |> xLine(-385.34, %, $seg_what)
|> yLine(-264.06, %) |> yLine(-170.06, %)
|> xLine(segLen(seg_what), %) |> xLine(segLen(seg_what), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)` |> lineTo([profileStartX(%), profileStartY(%)], %)`
) )
@ -138,7 +138,7 @@ const part001 = startSketchOn('XZ')
|> line([74.36, 130.4], %, $seg01) |> line([74.36, 130.4], %, $seg01)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> angledLine([segAng(seg01), 78.33], %) |> angledLine([segAng(seg01), 78.33], %)
|> line([41.19, 28.97], %) |> line([51.19, 48.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what) |> xLine(-425.34, %, $seg_what)
@ -237,7 +237,7 @@ const part001 = startSketchOn('XZ')
|> line([74.36, 130.4], %) |> line([74.36, 130.4], %)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> line([9.16, 77.79], %) |> line([9.16, 77.79], %)
|> line([41.19, 28.97], %) |> line([51.19, 48.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what) |> xLine(-425.34, %, $seg_what)
@ -343,7 +343,7 @@ const part001 = startSketchOn('XZ')
|> line([74.36, 130.4], %) |> line([74.36, 130.4], %)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> line([9.16, 77.79], %) |> line([9.16, 77.79], %)
|> line([41.19, 28.97], %) |> line([51.19, 48.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what) |> xLine(-425.34, %, $seg_what)
@ -450,7 +450,7 @@ const part001 = startSketchOn('XZ')
|> line([74.36, 130.4], %) |> line([74.36, 130.4], %)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> line([9.16, 77.79], %) |> line([9.16, 77.79], %)
|> line([41.19, 28.97], %) |> line([51.19, 48.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what) |> xLine(-425.34, %, $seg_what)
@ -560,7 +560,7 @@ const part001 = startSketchOn('XZ')
|> line([74.36, 130.4], %) |> line([74.36, 130.4], %)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> line([9.16, 77.79], %) |> line([9.16, 77.79], %)
|> line([41.19, 28.97], %) |> line([51.19, 48.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what) |> xLine(-425.34, %, $seg_what)
@ -613,14 +613,14 @@ const part002 = startSketchOn('XZ')
codeAfter: [ codeAfter: [
`|> yLine(130.4, %)`, `|> yLine(130.4, %)`,
`|> yLine(77.79, %)`, `|> yLine(77.79, %)`,
`|> yLine(28.97, %)`, `|> yLine(48.97, %)`,
], ],
}, },
{ {
codeAfter: [ codeAfter: [
`|> xLine(74.36, %)`, `|> xLine(74.36, %)`,
`|> xLine(9.16, %)`, `|> xLine(9.16, %)`,
`|> xLine(41.19, %)`, `|> xLine(51.19, %)`,
], ],
constraintName: 'Horizontal', constraintName: 'Horizontal',
}, },
@ -636,7 +636,7 @@ const part001 = startSketchOn('XZ')
|> line([74.36, 130.4], %) |> line([74.36, 130.4], %)
|> line([78.92, -120.11], %) |> line([78.92, -120.11], %)
|> line([9.16, 77.79], %) |> line([9.16, 77.79], %)
|> line([41.19, 28.97], %) |> line([51.19, 48.97], %)
const part002 = startSketchOn('XZ') const part002 = startSketchOn('XZ')
|> startProfileAt([299.05, 231.45], %) |> startProfileAt([299.05, 231.45], %)
|> xLine(-425.34, %, $seg_what) |> xLine(-425.34, %, $seg_what)

View File

@ -63,95 +63,55 @@ test.describe('Testing settings', () => {
.getByRole('button', { name: 'Start Sketch' }) .getByRole('button', { name: 'Start Sketch' })
.waitFor({ state: 'visible' }) .waitFor({ state: 'visible' })
const paneButtonLocator = page.getByTestId('debug-pane-button')
const headingLocator = page.getByRole('heading', {
name: 'Settings',
exact: true,
})
const inputLocator = page.locator('input[name="modeling-showDebugPanel"]')
// Open the settings modal with the browser keyboard shortcut // Open the settings modal with the browser keyboard shortcut
await page.keyboard.press('Meta+Shift+,') await page.keyboard.press('Meta+Shift+,')
await expect( await expect(headingLocator).toBeVisible()
page.getByRole('heading', { name: 'Settings', exact: true }) await page.locator('#showDebugPanel').getByText('OffOn').click()
).toBeVisible()
await page
.locator('select[name="app-theme"]')
.selectOption({ value: 'light' })
// Verify the toast appeared
await expect(
page.getByText(`Set theme to "light" for this project`)
).toBeVisible()
// Check that the theme changed
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
// Check that the user setting was not changed
await page.getByRole('radio', { name: 'User' }).click()
await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark')
// Roll back to default "system" theme
await page
.getByText(
'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
)
.hover()
await page
.getByRole('button', {
name: 'Roll back theme',
})
.click()
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
// Check that the project setting did not change
await page.getByRole('radio', { name: 'Project' }).click()
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
})
test('Project settings can be opened with keybinding from the editor', async ({
page,
}) => {
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await page
.getByRole('button', { name: 'Start Sketch' })
.waitFor({ state: 'visible' })
// Close it and open again with keyboard shortcut, while KCL editor is focused
// Put the cursor in the editor // Put the cursor in the editor
await page.locator('.cm-content').click() await test.step('Open settings with keyboard shortcut', async () => {
await page.getByTestId('settings-close-button').click()
// Open the settings modal with the browser keyboard shortcut await page.locator('.cm-content').click()
await page.keyboard.press('Meta+Shift+,') await page.keyboard.press('Meta+Shift+,')
await expect(headingLocator).toBeVisible()
await expect( })
page.getByRole('heading', { name: 'Settings', exact: true })
).toBeVisible()
await page
.locator('select[name="app-theme"]')
.selectOption({ value: 'light' })
// Verify the toast appeared // Verify the toast appeared
await expect( await expect(
page.getByText(`Set theme to "light" for this project`) page.getByText(`Set show debug panel to "false" for this project`)
).toBeVisible() ).toBeVisible()
// Check that the theme changed // Check that the theme changed
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`) await expect(paneButtonLocator).not.toBeVisible()
// Check that the user setting was not changed // Check that the user setting was not changed
await page.getByRole('radio', { name: 'User' }).click() await page.getByRole('radio', { name: 'User' }).click()
await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark') await expect(inputLocator).toBeChecked()
// Roll back to default "system" theme // Roll back to default of "off"
await page await await page
.getByText( .getByText('show debug panelRoll back show debug panelRoll back to match')
'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
)
.hover() .hover()
await page await page
.getByRole('button', { .getByRole('button', {
name: 'Roll back theme', name: 'Roll back show debug panel',
}) })
.click() .click()
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system') await expect(inputLocator).not.toBeChecked()
// Check that the project setting did not change // Check that the project setting did not change
await page.getByRole('radio', { name: 'Project' }).click() await page.getByRole('radio', { name: 'Project' }).click()
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light') await expect(
page.locator('input[name="modeling-showDebugPanel"]')
).not.toBeChecked()
}) })
test('Project and user settings can be reset', async ({ page }) => { test('Project and user settings can be reset', async ({ page }) => {
@ -162,69 +122,67 @@ test.describe('Testing settings', () => {
.getByRole('button', { name: 'Start Sketch' }) .getByRole('button', { name: 'Start Sketch' })
.waitFor({ state: 'visible' }) .waitFor({ state: 'visible' })
// Put the cursor in the editor const projectSettingsTab = page.getByRole('radio', { name: 'Project' })
await page.locator('.cm-content').click() const userSettingsTab = page.getByRole('radio', { name: 'User' })
const resetButton = page.getByRole('button', {
// Open the settings modal with the browser keyboard shortcut name: 'Restore default settings',
await page.keyboard.press('Meta+Shift+,') })
const themeColorSetting = page.locator('#themeColor').getByRole('slider')
const settingValues = {
default: '259',
user: '120',
project: '50',
}
// Open the settings modal with lower-right button
await page.getByRole('link', { name: 'Settings' }).last().click()
await expect( await expect(
page.getByRole('heading', { name: 'Settings', exact: true }) page.getByRole('heading', { name: 'Settings', exact: true })
).toBeVisible() ).toBeVisible()
// Click the reset settings button. await test.step('Set up theme color', async () => {
await page.getByRole('button', { name: 'Restore default settings' }).click() // Verify we're looking at the project-level settings,
// and it's set to default value
await expect(projectSettingsTab).toBeChecked()
await expect(themeColorSetting).toHaveValue(settingValues.default)
await page // Set project-level value to 50
.locator('select[name="app-theme"]') await themeColorSetting.fill(settingValues.project)
.selectOption({ value: 'light' })
// Verify the toast appeared // Set user-level value to 120
await expect( await userSettingsTab.click()
page.getByText(`Set theme to "light" for this project`) await themeColorSetting.fill(settingValues.user)
).toBeVisible() await projectSettingsTab.click()
// Check that the theme changed })
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
// Check that the user setting was not changed await test.step('Reset project settings', async () => {
await page.getByRole('radio', { name: 'User' }).click() // Click the reset settings button.
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system') await resetButton.click()
// Click the reset settings button. // Verify it is now set to the inherited user value
await page.getByRole('button', { name: 'Restore default settings' }).click() await expect(themeColorSetting).toHaveValue(settingValues.default)
// Verify it is now set to the default value // Check that the user setting also rolled back
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system') await userSettingsTab.click()
await expect(themeColorSetting).toHaveValue(settingValues.default)
await projectSettingsTab.click()
// Set the user theme to light. // Set project-level value to 50 again to test the user-level reset
await page await themeColorSetting.fill(settingValues.project)
.locator('select[name="app-theme"]') await userSettingsTab.click()
.selectOption({ value: 'light' }) })
// Verify the toast appeared await test.step('Reset user settings', async () => {
await expect( // Change the setting and click the reset settings button.
page.getByText(`Set theme to "light" as a user default`) await themeColorSetting.fill(settingValues.user)
).toBeVisible() await resetButton.click()
// Check that the theme changed
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
await page.getByRole('radio', { name: 'Project' }).click() // Verify it is now set to the default value
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light') await expect(themeColorSetting).toHaveValue(settingValues.default)
// Click the reset settings button. // Check that the project setting also changed
await page.getByRole('button', { name: 'Restore default settings' }).click() await projectSettingsTab.click()
// Verify it is now set to the default value await expect(themeColorSetting).toHaveValue(settingValues.default)
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system') })
await page.getByRole('radio', { name: 'User' }).click()
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
// Click the reset settings button.
await page.getByRole('button', { name: 'Restore default settings' }).click()
// Verify it is now set to the default value
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
}) })
}) })

View File

@ -468,7 +468,7 @@ test('Sketch on face', async ({ page }) => {
await u.openAndClearDebugPanel() await u.openAndClearDebugPanel()
await u.doAndWaitForCmd( await u.doAndWaitForCmd(
() => page.mouse.click(625, 133), () => page.mouse.click(625, 165),
'default_camera_get_settings', 'default_camera_get_settings',
true true
) )
@ -498,13 +498,14 @@ test('Sketch on face', async ({ page }) => {
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()
await expect(page.locator('.cm-content')) await expect.poll(u.normalisedEditorCode).toContain(
.toContainText(`const sketch002 = startSketchOn(extrude001, seg01) u.normalisedCode(`const 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()
@ -513,7 +514,7 @@ test('Sketch on face', async ({ page }) => {
await u.updateCamPosition([1049, 239, 686]) await u.updateCamPosition([1049, 239, 686])
await u.closeDebugPanel() await u.closeDebugPanel()
await page.getByText('startProfileAt([-12.94, 6.6], %)').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)
@ -549,7 +550,7 @@ test('Sketch on face', async ({ page }) => {
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.94, 6.6], %)').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)

View File

@ -79,7 +79,8 @@
"$ref": "#/components/schemas/Result" "$ref": "#/components/schemas/Result"
} }
], ],
"description": "The result of the info command." "description": "The result of the info command.",
"nullable": true
}, },
"sequence_id": { "sequence_id": {
"allOf": [ "allOf": [
@ -93,7 +94,6 @@
"required": [ "required": [
"command", "command",
"module", "module",
"result",
"sequence_id" "sequence_id"
], ],
"type": "object" "type": "object"

132
src-tauri/Cargo.lock generated
View File

@ -123,9 +123,9 @@ dependencies = [
[[package]] [[package]]
name = "anstyle" name = "anstyle"
version = "1.0.6" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]] [[package]]
name = "anstyle-parse" name = "anstyle-parse"
@ -334,7 +334,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -369,7 +369,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -409,7 +409,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -552,7 +552,7 @@ dependencies = [
"proc-macro-crate 3.1.0", "proc-macro-crate 3.1.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
"syn_derive", "syn_derive",
] ]
@ -800,9 +800,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.13" version = "4.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -810,9 +810,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.13" version = "4.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -831,7 +831,7 @@ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1081,7 +1081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1091,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1115,7 +1115,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim 0.10.0", "strsim 0.10.0",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1126,7 +1126,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1187,7 +1187,7 @@ checksum = "4078275de501a61ceb9e759d37bdd3d7210e654dbc167ac1a3678ef4435ed57b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
"synstructure", "synstructure",
] ]
@ -1214,7 +1214,7 @@ dependencies = [
[[package]] [[package]]
name = "derive-docs" name = "derive-docs"
version = "0.1.21" version = "0.1.22"
dependencies = [ dependencies = [
"Inflector", "Inflector",
"convert_case 0.6.0", "convert_case 0.6.0",
@ -1224,7 +1224,7 @@ dependencies = [
"regex", "regex",
"serde", "serde",
"serde_tokenstream", "serde_tokenstream",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1235,7 +1235,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1296,7 +1296,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1328,7 +1328,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1435,7 +1435,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1607,7 +1607,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1723,7 +1723,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -1999,7 +1999,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -2027,7 +2027,7 @@ dependencies = [
"inflections", "inflections",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -2102,7 +2102,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -2612,7 +2612,7 @@ dependencies = [
[[package]] [[package]]
name = "kcl-lib" name = "kcl-lib"
version = "0.2.3" version = "0.2.4"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"approx", "approx",
@ -2672,9 +2672,9 @@ dependencies = [
[[package]] [[package]]
name = "kittycad" name = "kittycad"
version = "0.3.10" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d798c82f6e62d786fca0a7ec073675bbe9550c885efb99390d2701ca557ec69" checksum = "7bc87dcc307aa8c8dd56a6f022da1cbdf13a0a1e2abacb9ca9f897118a75596d"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -3425,7 +3425,7 @@ dependencies = [
"regex", "regex",
"regex-syntax 0.8.3", "regex-syntax 0.8.3",
"structmeta", "structmeta",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -3544,7 +3544,7 @@ dependencies = [
"phf_shared 0.11.2", "phf_shared 0.11.2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -3612,7 +3612,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -4502,7 +4502,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde_derive_internals", "serde_derive_internals",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -4587,9 +4587,9 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.204" version = "1.0.206"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -4616,13 +4616,13 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.204" version = "1.0.206"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -4633,14 +4633,14 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.122" version = "1.0.124"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d"
dependencies = [ dependencies = [
"indexmap 2.2.6", "indexmap 2.2.6",
"itoa 1.0.11", "itoa 1.0.11",
@ -4667,7 +4667,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -4688,7 +4688,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde", "serde",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -4730,7 +4730,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -5001,7 +5001,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"structmeta-derive", "structmeta-derive",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -5012,7 +5012,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -5034,7 +5034,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustversion", "rustversion",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -5067,9 +5067,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.72" version = "2.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -5085,7 +5085,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -5102,7 +5102,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -5319,7 +5319,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"sha2", "sha2",
"syn 2.0.72", "syn 2.0.74",
"tauri-utils", "tauri-utils",
"thiserror", "thiserror",
"time", "time",
@ -5337,7 +5337,7 @@ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
"tauri-codegen", "tauri-codegen",
"tauri-utils", "tauri-utils",
] ]
@ -5710,7 +5710,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -5807,7 +5807,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -6007,7 +6007,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -6036,7 +6036,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -6166,7 +6166,7 @@ checksum = "c88cc88fd23b5a04528f3a8436024f20010a16ec18eb23c164b1242f65860130"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
"termcolor", "termcolor",
] ]
@ -6389,7 +6389,7 @@ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -6488,7 +6488,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -6522,7 +6522,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -6663,7 +6663,7 @@ checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -6769,7 +6769,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -6780,7 +6780,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]
@ -7232,7 +7232,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.72", "syn 2.0.74",
] ]
[[package]] [[package]]

View File

@ -16,7 +16,7 @@ tauri-build = { version = "2.0.0-beta.18", features = [] }
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"
kcl-lib = { version = "0.2", path = "../src/wasm-lib/kcl" } kcl-lib = { version = "0.2", path = "../src/wasm-lib/kcl" }
kittycad = "0.3.7" kittycad = "0.3.12"
log = "0.4.21" log = "0.4.21"
mdns-sd = "0.11.1" mdns-sd = "0.11.1"
oauth2 = "4.4.2" oauth2 = "4.4.2"

View File

@ -26,7 +26,7 @@ import {
PathToNode, PathToNode,
Program, Program,
SourceRange, SourceRange,
Value, Expr,
parse, parse,
recast, recast,
} from 'lang/wasm' } from 'lang/wasm'
@ -550,7 +550,7 @@ const ConstraintSymbol = ({
varNameMap[_type as LineInputsType]?.implicitConstraintDesc varNameMap[_type as LineInputsType]?.implicitConstraintDesc
const _node = useMemo( const _node = useMemo(
() => getNodeFromPath<Value>(kclManager.ast, pathToNode), () => getNodeFromPath<Expr>(kclManager.ast, pathToNode),
[kclManager.ast, pathToNode] [kclManager.ast, pathToNode]
) )
if (err(_node)) return if (err(_node)) return

View File

@ -1,5 +1,5 @@
import { useEffect, useState, useRef } from 'react' import { useEffect, useState, useRef } from 'react'
import { parse, BinaryPart, Value, ProgramMemory } from '../lang/wasm' import { parse, BinaryPart, Expr, ProgramMemory } from '../lang/wasm'
import { import {
createIdentifier, createIdentifier,
createLiteral, createLiteral,
@ -86,7 +86,7 @@ export function useCalc({
initialVariableName?: string initialVariableName?: string
}): { }): {
inputRef: React.RefObject<HTMLInputElement> inputRef: React.RefObject<HTMLInputElement>
valueNode: Value | null valueNode: Expr | null
calcResult: string calcResult: string
prevVariables: PrevVariable<unknown>[] prevVariables: PrevVariable<unknown>[]
newVariableName: string newVariableName: string
@ -105,7 +105,7 @@ export function useCalc({
insertIndex: 0, insertIndex: 0,
bodyPath: [], bodyPath: [],
}) })
const [valueNode, setValueNode] = useState<Value | null>(null) const [valueNode, setValueNode] = useState<Expr | null>(null)
const [calcResult, setCalcResult] = useState('NAN') const [calcResult, setCalcResult] = useState('NAN')
const [newVariableName, setNewVariableName] = useState('') const [newVariableName, setNewVariableName] = useState('')
const [isNewVariableNameUnique, setIsNewVariableNameUnique] = useState(true) const [isNewVariableNameUnique, setIsNewVariableNameUnique] = useState(true)

View File

@ -458,7 +458,7 @@ export const FileTreeInner = ({
}, [documentHasFocus]) }, [documentHasFocus])
return ( return (
<div className="overflow-auto max-h-full pb-12"> <div className="overflow-auto pb-12 absolute inset-0">
<ul <ul
className="m-0 p-0 text-sm" className="m-0 p-0 text-sm"
onClickCapture={(e) => { onClickCapture={(e) => {

View File

@ -80,7 +80,6 @@ import { modelingMachineEvent } from 'editor/manager'
import { hasValidFilletSelection } from 'lang/modifyAst/addFillet' import { hasValidFilletSelection } from 'lang/modifyAst/addFillet'
import { import {
ExportIntent, ExportIntent,
EngineConnectionState,
EngineConnectionStateType, EngineConnectionStateType,
EngineConnectionEvents, EngineConnectionEvents,
} from 'lang/std/engineConnection' } from 'lang/std/engineConnection'
@ -371,7 +370,6 @@ export const ModelingMachineProvider = ({
// Set the export intent. // Set the export intent.
engineCommandManager.exportIntent = ExportIntent.Make engineCommandManager.exportIntent = ExportIntent.Make
console.log('making', event.data)
// Set the current machine. // Set the current machine.
machineManager.currentMachine = event.data.machine machineManager.currentMachine = event.data.machine
@ -413,7 +411,6 @@ export const ModelingMachineProvider = ({
// Set the export intent. // Set the export intent.
engineCommandManager.exportIntent = ExportIntent.Save engineCommandManager.exportIntent = ExportIntent.Save
console.log('exporting', event.data)
const format = { const format = {
...event.data, ...event.data,
} as Partial<Models['OutputFormat_type']> } as Partial<Models['OutputFormat_type']>

View File

@ -1,7 +1,7 @@
import { TEST } from 'env' import { TEST } from 'env'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext' import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { Themes, getSystemTheme } from 'lib/theme' import { Themes, getSystemTheme } from 'lib/theme'
import { useEffect, useMemo, useRef } from 'react' import { useMemo, useRef } from 'react'
import { highlightSelectionMatches, searchKeymap } from '@codemirror/search' import { highlightSelectionMatches, searchKeymap } from '@codemirror/search'
import { lineHighlightField } from 'editor/highlightextension' import { lineHighlightField } from 'editor/highlightextension'
import { roundOff } from 'lib/utils' import { roundOff } from 'lib/utils'

View File

@ -1,7 +1,7 @@
import { Dialog, Transition } from '@headlessui/react' import { Dialog, Transition } from '@headlessui/react'
import { Fragment, useState } from 'react' import { Fragment, useState } from 'react'
import { type InstanceProps, create } from 'react-modal-promise' import { type InstanceProps, create } from 'react-modal-promise'
import { Value } from '../lang/wasm' import { Expr } from '../lang/wasm'
import { import {
AvailableVars, AvailableVars,
addToInputHelper, addToInputHelper,
@ -13,7 +13,7 @@ import { useCalculateKclExpression } from 'lib/useCalculateKclExpression'
type ModalResolve = { type ModalResolve = {
value: string value: string
sign: number sign: number
valueNode: Value valueNode: Expr
variableName?: string variableName?: string
newVariableInsertIndex: number newVariableInsertIndex: number
} }

Some files were not shown because too many files have changed in this diff Show More