Merge remote-tracking branch 'origin/main' into kurt-scale-sketch
2
.github/workflows/build-apps.yml
vendored
@ -362,7 +362,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Authenticate to Google Cloud
|
- name: Authenticate to Google Cloud
|
||||||
if: ${{ env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_STAGING == 'true' }}
|
||||||
uses: 'google-github-actions/auth@v2.1.8'
|
uses: 'google-github-actions/auth@v2.1.10'
|
||||||
with:
|
with:
|
||||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/kcl-language-server.yml
vendored
@ -328,7 +328,7 @@ jobs:
|
|||||||
mkdir -p releases/language-server/${{ env.TAG }}
|
mkdir -p releases/language-server/${{ env.TAG }}
|
||||||
cp -r build/* releases/language-server/${{ env.TAG }}
|
cp -r build/* releases/language-server/${{ env.TAG }}
|
||||||
- name: "Authenticate to Google Cloud"
|
- name: "Authenticate to Google Cloud"
|
||||||
uses: "google-github-actions/auth@v2.1.8"
|
uses: "google-github-actions/auth@v2.1.10"
|
||||||
with:
|
with:
|
||||||
credentials_json: "${{ secrets.GOOGLE_CLOUD_DL_SA }}"
|
credentials_json: "${{ secrets.GOOGLE_CLOUD_DL_SA }}"
|
||||||
- name: Set up Cloud SDK
|
- name: Set up Cloud SDK
|
||||||
|
|||||||
2
.github/workflows/publish-apps-release.yml
vendored
@ -108,7 +108,7 @@ jobs:
|
|||||||
run: npm run files:set-notes
|
run: npm run files:set-notes
|
||||||
|
|
||||||
- name: Authenticate to Google Cloud
|
- name: Authenticate to Google Cloud
|
||||||
uses: 'google-github-actions/auth@v2.1.8'
|
uses: 'google-github-actions/auth@v2.1.10'
|
||||||
with:
|
with:
|
||||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
||||||
|
|
||||||
|
|||||||
@ -280,6 +280,9 @@ Assign someone to each section of the manual checklist generated by the issue te
|
|||||||
Follow the instructions [here](./rust/README.md) to publish new crates.
|
Follow the instructions [here](./rust/README.md) to publish new crates.
|
||||||
This ensures that the KCL accepted by the app is also accepted by the CLI.
|
This ensures that the KCL accepted by the app is also accepted by the CLI.
|
||||||
|
|
||||||
|
If there are documentation changes, merge the corresponding Dependabot PRs [here](https://github.com/KittyCAD/website/pulls/app%2Fdependabot) for the website.
|
||||||
|
You can trigger Dependabot to check for updates [here](https://github.com/KittyCAD/website/network/updates/17261214/jobs).
|
||||||
|
|
||||||
#### 5. Publish the release
|
#### 5. Publish the release
|
||||||
|
|
||||||
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the **Release title** field as well.
|
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the **Release title** field as well.
|
||||||
|
|||||||
3
Makefile
@ -62,7 +62,10 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
public/kcl-samples/manifest.json: $(KCL_SOURCES)
|
public/kcl-samples/manifest.json: $(KCL_SOURCES)
|
||||||
|
ifndef WINDOWS
|
||||||
cd rust/kcl-lib && EXPECTORATE=overwrite cargo test generate_manifest
|
cd rust/kcl-lib && EXPECTORATE=overwrite cargo test generate_manifest
|
||||||
|
@ touch $@
|
||||||
|
endif
|
||||||
|
|
||||||
.vite/build/main.js: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
|
.vite/build/main.js: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
|
||||||
npm run tronb:vite:dev
|
npm run tronb:vite:dev
|
||||||
|
|||||||
@ -83,6 +83,13 @@ Allow orbiting in sketch mode.
|
|||||||
Whether to show the debug panel, which lets you see various states of the app to aid in development.
|
Whether to show the debug panel, which lets you see various states of the app to aid in development.
|
||||||
|
|
||||||
|
|
||||||
|
**Default:** None
|
||||||
|
|
||||||
|
##### fixed_size_grid
|
||||||
|
|
||||||
|
If true, the grid cells will be fixed-size, where the width is your default length unit. If false, the grid will get larger as you zoom out, and smaller as you zoom in.
|
||||||
|
|
||||||
|
|
||||||
**Default:** None
|
**Default:** None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'subtract',
|
name: 'subtract',
|
||||||
code: 'subtract([extrude001], tools = [extrude006])',
|
code: 'subtract(extrude001, tools = extrude006)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'intersect',
|
name: 'intersect',
|
||||||
@ -81,6 +81,8 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
if (operationName !== 'subtract') {
|
if (operationName !== 'subtract') {
|
||||||
// should down shift key to select multiple objects
|
// should down shift key to select multiple objects
|
||||||
await page.keyboard.down('Shift')
|
await page.keyboard.down('Shift')
|
||||||
|
} else {
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select second object
|
// Select second object
|
||||||
@ -103,8 +105,8 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Tool: '1 path',
|
Solids: '1 path',
|
||||||
Target: '1 path',
|
Tools: '1 path',
|
||||||
},
|
},
|
||||||
commandName,
|
commandName,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { uuidv4 } from '@src/lib/utils'
|
|||||||
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
|
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
|
||||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
||||||
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
||||||
|
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||||
import { getUtils } from '@e2e/playwright/test-utils'
|
import { getUtils } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
@ -14,13 +15,18 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
homePage: HomePageFixture,
|
homePage: HomePageFixture,
|
||||||
scene: SceneFixture,
|
scene: SceneFixture,
|
||||||
toolbar: ToolbarFixture,
|
toolbar: ToolbarFixture,
|
||||||
|
cmdBar: CmdBarFixture,
|
||||||
plane: string,
|
plane: string,
|
||||||
clickCoords: { x: number; y: number }
|
clickCoords: { x: number; y: number }
|
||||||
) => {
|
) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
// await page.addInitScript(() => {
|
||||||
|
// localStorage.setItem('persistCode', '@settings(defaultLengthUnit = in)')
|
||||||
|
// })
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
// await scene.settled(cmdBar)
|
||||||
const XYPlanRed: [number, number, number] = [98, 50, 51]
|
const XYPlanRed: [number, number, number] = [98, 50, 51]
|
||||||
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
||||||
|
|
||||||
@ -119,12 +125,166 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
]
|
]
|
||||||
|
|
||||||
for (const config of planeConfigs) {
|
for (const config of planeConfigs) {
|
||||||
test(config.plane, async ({ page, homePage, scene, toolbar }) => {
|
test(config.plane, async ({ page, homePage, scene, toolbar, cmdBar }) => {
|
||||||
await sketchOnPlaneAndBackSideTest(
|
await sketchOnPlaneAndBackSideTest(
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
scene,
|
scene,
|
||||||
toolbar,
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
config.plane,
|
||||||
|
config.coords
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
test.describe('Can create sketches on offset planes and their back sides', () => {
|
||||||
|
const sketchOnPlaneAndBackSideTest = async (
|
||||||
|
page: Page,
|
||||||
|
homePage: HomePageFixture,
|
||||||
|
scene: SceneFixture,
|
||||||
|
toolbar: ToolbarFixture,
|
||||||
|
cmdbar: CmdBarFixture,
|
||||||
|
plane: string,
|
||||||
|
clickCoords: { x: number; y: number }
|
||||||
|
) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.addInitScript(() => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`@settings(defaultLengthUnit = in)
|
||||||
|
xyPlane = offsetPlane(XY, offset = 0.05)
|
||||||
|
xzPlane = offsetPlane(XZ, offset = 0.05)
|
||||||
|
yzPlane = offsetPlane(YZ, offset = 0.05)
|
||||||
|
`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
// await scene.settled(cmdbar)
|
||||||
|
const XYPlanRed: [number, number, number] = [74, 74, 74]
|
||||||
|
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
||||||
|
|
||||||
|
await u.openDebugPanel()
|
||||||
|
|
||||||
|
const coord =
|
||||||
|
plane === '-XY' || plane === '-YZ' || plane === 'XZ' ? -100 : 100
|
||||||
|
const camCommand: EngineCommand = {
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_look_at',
|
||||||
|
center: { x: 0, y: 0, z: 0 },
|
||||||
|
vantage: { x: coord, y: coord, z: coord },
|
||||||
|
up: { x: 0, y: 0, z: 1 },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const updateCamCommand: EngineCommand = {
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_get_settings',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const prefix = plane.length === 3 ? '-' : ''
|
||||||
|
const planeName = plane
|
||||||
|
.slice(plane.length === 3 ? 1 : 0)
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
|
||||||
|
const codeLine1 = `sketch001 = startSketchOn(${prefix}${planeName}Plane)`
|
||||||
|
const codeLine2 = `profile001 = startProfile(sketch001, at = [${0.91 + (plane[0] === '-' ? 0.01 : 0)}, -${1.21 + (plane[0] === '-' ? 0.01 : 0)}])`
|
||||||
|
|
||||||
|
await u.openDebugPanel()
|
||||||
|
|
||||||
|
await u.clearCommandLogs()
|
||||||
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||||
|
|
||||||
|
await u.sendCustomCmd(camCommand)
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await u.sendCustomCmd(updateCamCommand)
|
||||||
|
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
await toolbar.openFeatureTreePane()
|
||||||
|
await toolbar.getDefaultPlaneVisibilityButton('XY').click()
|
||||||
|
await toolbar.getDefaultPlaneVisibilityButton('XZ').click()
|
||||||
|
await toolbar.getDefaultPlaneVisibilityButton('YZ').click()
|
||||||
|
await expect(
|
||||||
|
toolbar
|
||||||
|
.getDefaultPlaneVisibilityButton('YZ')
|
||||||
|
.locator('[aria-label="eye crossed out"]')
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
|
await page.mouse.click(clickCoords.x, clickCoords.y)
|
||||||
|
await page.waitForTimeout(600) // wait for animation
|
||||||
|
|
||||||
|
await toolbar.waitUntilSketchingReady()
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'line Line', exact: true })
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
await page.mouse.click(707, 393)
|
||||||
|
|
||||||
|
await expect(page.locator('.cm-content')).toContainText(codeLine1)
|
||||||
|
await expect(page.locator('.cm-content')).toContainText(codeLine2)
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByRole('button', { name: 'line Line', exact: true })
|
||||||
|
.first()
|
||||||
|
.click()
|
||||||
|
await u.openAndClearDebugPanel()
|
||||||
|
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
|
||||||
|
await u.clearCommandLogs()
|
||||||
|
await u.removeCurrentCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
const planeConfigs = [
|
||||||
|
{
|
||||||
|
plane: 'XY',
|
||||||
|
coords: { x: 600, y: 388 },
|
||||||
|
description: 'red plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: 'YZ',
|
||||||
|
coords: { x: 700, y: 250 },
|
||||||
|
description: 'green plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: 'XZ',
|
||||||
|
coords: { x: 684, y: 427 },
|
||||||
|
description: 'blue plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: '-XY',
|
||||||
|
coords: { x: 600, y: 118 },
|
||||||
|
description: 'back of red plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: '-YZ',
|
||||||
|
coords: { x: 700, y: 219 },
|
||||||
|
description: 'back of green plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: '-XZ',
|
||||||
|
coords: { x: 700, y: 80 },
|
||||||
|
description: 'back of blue plane',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const config of planeConfigs) {
|
||||||
|
test(config.plane, async ({ page, homePage, scene, toolbar, cmdBar }) => {
|
||||||
|
await sketchOnPlaneAndBackSideTest(
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
config.plane,
|
config.plane,
|
||||||
config.coords
|
config.coords
|
||||||
)
|
)
|
||||||
|
|||||||
@ -265,6 +265,8 @@ middle(0)
|
|||||||
})
|
})
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(`assert failed: Expected 0 to be greater than 0 but it wasn't
|
page.getByText(`assert failed: Expected 0 to be greater than 0 but it wasn't
|
||||||
|
|
||||||
|
Backtrace:
|
||||||
assert()
|
assert()
|
||||||
check()
|
check()
|
||||||
middle()`)
|
middle()`)
|
||||||
|
|||||||
@ -288,7 +288,7 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers must be lowerCamelCase').first()
|
page.getByText('Identifiers should be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
await page.locator('#code-pane button:first-child').click()
|
await page.locator('#code-pane button:first-child').click()
|
||||||
@ -314,7 +314,7 @@ sketch_001 = startSketchOn(XY)
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers must be lowerCamelCase').first()
|
page.getByText('Identifiers should be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -511,7 +511,7 @@ sketch_001 = startSketchOn(XY)
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers must be lowerCamelCase').first()
|
page.getByText('Identifiers should be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
// focus the editor
|
// focus the editor
|
||||||
@ -539,7 +539,7 @@ sketch_001 = startSketchOn(XY)
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers must be lowerCamelCase').first()
|
page.getByText('Identifiers should be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -681,7 +681,7 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
|
|||||||
// error text on hover
|
// error text on hover
|
||||||
await page.hover('.cm-lint-marker-info')
|
await page.hover('.cm-lint-marker-info')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText('Identifiers must be lowerCamelCase').first()
|
page.getByText('Identifiers should be lowerCamelCase').first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
// select the line that's causing the error and delete it
|
// select the line that's causing the error and delete it
|
||||||
@ -1617,4 +1617,33 @@ sketch001 = startSketchOn(XZ)
|
|||||||
// Verify error is still visible
|
// Verify error is still visible
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(1)
|
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Core dump hotkey', async ({ page, scene, cmdBar, homePage }) => {
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`sketch001 = startSketchOn(XZ)
|
||||||
|
profile001 = circle(sketch001, center = [-100.0, -100.0], radius = 50.0)
|
||||||
|
`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const viewportSize = { width: 1200, height: 800 }
|
||||||
|
await page.setBodyDimensions(viewportSize)
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
const modifier = process.platform === 'darwin' ? 'Meta' : 'Control'
|
||||||
|
|
||||||
|
await page.keyboard.press(`${modifier}+Shift+.`)
|
||||||
|
|
||||||
|
const toast1 = page.getByText('Starting core dump...')
|
||||||
|
await expect(toast1).toBeVisible()
|
||||||
|
|
||||||
|
const toast2 = page.getByText('Core dump completed')
|
||||||
|
await expect(toast2).toBeVisible()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -187,6 +187,13 @@ export class CmdBarFixture {
|
|||||||
return this.page.getByRole('option', options)
|
return this.page.getByRole('option', options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select an optional argument from the command bar during review
|
||||||
|
*/
|
||||||
|
clickOptionalArgument = async (argName: string) => {
|
||||||
|
await this.page.getByTestId(`cmd-bar-add-optional-arg-${argName}`).click()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clicks the Create new variable button for kcl input
|
* Clicks the Create new variable button for kcl input
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -274,6 +274,13 @@ export class ToolbarFixture {
|
|||||||
.nth(operationIndex)
|
.nth(operationIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDefaultPlaneVisibilityButton(plane: 'XY' | 'XZ' | 'YZ' = 'XY') {
|
||||||
|
const index = plane === 'XZ' ? 0 : plane === 'XY' ? 1 : 2
|
||||||
|
return this.featureTreePane
|
||||||
|
.getByTestId('feature-tree-visibility-toggle')
|
||||||
|
.nth(index)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View source on a specific operation in the Feature Tree pane.
|
* View source on a specific operation in the Feature Tree pane.
|
||||||
* @param operationName The name of the operation type
|
* @param operationName The name of the operation type
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
|||||||
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
import { bracket } from '@e2e/playwright/fixtures/bracket'
|
import { bracket } from '@e2e/playwright/fixtures/bracket'
|
||||||
|
import type { CmdBarSerialised } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||||
|
|
||||||
// test file is for testing point an click code gen functionality that's not sketch mode related
|
// test file is for testing point an click code gen functionality that's not sketch mode related
|
||||||
|
|
||||||
@ -1141,6 +1142,20 @@ openSketch = startSketchOn(XY)
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const initialCmdBarStateHelix: CmdBarSerialised = {
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'mode',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Mode: '',
|
||||||
|
AngleStart: '',
|
||||||
|
Revolutions: '',
|
||||||
|
Radius: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'mode',
|
||||||
|
commandName: 'Helix',
|
||||||
|
}
|
||||||
|
|
||||||
test('Helix point-and-click on default axis', async ({
|
test('Helix point-and-click on default axis', async ({
|
||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
@ -1150,30 +1165,14 @@ openSketch = startSketchOn(XY)
|
|||||||
toolbar,
|
toolbar,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
// One dumb hardcoded screen pixel value
|
const expectedOutput = `helix001 = helix( axis = X, radius = 5, length = 5, revolutions = 1, angleStart = 270,)`
|
||||||
const testPoint = { x: 620, y: 257 }
|
|
||||||
const expectedOutput = `helix001 = helix( axis = X, radius = 5, length = 5, revolutions = 1, angleStart = 270, ccw = false,)`
|
|
||||||
const expectedLine = `axis=X,`
|
const expectedLine = `axis=X,`
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.connectionEstablished()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
await test.step(`Go through the command bar flow`, async () => {
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
await toolbar.helixButton.click()
|
await toolbar.helixButton.click()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState(initialCmdBarStateHelix)
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'mode',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Mode: '',
|
|
||||||
AngleStart: '',
|
|
||||||
Revolutions: '',
|
|
||||||
Radius: '',
|
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'mode',
|
|
||||||
commandName: 'Helix',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await expect.poll(() => page.getByText('Axis').count()).toBe(6)
|
await expect.poll(() => page.getByText('Axis').count()).toBe(6)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -1190,7 +1189,6 @@ openSketch = startSketchOn(XY)
|
|||||||
AngleStart: '',
|
AngleStart: '',
|
||||||
Length: '',
|
Length: '',
|
||||||
Radius: '',
|
Radius: '',
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
},
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
@ -1207,11 +1205,10 @@ openSketch = startSketchOn(XY)
|
|||||||
Revolutions: '1',
|
Revolutions: '1',
|
||||||
Length: '5',
|
Length: '5',
|
||||||
Radius: '5',
|
Radius: '5',
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
},
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.submit()
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
@ -1221,8 +1218,6 @@ openSketch = startSketchOn(XY)
|
|||||||
activeLines: [expectedLine],
|
activeLines: [expectedLine],
|
||||||
highlightedCode: '',
|
highlightedCode: '',
|
||||||
})
|
})
|
||||||
// Red plane is now gone, white helix is there
|
|
||||||
await scene.expectPixelColor([250, 250, 250], testPoint, 15)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Edit helix through the feature tree`, async () => {
|
await test.step(`Edit helix through the feature tree`, async () => {
|
||||||
@ -1234,21 +1229,18 @@ openSketch = startSketchOn(XY)
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'CounterClockWise',
|
currentArgKey: 'length',
|
||||||
currentArgValue: '',
|
currentArgValue: '5',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Axis: 'X',
|
Axis: 'X',
|
||||||
AngleStart: '270',
|
AngleStart: '270',
|
||||||
Revolutions: '1',
|
Revolutions: '1',
|
||||||
Radius: '5',
|
Radius: '5',
|
||||||
Length: initialInput,
|
Length: initialInput,
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'CounterClockWise',
|
highlightedHeaderArg: 'length',
|
||||||
})
|
})
|
||||||
await page.keyboard.press('Shift+Backspace')
|
await page.keyboard.insertText(newInput)
|
||||||
await expect(cmdBar.currentArgumentInput).toBeVisible()
|
|
||||||
await cmdBar.currentArgumentInput.locator('.cm-content').fill(newInput)
|
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
@ -1258,11 +1250,10 @@ openSketch = startSketchOn(XY)
|
|||||||
Revolutions: '1',
|
Revolutions: '1',
|
||||||
Radius: '5',
|
Radius: '5',
|
||||||
Length: newInput,
|
Length: newInput,
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
},
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.submit()
|
||||||
await toolbar.closeFeatureTreePane()
|
await toolbar.closeFeatureTreePane()
|
||||||
await editor.openPane()
|
await editor.openPane()
|
||||||
await editor.expectEditor.toContain('length = ' + newInput)
|
await editor.expectEditor.toContain('length = ' + newInput)
|
||||||
@ -1273,174 +1264,238 @@ openSketch = startSketchOn(XY)
|
|||||||
const operationButton = await toolbar.getFeatureTreeOperation('Helix', 0)
|
const operationButton = await toolbar.getFeatureTreeOperation('Helix', 0)
|
||||||
await operationButton.click({ button: 'left' })
|
await operationButton.click({ button: 'left' })
|
||||||
await page.keyboard.press('Delete')
|
await page.keyboard.press('Delete')
|
||||||
// Red plane is back
|
await scene.settled(cmdBar)
|
||||||
await scene.expectPixelColor([96, 52, 52], testPoint, 15)
|
await editor.expectEditor.not.toContain('helix')
|
||||||
|
await expect(
|
||||||
|
await toolbar.getFeatureTreeOperation('Helix', 0)
|
||||||
|
).not.toBeVisible()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const helixCases = [
|
test(`Helix point-and-click around segment`, async ({
|
||||||
{
|
context,
|
||||||
selectionType: 'segment',
|
page,
|
||||||
testPoint: { x: 513, y: 221 },
|
homePage,
|
||||||
expectedOutput: `helix001 = helix( axis = seg01, radius = 1, revolutions = 20, angleStart = 0, ccw = false,)`,
|
scene,
|
||||||
expectedEditedOutput: `helix001 = helix( axis = seg01, radius = 5, revolutions = 20, angleStart = 0, ccw = false,)`,
|
editor,
|
||||||
},
|
toolbar,
|
||||||
{
|
cmdBar,
|
||||||
selectionType: 'sweepEdge',
|
}) => {
|
||||||
testPoint: { x: 564, y: 364 },
|
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||||
expectedOutput: `helix001 = helix( axis = getOppositeEdge(seg01), radius = 1, revolutions = 20, angleStart = 0, ccw = false,)`,
|
profile001 = startProfile(sketch001, at = [0, 0])
|
||||||
expectedEditedOutput: `helix001 = helix( axis = getOppositeEdge(seg01), radius = 5, revolutions = 20, angleStart = 0, ccw = false,)`,
|
|> yLine(length = 100)
|
||||||
},
|
|> line(endAbsolute = [100, 0])
|
||||||
]
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
helixCases.map(
|
|> close()`
|
||||||
({ selectionType, testPoint, expectedOutput, expectedEditedOutput }) => {
|
await context.addInitScript((initialCode) => {
|
||||||
test(`Helix point-and-click around ${selectionType}`, async ({
|
localStorage.setItem('persistCode', initialCode)
|
||||||
context,
|
}, initialCode)
|
||||||
page,
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
homePage,
|
await homePage.goToModelingScene()
|
||||||
scene,
|
await scene.settled(cmdBar)
|
||||||
editor,
|
|
||||||
toolbar,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
page.on('console', console.log)
|
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = startProfile(sketch001, at = [0, 0])
|
|
||||||
|> yLine(length = 100)
|
|
||||||
|> line(endAbsolute = [100, 0])
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
extrude001 = extrude(profile001, length = 100)`
|
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
const [clickOnEdge] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
await toolbar.closePane('code')
|
||||||
|
await toolbar.helixButton.click()
|
||||||
await context.addInitScript((initialCode) => {
|
await cmdBar.expectState(initialCmdBarStateHelix)
|
||||||
localStorage.setItem('persistCode', initialCode)
|
await cmdBar.selectOption({ name: 'Edge' }).click()
|
||||||
}, initialCode)
|
await editor.selectText('yLine(length = 100)')
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await cmdBar.progressCmdBar()
|
||||||
await homePage.goToModelingScene()
|
await page.keyboard.insertText('1')
|
||||||
await scene.settled(cmdBar)
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.keyboard.insertText('2')
|
||||||
await test.step(`Go through the command bar flow`, async () => {
|
await cmdBar.progressCmdBar()
|
||||||
await toolbar.closePane('code')
|
await page.keyboard.insertText('3')
|
||||||
await toolbar.helixButton.click()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'review',
|
||||||
currentArgKey: 'mode',
|
headerArguments: {
|
||||||
currentArgValue: '',
|
Mode: 'Edge',
|
||||||
headerArguments: {
|
Edge: `1 segment`,
|
||||||
AngleStart: '',
|
AngleStart: '2',
|
||||||
Mode: '',
|
Revolutions: '1',
|
||||||
CounterClockWise: '',
|
Radius: '3',
|
||||||
Radius: '',
|
},
|
||||||
Revolutions: '',
|
commandName: 'Helix',
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'mode',
|
|
||||||
commandName: 'Helix',
|
|
||||||
})
|
|
||||||
await cmdBar.selectOption({ name: 'Edge' }).click()
|
|
||||||
await expect
|
|
||||||
.poll(() => page.getByText('Please select one').count())
|
|
||||||
.toBe(1)
|
|
||||||
await clickOnEdge()
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await cmdBar.argumentInput.focus()
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await page.keyboard.insertText('20')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('0')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('1')
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.keyboard.insertText('100')
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
Mode: 'Edge',
|
|
||||||
Edge: `1 ${selectionType}`,
|
|
||||||
AngleStart: '0',
|
|
||||||
Revolutions: '20',
|
|
||||||
Radius: '1',
|
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
|
||||||
commandName: 'Helix',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(expectedOutput)
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step(`Edit helix through the feature tree`, async () => {
|
|
||||||
await toolbar.openPane('feature-tree')
|
|
||||||
const operationButton = await toolbar.getFeatureTreeOperation(
|
|
||||||
'Helix',
|
|
||||||
0
|
|
||||||
)
|
|
||||||
await operationButton.dblclick()
|
|
||||||
const initialInput = '1'
|
|
||||||
const newInput = '5'
|
|
||||||
await cmdBar.expectState({
|
|
||||||
commandName: 'Helix',
|
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'CounterClockWise',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
AngleStart: '0',
|
|
||||||
Revolutions: '20',
|
|
||||||
Radius: initialInput,
|
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'CounterClockWise',
|
|
||||||
})
|
|
||||||
await page
|
|
||||||
.getByRole('button', { name: 'radius', exact: false })
|
|
||||||
.click()
|
|
||||||
await expect(cmdBar.currentArgumentInput).toBeVisible()
|
|
||||||
await cmdBar.currentArgumentInput
|
|
||||||
.locator('.cm-content')
|
|
||||||
.fill(newInput)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'review',
|
|
||||||
headerArguments: {
|
|
||||||
AngleStart: '0',
|
|
||||||
Revolutions: '20',
|
|
||||||
Radius: newInput,
|
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
|
||||||
commandName: 'Helix',
|
|
||||||
})
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await toolbar.closePane('feature-tree')
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(expectedEditedOutput)
|
|
||||||
await toolbar.closePane('code')
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Delete helix via feature tree selection', async () => {
|
|
||||||
await toolbar.openPane('feature-tree')
|
|
||||||
const operationButton = await toolbar.getFeatureTreeOperation(
|
|
||||||
'Helix',
|
|
||||||
0
|
|
||||||
)
|
|
||||||
await operationButton.click({ button: 'left' })
|
|
||||||
await page.keyboard.press('Delete')
|
|
||||||
await editor.expectEditor.not.toContain(expectedEditedOutput)
|
|
||||||
await expect(
|
|
||||||
await toolbar.getFeatureTreeOperation('Helix', 0)
|
|
||||||
).not.toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
await cmdBar.submit()
|
||||||
)
|
await scene.settled(cmdBar)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`
|
||||||
|
helix001 = helix(
|
||||||
|
axis = seg01,
|
||||||
|
radius = 3,
|
||||||
|
revolutions = 1,
|
||||||
|
angleStart = 2,
|
||||||
|
)`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test(`Helix point-and-click around sweepEdge with edit and delete flows`, async ({
|
||||||
|
context,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||||
|
profile001 = startProfile(sketch001, at = [0, 0])
|
||||||
|
|> yLine(length = 100)
|
||||||
|
|> line(endAbsolute = [100, 0])
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
extrude001 = extrude(profile001, length = 100)`
|
||||||
|
|
||||||
|
// One dumb hardcoded screen pixel value to click on the sweepEdge, can't think of another way?
|
||||||
|
const testPoint = { x: 564, y: 364 }
|
||||||
|
const [clickOnEdge] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||||
|
|
||||||
|
await context.addInitScript((initialCode) => {
|
||||||
|
localStorage.setItem('persistCode', initialCode)
|
||||||
|
}, initialCode)
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
await toolbar.helixButton.click()
|
||||||
|
await cmdBar.expectState(initialCmdBarStateHelix)
|
||||||
|
await cmdBar.selectOption({ name: 'Edge' }).click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
|
await clickOnEdge()
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.argumentInput.focus()
|
||||||
|
await page.keyboard.insertText('20')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.keyboard.insertText('0')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.keyboard.insertText('1')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.keyboard.insertText('100')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Mode: 'Edge',
|
||||||
|
Edge: `1 sweepEdge`,
|
||||||
|
AngleStart: '0',
|
||||||
|
Revolutions: '20',
|
||||||
|
Radius: '1',
|
||||||
|
},
|
||||||
|
commandName: 'Helix',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`
|
||||||
|
helix001 = helix(
|
||||||
|
axis = getOppositeEdge(seg01),
|
||||||
|
radius = 1,
|
||||||
|
revolutions = 20,
|
||||||
|
angleStart = 0,
|
||||||
|
)`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step(`Edit helix through the feature tree`, async () => {
|
||||||
|
await toolbar.openPane('feature-tree')
|
||||||
|
const operationButton = await toolbar.getFeatureTreeOperation('Helix', 0)
|
||||||
|
await operationButton.dblclick()
|
||||||
|
const initialInput = '1'
|
||||||
|
const newInput = '5'
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Helix',
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'radius',
|
||||||
|
currentArgValue: initialInput,
|
||||||
|
headerArguments: {
|
||||||
|
AngleStart: '0',
|
||||||
|
Revolutions: '20',
|
||||||
|
Radius: initialInput,
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'radius',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText(newInput)
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
AngleStart: '0',
|
||||||
|
Revolutions: '20',
|
||||||
|
Radius: newInput,
|
||||||
|
},
|
||||||
|
commandName: 'Helix',
|
||||||
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('ccw')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Helix',
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'CounterClockWise',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
AngleStart: '0',
|
||||||
|
Revolutions: '20',
|
||||||
|
Radius: newInput,
|
||||||
|
CounterClockWise: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'CounterClockWise',
|
||||||
|
})
|
||||||
|
await cmdBar.selectOption({ name: 'True' }).click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
AngleStart: '0',
|
||||||
|
Revolutions: '20',
|
||||||
|
Radius: newInput,
|
||||||
|
CounterClockWise: '',
|
||||||
|
},
|
||||||
|
commandName: 'Helix',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
await toolbar.closePane('feature-tree')
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`
|
||||||
|
helix001 = helix(
|
||||||
|
axis = getOppositeEdge(seg01),
|
||||||
|
radius = 5,
|
||||||
|
revolutions = 20,
|
||||||
|
angleStart = 0,
|
||||||
|
ccw = true,
|
||||||
|
)`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Delete helix via feature tree selection', async () => {
|
||||||
|
await toolbar.openPane('feature-tree')
|
||||||
|
const operationButton = await toolbar.getFeatureTreeOperation('Helix', 0)
|
||||||
|
await operationButton.click({ button: 'left' })
|
||||||
|
await page.keyboard.press('Delete')
|
||||||
|
await editor.expectEditor.not.toContain('helix')
|
||||||
|
await expect(
|
||||||
|
await toolbar.getFeatureTreeOperation('Helix', 0)
|
||||||
|
).not.toBeVisible()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('Helix point-and-click on cylinder', async ({
|
test('Helix point-and-click on cylinder', async ({
|
||||||
context,
|
context,
|
||||||
@ -1470,26 +1525,12 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 620, y: 257 }
|
const testPoint = { x: 620, y: 257 }
|
||||||
const [clickOnWall] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
const [clickOnWall] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||||
const expectedOutput = `helix001 = helix( cylinder = extrude001, revolutions = 1, angleStart = 360, ccw = false,)`
|
const expectedOutput = `helix001 = helix(cylinder = extrude001, revolutions = 1, angleStart = 360)`
|
||||||
const expectedLine = `cylinder = extrude001,`
|
const expectedEditedOutput = `helix001 = helix(cylinder = extrude001, revolutions = 1, angleStart = 10)`
|
||||||
const expectedEditedOutput = `helix001 = helix( cylinder = extrude001, revolutions = 1, angleStart = 360, ccw = true,)`
|
|
||||||
|
|
||||||
await test.step(`Go through the command bar flow`, async () => {
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
await toolbar.helixButton.click()
|
await toolbar.helixButton.click()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState(initialCmdBarStateHelix)
|
||||||
stage: 'arguments',
|
|
||||||
currentArgKey: 'mode',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Mode: '',
|
|
||||||
AngleStart: '',
|
|
||||||
Revolutions: '',
|
|
||||||
Radius: '',
|
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'mode',
|
|
||||||
commandName: 'Helix',
|
|
||||||
})
|
|
||||||
await cmdBar.selectOption({ name: 'Cylinder' }).click()
|
await cmdBar.selectOption({ name: 'Cylinder' }).click()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
@ -1500,7 +1541,6 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
Cylinder: '',
|
Cylinder: '',
|
||||||
AngleStart: '',
|
AngleStart: '',
|
||||||
Revolutions: '',
|
Revolutions: '',
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'cylinder',
|
highlightedHeaderArg: 'cylinder',
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
@ -1516,18 +1556,17 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
Cylinder: '1 face',
|
Cylinder: '1 face',
|
||||||
AngleStart: '360',
|
AngleStart: '360',
|
||||||
Revolutions: '1',
|
Revolutions: '1',
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
},
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.submit()
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
await editor.expectEditor.toContain(expectedOutput)
|
await editor.expectEditor.toContain(expectedOutput)
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
activeLines: [expectedLine],
|
activeLines: [expectedOutput],
|
||||||
highlightedCode: '',
|
highlightedCode: '',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1539,22 +1578,21 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'CounterClockWise',
|
currentArgKey: 'angleStart',
|
||||||
currentArgValue: '',
|
currentArgValue: '360',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
AngleStart: '360',
|
AngleStart: '360',
|
||||||
Revolutions: '1',
|
Revolutions: '1',
|
||||||
CounterClockWise: '',
|
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'CounterClockWise',
|
highlightedHeaderArg: 'angleStart',
|
||||||
})
|
})
|
||||||
await cmdBar.selectOption({ name: 'True' }).click()
|
await page.keyboard.insertText('10')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
AngleStart: '360',
|
AngleStart: '10',
|
||||||
Revolutions: '1',
|
Revolutions: '1',
|
||||||
CounterClockWise: 'true',
|
|
||||||
},
|
},
|
||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
@ -1610,6 +1648,8 @@ sketch002 = startSketchOn(plane001)
|
|||||||
testPoint.y + 80
|
testPoint.y + 80
|
||||||
)
|
)
|
||||||
const loftDeclaration = 'loft001 = loft([sketch001, sketch002])'
|
const loftDeclaration = 'loft001 = loft([sketch001, sketch002])'
|
||||||
|
const editedLoftDeclaration =
|
||||||
|
'loft001 = loft([sketch001, sketch002], vDegree = 3)'
|
||||||
|
|
||||||
await test.step(`Look for the white of the sketch001 shape`, async () => {
|
await test.step(`Look for the white of the sketch001 shape`, async () => {
|
||||||
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
|
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
|
||||||
@ -1681,6 +1721,39 @@ sketch002 = startSketchOn(plane001)
|
|||||||
await scene.expectPixelColor([89, 89, 89], testPoint, 15)
|
await scene.expectPixelColor([89, 89, 89], testPoint, 15)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await test.step('Go through the edit flow via feature tree', async () => {
|
||||||
|
await toolbar.openPane('feature-tree')
|
||||||
|
const op = await toolbar.getFeatureTreeOperation('Loft', 0)
|
||||||
|
await op.dblclick()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {},
|
||||||
|
commandName: 'Loft',
|
||||||
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('vDegree')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'vDegree',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
VDegree: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'vDegree',
|
||||||
|
commandName: 'Loft',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText('3')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
VDegree: '3',
|
||||||
|
},
|
||||||
|
commandName: 'Loft',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
await editor.expectEditor.toContain(editedLoftDeclaration)
|
||||||
|
})
|
||||||
|
|
||||||
await test.step('Delete loft via feature tree selection', async () => {
|
await test.step('Delete loft via feature tree selection', async () => {
|
||||||
await editor.closePane()
|
await editor.closePane()
|
||||||
const operationButton = await toolbar.getFeatureTreeOperation('Loft', 0)
|
const operationButton = await toolbar.getFeatureTreeOperation('Loft', 0)
|
||||||
@ -1691,72 +1764,6 @@ sketch002 = startSketchOn(plane001)
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: merge with above test. Right now we're not able to delete a loft
|
|
||||||
// right after creation via selection for some reason, so we go with a new instance
|
|
||||||
test('Loft and offset plane deletion via selection', async ({
|
|
||||||
context,
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
|
||||||
|> circle(center = [0, 0], radius = 30)
|
|
||||||
plane001 = offsetPlane(XZ, offset = 50)
|
|
||||||
sketch002 = startSketchOn(plane001)
|
|
||||||
|> circle(center = [0, 0], radius = 20)
|
|
||||||
loft001 = loft([sketch001, sketch002])
|
|
||||||
`
|
|
||||||
await context.addInitScript((initialCode) => {
|
|
||||||
localStorage.setItem('persistCode', initialCode)
|
|
||||||
}, initialCode)
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
|
||||||
const testPoint = { x: 575, y: 200 }
|
|
||||||
const [clickOnSketch1] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
|
||||||
const [clickOnSketch2] = scene.makeMouseHelpers(
|
|
||||||
testPoint.x,
|
|
||||||
testPoint.y + 80
|
|
||||||
)
|
|
||||||
|
|
||||||
await test.step(`Delete loft`, async () => {
|
|
||||||
// Check for loft
|
|
||||||
await scene.expectPixelColor([89, 89, 89], testPoint, 15)
|
|
||||||
await clickOnSketch1()
|
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
|
||||||
|> circle(center = [0, 0], radius = 30)
|
|
||||||
`)
|
|
||||||
await page.keyboard.press('Delete')
|
|
||||||
// Check for sketch 1
|
|
||||||
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Delete sketch002', async () => {
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await clickOnSketch2()
|
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
|
||||||
|> circle(center = [0, 0], radius = 20)
|
|
||||||
`)
|
|
||||||
await page.keyboard.press('Delete')
|
|
||||||
// Check for plane001
|
|
||||||
await scene.expectPixelColor([228, 228, 228], testPoint, 15)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Delete plane001', async () => {
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await clickOnSketch2()
|
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(`
|
|
||||||
plane001 = offsetPlane(XZ, offset = 50)
|
|
||||||
`)
|
|
||||||
await page.keyboard.press('Delete')
|
|
||||||
// Check for sketch 1
|
|
||||||
await scene.expectPixelColor([254, 254, 254], testPoint, 15)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const sweepCases = [
|
const sweepCases = [
|
||||||
{
|
{
|
||||||
targetType: 'circle',
|
targetType: 'circle',
|
||||||
@ -1954,6 +1961,7 @@ profile002 = startProfile(sketch002, at = [0, 0])
|
|||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
profile001 = ${circleCode}`
|
profile001 = ${circleCode}`
|
||||||
const sweepDeclaration = 'sweep001 = sweep(profile001, path = helix001)'
|
const sweepDeclaration = 'sweep001 = sweep(profile001, path = helix001)'
|
||||||
|
const editedSweepDeclaration = `sweep001 = sweep(profile001, path = helix001, relativeTo = 'sketchPlane')`
|
||||||
|
|
||||||
await context.addInitScript((initialCode) => {
|
await context.addInitScript((initialCode) => {
|
||||||
localStorage.setItem('persistCode', initialCode)
|
localStorage.setItem('persistCode', initialCode)
|
||||||
@ -2015,11 +2023,43 @@ profile001 = ${circleCode}`
|
|||||||
await editor.expectEditor.toContain(sweepDeclaration)
|
await editor.expectEditor.toContain(sweepDeclaration)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await test.step('Go through the edit flow via feature tree', async () => {
|
||||||
|
await toolbar.openPane('feature-tree')
|
||||||
|
const op = await toolbar.getFeatureTreeOperation('Sweep', 0)
|
||||||
|
await op.dblclick()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {},
|
||||||
|
commandName: 'Sweep',
|
||||||
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('relativeTo')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'relativeTo',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
RelativeTo: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'relativeTo',
|
||||||
|
commandName: 'Sweep',
|
||||||
|
})
|
||||||
|
await cmdBar.selectOption({ name: 'sketchPlane' }).click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
RelativeTo: 'sketchPlane',
|
||||||
|
},
|
||||||
|
commandName: 'Sweep',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
await editor.expectEditor.toContain(editedSweepDeclaration)
|
||||||
|
})
|
||||||
|
|
||||||
await test.step('Delete sweep via feature tree selection', async () => {
|
await test.step('Delete sweep via feature tree selection', async () => {
|
||||||
const sweep = await toolbar.getFeatureTreeOperation('Sweep', 0)
|
const sweep = await toolbar.getFeatureTreeOperation('Sweep', 0)
|
||||||
await sweep.click()
|
await sweep.click()
|
||||||
await page.keyboard.press('Delete')
|
await page.keyboard.press('Delete')
|
||||||
await editor.expectEditor.not.toContain(sweepDeclaration)
|
await editor.expectEditor.not.toContain(editedSweepDeclaration)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3879,6 +3919,8 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
|
|
||||||
// Edit flow
|
// Edit flow
|
||||||
const newAngle = '270'
|
const newAngle = '270'
|
||||||
|
const newAngle2 = '5'
|
||||||
|
const editedCodeToFind = `revolve001 = revolve(sketch003, angle = ${newAngle}, axis = seg01, bidirectionalAngle = ${newAngle2}, )`
|
||||||
await toolbar.openPane('feature-tree')
|
await toolbar.openPane('feature-tree')
|
||||||
const operationButton = await toolbar.getFeatureTreeOperation(
|
const operationButton = await toolbar.getFeatureTreeOperation(
|
||||||
'Revolve',
|
'Revolve',
|
||||||
@ -3904,11 +3946,33 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
},
|
},
|
||||||
commandName: 'Revolve',
|
commandName: 'Revolve',
|
||||||
})
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('bidirectionalAngle')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Revolve',
|
||||||
|
currentArgKey: 'bidirectionalAngle',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Angle: newAngle,
|
||||||
|
BidirectionalAngle: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'bidirectionalAngle',
|
||||||
|
stage: 'arguments',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText(newAngle2)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Angle: newAngle,
|
||||||
|
BidirectionalAngle: newAngle2,
|
||||||
|
},
|
||||||
|
commandName: 'Revolve',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(editedCodeToFind, {
|
||||||
newCodeToFind.replace('angle = 360', 'angle = ' + newAngle)
|
shouldNormalise: true,
|
||||||
)
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -4923,4 +4987,154 @@ extrude001 = extrude(profile001 length = 1)`
|
|||||||
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
await editor.expectEditor.toContain(badCode, { shouldNormalise: true })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Point-and-click extrude with optional args', async ({
|
||||||
|
context,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
const squareProfileCode = `length001 = 100
|
||||||
|
sketch001 = startSketchOn(XY)
|
||||||
|
profile001 = startProfile(sketch001, at = [0, 0])
|
||||||
|
|> yLine(length = length001)
|
||||||
|
|> xLine(length = length001)
|
||||||
|
|> yLine(length = -length001)
|
||||||
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
|> close()
|
||||||
|
`
|
||||||
|
await context.addInitScript((initialCode) => {
|
||||||
|
localStorage.setItem('persistCode', initialCode)
|
||||||
|
}, squareProfileCode)
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await test.step('Select through code', async () => {
|
||||||
|
await editor.selectText('startProfile(sketch001, at = [0, 0])')
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Go through command bar flow', async () => {
|
||||||
|
await toolbar.extrudeButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'sketches',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '',
|
||||||
|
Length: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'Profiles',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'length',
|
||||||
|
currentArgValue: '5',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '1 profile',
|
||||||
|
Length: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'length',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '1 profile',
|
||||||
|
Length: '5',
|
||||||
|
},
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.clickOptionalArgument('bidirectionalLength')
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'bidirectionalLength',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '1 profile',
|
||||||
|
Length: '5',
|
||||||
|
BidirectionalLength: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'bidirectionalLength',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText('10')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Profiles: '1 profile',
|
||||||
|
Length: '5',
|
||||||
|
BidirectionalLength: '10',
|
||||||
|
},
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Check that the code has changed', async () => {
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`extrude001 = extrude(profile001, length = 5, bidirectionalLength = 10)`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Go through the edit flow via feature tree', async () => {
|
||||||
|
await toolbar.openPane('feature-tree')
|
||||||
|
const op = await toolbar.getFeatureTreeOperation('Extrude', 0)
|
||||||
|
await op.dblclick()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'length',
|
||||||
|
currentArgValue: '5',
|
||||||
|
headerArguments: {
|
||||||
|
Length: '5',
|
||||||
|
BidirectionalLength: '10',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'length',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText('10')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.getByRole('button', { name: 'BidirectionalLength' }).click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'bidirectionalLength',
|
||||||
|
currentArgValue: '10',
|
||||||
|
headerArguments: {
|
||||||
|
Length: '10',
|
||||||
|
BidirectionalLength: '10',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'bidirectionalLength',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText('20')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: {
|
||||||
|
Length: '10',
|
||||||
|
BidirectionalLength: '20',
|
||||||
|
},
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.submit()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Check that the code has changed again', async () => {
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await toolbar.closePane('feature-tree')
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`extrude001 = extrude(profile001, length = 10, bidirectionalLength = 20)`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
@ -12,6 +12,7 @@ export const TEST_SETTINGS: DeepPartial<Settings> = {
|
|||||||
},
|
},
|
||||||
onboarding_status: 'dismissed',
|
onboarding_status: 'dismissed',
|
||||||
show_debug_panel: true,
|
show_debug_panel: true,
|
||||||
|
fixed_size_grid: false,
|
||||||
},
|
},
|
||||||
modeling: {
|
modeling: {
|
||||||
enable_ssao: false,
|
enable_ssao: false,
|
||||||
|
|||||||
@ -880,6 +880,10 @@ export async function setup(
|
|||||||
},
|
},
|
||||||
...TEST_SETTINGS.project,
|
...TEST_SETTINGS.project,
|
||||||
onboarding_status: 'dismissed',
|
onboarding_status: 'dismissed',
|
||||||
|
// Tests were written before this setting existed.
|
||||||
|
// It's true by default because it's a good user experience, but
|
||||||
|
// these tests require it to be false.
|
||||||
|
fixed_size_grid: false,
|
||||||
},
|
},
|
||||||
project: {
|
project: {
|
||||||
...TEST_SETTINGS.project,
|
...TEST_SETTINGS.project,
|
||||||
|
|||||||
18
flake.lock
generated
@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745998881,
|
"lastModified": 1750865895,
|
||||||
"narHash": "sha256-vonyYAKJSlsX4n9GCsS0pHxR6yCrfqBIuGvANlkwG6U=",
|
"narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "423d2df5b04b4ee7688c3d71396e872afa236a89",
|
"rev": "61c0f513911459945e2cb8bf333dc849f1b976ff",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -36,11 +36,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745998881,
|
"lastModified": 1750865895,
|
||||||
"narHash": "sha256-vonyYAKJSlsX4n9GCsS0pHxR6yCrfqBIuGvANlkwG6U=",
|
"narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "423d2df5b04b4ee7688c3d71396e872afa236a89",
|
"rev": "61c0f513911459945e2cb8bf333dc849f1b976ff",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -78,11 +78,11 @@
|
|||||||
"nixpkgs": "nixpkgs_3"
|
"nixpkgs": "nixpkgs_3"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745980514,
|
"lastModified": 1750964660,
|
||||||
"narHash": "sha256-CITAeiuXGjDvT5iZBXr6vKVWQwsUQLJUMFO91bfJFC4=",
|
"narHash": "sha256-YQ6EyFetjH1uy5JhdhRdPe6cuNXlYpMAQePFfZj4W7M=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "7fbdae44b0f40ea432e46fd152ad8be0f8f41ad6",
|
"rev": "04f0fcfb1a50c63529805a798b4b5c21610ff390",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@ -125,18 +125,57 @@ test('Shows a loading spinner when uninitialized credit count', async () => {
|
|||||||
await expect(queryByTestId('spinner')).toBeVisible()
|
await expect(queryByTestId('spinner')).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Shows the total credits for Unknown subscription', async () => {
|
const unKnownTierData = {
|
||||||
const data = {
|
balance: {
|
||||||
balance: {
|
monthlyApiCreditsRemaining: 10,
|
||||||
monthlyApiCreditsRemaining: 10,
|
stableApiCreditsRemaining: 25,
|
||||||
stableApiCreditsRemaining: 25,
|
},
|
||||||
},
|
subscriptions: {
|
||||||
subscriptions: {
|
monthlyPayAsYouGoApiCreditsTotal: 20,
|
||||||
monthlyPayAsYouGoApiCreditsTotal: 20,
|
name: "unknown",
|
||||||
name: "unknown",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const freeTierData = {
|
||||||
|
balance: {
|
||||||
|
monthlyApiCreditsRemaining: 10,
|
||||||
|
stableApiCreditsRemaining: 0,
|
||||||
|
},
|
||||||
|
subscriptions: {
|
||||||
|
monthlyPayAsYouGoApiCreditsTotal: 20,
|
||||||
|
name: "free",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const proTierData = {
|
||||||
|
// These are all ignored
|
||||||
|
balance: {
|
||||||
|
monthlyApiCreditsRemaining: 10,
|
||||||
|
stableApiCreditsRemaining: 0,
|
||||||
|
},
|
||||||
|
subscriptions: {
|
||||||
|
// This should be ignored because it's Pro tier.
|
||||||
|
monthlyPayAsYouGoApiCreditsTotal: 20,
|
||||||
|
name: "pro",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const enterpriseTierData = {
|
||||||
|
// These are all ignored, user is part of an org.
|
||||||
|
balance: {
|
||||||
|
monthlyApiCreditsRemaining: 10,
|
||||||
|
stableApiCreditsRemaining: 0,
|
||||||
|
},
|
||||||
|
subscriptions: {
|
||||||
|
// This should be ignored because it's Pro tier.
|
||||||
|
monthlyPayAsYouGoApiCreditsTotal: 20,
|
||||||
|
// This should be ignored because the user is part of an Org.
|
||||||
|
name: "free",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test('Shows the total credits for Unknown subscription', async () => {
|
||||||
|
const data = unKnownTierData
|
||||||
server.use(
|
server.use(
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
||||||
@ -166,17 +205,7 @@ test('Shows the total credits for Unknown subscription', async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('Progress bar reflects ratio left of Free subscription', async () => {
|
test('Progress bar reflects ratio left of Free subscription', async () => {
|
||||||
const data = {
|
const data = freeTierData
|
||||||
balance: {
|
|
||||||
monthlyApiCreditsRemaining: 10,
|
|
||||||
stableApiCreditsRemaining: 0,
|
|
||||||
},
|
|
||||||
subscriptions: {
|
|
||||||
monthlyPayAsYouGoApiCreditsTotal: 20,
|
|
||||||
name: "free",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server.use(
|
server.use(
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
||||||
@ -212,19 +241,7 @@ test('Progress bar reflects ratio left of Free subscription', async () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
test('Shows infinite credits for Pro subscription', async () => {
|
test('Shows infinite credits for Pro subscription', async () => {
|
||||||
const data = {
|
const data = proTierData
|
||||||
// These are all ignored
|
|
||||||
balance: {
|
|
||||||
monthlyApiCreditsRemaining: 10,
|
|
||||||
stableApiCreditsRemaining: 0,
|
|
||||||
},
|
|
||||||
subscriptions: {
|
|
||||||
// This should be ignored because it's Pro tier.
|
|
||||||
monthlyPayAsYouGoApiCreditsTotal: 20,
|
|
||||||
name: "pro",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server.use(
|
server.use(
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
||||||
@ -255,19 +272,7 @@ test('Shows infinite credits for Pro subscription', async () => {
|
|||||||
await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
|
await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
|
||||||
})
|
})
|
||||||
test('Shows infinite credits for Enterprise subscription', async () => {
|
test('Shows infinite credits for Enterprise subscription', async () => {
|
||||||
const data = {
|
const data = enterpriseTierData
|
||||||
// These are all ignored, user is part of an org.
|
|
||||||
balance: {
|
|
||||||
monthlyApiCreditsRemaining: 10,
|
|
||||||
stableApiCreditsRemaining: 0,
|
|
||||||
},
|
|
||||||
subscriptions: {
|
|
||||||
// This should be ignored because it's Pro tier.
|
|
||||||
monthlyPayAsYouGoApiCreditsTotal: 20,
|
|
||||||
// This should be ignored because the user is part of an Org.
|
|
||||||
name: "free",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server.use(
|
server.use(
|
||||||
http.get('*/user/payment/balance', (req, res, ctx) => {
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
@ -297,3 +302,58 @@ test('Shows infinite credits for Enterprise subscription', async () => {
|
|||||||
await expect(queryByTestId('infinity')).toBeVisible()
|
await expect(queryByTestId('infinity')).toBeVisible()
|
||||||
await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
|
await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Show upgrade button if credits are not infinite', async () => {
|
||||||
|
const data = freeTierData
|
||||||
|
server.use(
|
||||||
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
|
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
||||||
|
}),
|
||||||
|
http.get('*/user/payment/subscriptions', (req, res, ctx) => {
|
||||||
|
return HttpResponse.json(createUserPaymentSubscriptionsResponse(data.subscriptions))
|
||||||
|
}),
|
||||||
|
http.get('*/org', (req, res, ctx) => {
|
||||||
|
return new HttpResponse(403)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
|
||||||
|
|
||||||
|
const { queryByTestId } = render(<BillingDialog
|
||||||
|
billingActor={billingActor}
|
||||||
|
/>)
|
||||||
|
|
||||||
|
await act(() => {
|
||||||
|
billingActor.send({ type: BillingTransition.Update, apiToken: "it doesn't matter wtf this is :)" })
|
||||||
|
})
|
||||||
|
|
||||||
|
await expect(queryByTestId('billing-upgrade-button')).toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Hide upgrade button if credits are infinite', async () => {
|
||||||
|
const data = enterpriseTierData
|
||||||
|
server.use(
|
||||||
|
http.get('*/user/payment/balance', (req, res, ctx) => {
|
||||||
|
return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
|
||||||
|
}),
|
||||||
|
http.get('*/user/payment/subscriptions', (req, res, ctx) => {
|
||||||
|
return HttpResponse.json(createUserPaymentSubscriptionsResponse(data.subscriptions))
|
||||||
|
}),
|
||||||
|
// Ok finally the first use of an org lol
|
||||||
|
http.get('*/org', (req, res, ctx) => {
|
||||||
|
return HttpResponse.json(createOrgResponse())
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
|
||||||
|
|
||||||
|
const { queryByTestId } = render(<BillingDialog
|
||||||
|
billingActor={billingActor}
|
||||||
|
/>)
|
||||||
|
|
||||||
|
await act(() => {
|
||||||
|
billingActor.send({ type: BillingTransition.Update, apiToken: "it doesn't matter wtf this is :)" })
|
||||||
|
})
|
||||||
|
|
||||||
|
await expect(queryByTestId('billing-upgrade-button')).toBe(null)
|
||||||
|
})
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
33
rust/Cargo.lock
generated
@ -1814,7 +1814,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-bumper"
|
name = "kcl-bumper"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1825,7 +1825,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-derive-docs"
|
name = "kcl-derive-docs"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1834,7 +1834,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-directory-test-macro"
|
name = "kcl-directory-test-macro"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"convert_case",
|
"convert_case",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@ -1844,7 +1844,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-language-server"
|
name = "kcl-language-server"
|
||||||
version = "0.2.82"
|
version = "0.2.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1865,7 +1865,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-language-server-release"
|
name = "kcl-language-server-release"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1885,7 +1885,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.2.82"
|
version = "0.2.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx 0.5.1",
|
"approx 0.5.1",
|
||||||
@ -1962,7 +1962,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-python-bindings"
|
name = "kcl-python-bindings"
|
||||||
version = "0.3.82"
|
version = "0.3.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"kcl-lib",
|
"kcl-lib",
|
||||||
@ -1977,7 +1977,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hyper 0.14.32",
|
"hyper 0.14.32",
|
||||||
@ -1990,7 +1990,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-to-core"
|
name = "kcl-to-core"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -2004,7 +2004,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-wasm-lib"
|
name = "kcl-wasm-lib"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bson",
|
"bson",
|
||||||
@ -2071,9 +2071,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kittycad-modeling-cmds"
|
name = "kittycad-modeling-cmds"
|
||||||
version = "0.2.123"
|
version = "0.2.125"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8f3c1b4b4ddb9aa336a09933f2550f9882552e321187b7bcff47f006379c3aa"
|
checksum = "cfd09d95f8bbeb090d4d1137c9bf421eb75763f7a30e4a9e8eefa249ddf20bd3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -4428,13 +4428,12 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ts-rs"
|
name = "ts-rs"
|
||||||
version = "10.1.0"
|
version = "11.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e640d9b0964e9d39df633548591090ab92f7a4567bc31d3891af23471a3365c6"
|
checksum = "6ef1b7a6d914a34127ed8e1fa927eb7088903787bcded4fa3eef8f85ee1568be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"indexmap 2.9.0",
|
"indexmap 2.9.0",
|
||||||
"lazy_static",
|
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"ts-rs-macros",
|
"ts-rs-macros",
|
||||||
@ -4444,9 +4443,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ts-rs-macros"
|
name = "ts-rs-macros"
|
||||||
version = "10.1.0"
|
version = "11.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e9d8656589772eeec2cf7a8264d9cda40fb28b9bc53118ceb9e8c07f8f38730"
|
checksum = "e9d4ed7b4c18cc150a6a0a1e9ea1ecfa688791220781af6e119f9599a8502a0a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|||||||
@ -36,7 +36,7 @@ dashmap = { version = "6.1.0" }
|
|||||||
http = "1"
|
http = "1"
|
||||||
indexmap = "2.9.0"
|
indexmap = "2.9.0"
|
||||||
kittycad = { version = "0.3.37", default-features = false, features = ["js", "requests"] }
|
kittycad = { version = "0.3.37", default-features = false, features = ["js", "requests"] }
|
||||||
kittycad-modeling-cmds = { version = "0.2.123", features = ["ts-rs", "websocket"] }
|
kittycad-modeling-cmds = { version = "0.2.125", features = ["ts-rs", "websocket"] }
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
miette = "7.6.0"
|
miette = "7.6.0"
|
||||||
pyo3 = { version = "0.24.2" }
|
pyo3 = { version = "0.24.2" }
|
||||||
@ -60,6 +60,6 @@ lossy_float_literal = "warn"
|
|||||||
result_large_err = "allow"
|
result_large_err = "allow"
|
||||||
|
|
||||||
# Example: how to point modeling-app at a different repo (e.g. a branch or a local clone)
|
# Example: how to point modeling-app at a different repo (e.g. a branch or a local clone)
|
||||||
#[patch.crates-io]
|
# [patch.crates-io]
|
||||||
#kittycad-modeling-cmds = { path = "../../../modeling-api/modeling-cmds" }
|
# kittycad-modeling-cmds = { path = "../../modeling-api/modeling-cmds/" }
|
||||||
#kittycad-modeling-session = { path = "../../../modeling-api/modeling-session" }
|
# kittycad-modeling-session = { path = "../../modeling-api/modeling-session" }
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "kcl-bumper"
|
name = "kcl-bumper"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://github.com/KittyCAD/modeling-api"
|
repository = "https://github.com/KittyCAD/modeling-api"
|
||||||
rust-version = "1.76"
|
rust-version = "1.76"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-derive-docs"
|
name = "kcl-derive-docs"
|
||||||
description = "A tool for generating documentation from Rust derive macros"
|
description = "A tool for generating documentation from Rust derive macros"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-directory-test-macro"
|
name = "kcl-directory-test-macro"
|
||||||
description = "A tool for generating tests from a directory of kcl files"
|
description = "A tool for generating tests from a directory of kcl files"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-language-server-release"
|
name = "kcl-language-server-release"
|
||||||
version = "0.1.82"
|
version = "0.1.83"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||||
publish = false
|
publish = false
|
||||||
|
|||||||