2025-04-01 15:31:19 -07:00
import fs from 'node:fs/promises'
import path from 'node:path'
2025-04-16 00:11:25 +10:00
import type { Locator , Page } from '@playwright/test'
2025-04-01 23:54:26 -07:00
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
import { expect , test } from '@e2e/playwright/zoo-test'
2025-05-06 17:57:27 -04:00
import { bracket } from '@e2e/playwright/fixtures/bracket'
2025-06-26 14:12:36 -04:00
import type { CmdBarSerialised } from '@e2e/playwright/fixtures/cmdBarFixture'
2024-09-23 22:42:51 +10:00
// test file is for testing point an click code gen functionality that's not sketch mode related
2025-02-27 09:34:15 -05:00
test . describe ( 'Point-and-click tests' , ( ) = > {
2025-02-04 16:49:49 -05:00
test ( 'verify extruding circle works' , async ( {
2025-04-07 07:08:31 -04:00
page ,
2025-02-04 16:49:49 -05:00
context ,
homePage ,
cmdBar ,
editor ,
toolbar ,
scene ,
} ) = > {
const file = await fs . readFile (
path . resolve (
__dirname ,
'../../' ,
2025-03-01 13:59:01 -08:00
'./rust/kcl-lib/e2e/executor/inputs/test-circle-extrude.kcl'
2025-02-04 16:49:49 -05:00
) ,
'utf-8'
)
await context . addInitScript ( ( file ) = > {
localStorage . setItem ( 'persistCode' , file )
} , file )
2025-04-07 07:08:31 -04:00
2025-02-04 16:49:49 -05:00
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . connectionEstablished ( )
2025-02-04 16:49:49 -05:00
const [ clickCircle , moveToCircle ] = scene . makeMouseHelpers ( 582 , 217 )
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
2025-02-04 16:49:49 -05:00
await test . step ( 'because there is sweepable geometry, verify extrude is enable when nothing is selected' , async ( ) = > {
2025-02-11 11:13:25 -06:00
// FIXME: Do not click, clicking removes the activeLines in future checks
// await scene.clickNoWhere()
2025-02-04 16:49:49 -05:00
await expect ( toolbar . extrudeButton ) . toBeEnabled ( )
2024-09-26 18:25:05 +10:00
} )
2024-09-23 22:42:51 +10:00
2024-10-02 11:58:17 -04:00
await test . step ( 'check code model connection works and that button is still enable once circle is selected ' , async ( ) = > {
await moveToCircle ( )
2025-02-28 17:40:01 -08:00
const circleSnippet = 'circle(center = [318.33, 168.1], radius = 182.8)'
2024-10-02 11:58:17 -04:00
await editor . expectState ( {
2025-03-21 22:39:12 +13:00
activeLines : [ 'sketch002=startSketchOn(XZ)' ] ,
2024-10-02 11:58:17 -04:00
highlightedCode : circleSnippet ,
diagnostics : [ ] ,
} )
2025-02-04 16:49:49 -05:00
await test . step ( 'check code model connection works and that button is still enable once circle is selected ' , async ( ) = > {
await moveToCircle ( )
2025-02-28 17:40:01 -08:00
const circleSnippet = 'circle(center = [318.33, 168.1], radius = 182.8)'
2025-02-04 16:49:49 -05:00
await editor . expectState ( {
2025-03-21 22:39:12 +13:00
activeLines : [ 'sketch002=startSketchOn(XZ)' ] ,
2025-02-04 16:49:49 -05:00
highlightedCode : circleSnippet ,
diagnostics : [ ] ,
} )
await clickCircle ( )
await editor . expectState ( {
2025-02-28 17:40:01 -08:00
activeLines : [ '|>' + circleSnippet ] ,
2025-02-04 16:49:49 -05:00
highlightedCode : circleSnippet ,
diagnostics : [ ] ,
} )
await expect ( toolbar . extrudeButton ) . toBeEnabled ( )
2024-10-02 11:58:17 -04:00
} )
await expect ( toolbar . extrudeButton ) . toBeEnabled ( )
2024-09-26 18:25:05 +10:00
} )
2024-09-23 22:42:51 +10:00
2025-02-04 16:49:49 -05:00
await test . step ( 'do extrude flow and check extrude code is added to editor' , async ( ) = > {
await toolbar . extrudeButton . click ( )
2025-05-20 16:07:56 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'sketches' ,
currentArgValue : '' ,
headerArguments : { Profiles : '' , Length : '' } ,
highlightedHeaderArg : 'Profiles' ,
commandName : 'Extrude' ,
} )
await cmdBar . progressCmdBar ( )
2025-05-06 17:57:27 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'length' ,
2025-02-04 16:49:49 -05:00
currentArgValue : '5' ,
2025-05-19 11:21:29 -04:00
headerArguments : { Profiles : '1 profile' , Length : '' } ,
2025-05-06 17:57:27 -04:00
highlightedHeaderArg : 'length' ,
2025-02-04 16:49:49 -05:00
commandName : 'Extrude' ,
} )
await cmdBar . progressCmdBar ( )
2024-09-23 22:42:51 +10:00
2025-02-04 16:49:49 -05:00
const expectString = 'extrude001 = extrude(sketch001, length = 5)'
await editor . expectEditor . not . toContain ( expectString )
2024-09-26 18:25:05 +10:00
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'review' ,
2025-05-19 11:21:29 -04:00
headerArguments : { Profiles : '1 profile' , Length : '5' } ,
2025-02-04 16:49:49 -05:00
commandName : 'Extrude' ,
} )
await cmdBar . progressCmdBar ( )
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain ( expectString )
} )
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
} )
2024-09-26 18:25:05 +10:00
2025-05-06 17:57:27 -04:00
test ( 'Verify in-pipe extrudes in bracket can be edited' , async ( {
tronApp ,
context ,
editor ,
homePage ,
page ,
scene ,
toolbar ,
cmdBar ,
} ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , bracket )
await homePage . goToModelingScene ( )
await scene . settled ( cmdBar )
await test . step ( ` Edit first extrude via feature tree ` , async ( ) = > {
await ( await toolbar . getFeatureTreeOperation ( 'Extrude' , 0 ) ) . dblclick ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'length' ,
currentArgValue : 'width' ,
headerArguments : {
Length : '5' ,
} ,
highlightedHeaderArg : 'length' ,
commandName : 'Extrude' ,
} )
2025-06-30 15:26:45 -04:00
await page . keyboard . insertText ( 'width - 0.001in' )
2025-05-06 17:57:27 -04:00
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
2025-06-30 15:26:45 -04:00
Length : '4.999in' ,
2025-05-06 17:57:27 -04:00
} ,
commandName : 'Extrude' ,
} )
await cmdBar . progressCmdBar ( )
2025-06-30 15:26:45 -04:00
await editor . expectEditor . toContain ( 'extrude(length = width - 0.001in)' )
2025-05-06 17:57:27 -04:00
} )
await test . step ( ` Edit second extrude via feature tree ` , async ( ) = > {
await ( await toolbar . getFeatureTreeOperation ( 'Extrude' , 1 ) ) . dblclick ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'length' ,
currentArgValue : '-thickness - .01' ,
headerArguments : {
Length : '-0.3949' ,
} ,
highlightedHeaderArg : 'length' ,
commandName : 'Extrude' ,
} )
await page . keyboard . insertText ( '-thickness - .01 - 0.001' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Length : '-0.3959' ,
} ,
commandName : 'Extrude' ,
} )
await cmdBar . progressCmdBar ( )
await editor . expectEditor . toContain (
'extrude(length = -thickness - .01 - 0.001)'
)
} )
await test . step ( ` Edit third extrude via feature tree ` , async ( ) = > {
await ( await toolbar . getFeatureTreeOperation ( 'Extrude' , 2 ) ) . dblclick ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'length' ,
currentArgValue : '-thickness - 0.1' ,
headerArguments : {
Length : '-0.4849' ,
} ,
highlightedHeaderArg : 'length' ,
commandName : 'Extrude' ,
} )
await page . keyboard . insertText ( '-thickness - 0.1 - 0.001' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Length : '-0.4859' ,
} ,
commandName : 'Extrude' ,
} )
await cmdBar . progressCmdBar ( )
await editor . expectEditor . toContain (
'extrude(length = -thickness - 0.1 - 0.001)'
)
} )
} )
2025-02-04 16:49:49 -05:00
test . describe ( 'verify sketch on chamfer works' , ( ) = > {
const _sketchOnAChamfer =
(
page : Page ,
editor : EditorFixture ,
toolbar : ToolbarFixture ,
scene : SceneFixture
) = >
async ( {
clickCoords ,
cameraPos ,
cameraTarget ,
beforeChamferSnippet ,
afterChamferSelectSnippet ,
afterRectangle1stClickSnippet ,
afterRectangle2ndClickSnippet ,
beforeChamferSnippetEnd ,
} : {
clickCoords : { x : number ; y : number }
cameraPos : { x : number ; y : number ; z : number }
cameraTarget : { x : number ; y : number ; z : number }
beforeChamferSnippet : string
afterChamferSelectSnippet : string
afterRectangle1stClickSnippet : string
afterRectangle2ndClickSnippet : string
beforeChamferSnippetEnd? : string
} ) = > {
const [ clickChamfer ] = scene . makeMouseHelpers (
clickCoords . x ,
clickCoords . y
)
const [ rectangle1stClick ] = scene . makeMouseHelpers ( 573 , 149 )
const [ rectangle2ndClick , rectangle2ndMove ] = scene . makeMouseHelpers (
598 ,
380 ,
{ steps : 5 }
)
2024-09-23 22:42:51 +10:00
2025-02-04 16:49:49 -05:00
await scene . moveCameraTo ( cameraPos , cameraTarget )
2025-03-31 10:56:03 -04:00
await test . step ( 'check chamfer selection changes cursor position' , async ( ) = > {
2025-05-07 08:25:12 +10:00
await toolbar . waitForFeatureTreeToBeBuilt ( )
2025-02-04 16:49:49 -05:00
await expect ( async ( ) = > {
// sometimes initial click doesn't register
await clickChamfer ( )
// await editor.expectActiveLinesToBe([beforeChamferSnippet.slice(-5)])
await editor . expectActiveLinesToBe ( [
beforeChamferSnippetEnd || beforeChamferSnippet . slice ( - 5 ) ,
] )
} ) . toPass ( { timeout : 15_000 , intervals : [ 500 ] } )
} )
2024-09-26 18:25:05 +10:00
2025-02-04 16:49:49 -05:00
await test . step ( 'starting a new and selecting a chamfer should animate to the new sketch and possible break up the initial chamfer if it had one than more tag' , async ( ) = > {
await toolbar . startSketchPlaneSelection ( )
2024-09-26 18:25:05 +10:00
await clickChamfer ( )
2025-02-04 16:49:49 -05:00
// timeout wait for engine animation is unavoidable
await page . waitForTimeout ( 1000 )
await editor . expectEditor . toContain ( afterChamferSelectSnippet )
2024-09-26 18:25:05 +10:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( 'make sure a basic sketch can be added' , async ( ) = > {
await toolbar . rectangleBtn . click ( )
await rectangle1stClick ( )
await editor . expectEditor . toContain ( afterRectangle1stClickSnippet )
await rectangle2ndMove ( {
pixelDiff : 50 ,
} )
await rectangle2ndClick ( )
await editor . expectEditor . toContain ( afterRectangle2ndClickSnippet , {
shouldNormalise : true ,
} )
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
} )
2024-09-26 18:25:05 +10:00
2025-02-04 16:49:49 -05:00
await test . step ( 'Clean up so that `_sketchOnAChamfer` util can be called again' , async ( ) = > {
2025-03-06 11:19:13 -05:00
await toolbar . exitSketch ( )
2024-09-26 18:25:05 +10:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( 'Check there is no errors after code created in previous steps executes' , async ( ) = > {
await editor . expectState ( {
2025-03-31 10:56:03 -04:00
activeLines : [ '@settings(defaultLengthUnit = in)' ] ,
2025-02-04 16:49:49 -05:00
highlightedCode : '' ,
diagnostics : [ ] ,
} )
2025-05-07 08:25:12 +10:00
await toolbar . waitForFeatureTreeToBeBuilt ( )
2025-02-04 16:49:49 -05:00
} )
}
test ( 'works on all edge selections and can break up multi edges in a chamfer array' , async ( {
context ,
page ,
homePage ,
editor ,
toolbar ,
scene ,
2025-04-07 07:08:31 -04:00
cmdBar ,
2025-02-04 16:49:49 -05:00
} ) = > {
const file = await fs . readFile (
path . resolve (
__dirname ,
'../../' ,
2025-03-01 13:59:01 -08:00
'./rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer.kcl'
2025-02-04 16:49:49 -05:00
) ,
'utf-8'
)
await context . addInitScript ( ( file ) = > {
localStorage . setItem ( 'persistCode' , file )
} , file )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
const sketchOnAChamfer = _sketchOnAChamfer ( page , editor , toolbar , scene )
await sketchOnAChamfer ( {
clickCoords : { x : 570 , y : 220 } ,
cameraPos : { x : 16020 , y : - 2000 , z : 10500 } ,
cameraTarget : { x : - 150 , y : - 4500 , z : - 80 } ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
beforeChamferSnippet : ` angledLine(angle=segAng(rectangleSegmentA001)-90,length=217.26,tag= $ seg01)
2025-02-21 14:41:25 -06:00
chamfer ( length = 30 , tags = [
2024-09-26 18:25:05 +10:00
seg01 ,
getNextAdjacentEdge ( yo ) ,
getNextAdjacentEdge ( seg02 ) ,
getOppositeEdge ( seg01 )
2025-02-21 14:41:25 -06:00
] ,
) ` ,
2024-10-02 14:19:40 -05:00
2025-02-04 16:49:49 -05:00
afterChamferSelectSnippet :
2025-04-14 05:58:19 -04:00
'sketch002 = startSketchOn(extrude001, face = seg03)' ,
2025-02-15 00:57:04 +11:00
afterRectangle1stClickSnippet :
2025-04-25 16:01:35 -05:00
'startProfile(sketch002, at = [205.96, 254.59])' ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
afterRectangle2ndClickSnippet : ` angledLine(angle=0,length=11.39,tag= $ rectangleSegmentA002)
| > angledLine ( angle = segAng ( rectangleSegmentA002 ) - 90 , length = 105.26 )
| > angledLine ( angle = segAng ( rectangleSegmentA002 ) , length = - segLen ( rectangleSegmentA002 ) )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( ) ` ,
2025-02-04 16:49:49 -05:00
} )
2024-09-26 18:25:05 +10:00
2025-02-04 16:49:49 -05:00
await sketchOnAChamfer ( {
clickCoords : { x : 690 , y : 250 } ,
cameraPos : { x : 16020 , y : - 2000 , z : 10500 } ,
cameraTarget : { x : - 150 , y : - 4500 , z : - 80 } ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
beforeChamferSnippet : ` angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $ seg01)chamfer(
2024-11-25 09:21:55 +13:00
length = 30 ,
tags = [
2024-09-26 18:25:05 +10:00
seg01 ,
getNextAdjacentEdge ( yo ) ,
getNextAdjacentEdge ( seg02 )
]
2025-02-21 14:41:25 -06:00
) ` ,
2024-10-02 14:19:40 -05:00
2025-02-04 16:49:49 -05:00
afterChamferSelectSnippet :
2025-04-14 05:58:19 -04:00
'sketch003 = startSketchOn(extrude001, face = seg04)' ,
2025-02-15 00:57:04 +11:00
afterRectangle1stClickSnippet :
2025-04-25 16:01:35 -05:00
'startProfile(sketch003, at = [-209.64, 255.28])' ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
afterRectangle2ndClickSnippet : ` angledLine(angle=0,length=11.56,tag= $ rectangleSegmentA003)
| > angledLine ( angle = segAng ( rectangleSegmentA003 ) - 90 , length = 106.84 )
| > angledLine ( angle = segAng ( rectangleSegmentA003 ) , length = - segLen ( rectangleSegmentA003 ) )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( ) ` ,
2025-02-04 16:49:49 -05:00
} )
2025-02-15 00:57:04 +11:00
2025-02-04 16:49:49 -05:00
await sketchOnAChamfer ( {
clickCoords : { x : 677 , y : 87 } ,
cameraPos : { x : - 6200 , y : 1500 , z : 6200 } ,
cameraTarget : { x : 8300 , y : 1100 , z : 4800 } ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
beforeChamferSnippet : ` angledLine(angle = 0, length = 268.43, tag = $ rectangleSegmentA001)chamfer(
2024-11-25 09:21:55 +13:00
length = 30 ,
tags = [
2024-09-26 18:25:05 +10:00
getNextAdjacentEdge ( yo ) ,
getNextAdjacentEdge ( seg02 )
]
2025-02-21 14:41:25 -06:00
) ` ,
2025-02-04 16:49:49 -05:00
afterChamferSelectSnippet :
2025-04-14 05:58:19 -04:00
'sketch004 = startSketchOn(extrude001, face = seg05)' ,
2025-02-15 00:57:04 +11:00
afterRectangle1stClickSnippet :
2025-04-25 16:01:35 -05:00
'startProfile(sketch004, at = [82.57, 322.96])' ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
afterRectangle2ndClickSnippet : ` angledLine(angle=0,length=11.16,tag= $ rectangleSegmentA004)
| > angledLine ( angle = segAng ( rectangleSegmentA004 ) - 90 , length = 103.07 )
| > angledLine ( angle = segAng ( rectangleSegmentA004 ) , length = - segLen ( rectangleSegmentA004 ) )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( ) ` ,
2025-02-04 16:49:49 -05:00
} )
/// last one
await sketchOnAChamfer ( {
clickCoords : { x : 620 , y : 300 } ,
cameraPos : { x : - 1100 , y : - 7700 , z : 1600 } ,
cameraTarget : { x : 1450 , y : 670 , z : 4000 } ,
2025-02-21 14:41:25 -06:00
beforeChamferSnippet : ` chamfer(length = 30, tags = [getNextAdjacentEdge(yo)]) ` ,
beforeChamferSnippetEnd :
'|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)])' ,
2025-02-04 16:49:49 -05:00
afterChamferSelectSnippet :
2025-04-14 05:58:19 -04:00
'sketch005 = startSketchOn(extrude001, face = seg06)' ,
2025-02-15 00:57:04 +11:00
afterRectangle1stClickSnippet :
2025-04-25 16:01:35 -05:00
'startProfile(sketch005, at = [-23.43, 19.69])' ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
afterRectangle2ndClickSnippet : ` angledLine(angle=0,length=9.1,tag= $ rectangleSegmentA005)
| > angledLine ( angle = segAng ( rectangleSegmentA005 ) - 90 , length = 84.07 )
| > angledLine ( angle = segAng ( rectangleSegmentA005 ) , length = - segLen ( rectangleSegmentA005 ) )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( ) ` ,
2025-02-04 16:49:49 -05:00
} )
2024-09-26 18:25:05 +10:00
2025-02-04 16:49:49 -05:00
await test . step ( 'verify at the end of the test that final code is what is expected' , async ( ) = > {
await editor . expectEditor . toContain (
2025-03-31 10:56:03 -04:00
` @settings(defaultLengthUnit = in)
2025-05-07 08:25:12 +10:00
2025-03-31 10:56:03 -04:00
sketch001 = startSketchOn ( XZ )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ 75.8 , 317.2 ] ) // [$startCapTag, $EndCapTag]
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 0 , length = 268.43 , tag = $rectangleSegmentA001 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) - 90 , length = 217.26 , tag = $seg01 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) , length = - segLen ( rectangleSegmentA001 ) , tag = $yo )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] , tag = $seg02 )
| > close ( )
extrude001 = extrude ( sketch001 , length = 100 )
2025-02-21 14:41:25 -06:00
| > chamfer ( length = 30 , tags = [ getOppositeEdge ( seg01 ) ] , tag = $seg03 )
| > chamfer ( length = 30 , tags = [ seg01 ] , tag = $seg04 )
| > chamfer ( length = 30 , tags = [ getNextAdjacentEdge ( seg02 ) ] , tag = $seg05 )
| > chamfer ( length = 30 , tags = [ getNextAdjacentEdge ( yo ) ] , tag = $seg06 )
2025-05-07 08:25:12 +10:00
sketch002 = startSketchOn ( extrude001 , face = seg03 )
profile001 = startProfile ( sketch002 , at = [ 205.96 , 254.59 ] )
| > angledLine ( angle = 0 , length = 11.39 , tag = $rectangleSegmentA002 )
| > angledLine ( angle = segAng ( rectangleSegmentA002 ) - 90 , length = 105.26 )
| > angledLine ( angle = segAng ( rectangleSegmentA002 ) , length = - segLen ( rectangleSegmentA002 ) )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
2025-04-14 05:58:19 -04:00
sketch003 = startSketchOn ( extrude001 , face = seg04 )
2025-04-25 16:01:35 -05:00
profile002 = startProfile ( sketch003 , at = [ - 209.64 , 255.28 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 0 , length = 11.56 , tag = $rectangleSegmentA003 )
| > angledLine ( angle = segAng ( rectangleSegmentA003 ) - 90 , length = 106.84 )
| > angledLine ( angle = segAng ( rectangleSegmentA003 ) , length = - segLen ( rectangleSegmentA003 ) )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
2025-05-07 08:25:12 +10:00
sketch004 = startSketchOn ( extrude001 , face = seg05 )
profile003 = startProfile ( sketch004 , at = [ 82.57 , 322.96 ] )
| > angledLine ( angle = 0 , length = 11.16 , tag = $rectangleSegmentA004 )
| > angledLine ( angle = segAng ( rectangleSegmentA004 ) - 90 , length = 103.07 )
| > angledLine ( angle = segAng ( rectangleSegmentA004 ) , length = - segLen ( rectangleSegmentA004 ) )
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
sketch005 = startSketchOn ( extrude001 , face = seg06 )
profile004 = startProfile ( sketch005 , at = [ - 23.43 , 19.69 ] )
| > angledLine ( angle = 0 , length = 9.1 , tag = $rectangleSegmentA005 )
| > angledLine ( angle = segAng ( rectangleSegmentA005 ) - 90 , length = 84.07 )
| > angledLine ( angle = segAng ( rectangleSegmentA005 ) , length = - segLen ( rectangleSegmentA005 ) )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
` ,
2025-02-04 16:49:49 -05:00
{ shouldNormalise : true }
)
} )
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
} )
2024-09-26 18:25:05 +10:00
2025-03-31 10:56:03 -04:00
test ( 'Works on chamfers that are not in a pipeExpression can break up multi edges in a chamfer array' , async ( {
2025-02-04 16:49:49 -05:00
context ,
page ,
homePage ,
editor ,
toolbar ,
scene ,
2025-04-07 07:08:31 -04:00
cmdBar ,
2025-02-04 16:49:49 -05:00
} ) = > {
const file = await fs . readFile (
path . resolve (
__dirname ,
'../../' ,
2025-03-01 13:59:01 -08:00
'./rust/kcl-lib/e2e/executor/inputs/e2e-can-sketch-on-chamfer-no-pipeExpr.kcl'
2025-02-04 16:49:49 -05:00
) ,
'utf-8'
)
await context . addInitScript ( ( file ) = > {
localStorage . setItem ( 'persistCode' , file )
} , file )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-03-06 11:19:13 -05:00
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
const sketchOnAChamfer = _sketchOnAChamfer ( page , editor , toolbar , scene )
await sketchOnAChamfer ( {
clickCoords : { x : 570 , y : 220 } ,
cameraPos : { x : 16020 , y : - 2000 , z : 10500 } ,
cameraTarget : { x : - 150 , y : - 4500 , z : - 80 } ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
beforeChamferSnippet : ` angledLine(angle=segAng(rectangleSegmentA001)-90,length=217.26,tag= $ seg01)
2025-02-21 14:41:25 -06:00
chamfer ( extrude001 , length = 30 , tags = [
2024-09-26 18:25:05 +10:00
seg01 ,
getNextAdjacentEdge ( yo ) ,
getNextAdjacentEdge ( seg02 ) ,
2025-02-21 14:41:25 -06:00
getOppositeEdge ( seg01 ) ,
] ) ` ,
beforeChamferSnippetEnd : ')' ,
2025-02-04 16:49:49 -05:00
afterChamferSelectSnippet :
2025-04-14 05:58:19 -04:00
'sketch002 = startSketchOn(extrude001, face = seg03)' ,
2025-02-15 00:57:04 +11:00
afterRectangle1stClickSnippet :
2025-04-25 16:01:35 -05:00
'startProfile(sketch002, at = [205.96, 254.59])' ,
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
afterRectangle2ndClickSnippet : ` angledLine(angle=0,length=11.39,tag= $ rectangleSegmentA002)
| > angledLine ( angle = segAng ( rectangleSegmentA002 ) - 90 , length = 105.26 )
| > angledLine ( angle = segAng ( rectangleSegmentA002 ) , length = - segLen ( rectangleSegmentA002 ) )
2025-02-15 00:57:04 +11:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( ) ` ,
2025-02-04 16:49:49 -05:00
} )
await editor . expectEditor . toContain (
2025-03-31 10:56:03 -04:00
` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( XZ )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ 75.8 , 317.2 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 0 , length = 268.43 , tag = $rectangleSegmentA001 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) - 90 , length = 217.26 , tag = $seg01 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) , length = - segLen ( rectangleSegmentA001 ) , tag = $yo )
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] , tag = $seg02 )
| > close ( )
extrude001 = extrude ( sketch001 , length = 100 )
2025-02-21 14:41:25 -06:00
chamf = chamfer (
extrude001 ,
2024-11-25 09:21:55 +13:00
length = 30 ,
2025-02-21 14:41:25 -06:00
tags = [ getOppositeEdge ( seg01 ) ] ,
tag = $seg03 ,
)
| > chamfer (
2024-11-25 09:21:55 +13:00
length = 30 ,
tags = [
2024-09-26 18:25:05 +10:00
seg01 ,
getNextAdjacentEdge ( yo ) ,
getNextAdjacentEdge ( seg02 )
2025-02-21 14:41:25 -06:00
] ,
)
2025-04-14 05:58:19 -04:00
sketch002 = startSketchOn ( extrude001 , face = seg03 )
2025-04-25 16:01:35 -05:00
profile001 = startProfile ( sketch002 , at = [ 205.96 , 254.59 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 0 , length = 11.39 , tag = $rectangleSegmentA002 )
| > angledLine ( angle = segAng ( rectangleSegmentA002 ) - 90 , length = 105.26 )
| > angledLine ( angle = segAng ( rectangleSegmentA002 ) , length = - segLen ( rectangleSegmentA002 ) )
2025-02-21 14:41:25 -06:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > close ( )
2024-09-26 18:25:05 +10:00
` ,
2025-02-04 16:49:49 -05:00
{ shouldNormalise : true }
)
} )
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
} )
2024-10-31 07:04:38 -07:00
2025-02-04 16:49:49 -05:00
test ( ` Verify axis, origin, and horizontal snapping ` , async ( {
page ,
homePage ,
editor ,
toolbar ,
scene ,
} ) = > {
const viewPortSize = { width : 1200 , height : 500 }
await page . setBodyDimensions ( viewPortSize )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . connectionEstablished ( )
2025-02-04 16:49:49 -05:00
// Constants and locators
// These are mappings from screenspace to KCL coordinates,
// until we merge in our coordinate system helpers
const xzPlane = [
viewPortSize . width * 0.65 ,
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
viewPortSize . height * 0.3 ,
2025-02-04 16:49:49 -05:00
] as const
const originSloppy = {
screen : [
viewPortSize . width / 2 + 3 , // 3px off the center of the screen
viewPortSize . height / 2 ,
] ,
kcl : [ 0 , 0 ] ,
} as const
const xAxisSloppy = {
screen : [
viewPortSize . width * 0.75 ,
viewPortSize . height / 2 - 3 , // 3px off the X-axis
] ,
kcl : [ 20.34 , 0 ] ,
} as const
const offYAxis = {
screen : [
viewPortSize . width * 0.6 , // Well off the Y-axis, out of snapping range
viewPortSize . height * 0.3 ,
] ,
kcl : [ 8.14 , 6.78 ] ,
} as const
const yAxisSloppy = {
screen : [
viewPortSize . width / 2 + 5 , // 5px off the Y-axis
viewPortSize . height * 0.3 ,
] ,
kcl : [ 0 , 6.78 ] ,
} as const
const [ clickOnXzPlane , moveToXzPlane ] = scene . makeMouseHelpers ( . . . xzPlane )
const [ clickOriginSloppy ] = scene . makeMouseHelpers ( . . . originSloppy . screen )
const [ clickXAxisSloppy , moveXAxisSloppy ] = scene . makeMouseHelpers (
. . . xAxisSloppy . screen
2024-10-31 07:04:38 -07:00
)
2025-02-04 16:49:49 -05:00
const [ dragToOffYAxis , dragFromOffAxis ] = scene . makeDragHelpers (
. . . offYAxis . screen
2024-10-31 07:04:38 -07:00
)
2025-02-04 16:49:49 -05:00
const expectedCodeSnippets = {
2025-03-21 22:39:12 +13:00
sketchOnXzPlane : ` sketch001 = startSketchOn(XZ) ` ,
2025-04-25 16:01:35 -05:00
pointAtOrigin : ` startProfile(sketch001, at = [ ${ originSloppy . kcl [ 0 ] } , ${ originSloppy . kcl [ 1 ] } ]) ` ,
2025-03-07 22:07:16 -06:00
segmentOnXAxis : ` xLine(length = ${ xAxisSloppy . kcl [ 0 ] } ) ` ,
2025-04-25 16:01:35 -05:00
afterSegmentDraggedOffYAxis : ` startProfile(sketch001, at = [ ${ offYAxis . kcl [ 0 ] } , ${ offYAxis . kcl [ 1 ] } ]) ` ,
afterSegmentDraggedOnYAxis : ` startProfile(sketch001, at = [ ${ yAxisSloppy . kcl [ 0 ] } , ${ yAxisSloppy . kcl [ 1 ] } ]) ` ,
2025-02-04 16:49:49 -05:00
}
await test . step ( ` Start a sketch on the XZ plane ` , async ( ) = > {
await editor . closePane ( )
await toolbar . startSketchPlaneSelection ( )
await moveToXzPlane ( )
await clickOnXzPlane ( )
2025-04-07 07:08:31 -04:00
await toolbar . waitUntilSketchingReady ( )
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain ( expectedCodeSnippets . sketchOnXzPlane )
} )
await test . step ( ` Place a point a few pixels off the middle, verify it still snaps to 0,0 ` , async ( ) = > {
await clickOriginSloppy ( )
await editor . expectEditor . toContain ( expectedCodeSnippets . pointAtOrigin )
} )
await test . step ( ` Add a segment on x-axis after moving the mouse a bit, verify it snaps ` , async ( ) = > {
await moveXAxisSloppy ( )
await clickXAxisSloppy ( )
await editor . expectEditor . toContain ( expectedCodeSnippets . segmentOnXAxis )
} )
await test . step ( ` Unequip line tool ` , async ( ) = > {
await toolbar . lineBtn . click ( )
await expect ( toolbar . lineBtn ) . not . toHaveAttribute ( 'aria-pressed' , 'true' )
} )
await test . step ( ` Drag the origin point up and to the right, verify it's past snapping ` , async ( ) = > {
await dragToOffYAxis ( {
fromPoint : { x : originSloppy.screen [ 0 ] , y : originSloppy.screen [ 1 ] } ,
} )
await editor . expectEditor . toContain (
expectedCodeSnippets . afterSegmentDraggedOffYAxis
)
} )
await test . step ( ` Drag the origin point left to the y-axis, verify it snaps back ` , async ( ) = > {
await dragFromOffAxis ( {
toPoint : { x : yAxisSloppy.screen [ 0 ] , y : yAxisSloppy.screen [ 1 ] } ,
} )
await editor . expectEditor . toContain (
expectedCodeSnippets . afterSegmentDraggedOnYAxis
)
} )
2025-02-15 00:57:04 +11:00
await editor . page . waitForTimeout ( 1000 )
2024-10-31 07:04:38 -07:00
} )
2024-11-26 11:36:14 -05:00
2025-02-04 16:49:49 -05:00
test ( ` Verify user can double-click to edit a sketch ` , async ( {
context ,
page ,
homePage ,
editor ,
toolbar ,
scene ,
2025-04-07 07:08:31 -04:00
cmdBar ,
2025-02-04 16:49:49 -05:00
} ) = > {
2025-03-21 22:39:12 +13:00
const initialCode = ` closedSketch = startSketchOn(XZ)
2025-02-28 17:40:01 -08:00
| > circle ( center = [ 8 , 5 ] , radius = 2 )
2025-03-21 22:39:12 +13:00
openSketch = startSketchOn ( XY )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 5 , 0 ] )
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > line ( endAbsolute = [ 0 , 5 ] )
2025-03-07 22:07:16 -06:00
| > xLine ( length = 5 )
2025-04-11 14:17:20 -04:00
| > tangentialArc ( endAbsolute = [ 10 , 0 ] )
2024-11-27 10:08:23 -05:00
`
2025-02-04 16:49:49 -05:00
const viewPortSize = { width : 1000 , height : 500 }
await page . setBodyDimensions ( viewPortSize )
await context . addInitScript ( ( code ) = > {
localStorage . setItem ( 'persistCode' , code )
} , initialCode )
2024-11-27 10:08:23 -05:00
2025-02-04 16:49:49 -05:00
await homePage . goToModelingScene ( )
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
2025-02-04 16:49:49 -05:00
const pointInsideCircle = {
x : viewPortSize.width * 0.63 ,
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
y : viewPortSize.height * 0.5 ,
2025-02-04 16:49:49 -05:00
}
const pointOnPathAfterSketching = {
x : viewPortSize.width * 0.65 ,
y : viewPortSize.height * 0.5 ,
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [ _clickOpenPath , moveToOpenPath , dblClickOpenPath ] =
scene . makeMouseHelpers (
pointOnPathAfterSketching . x ,
pointOnPathAfterSketching . y
)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [ _clickCircle , moveToCircle , dblClickCircle ] = scene . makeMouseHelpers (
pointInsideCircle . x ,
pointInsideCircle . y
)
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
2025-02-04 16:49:49 -05:00
const exitSketch = async ( ) = > {
await test . step ( ` Exit sketch mode ` , async ( ) = > {
await toolbar . exitSketchBtn . click ( )
await expect ( toolbar . startSketchBtn ) . toBeEnabled ( )
} )
}
2024-11-27 10:08:23 -05:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Double-click on the closed sketch ` , async ( ) = > {
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
await moveToCircle ( )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 1000 )
2025-02-04 16:49:49 -05:00
await dblClickCircle ( )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 1000 )
2025-02-04 16:49:49 -05:00
await expect ( toolbar . exitSketchBtn ) . toBeVisible ( )
await editor . expectState ( {
2025-02-28 17:40:01 -08:00
activeLines : [ ` |>circle(center=[8,5],radius=2) ` ] ,
highlightedCode : 'circle(center=[8,5],radius=2)' ,
2025-02-04 16:49:49 -05:00
diagnostics : [ ] ,
} )
2024-11-27 10:08:23 -05:00
} )
2025-02-04 16:49:49 -05:00
await page . waitForTimeout ( 1000 )
2024-11-27 10:08:23 -05:00
2025-02-04 16:49:49 -05:00
await exitSketch ( )
await page . waitForTimeout ( 1000 )
2024-11-26 11:36:14 -05:00
2025-02-04 16:49:49 -05:00
// Drag the sketch line out of the axis view which blocks the click
await page . dragAndDrop ( '#stream' , '#stream' , {
sourcePosition : {
x : viewPortSize.width * 0.7 ,
y : viewPortSize.height * 0.5 ,
} ,
targetPosition : {
x : viewPortSize.width * 0.7 ,
y : viewPortSize.height * 0.4 ,
} ,
2024-11-26 11:36:14 -05:00
} )
2025-01-09 15:36:50 -05:00
2025-02-04 16:49:49 -05:00
await page . waitForTimeout ( 500 )
await test . step ( ` Double-click on the open sketch ` , async ( ) = > {
await moveToOpenPath ( )
await scene . expectPixelColor (
[ 250 , 250 , 250 ] ,
pointOnPathAfterSketching ,
15
)
// There is a full execution after exiting sketch that clears the scene.
await page . waitForTimeout ( 500 )
await dblClickOpenPath ( )
await expect ( toolbar . exitSketchBtn ) . toBeVisible ( )
// Wait for enter sketch mode to complete
await page . waitForTimeout ( 500 )
await editor . expectState ( {
2025-04-11 14:17:20 -04:00
activeLines : [ ` |>tangentialArc(endAbsolute=[10,0]) ` ] ,
highlightedCode : 'tangentialArc(endAbsolute=[10,0])' ,
2025-02-04 16:49:49 -05:00
diagnostics : [ ] ,
} )
} )
2025-01-09 15:36:50 -05:00
} )
2024-12-04 17:24:16 -05:00
2025-02-11 14:16:48 +01:00
test ( ` Shift-click to select and deselect edges and faces ` , async ( {
context ,
page ,
homePage ,
scene ,
} ) = > {
// Code samples
2025-03-21 22:39:12 +13:00
const initialCode = ` sketch001 = startSketchOn(XY)
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 12 , - 6 ] )
2025-02-11 14:16:48 +01:00
| > line ( end = [ 0 , 12 ] )
| > line ( end = [ 24 , 0 ] )
| > line ( end = [ 0 , - 12 ] )
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
| > extrude ( % , length = - 12 ) `
// Locators
const upperEdgeLocation = { x : 600 , y : 192 }
const lowerEdgeLocation = { x : 600 , y : 383 }
const faceLocation = { x : 630 , y : 290 }
// Click helpers
const [ clickOnUpperEdge ] = scene . makeMouseHelpers (
upperEdgeLocation . x ,
upperEdgeLocation . y
)
const [ clickOnLowerEdge ] = scene . makeMouseHelpers (
lowerEdgeLocation . x ,
lowerEdgeLocation . y
)
const [ clickOnFace ] = scene . makeMouseHelpers ( faceLocation . x , faceLocation . y )
// Colors
const edgeColorWhite : [ number , number , number ] = [ 220 , 220 , 220 ] // varies from 192 to 255
const edgeColorYellow : [ number , number , number ] = [ 251 , 251 , 40 ] // vaies from 12 to 67
const faceColorGray : [ number , number , number ] = [ 168 , 168 , 168 ]
const faceColorYellow : [ number , number , number ] = [ 155 , 155 , 155 ]
const tolerance = 40
const timeout = 150
// Setup
await test . step ( ` Initial test setup ` , async ( ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
// Wait for the scene and stream to load
await scene . expectPixelColor ( faceColorGray , faceLocation , tolerance )
} )
await test . step ( 'Select and deselect a single edge' , async ( ) = > {
await test . step ( 'Click the edge' , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
upperEdgeLocation ,
tolerance
)
await clickOnUpperEdge ( )
await scene . expectPixelColor (
edgeColorYellow ,
upperEdgeLocation ,
tolerance
)
} )
await test . step ( 'Shift-click the same edge to deselect' , async ( ) = > {
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickOnUpperEdge ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor (
edgeColorWhite ,
upperEdgeLocation ,
tolerance
)
} )
} )
await test . step ( 'Select and deselect multiple objects' , async ( ) = > {
await test . step ( 'Select both edges and the face' , async ( ) = > {
await test . step ( 'Select the upper edge' , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
upperEdgeLocation ,
tolerance
)
await clickOnUpperEdge ( )
await scene . expectPixelColor (
edgeColorYellow ,
upperEdgeLocation ,
tolerance
)
} )
await test . step ( 'Select the lower edge (Shift-click)' , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
lowerEdgeLocation ,
tolerance
)
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickOnLowerEdge ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor (
edgeColorYellow ,
lowerEdgeLocation ,
tolerance
)
} )
await test . step ( 'Select the face (Shift-click)' , async ( ) = > {
await scene . expectPixelColor ( faceColorGray , faceLocation , tolerance )
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickOnFace ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor ( faceColorYellow , faceLocation , tolerance )
} )
} )
await test . step ( 'Deselect them one by one' , async ( ) = > {
await test . step ( 'Deselect the face (Shift-click)' , async ( ) = > {
await scene . expectPixelColor ( faceColorYellow , faceLocation , tolerance )
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickOnFace ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor ( faceColorGray , faceLocation , tolerance )
} )
await test . step ( 'Deselect the lower edge (Shift-click)' , async ( ) = > {
await scene . expectPixelColor (
edgeColorYellow ,
lowerEdgeLocation ,
tolerance
)
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickOnLowerEdge ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor (
edgeColorWhite ,
lowerEdgeLocation ,
tolerance
)
} )
await test . step ( 'Deselect the upper edge (Shift-click)' , async ( ) = > {
await scene . expectPixelColor (
edgeColorYellow ,
upperEdgeLocation ,
tolerance
)
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickOnUpperEdge ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor (
edgeColorWhite ,
upperEdgeLocation ,
tolerance
)
} )
} )
} )
} )
2025-03-20 16:28:08 -04:00
test ( ` Shift-click to select and deselect sketch segments ` , async ( {
page ,
homePage ,
scene ,
editor ,
} ) = > {
// Locators
const firstPointLocation = { x : 200 , y : 100 }
const secondPointLocation = { x : 800 , y : 100 }
const thirdPointLocation = { x : 800 , y : 400 }
2025-05-07 12:48:23 -05:00
const firstSegmentLocation = { x : 750 , y : 100 }
2025-03-20 16:28:08 -04:00
const secondSegmentLocation = { x : 800 , y : 150 }
const planeLocation = { x : 700 , y : 200 }
2025-02-11 14:16:48 +01:00
2025-03-20 16:28:08 -04:00
// Click helpers
const [ clickFirstPoint ] = scene . makeMouseHelpers (
firstPointLocation . x ,
firstPointLocation . y
)
const [ clickSecondPoint ] = scene . makeMouseHelpers (
secondPointLocation . x ,
secondPointLocation . y
)
const [ clickThirdPoint ] = scene . makeMouseHelpers (
thirdPointLocation . x ,
thirdPointLocation . y
)
const [ clickFirstSegment ] = scene . makeMouseHelpers (
2025-05-07 12:48:23 -05:00
firstSegmentLocation . x ,
firstSegmentLocation . y
2025-03-20 16:28:08 -04:00
)
const [ clickSecondSegment ] = scene . makeMouseHelpers (
secondSegmentLocation . x ,
secondSegmentLocation . y
)
const [ clickPlane ] = scene . makeMouseHelpers (
planeLocation . x ,
planeLocation . y
)
// Colors
const edgeColorWhite : [ number , number , number ] = [ 220 , 220 , 220 ]
const edgeColorBlue : [ number , number , number ] = [ 20 , 20 , 200 ]
const backgroundColor : [ number , number , number ] = [ 30 , 30 , 30 ]
const tolerance = 40
const timeout = 150
2025-02-11 14:16:48 +01:00
2025-03-20 16:28:08 -04:00
// Setup
await test . step ( ` Initial test setup ` , async ( ) = > {
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-02-11 14:16:48 +01:00
2025-03-20 16:28:08 -04:00
// Wait for the scene and stream to load
await scene . expectPixelColor (
backgroundColor ,
secondPointLocation ,
tolerance
)
} )
2025-02-11 14:16:48 +01:00
2025-03-20 16:28:08 -04:00
await test . step ( 'Select and deselect a single sketch segment' , async ( ) = > {
await test . step ( 'Get into sketch mode' , async ( ) = > {
await editor . closePane ( )
await page . waitForTimeout ( timeout )
await page . getByRole ( 'button' , { name : 'Start Sketch' } ) . click ( )
await page . waitForTimeout ( timeout )
await clickPlane ( )
await page . waitForTimeout ( 1000 )
} )
await test . step ( 'Draw sketch' , async ( ) = > {
await clickFirstPoint ( )
await page . waitForTimeout ( timeout )
await clickSecondPoint ( )
await page . waitForTimeout ( timeout )
await clickThirdPoint ( )
await page . waitForTimeout ( timeout )
} )
await test . step ( 'Deselect line tool' , async ( ) = > {
const btnLine = page . getByTestId ( 'line' )
const btnLineAriaPressed = await btnLine . getAttribute ( 'aria-pressed' )
if ( btnLineAriaPressed === 'true' ) {
await btnLine . click ( )
}
await page . waitForTimeout ( timeout )
} )
await test . step ( 'Select the first segment' , async ( ) = > {
await page . waitForTimeout ( timeout )
await clickFirstSegment ( )
await page . waitForTimeout ( timeout )
await scene . expectPixelColor (
edgeColorBlue ,
2025-05-07 12:48:23 -05:00
firstSegmentLocation ,
2025-03-20 16:28:08 -04:00
tolerance
)
2025-02-11 14:16:48 +01:00
await scene . expectPixelColor (
2025-03-20 16:28:08 -04:00
edgeColorWhite ,
secondSegmentLocation ,
2025-02-11 14:16:48 +01:00
tolerance
)
} )
2025-03-20 16:28:08 -04:00
await test . step ( 'Select the second segment (Shift-click)' , async ( ) = > {
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickSecondSegment ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor (
edgeColorBlue ,
2025-05-07 12:48:23 -05:00
firstSegmentLocation ,
2025-03-20 16:28:08 -04:00
tolerance
)
await scene . expectPixelColor (
edgeColorBlue ,
secondSegmentLocation ,
tolerance
)
2025-02-11 14:16:48 +01:00
} )
2025-03-20 16:28:08 -04:00
await test . step ( 'Deselect the first segment' , async ( ) = > {
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickFirstSegment ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor (
edgeColorWhite ,
2025-05-07 12:48:23 -05:00
firstSegmentLocation ,
2025-03-20 16:28:08 -04:00
tolerance
)
await scene . expectPixelColor (
edgeColorBlue ,
secondSegmentLocation ,
tolerance
)
} )
await test . step ( 'Deselect the second segment' , async ( ) = > {
await page . keyboard . down ( 'Shift' )
await page . waitForTimeout ( timeout )
await clickSecondSegment ( )
await page . waitForTimeout ( timeout )
await page . keyboard . up ( 'Shift' )
await scene . expectPixelColor (
edgeColorWhite ,
2025-05-07 12:48:23 -05:00
firstSegmentLocation ,
2025-03-20 16:28:08 -04:00
tolerance
)
await scene . expectPixelColor (
edgeColorWhite ,
secondSegmentLocation ,
tolerance
)
} )
} )
} )
2025-02-11 14:16:48 +01:00
2025-02-04 16:49:49 -05:00
test ( ` Offset plane point-and-click ` , async ( {
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
context ,
2024-12-04 17:24:16 -05:00
page ,
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
homePage ,
2024-12-04 17:24:16 -05:00
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
2025-02-04 16:49:49 -05:00
// One dumb hardcoded screen pixel value
2025-06-20 12:05:20 -04:00
const testPoint = { x : 700 , y : 200 }
// TODO: replace the testPoint selection with a feature tree click once that's supported #7544
2025-02-04 16:49:49 -05:00
const [ clickOnXzPlane ] = scene . makeMouseHelpers ( testPoint . x , testPoint . y )
2025-03-21 22:39:12 +13:00
const expectedOutput = ` plane001 = offsetPlane(XZ, offset = 5) `
2025-02-04 16:49:49 -05:00
await homePage . goToModelingScene ( )
2025-06-20 12:05:20 -04:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
await test . step ( ` Look for the blue of the XZ plane ` , async ( ) = > {
2025-03-15 10:08:39 -07:00
//await scene.expectPixelColor([50, 51, 96], testPoint, 15) // FIXME
2025-02-04 16:49:49 -05:00
} )
await test . step ( ` Go through the command bar flow ` , async ( ) = > {
await toolbar . offsetPlaneButton . click ( )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'plane' ,
currentArgValue : '' ,
headerArguments : { Plane : '' , Distance : '' } ,
highlightedHeaderArg : 'plane' ,
commandName : 'Offset plane' ,
} )
await clickOnXzPlane ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'distance' ,
currentArgValue : '5' ,
headerArguments : { Plane : '1 plane' , Distance : '' } ,
highlightedHeaderArg : 'distance' ,
commandName : 'Offset plane' ,
} )
await cmdBar . progressCmdBar ( )
} )
await test . step ( ` Confirm code is added to the editor, scene has changed ` , async ( ) = > {
await editor . expectEditor . toContain ( expectedOutput )
await editor . expectState ( {
diagnostics : [ ] ,
activeLines : [ expectedOutput ] ,
highlightedCode : '' ,
} )
await scene . expectPixelColor ( [ 74 , 74 , 74 ] , testPoint , 15 )
} )
await test . step ( 'Delete offset plane via feature tree selection' , async ( ) = > {
await editor . closePane ( )
const operationButton = await toolbar . getFeatureTreeOperation (
'Offset Plane' ,
0
)
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-03-15 10:08:39 -07:00
//await scene.expectPixelColor([50, 51, 96], testPoint, 15) // FIXME
2025-02-04 16:49:49 -05:00
} )
} )
2025-06-26 14:12:36 -04:00
const initialCmdBarStateHelix : CmdBarSerialised = {
stage : 'arguments' ,
currentArgKey : 'mode' ,
currentArgValue : '' ,
headerArguments : {
Mode : '' ,
AngleStart : '' ,
Revolutions : '' ,
Radius : '' ,
} ,
highlightedHeaderArg : 'mode' ,
commandName : 'Helix' ,
}
2025-03-24 16:08:19 -04:00
test ( 'Helix point-and-click on default axis' , async ( {
2025-02-07 10:16:36 -05:00
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
2025-06-26 14:12:36 -04:00
const expectedOutput = ` helix001 = helix( axis = X, radius = 5, length = 5, revolutions = 1, angleStart = 270,) `
2025-04-03 22:44:52 +13:00
const expectedLine = ` axis=X, `
2025-02-07 10:16:36 -05:00
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . connectionEstablished ( )
2025-02-07 10:16:36 -05:00
await test . step ( ` Go through the command bar flow ` , async ( ) = > {
await toolbar . helixButton . click ( )
2025-06-26 14:12:36 -04:00
await cmdBar . expectState ( initialCmdBarStateHelix )
2025-02-07 10:16:36 -05:00
await cmdBar . progressCmdBar ( )
2025-04-07 07:08:31 -04:00
await expect . poll ( ( ) = > page . getByText ( 'Axis' ) . count ( ) ) . toBe ( 6 )
2025-02-07 10:16:36 -05:00
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
2025-04-15 20:09:58 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'angleStart' ,
highlightedHeaderArg : 'angleStart' ,
currentArgValue : '360' ,
headerArguments : {
Mode : 'Axis' ,
Axis : 'X' ,
Revolutions : '1' ,
AngleStart : '' ,
Length : '' ,
Radius : '' ,
} ,
commandName : 'Helix' ,
} )
await cmdBar . currentArgumentInput . locator ( '.cm-content' ) . fill ( '270' )
2025-02-07 10:16:36 -05:00
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
2025-03-26 17:57:30 -04:00
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Mode : 'Axis' ,
Axis : 'X' ,
2025-04-15 20:09:58 -04:00
AngleStart : '270' ,
2025-03-26 17:57:30 -04:00
Revolutions : '1' ,
Length : '5' ,
Radius : '5' ,
} ,
commandName : 'Helix' ,
} )
2025-06-26 14:12:36 -04:00
await cmdBar . submit ( )
2025-02-07 10:16:36 -05:00
} )
await test . step ( ` Confirm code is added to the editor, scene has changed ` , async ( ) = > {
await editor . expectEditor . toContain ( expectedOutput )
await editor . expectState ( {
diagnostics : [ ] ,
2025-02-11 16:06:47 -06:00
activeLines : [ expectedLine ] ,
2025-02-07 10:16:36 -05:00
highlightedCode : '' ,
} )
} )
2025-02-24 18:44:13 -05:00
await test . step ( ` Edit helix through the feature tree ` , async ( ) = > {
await editor . closePane ( )
const operationButton = await toolbar . getFeatureTreeOperation ( 'Helix' , 0 )
await operationButton . dblclick ( )
const initialInput = '5'
const newInput = '50'
await cmdBar . expectState ( {
commandName : 'Helix' ,
stage : 'arguments' ,
2025-06-26 14:12:36 -04:00
currentArgKey : 'length' ,
currentArgValue : '5' ,
2025-02-24 18:44:13 -05:00
headerArguments : {
Axis : 'X' ,
2025-04-15 20:09:58 -04:00
AngleStart : '270' ,
2025-02-24 18:44:13 -05:00
Revolutions : '1' ,
2025-03-26 17:57:30 -04:00
Radius : '5' ,
Length : initialInput ,
2025-02-24 18:44:13 -05:00
} ,
2025-06-26 14:12:36 -04:00
highlightedHeaderArg : 'length' ,
2025-02-24 18:44:13 -05:00
} )
2025-06-26 14:12:36 -04:00
await page . keyboard . insertText ( newInput )
2025-02-24 18:44:13 -05:00
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Axis : 'X' ,
2025-04-15 20:09:58 -04:00
AngleStart : '270' ,
2025-02-24 18:44:13 -05:00
Revolutions : '1' ,
2025-03-26 17:57:30 -04:00
Radius : '5' ,
Length : newInput ,
2025-02-24 18:44:13 -05:00
} ,
commandName : 'Helix' ,
} )
2025-06-26 14:12:36 -04:00
await cmdBar . submit ( )
2025-02-24 18:44:13 -05:00
await toolbar . closeFeatureTreePane ( )
await editor . openPane ( )
await editor . expectEditor . toContain ( 'length = ' + newInput )
} )
await test . step ( 'Delete helix via feature tree selection' , async ( ) = > {
2025-02-07 10:16:36 -05:00
await editor . closePane ( )
const operationButton = await toolbar . getFeatureTreeOperation ( 'Helix' , 0 )
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-06-26 14:12:36 -04:00
await scene . settled ( cmdBar )
await editor . expectEditor . not . toContain ( 'helix' )
await expect (
await toolbar . getFeatureTreeOperation ( 'Helix' , 0 )
) . not . toBeVisible ( )
2025-02-07 10:16:36 -05:00
} )
} )
2025-06-26 14:12:36 -04:00
test ( ` Helix point-and-click around segment ` , 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 ( ) `
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await scene . settled ( cmdBar )
2025-03-24 16:08:19 -04:00
2025-06-26 14:12:36 -04:00
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 editor . selectText ( 'yLine(length = 100)' )
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '1' )
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '2' )
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '3' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Mode : 'Edge' ,
Edge : ` 1 segment ` ,
AngleStart : '2' ,
Revolutions : '1' ,
Radius : '3' ,
} ,
commandName : 'Helix' ,
} )
await cmdBar . submit ( )
await scene . settled ( cmdBar )
} )
2025-03-24 16:08:19 -04:00
2025-06-26 14:12:36 -04:00
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' )
} )
} )
2025-03-24 16:08:19 -04:00
2025-06-26 14:12:36 -04:00
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' ,
2025-03-24 16:08:19 -04:00
} )
2025-06-26 14:12:36 -04:00
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 ( )
} )
} )
2025-03-24 16:08:19 -04:00
2025-03-26 17:57:30 -04:00
test ( 'Helix point-and-click on cylinder' , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
const initialCode = ` sketch001 = startSketchOn(XY)
profile001 = circle (
sketch001 ,
center = [ 0 , 0 ] ,
radius = 100 ,
tag = $seg01 ,
)
extrude001 = extrude ( profile001 , length = 100 )
`
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-03-26 17:57:30 -04:00
// One dumb hardcoded screen pixel value
const testPoint = { x : 620 , y : 257 }
const [ clickOnWall ] = scene . makeMouseHelpers ( testPoint . x , testPoint . y )
2025-06-26 14:12:36 -04:00
const expectedOutput = ` helix001 = helix(cylinder = extrude001, revolutions = 1, angleStart = 360) `
const expectedEditedOutput = ` helix001 = helix(cylinder = extrude001, revolutions = 1, angleStart = 10) `
2025-03-26 17:57:30 -04:00
await test . step ( ` Go through the command bar flow ` , async ( ) = > {
await toolbar . helixButton . click ( )
2025-06-26 14:12:36 -04:00
await cmdBar . expectState ( initialCmdBarStateHelix )
2025-03-26 17:57:30 -04:00
await cmdBar . selectOption ( { name : 'Cylinder' } ) . click ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'cylinder' ,
currentArgValue : '' ,
headerArguments : {
Mode : 'Cylinder' ,
Cylinder : '' ,
AngleStart : '' ,
Revolutions : '' ,
} ,
highlightedHeaderArg : 'cylinder' ,
commandName : 'Helix' ,
} )
await clickOnWall ( )
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Mode : 'Cylinder' ,
Cylinder : '1 face' ,
AngleStart : '360' ,
Revolutions : '1' ,
} ,
commandName : 'Helix' ,
} )
2025-06-26 14:12:36 -04:00
await cmdBar . submit ( )
2025-03-26 17:57:30 -04:00
} )
await test . step ( ` Confirm code is added to the editor, scene has changed ` , async ( ) = > {
await editor . expectEditor . toContain ( expectedOutput )
await editor . expectState ( {
diagnostics : [ ] ,
2025-06-26 14:12:36 -04:00
activeLines : [ expectedOutput ] ,
2025-03-26 17:57:30 -04:00
highlightedCode : '' ,
} )
} )
await test . step ( ` Edit helix through the feature tree ` , async ( ) = > {
await editor . closePane ( )
const operationButton = await toolbar . getFeatureTreeOperation ( 'Helix' , 0 )
await operationButton . dblclick ( )
await cmdBar . expectState ( {
commandName : 'Helix' ,
stage : 'arguments' ,
2025-06-26 14:12:36 -04:00
currentArgKey : 'angleStart' ,
currentArgValue : '360' ,
2025-03-26 17:57:30 -04:00
headerArguments : {
AngleStart : '360' ,
Revolutions : '1' ,
} ,
2025-06-26 14:12:36 -04:00
highlightedHeaderArg : 'angleStart' ,
2025-03-26 17:57:30 -04:00
} )
2025-06-26 14:12:36 -04:00
await page . keyboard . insertText ( '10' )
await cmdBar . progressCmdBar ( )
2025-03-26 17:57:30 -04:00
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
2025-06-26 14:12:36 -04:00
AngleStart : '10' ,
2025-03-26 17:57:30 -04:00
Revolutions : '1' ,
} ,
commandName : 'Helix' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain ( expectedEditedOutput )
await editor . closePane ( )
} )
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 toolbar . closePane ( 'feature-tree' )
await toolbar . openPane ( 'code' )
await editor . expectEditor . not . toContain ( expectedEditedOutput )
} )
} )
2025-02-04 16:49:49 -05:00
const loftPointAndClickCases = [
{ shouldPreselect : true } ,
{ shouldPreselect : false } ,
]
loftPointAndClickCases . forEach ( ( { shouldPreselect } ) = > {
test ( ` Loft point-and-click (preselected sketches: ${ shouldPreselect } ) ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
2025-03-21 22:39:12 +13:00
const initialCode = ` sketch001 = startSketchOn(XZ)
2025-05-06 17:57:27 -04:00
| > circle ( center = [ 0 , 0 ] , radius = 30 )
plane001 = offsetPlane ( XZ , offset = 50 )
sketch002 = startSketchOn ( plane001 )
| > circle ( center = [ 0 , 0 ] , radius = 20 )
`
2025-02-04 16:49:49 -05:00
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
// 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
)
const loftDeclaration = 'loft001 = loft([sketch001, sketch002])'
2025-06-23 18:24:52 -04:00
const editedLoftDeclaration =
'loft001 = loft([sketch001, sketch002], vDegree = 3)'
2024-12-04 17:24:16 -05:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Look for the white of the sketch001 shape ` , async ( ) = > {
await scene . expectPixelColor ( [ 254 , 254 , 254 ] , testPoint , 15 )
} )
2024-12-04 17:24:16 -05:00
2025-02-04 16:49:49 -05:00
async function selectSketches() {
await clickOnSketch1 ( )
await page . keyboard . down ( 'Shift' )
await clickOnSketch2 ( )
await page . waitForTimeout ( 500 )
await page . keyboard . up ( 'Shift' )
}
if ( ! shouldPreselect ) {
await test . step ( ` Go through the command bar flow without preselected sketches ` , async ( ) = > {
await toolbar . loftButton . click ( )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'arguments' ,
2025-05-06 17:57:27 -04:00
currentArgKey : 'sketches' ,
2025-02-04 16:49:49 -05:00
currentArgValue : '' ,
2025-05-19 11:21:29 -04:00
headerArguments : { Profiles : '' } ,
highlightedHeaderArg : 'Profiles' ,
2025-02-04 16:49:49 -05:00
commandName : 'Loft' ,
} )
await selectSketches ( )
await cmdBar . progressCmdBar ( )
2025-05-06 17:57:27 -04:00
await cmdBar . expectState ( {
stage : 'review' ,
2025-05-19 11:21:29 -04:00
headerArguments : { Profiles : '2 profiles' } ,
2025-05-06 17:57:27 -04:00
commandName : 'Loft' ,
} )
await cmdBar . submit ( )
2025-02-04 16:49:49 -05:00
} )
} else {
await test . step ( ` Preselect the two sketches ` , async ( ) = > {
await selectSketches ( )
} )
2024-12-04 17:24:16 -05:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Go through the command bar flow with preselected sketches ` , async ( ) = > {
await toolbar . loftButton . click ( )
2025-05-20 16:07:56 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'sketches' ,
currentArgValue : '' ,
headerArguments : { Profiles : '' } ,
highlightedHeaderArg : 'Profiles' ,
commandName : 'Loft' ,
} )
await cmdBar . progressCmdBar ( )
2025-05-06 17:57:27 -04:00
await cmdBar . expectState ( {
stage : 'review' ,
2025-05-19 11:21:29 -04:00
headerArguments : { Profiles : '2 profiles' } ,
2025-05-06 17:57:27 -04:00
commandName : 'Loft' ,
} )
await cmdBar . submit ( )
2024-12-04 17:24:16 -05:00
} )
2025-02-04 16:49:49 -05:00
}
2024-12-04 17:24:16 -05:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm code is added to the editor, scene has changed ` , async ( ) = > {
await editor . expectEditor . toContain ( loftDeclaration )
await editor . expectState ( {
diagnostics : [ ] ,
activeLines : [ loftDeclaration ] ,
highlightedCode : '' ,
} )
await scene . expectPixelColor ( [ 89 , 89 , 89 ] , testPoint , 15 )
2024-12-04 17:24:16 -05:00
} )
2025-06-23 18:24:52 -04:00
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 )
} )
2025-02-04 16:49:49 -05:00
await test . step ( 'Delete loft via feature tree selection' , async ( ) = > {
await editor . closePane ( )
const operationButton = await toolbar . getFeatureTreeOperation ( 'Loft' , 0 )
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-02-04 16:49:49 -05:00
await scene . expectPixelColor ( [ 254 , 254 , 254 ] , testPoint , 15 )
2024-12-04 17:24:16 -05:00
} )
2025-01-09 15:36:50 -05:00
} )
} )
2025-03-21 14:52:04 -04:00
const sweepCases = [
{
targetType : 'circle' ,
testPoint : { x : 700 , y : 250 } ,
2025-03-31 10:56:03 -04:00
initialCode : ` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( YZ )
2025-03-21 14:52:04 -04:00
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 500 )
2025-03-31 10:56:03 -04:00
sketch002 = startSketchOn ( XZ )
2025-06-02 22:49:20 +02:00
profile002 = startProfile ( sketch002 , at = [ 0 , 0 ] )
2025-03-07 22:07:16 -06:00
| > xLine ( length = - 500 )
2025-04-11 14:17:20 -04:00
| > tangentialArc ( endAbsolute = [ - 2000 , 500 ] ) ` ,
2025-03-21 14:52:04 -04:00
} ,
{
targetType : 'rectangle' ,
testPoint : { x : 710 , y : 255 } ,
2025-03-31 10:56:03 -04:00
initialCode : ` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( YZ )
2025-04-25 16:01:35 -05:00
profile001 = startProfile ( sketch001 , at = [ - 400 , - 400 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 0 , length = 800 , tag = $rectangleSegmentA001 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) + 90 , length = 800 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) , length = - segLen ( rectangleSegmentA001 ) )
2025-03-21 14:52:04 -04:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
2025-03-31 10:56:03 -04:00
sketch002 = startSketchOn ( XZ )
2025-06-02 22:49:20 +02:00
profile002 = startProfile ( sketch002 , at = [ 0 , 0 ] )
2025-03-21 14:52:04 -04:00
| > xLine ( length = - 500 )
2025-04-11 14:17:20 -04:00
| > tangentialArc ( endAbsolute = [ - 2000 , 500 ] ) ` ,
2025-03-21 14:52:04 -04:00
} ,
]
sweepCases . map ( ( { initialCode , targetType , testPoint } ) = > {
test ( ` Sweep point-and-click ${ targetType } ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-01-11 08:20:49 -05:00
2025-03-21 14:52:04 -04:00
// One dumb hardcoded screen pixel value
const [ clickOnSketch1 ] = scene . makeMouseHelpers ( testPoint . x , testPoint . y )
const [ clickOnSketch2 ] = scene . makeMouseHelpers (
testPoint . x - 50 ,
testPoint . y
)
2025-06-02 22:49:20 +02:00
const sweepDeclaration = 'sweep001 = sweep(profile001, path = profile002)'
2025-03-21 14:52:04 -04:00
const editedSweepDeclaration =
2025-06-02 22:49:20 +02:00
'sweep001 = sweep(profile001, path = profile002, sectional = true)'
2025-03-21 14:52:04 -04:00
await test . step ( ` Look for sketch001 ` , async ( ) = > {
await toolbar . closePane ( 'code' )
await scene . expectPixelColor ( [ 53 , 53 , 53 ] , testPoint , 15 )
2025-03-20 20:42:41 -04:00
} )
2025-01-11 08:20:49 -05:00
2025-03-21 14:52:04 -04:00
await test . step ( ` Go through the command bar flow ` , async ( ) = > {
await toolbar . sweepButton . click ( )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2025-03-21 14:52:04 -04:00
await cmdBar . expectState ( {
commandName : 'Sweep' ,
2025-05-06 17:57:27 -04:00
currentArgKey : 'sketches' ,
2025-03-21 14:52:04 -04:00
currentArgValue : '' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '' ,
2025-05-06 17:57:27 -04:00
Path : '' ,
2025-03-21 14:52:04 -04:00
} ,
2025-05-19 11:21:29 -04:00
highlightedHeaderArg : 'Profiles' ,
2025-03-21 14:52:04 -04:00
stage : 'arguments' ,
} )
await clickOnSketch1 ( )
2025-05-06 17:57:27 -04:00
await cmdBar . progressCmdBar ( )
2025-03-21 14:52:04 -04:00
await cmdBar . expectState ( {
commandName : 'Sweep' ,
2025-05-06 17:57:27 -04:00
currentArgKey : 'path' ,
2025-03-21 14:52:04 -04:00
currentArgValue : '' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '1 profile' ,
2025-05-06 17:57:27 -04:00
Path : '' ,
2025-03-21 14:52:04 -04:00
} ,
2025-05-06 17:57:27 -04:00
highlightedHeaderArg : 'path' ,
2025-03-21 14:52:04 -04:00
stage : 'arguments' ,
} )
await clickOnSketch2 ( )
2025-05-06 17:57:27 -04:00
await cmdBar . expectState ( {
commandName : 'Sweep' ,
currentArgKey : 'path' ,
currentArgValue : '' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '1 profile' ,
2025-05-06 17:57:27 -04:00
Path : '' ,
} ,
highlightedHeaderArg : 'path' ,
stage : 'arguments' ,
} )
2025-03-21 14:52:04 -04:00
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Sweep' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '1 profile' ,
2025-05-06 17:57:27 -04:00
Path : '1 segment' ,
2025-03-21 14:52:04 -04:00
} ,
stage : 'review' ,
} )
2025-05-20 12:04:56 -04:00
// Confirm we can submit from the review step with just `Enter`
await cmdBar . progressCmdBar ( true )
await cmdBar . expectState ( {
stage : 'commandBarClosed' ,
} )
2025-03-21 14:52:04 -04:00
} )
2025-03-20 20:42:41 -04:00
2025-03-21 14:52:04 -04:00
await test . step ( ` Confirm code is added to the editor, scene has changed ` , async ( ) = > {
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain ( sweepDeclaration )
await scene . expectPixelColor ( [ 120 , 120 , 120 ] , testPoint , 40 )
await toolbar . closePane ( 'code' )
2025-02-04 16:49:49 -05:00
} )
2025-03-21 14:52:04 -04:00
await test . step ( 'Edit sweep via feature tree selection works' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
const operationButton = await toolbar . getFeatureTreeOperation (
'Sweep' ,
0
)
await operationButton . dblclick ( { button : 'left' } )
2025-06-20 12:05:20 -04:00
await page
. getByRole ( 'button' , { name : 'sectional' , exact : false } )
. click ( )
2025-03-21 14:52:04 -04:00
await cmdBar . expectState ( {
commandName : 'Sweep' ,
currentArgKey : 'sectional' ,
currentArgValue : '' ,
headerArguments : {
Sectional : '' ,
} ,
highlightedHeaderArg : 'sectional' ,
stage : 'arguments' ,
} )
await cmdBar . selectOption ( { name : 'True' } ) . click ( )
await cmdBar . expectState ( {
commandName : 'Sweep' ,
headerArguments : {
Sectional : '' ,
} ,
stage : 'review' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain ( editedSweepDeclaration )
await toolbar . closePane ( 'code' )
2025-03-20 20:42:41 -04:00
} )
2025-02-04 16:49:49 -05:00
2025-03-21 14:52:04 -04:00
await test . step ( 'Delete sweep via feature tree selection' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
await page . waitForTimeout ( 500 )
const operationButton = await toolbar . getFeatureTreeOperation (
'Sweep' ,
0
)
await operationButton . click ( { button : 'left' } )
await page . keyboard . press ( 'Delete' )
await page . waitForTimeout ( 500 )
await toolbar . closePane ( 'feature-tree' )
await scene . expectPixelColor ( [ 53 , 53 , 53 ] , testPoint , 15 )
} )
2025-02-04 16:49:49 -05:00
} )
2025-01-11 08:20:49 -05:00
} )
2025-05-15 16:42:38 -04:00
test ( ` Sweep point-and-click helix ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
const circleCode = ` circle(sketch001, center = [0, -1], radius = .1) `
const initialCode = ` helix001 = helix(
axis = X ,
radius = 1 ,
length = 10 ,
revolutions = 10 ,
angleStart = 0 ,
ccw = false ,
)
sketch001 = startSketchOn ( XZ )
profile001 = $ { circleCode } `
const sweepDeclaration = 'sweep001 = sweep(profile001, path = helix001)'
2025-06-23 16:17:17 -04:00
const editedSweepDeclaration = ` sweep001 = sweep(profile001, path = helix001, relativeTo = 'sketchPlane') `
2025-05-15 16:42:38 -04:00
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await homePage . goToModelingScene ( )
await scene . settled ( cmdBar )
await test . step ( ` Add sweep through the command bar flow ` , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
await toolbar . sweepButton . click ( )
await cmdBar . expectState ( {
commandName : 'Sweep' ,
currentArgKey : 'sketches' ,
currentArgValue : '' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '' ,
2025-05-15 16:42:38 -04:00
Path : '' ,
} ,
2025-05-19 11:21:29 -04:00
highlightedHeaderArg : 'Profiles' ,
2025-05-15 16:42:38 -04:00
stage : 'arguments' ,
} )
await editor . scrollToText ( circleCode )
await page . getByText ( circleCode ) . click ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Sweep' ,
currentArgKey : 'path' ,
currentArgValue : '' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '1 profile' ,
2025-05-15 16:42:38 -04:00
Path : '' ,
} ,
highlightedHeaderArg : 'path' ,
stage : 'arguments' ,
} )
const helix = await toolbar . getFeatureTreeOperation ( 'Helix' , 0 )
await helix . click ( )
await cmdBar . expectState ( {
commandName : 'Sweep' ,
currentArgKey : 'path' ,
currentArgValue : '' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '1 profile' ,
2025-05-15 16:42:38 -04:00
Path : '' ,
} ,
highlightedHeaderArg : 'path' ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Sweep' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '1 profile' ,
2025-05-15 16:42:38 -04:00
Path : '1 helix' ,
} ,
stage : 'review' ,
} )
2025-05-20 12:04:56 -04:00
await cmdBar . progressCmdBar ( true )
2025-05-15 16:42:38 -04:00
await editor . expectEditor . toContain ( sweepDeclaration )
} )
2025-06-23 16:17:17 -04:00
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 )
} )
2025-05-15 16:42:38 -04:00
await test . step ( 'Delete sweep via feature tree selection' , async ( ) = > {
const sweep = await toolbar . getFeatureTreeOperation ( 'Sweep' , 0 )
await sweep . click ( )
await page . keyboard . press ( 'Delete' )
2025-06-23 16:17:17 -04:00
await editor . expectEditor . not . toContain ( editedSweepDeclaration )
2025-05-15 16:42:38 -04:00
} )
} )
2025-02-04 16:49:49 -05:00
test ( ` Fillet point-and-click ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
// Code samples
2025-03-21 22:39:12 +13:00
const initialCode = ` sketch001 = startSketchOn(XY)
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 12 , - 6 ] )
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > line ( end = [ 0 , 12 ] )
| > line ( end = [ 24 , 0 ] )
| > line ( end = [ 0 , - 12 ] )
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
extrude001 = extrude ( sketch001 , length = - 12 )
2025-01-17 10:21:55 +01:00
`
2025-04-26 14:00:28 +10:00
const firstFilletDeclaration = ` fillet(radius=5,tags=[getCommonEdge(faces=[seg01,capEnd001])],) `
const secondFilletDeclaration = ` fillet(radius=5,tags=[getCommonEdge(faces=[seg01,capStart001])],) `
2025-02-04 16:49:49 -05:00
// Locators
const firstEdgeLocation = { x : 600 , y : 193 }
const secondEdgeLocation = { x : 600 , y : 383 }
const bodyLocation = { x : 630 , y : 290 }
const [ clickOnFirstEdge ] = scene . makeMouseHelpers (
firstEdgeLocation . x ,
firstEdgeLocation . y
)
const [ clickOnSecondEdge ] = scene . makeMouseHelpers (
secondEdgeLocation . x ,
secondEdgeLocation . y
2025-01-17 10:21:55 +01:00
)
2025-02-04 16:49:49 -05:00
// Colors
const edgeColorWhite : [ number , number , number ] = [ 248 , 248 , 248 ]
const edgeColorYellow : [ number , number , number ] = [ 251 , 251 , 40 ] // Mac:B=67 Ubuntu:B=12
const bodyColor : [ number , number , number ] = [ 155 , 155 , 155 ]
const filletColor : [ number , number , number ] = [ 127 , 127 , 127 ]
const backgroundColor : [ number , number , number ] = [ 30 , 30 , 30 ]
const lowTolerance = 20
2025-03-26 07:57:08 -04:00
const highTolerance = 70 // TODO: understand why I needed that for edgeColorYellow on macos (local)
2025-02-04 16:49:49 -05:00
// Setup
await test . step ( ` Initial test setup ` , async ( ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
// verify modeling scene is loaded
await scene . expectPixelColor (
backgroundColor ,
secondEdgeLocation ,
lowTolerance
)
2025-01-17 10:21:55 +01:00
2025-02-04 16:49:49 -05:00
// wait for stream to load
await scene . expectPixelColor ( bodyColor , bodyLocation , highTolerance )
} )
2025-01-17 10:21:55 +01:00
2025-02-04 16:49:49 -05:00
// Test 1: Command bar flow with preselected edges
await test . step ( ` Select first edge ` , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
firstEdgeLocation ,
lowTolerance
)
await clickOnFirstEdge ( )
await scene . expectPixelColor (
edgeColorYellow ,
firstEdgeLocation ,
highTolerance // Ubuntu color mismatch can require high tolerance
)
2025-01-17 10:21:55 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Apply fillet to the preselected edge ` , async ( ) = > {
await page . waitForTimeout ( 100 )
await toolbar . filletButton . click ( )
2025-05-20 16:07:56 -04:00
await cmdBar . expectState ( {
commandName : 'Fillet' ,
highlightedHeaderArg : 'selection' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Radius : '' ,
} ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
commandName : 'Fillet' ,
highlightedHeaderArg : 'radius' ,
currentArgKey : 'radius' ,
currentArgValue : '5' ,
headerArguments : {
Selection : '1 segment' ,
Radius : '' ,
} ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Fillet' ,
headerArguments : {
Selection : '1 segment' ,
Radius : '5' ,
} ,
stage : 'review' ,
} )
await cmdBar . progressCmdBar ( )
2025-01-17 10:21:55 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm code is added to the editor ` , async ( ) = > {
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( firstFilletDeclaration , {
shouldNormalise : true ,
} )
2025-02-04 16:49:49 -05:00
await editor . expectState ( {
diagnostics : [ ] ,
2025-04-26 14:00:28 +10:00
activeLines : [ ')' ] ,
2025-02-04 16:49:49 -05:00
highlightedCode : '' ,
} )
} )
2025-01-17 10:21:55 +01:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm scene has changed ` , async ( ) = > {
await scene . expectPixelColor ( filletColor , firstEdgeLocation , lowTolerance )
2025-01-17 10:21:55 +01:00
} )
2025-03-26 07:57:08 -04:00
// Test 1.1: Edit fillet (segment type)
async function editFillet (
featureTreeIndex : number ,
oldValue : string ,
newValue : string
) {
await toolbar . openPane ( 'feature-tree' )
const operationButton = await toolbar . getFeatureTreeOperation (
'Fillet' ,
featureTreeIndex
)
await operationButton . dblclick ( { button : 'left' } )
await cmdBar . expectState ( {
commandName : 'Fillet' ,
currentArgKey : 'radius' ,
currentArgValue : oldValue ,
headerArguments : {
Radius : oldValue ,
} ,
highlightedHeaderArg : 'radius' ,
stage : 'arguments' ,
} )
await page . keyboard . insertText ( newValue )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Radius : newValue ,
} ,
commandName : 'Fillet' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
}
await test . step ( 'Edit fillet via feature tree selection works' , async ( ) = > {
const firstFilletFeatureTreeIndex = 0
const editedRadius = '1'
await editFillet ( firstFilletFeatureTreeIndex , '5' , editedRadius )
await editor . expectEditor . toContain (
2025-04-26 14:00:28 +10:00
firstFilletDeclaration . replace ( 'radius=5' , 'radius=' + editedRadius ) ,
{ shouldNormalise : true }
2025-03-26 07:57:08 -04:00
)
// Edit back to original radius
await editFillet ( firstFilletFeatureTreeIndex , editedRadius , '5' )
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( firstFilletDeclaration , {
shouldNormalise : true ,
} )
2025-03-26 07:57:08 -04:00
} )
2025-02-04 16:49:49 -05:00
// Test 2: Command bar flow without preselected edges
await test . step ( ` Open fillet UI without selecting edges ` , async ( ) = > {
await page . waitForTimeout ( 100 )
await toolbar . filletButton . click ( )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Radius : '' ,
} ,
highlightedHeaderArg : 'selection' ,
commandName : 'Fillet' ,
} )
} )
2025-01-14 18:08:32 +01:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Select second edge ` , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
secondEdgeLocation ,
lowTolerance
)
await clickOnSecondEdge ( )
await scene . expectPixelColor (
edgeColorYellow ,
secondEdgeLocation ,
highTolerance // Ubuntu color mismatch can require high tolerance
)
2025-01-17 10:21:55 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Apply fillet to the second edge ` , async ( ) = > {
await cmdBar . expectState ( {
commandName : 'Fillet' ,
highlightedHeaderArg : 'selection' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Radius : '' ,
} ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Fillet' ,
highlightedHeaderArg : 'radius' ,
currentArgKey : 'radius' ,
currentArgValue : '5' ,
headerArguments : {
Selection : '1 sweepEdge' ,
Radius : '' ,
} ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Fillet' ,
headerArguments : {
Selection : '1 sweepEdge' ,
Radius : '5' ,
} ,
stage : 'review' ,
} )
await cmdBar . progressCmdBar ( )
2025-01-17 10:21:55 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm code is added to the editor ` , async ( ) = > {
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( secondFilletDeclaration , {
shouldNormalise : true ,
} )
2025-02-04 16:49:49 -05:00
await editor . expectState ( {
diagnostics : [ ] ,
2025-04-26 14:00:28 +10:00
activeLines : [ ')' ] ,
2025-02-04 16:49:49 -05:00
highlightedCode : '' ,
} )
} )
2025-02-03 18:11:26 +01:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm scene has changed ` , async ( ) = > {
await scene . expectPixelColor (
backgroundColor ,
secondEdgeLocation ,
lowTolerance
)
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
2025-03-26 07:57:08 -04:00
// Test 2.1: Edit fillet (edgeSweep type)
await test . step ( 'Edit fillet via feature tree selection works' , async ( ) = > {
const secondFilletFeatureTreeIndex = 1
const editedRadius = '2'
await editFillet ( secondFilletFeatureTreeIndex , '5' , editedRadius )
await editor . expectEditor . toContain (
2025-04-26 14:00:28 +10:00
secondFilletDeclaration . replace ( 'radius=5' , 'radius=' + editedRadius ) ,
{ shouldNormalise : true }
2025-03-26 07:57:08 -04:00
)
// Edit back to original radius
await editFillet ( secondFilletFeatureTreeIndex , editedRadius , '5' )
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( secondFilletDeclaration , {
shouldNormalise : true ,
} )
2025-03-26 07:57:08 -04:00
} )
2025-02-04 16:49:49 -05:00
// Test 3: Delete fillets
2025-02-03 18:11:26 +01:00
await test . step ( 'Delete fillet via feature tree selection' , async ( ) = > {
2025-02-04 16:49:49 -05:00
await test . step ( 'Open Feature Tree Pane' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
await page . waitForTimeout ( 500 )
} )
await test . step ( 'Delete fillet via feature tree selection' , async ( ) = > {
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( secondFilletDeclaration , {
shouldNormalise : true ,
} )
2025-02-04 16:49:49 -05:00
const operationButton = await toolbar . getFeatureTreeOperation (
'Fillet' ,
1
)
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-02-04 16:49:49 -05:00
await page . waitForTimeout ( 500 )
await scene . expectPixelColor ( edgeColorWhite , secondEdgeLocation , 15 ) // deleted
await editor . expectEditor . not . toContain ( secondFilletDeclaration )
await scene . expectPixelColor ( filletColor , firstEdgeLocation , 15 ) // stayed
} )
2025-02-03 18:11:26 +01:00
} )
} )
2025-05-08 22:16:36 +02:00
test ( ` Fillet point-and-click edit standalone expression ` , async ( {
2025-03-26 07:57:08 -04:00
context ,
page ,
homePage ,
scene ,
2025-05-08 22:16:36 +02:00
editor ,
2025-03-26 07:57:08 -04:00
toolbar ,
2025-04-07 07:08:31 -04:00
cmdBar ,
2025-03-26 07:57:08 -04:00
} ) = > {
const initialCode = ` sketch001 = startSketchOn(XY)
profile001 = circle (
sketch001 ,
center = [ 0 , 0 ] ,
radius = 100 ,
tag = $seg01 ,
)
extrude001 = extrude ( profile001 , length = 100 )
fillet001 = fillet ( extrude001 , radius = 5 , tags = [ getOppositeEdge ( seg01 ) ] )
`
2025-05-08 22:16:36 +02:00
await test . step ( ` Initial test setup ` , async ( ) = > {
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 ( 'Edit fillet' , async ( ) = > {
2025-03-26 07:57:08 -04:00
await toolbar . openPane ( 'feature-tree' )
2025-05-08 22:16:36 +02:00
await toolbar . closePane ( 'code' )
2025-03-26 07:57:08 -04:00
const operationButton = await toolbar . getFeatureTreeOperation ( 'Fillet' , 0 )
await operationButton . dblclick ( { button : 'left' } )
2025-05-08 22:16:36 +02:00
await cmdBar . expectState ( {
commandName : 'Fillet' ,
currentArgKey : 'radius' ,
currentArgValue : '5' ,
headerArguments : {
Radius : '5' ,
} ,
highlightedHeaderArg : 'radius' ,
stage : 'arguments' ,
} )
await page . keyboard . insertText ( '20' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Radius : '20' ,
} ,
commandName : 'Fillet' ,
} )
await cmdBar . progressCmdBar ( )
} )
await test . step ( 'Confirm changes' , async ( ) = > {
await toolbar . openPane ( 'code' )
await toolbar . closePane ( 'feature-tree' )
await editor . expectEditor . toContain ( 'radius = 20' )
2025-03-26 07:57:08 -04:00
} )
} )
2025-02-04 16:49:49 -05:00
test ( ` Fillet point-and-click delete ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
2025-05-10 18:53:05 +02:00
cmdBar ,
2025-02-04 16:49:49 -05:00
} ) = > {
// Code samples
2025-03-21 22:39:12 +13:00
const initialCode = ` sketch001 = startSketchOn(XY)
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 12 , - 6 ] )
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > line ( end = [ 0 , 12 ] )
| > line ( end = [ 24 , 0 ] , tag = $seg02 )
| > line ( end = [ 0 , - 12 ] )
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] , tag = $seg01 )
| > close ( )
extrude001 = extrude ( sketch001 , length = - 12 )
2025-02-21 14:41:25 -06:00
| > fillet ( radius = 5 , tags = [ seg01 ] ) // fillet01
| > fillet ( radius = 5 , tags = [ seg02 ] ) // fillet02
fillet03 = fillet ( extrude001 , radius = 5 , tags = [ getOppositeEdge ( seg01 ) ] )
2025-05-10 18:53:05 +02:00
fillet ( extrude001 , radius = 5 , tags = [ getOppositeEdge ( seg02 ) ] )
2025-02-03 18:11:26 +01:00
`
2025-05-10 18:53:05 +02:00
const firstPipedFilletDeclaration = 'fillet(radius = 5, tags = [seg01])'
2025-02-21 14:41:25 -06:00
const secondPipedFilletDeclaration = 'fillet(radius = 5, tags = [seg02])'
2025-05-10 18:53:05 +02:00
const standaloneAssignedFilletDeclaration =
2025-02-21 14:41:25 -06:00
'fillet03 = fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg01)])'
2025-05-10 18:53:05 +02:00
const standaloneUnassignedFilletDeclaration =
'fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg02)])'
2025-02-04 16:49:49 -05:00
// Locators
const pipedFilletEdgeLocation = { x : 600 , y : 193 }
const standaloneFilletEdgeLocation = { x : 600 , y : 383 }
const bodyLocation = { x : 630 , y : 290 }
// Colors
const edgeColorWhite : [ number , number , number ] = [ 248 , 248 , 248 ]
const bodyColor : [ number , number , number ] = [ 155 , 155 , 155 ]
const filletColor : [ number , number , number ] = [ 127 , 127 , 127 ]
const backgroundColor : [ number , number , number ] = [ 30 , 30 , 30 ]
const lowTolerance = 20
const highTolerance = 40
// Setup
await test . step ( ` Initial test setup ` , async ( ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-05-10 18:53:05 +02:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
// verify modeling scene is loaded
await scene . expectPixelColor (
backgroundColor ,
standaloneFilletEdgeLocation ,
lowTolerance
)
2025-02-03 18:11:26 +01:00
2025-02-04 16:49:49 -05:00
// wait for stream to load
await scene . expectPixelColor ( bodyColor , bodyLocation , highTolerance )
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
// Test
await test . step ( 'Delete fillet via feature tree selection' , async ( ) = > {
await test . step ( 'Open Feature Tree Pane' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
2025-05-10 18:53:05 +02:00
await scene . settled ( cmdBar )
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( 'Delete piped fillet via feature tree selection' , async ( ) = > {
await test . step ( 'Verify all fillets are present in the editor' , async ( ) = > {
2025-05-10 18:53:05 +02:00
await editor . expectEditor . toContain ( firstPipedFilletDeclaration )
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain ( secondPipedFilletDeclaration )
2025-05-10 18:53:05 +02:00
await editor . expectEditor . toContain (
standaloneAssignedFilletDeclaration
)
await editor . expectEditor . toContain (
standaloneUnassignedFilletDeclaration
)
2025-02-04 16:49:49 -05:00
} )
await test . step ( 'Verify test fillets are present in the scene' , async ( ) = > {
await scene . expectPixelColor (
filletColor ,
pipedFilletEdgeLocation ,
lowTolerance
)
await scene . expectPixelColor (
backgroundColor ,
standaloneFilletEdgeLocation ,
lowTolerance
)
} )
await test . step ( 'Delete piped fillet' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Fillet' ,
0
)
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-05-10 18:53:05 +02:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
} )
await test . step ( 'Verify piped fillet is deleted but other fillets are not (in the editor)' , async ( ) = > {
2025-05-10 18:53:05 +02:00
await editor . expectEditor . not . toContain ( firstPipedFilletDeclaration )
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain ( secondPipedFilletDeclaration )
2025-05-10 18:53:05 +02:00
await editor . expectEditor . toContain (
standaloneAssignedFilletDeclaration
)
await editor . expectEditor . toContain (
standaloneUnassignedFilletDeclaration
)
2025-02-04 16:49:49 -05:00
} )
await test . step ( 'Verify piped fillet is deleted but non-piped is not (in the scene)' , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite , // you see edge because fillet is deleted
pipedFilletEdgeLocation ,
lowTolerance
)
await scene . expectPixelColor (
backgroundColor , // you see background because fillet is not deleted
standaloneFilletEdgeLocation ,
lowTolerance
)
} )
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
2025-05-10 18:53:05 +02:00
await test . step ( 'Delete standalone assigned fillet via feature tree selection' , async ( ) = > {
await test . step ( 'Delete standalone assigned fillet' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Fillet' ,
1
)
await operationButton . click ( { button : 'left' } )
await page . keyboard . press ( 'Delete' )
await scene . settled ( cmdBar )
} )
await test . step ( 'Verify standalone assigned fillet is deleted but other two fillets are not (in the editor)' , async ( ) = > {
await editor . expectEditor . toContain ( secondPipedFilletDeclaration )
await editor . expectEditor . not . toContain (
standaloneAssignedFilletDeclaration
)
await editor . expectEditor . toContain (
standaloneUnassignedFilletDeclaration
)
} )
await test . step ( 'Verify standalone assigned fillet is deleted but piped is not (in the scene)' , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
standaloneFilletEdgeLocation ,
lowTolerance
)
} )
} )
await test . step ( 'Delete standalone unassigned fillet via feature tree selection' , async ( ) = > {
await test . step ( 'Delete standalone unassigned fillet' , async ( ) = > {
2025-02-04 16:49:49 -05:00
const operationButton = await toolbar . getFeatureTreeOperation (
'Fillet' ,
1
)
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-05-10 18:53:05 +02:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
} )
2025-05-10 18:53:05 +02:00
await test . step ( 'Verify standalone unassigned fillet is deleted but other fillet is not (in the editor)' , async ( ) = > {
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain ( secondPipedFilletDeclaration )
2025-05-10 18:53:05 +02:00
await editor . expectEditor . not . toContain (
standaloneUnassignedFilletDeclaration
)
2025-02-04 16:49:49 -05:00
} )
2025-05-10 18:53:05 +02:00
await test . step ( 'Verify standalone unassigned fillet is deleted but piped is not (in the scene)' , async ( ) = > {
2025-02-04 16:49:49 -05:00
await scene . expectPixelColor (
edgeColorWhite ,
standaloneFilletEdgeLocation ,
lowTolerance
)
} )
2025-02-03 18:11:26 +01:00
} )
} )
} )
2025-01-17 10:21:55 +01:00
2025-03-19 17:48:29 +01:00
test ( ` Fillet with large radius should update code even if engine fails ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
// Create a cube with small edges that will cause some fillets to fail
2025-03-21 22:39:12 +13:00
const initialCode = ` sketch001 = startSketchOn(XY)
2025-04-25 16:01:35 -05:00
profile001 = startProfile ( sketch001 , at = [ 0 , 0 ] )
2025-03-19 17:48:29 +01:00
| > yLine ( length = - 1 )
| > xLine ( length = - 10 )
| > yLine ( length = 10 )
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
extrude001 = extrude ( profile001 , length = 5 )
`
2025-04-26 14:00:28 +10:00
const taggedSegment1 = ` xLine(length = -10, tag = $ seg01) `
const taggedSegment2 = ` yLine(length = -1, tag = $ seg02) `
const filletExpression = ` fillet(radius = 1000, tags = [getCommonEdge(faces = [seg01, seg02])]) `
2025-03-19 17:48:29 +01:00
// Locators
const edgeLocation = { x : 659 , y : 313 }
const bodyLocation = { x : 594 , y : 313 }
// Colors
const edgeColorWhite : [ number , number , number ] = [ 248 , 248 , 248 ]
const edgeColorYellow : [ number , number , number ] = [ 251 , 251 , 120 ] // Mac:B=251,251,90 Ubuntu:240,241,180, Windows:240,241,180
const backgroundColor : [ number , number , number ] = [ 30 , 30 , 30 ]
const bodyColor : [ number , number , number ] = [ 155 , 155 , 155 ]
const lowTolerance = 20
const highTolerance = 70
// Setup
await test . step ( ` Initial test setup ` , async ( ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
// verify modeling scene is loaded
await scene . expectPixelColor ( backgroundColor , edgeLocation , lowTolerance )
// wait for stream to load
await scene . expectPixelColor ( bodyColor , bodyLocation , highTolerance )
} )
// Test
await test . step ( 'Select edges and apply oversized fillet' , async ( ) = > {
await test . step ( ` Select the edge ` , async ( ) = > {
await scene . expectPixelColor ( edgeColorWhite , edgeLocation , lowTolerance )
const [ clickOnTheEdge ] = scene . makeMouseHelpers (
edgeLocation . x ,
edgeLocation . y
)
await clickOnTheEdge ( )
await scene . expectPixelColor (
edgeColorYellow ,
edgeLocation ,
highTolerance // Ubuntu color mismatch can require high tolerance
)
} )
await test . step ( ` Apply fillet ` , async ( ) = > {
await page . waitForTimeout ( 100 )
await toolbar . filletButton . click ( )
2025-05-20 16:07:56 -04:00
await cmdBar . expectState ( {
commandName : 'Fillet' ,
highlightedHeaderArg : 'selection' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Radius : '' ,
} ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
2025-03-19 17:48:29 +01:00
await cmdBar . expectState ( {
commandName : 'Fillet' ,
highlightedHeaderArg : 'radius' ,
currentArgKey : 'radius' ,
currentArgValue : '5' ,
headerArguments : {
Selection : '1 sweepEdge' ,
Radius : '' ,
} ,
stage : 'arguments' ,
} )
// Set a large radius (1000)
await cmdBar . currentArgumentInput . locator ( '.cm-content' ) . fill ( '1000' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Fillet' ,
headerArguments : {
Selection : '1 sweepEdge' ,
Radius : '1000' ,
} ,
stage : 'review' ,
} )
// Apply fillet with large radius
await cmdBar . progressCmdBar ( )
} )
} )
await test . step ( 'Verify code is updated regardless of execution errors' , async ( ) = > {
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( taggedSegment1 )
await editor . expectEditor . toContain ( taggedSegment2 )
2025-03-19 17:48:29 +01:00
await editor . expectEditor . toContain ( filletExpression )
} )
} )
2025-02-04 16:49:49 -05:00
test ( ` Chamfer point-and-click ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
// Code samples
2025-03-31 10:56:03 -04:00
const initialCode = ` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( XY )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 12 , - 6 ] )
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > line ( end = [ 0 , 12 ] )
| > line ( end = [ 24 , 0 ] )
| > line ( end = [ 0 , - 12 ] )
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
extrude001 = extrude ( sketch001 , length = - 12 )
2025-01-14 18:08:32 +01:00
`
2025-04-26 14:00:28 +10:00
const firstChamferDeclaration = ` chamfer(length=5,tags=[getCommonEdge(faces=[seg01,capEnd001])],) `
const secondChamferDeclaration = ` chamfer(length=5,tags=[getCommonEdge(faces=[seg01,capStart001])],) `
2025-02-04 16:49:49 -05:00
// Locators
const firstEdgeLocation = { x : 600 , y : 193 }
const secondEdgeLocation = { x : 600 , y : 383 }
const [ clickOnFirstEdge ] = scene . makeMouseHelpers (
firstEdgeLocation . x ,
firstEdgeLocation . y
)
const [ clickOnSecondEdge ] = scene . makeMouseHelpers (
secondEdgeLocation . x ,
secondEdgeLocation . y
2025-01-14 18:08:32 +01:00
)
2025-02-04 16:49:49 -05:00
// Colors
const edgeColorWhite : [ number , number , number ] = [ 248 , 248 , 248 ]
const edgeColorYellow : [ number , number , number ] = [ 251 , 251 , 40 ] // Mac:B=67 Ubuntu:B=12
const chamferColor : [ number , number , number ] = [ 168 , 168 , 168 ]
const backgroundColor : [ number , number , number ] = [ 30 , 30 , 30 ]
const lowTolerance = 20
2025-03-26 07:57:08 -04:00
const highTolerance = 70 // TODO: understand why I needed that for edgeColorYellow on macos (local)
2025-02-04 16:49:49 -05:00
// Setup
await test . step ( ` Initial test setup ` , async ( ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
} )
2025-01-14 18:08:32 +01:00
2025-02-04 16:49:49 -05:00
// Test 1: Command bar flow with preselected edges
await test . step ( ` Select first edge ` , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
firstEdgeLocation ,
lowTolerance
)
await clickOnFirstEdge ( )
await scene . expectPixelColor (
edgeColorYellow ,
firstEdgeLocation ,
highTolerance // Ubuntu color mismatch can require high tolerance
)
2025-01-14 18:08:32 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Apply chamfer to the preselected edge ` , async ( ) = > {
await page . waitForTimeout ( 100 )
await toolbar . chamferButton . click ( )
2025-05-20 16:07:56 -04:00
await cmdBar . expectState ( {
commandName : 'Chamfer' ,
highlightedHeaderArg : 'selection' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Length : '' ,
} ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
await page . waitForTimeout ( 1000 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
commandName : 'Chamfer' ,
highlightedHeaderArg : 'length' ,
currentArgKey : 'length' ,
currentArgValue : '5' ,
headerArguments : {
Selection : '1 segment' ,
Length : '' ,
} ,
stage : 'arguments' ,
} )
2025-04-07 07:08:31 -04:00
await cmdBar . argumentInput . focus ( )
await page . waitForTimeout ( 1000 )
2025-02-04 16:49:49 -05:00
await cmdBar . progressCmdBar ( )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 1000 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
commandName : 'Chamfer' ,
headerArguments : {
Selection : '1 segment' ,
Length : '5' ,
} ,
stage : 'review' ,
} )
await cmdBar . progressCmdBar ( )
2025-01-14 18:08:32 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm code is added to the editor ` , async ( ) = > {
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( firstChamferDeclaration , {
shouldNormalise : true ,
} )
2025-02-04 16:49:49 -05:00
await editor . expectState ( {
diagnostics : [ ] ,
2025-04-26 14:00:28 +10:00
activeLines : [ ')' ] ,
2025-02-04 16:49:49 -05:00
highlightedCode : '' ,
} )
} )
2025-01-14 18:08:32 +01:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm scene has changed ` , async ( ) = > {
await scene . expectPixelColor (
chamferColor ,
firstEdgeLocation ,
lowTolerance
)
2025-01-14 18:08:32 +01:00
} )
2025-03-26 07:57:08 -04:00
// Test 1.1: Edit sweep
async function editChamfer (
featureTreeIndex : number ,
oldValue : string ,
newValue : string
) {
await toolbar . openPane ( 'feature-tree' )
const operationButton = await toolbar . getFeatureTreeOperation (
'Chamfer' ,
featureTreeIndex
)
await operationButton . dblclick ( { button : 'left' } )
await cmdBar . expectState ( {
commandName : 'Chamfer' ,
currentArgKey : 'length' ,
currentArgValue : oldValue ,
headerArguments : {
Length : oldValue ,
} ,
highlightedHeaderArg : 'length' ,
stage : 'arguments' ,
} )
await page . keyboard . insertText ( newValue )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Length : newValue ,
} ,
commandName : 'Chamfer' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
}
await test . step ( 'Edit chamfer via feature tree selection works' , async ( ) = > {
const firstChamferFeatureTreeIndex = 0
const editedLength = '1'
await editChamfer ( firstChamferFeatureTreeIndex , '5' , editedLength )
await editor . expectEditor . toContain (
2025-04-26 14:00:28 +10:00
firstChamferDeclaration . replace ( 'length=5' , 'length=' + editedLength ) ,
{ shouldNormalise : true }
2025-03-26 07:57:08 -04:00
)
// Edit back to original radius
await editChamfer ( firstChamferFeatureTreeIndex , editedLength , '5' )
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( firstChamferDeclaration , {
shouldNormalise : true ,
} )
2025-03-26 07:57:08 -04:00
} )
2025-02-04 16:49:49 -05:00
// Test 2: Command bar flow without preselected edges
await test . step ( ` Open chamfer UI without selecting edges ` , async ( ) = > {
await page . waitForTimeout ( 100 )
await toolbar . chamferButton . click ( )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Length : '' ,
} ,
highlightedHeaderArg : 'selection' ,
commandName : 'Chamfer' ,
} )
} )
2025-01-14 18:08:32 +01:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Select second edge ` , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
secondEdgeLocation ,
lowTolerance
)
await clickOnSecondEdge ( )
await scene . expectPixelColor (
edgeColorYellow ,
secondEdgeLocation ,
highTolerance // Ubuntu color mismatch can require high tolerance
)
} )
await test . step ( ` Apply chamfer to the second edge ` , async ( ) = > {
await cmdBar . expectState ( {
commandName : 'Chamfer' ,
highlightedHeaderArg : 'selection' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Length : '' ,
} ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Chamfer' ,
highlightedHeaderArg : 'length' ,
currentArgKey : 'length' ,
currentArgValue : '5' ,
headerArguments : {
Selection : '1 sweepEdge' ,
Length : '' ,
} ,
stage : 'arguments' ,
} )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
commandName : 'Chamfer' ,
headerArguments : {
Selection : '1 sweepEdge' ,
Length : '5' ,
} ,
stage : 'review' ,
} )
await cmdBar . progressCmdBar ( )
2025-01-14 18:08:32 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm code is added to the editor ` , async ( ) = > {
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( secondChamferDeclaration , {
shouldNormalise : true ,
} )
2025-02-04 16:49:49 -05:00
await editor . expectState ( {
diagnostics : [ ] ,
2025-04-26 14:00:28 +10:00
activeLines : [ ')' ] ,
2025-02-04 16:49:49 -05:00
highlightedCode : '' ,
} )
2025-01-14 18:08:32 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm scene has changed ` , async ( ) = > {
await scene . expectPixelColor (
backgroundColor ,
secondEdgeLocation ,
lowTolerance
)
} )
2025-02-03 18:11:26 +01:00
2025-03-26 07:57:08 -04:00
// Test 2.1: Edit chamfer (edgeSweep type)
await test . step ( 'Edit chamfer via feature tree selection works' , async ( ) = > {
const secondChamferFeatureTreeIndex = 1
const editedLength = '2'
await editChamfer ( secondChamferFeatureTreeIndex , '5' , editedLength )
await editor . expectEditor . toContain (
2025-04-26 14:00:28 +10:00
secondChamferDeclaration . replace ( 'length=5' , 'length=' + editedLength ) ,
{ shouldNormalise : true }
2025-03-26 07:57:08 -04:00
)
// Edit back to original length
await editChamfer ( secondChamferFeatureTreeIndex , editedLength , '5' )
2025-04-26 14:00:28 +10:00
await editor . expectEditor . toContain ( secondChamferDeclaration , {
shouldNormalise : true ,
} )
2025-03-26 07:57:08 -04:00
} )
2025-02-04 16:49:49 -05:00
// Test 3: Delete chamfer via feature tree selection
await test . step ( 'Open Feature Tree Pane' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
await page . waitForTimeout ( 500 )
} )
await test . step ( 'Delete chamfer via feature tree selection' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Chamfer' ,
1
)
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-02-04 16:49:49 -05:00
await page . waitForTimeout ( 500 )
await scene . expectPixelColor ( edgeColorWhite , secondEdgeLocation , 15 ) // deleted
await scene . expectPixelColor ( chamferColor , firstEdgeLocation , 15 ) // stayed
} )
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
test ( ` Chamfer point-and-click delete ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
2025-04-07 07:08:31 -04:00
cmdBar ,
2025-02-04 16:49:49 -05:00
} ) = > {
// Code samples
2025-03-31 10:56:03 -04:00
const initialCode = ` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( XY )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 12 , - 6 ] )
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > line ( end = [ 0 , 12 ] )
| > line ( end = [ 24 , 0 ] , tag = $seg02 )
| > line ( end = [ 0 , - 12 ] )
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] , tag = $seg01 )
| > close ( )
extrude001 = extrude ( sketch001 , length = - 12 )
2025-02-21 14:41:25 -06:00
| > chamfer ( length = 5 , tags = [ seg01 ] ) // chamfer01
| > chamfer ( length = 5 , tags = [ seg02 ] ) // chamfer02
chamfer03 = chamfer ( extrude001 , length = 5 , tags = [ getOppositeEdge ( seg01 ) ] )
2025-05-10 18:53:05 +02:00
chamfer ( extrude001 , length = 5 , tags = [ getOppositeEdge ( seg02 ) ] )
2025-02-03 18:11:26 +01:00
`
2025-05-10 18:53:05 +02:00
const firstPipedChamferDeclaration = 'chamfer(length = 5, tags = [seg01])'
2025-02-21 14:41:25 -06:00
const secondPipedChamferDeclaration = 'chamfer(length = 5, tags = [seg02])'
2025-05-10 18:53:05 +02:00
const standaloneAssignedChamferDeclaration =
2025-02-21 14:41:25 -06:00
'chamfer03 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg01)])'
2025-05-10 18:53:05 +02:00
const standaloneUnassignedChamferDeclaration =
'chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)])'
2025-02-04 16:49:49 -05:00
// Locators
const pipedChamferEdgeLocation = { x : 600 , y : 193 }
const standaloneChamferEdgeLocation = { x : 600 , y : 383 }
const bodyLocation = { x : 630 , y : 290 }
// Colors
const edgeColorWhite : [ number , number , number ] = [ 248 , 248 , 248 ]
const bodyColor : [ number , number , number ] = [ 155 , 155 , 155 ]
const chamferColor : [ number , number , number ] = [ 168 , 168 , 168 ]
const backgroundColor : [ number , number , number ] = [ 30 , 30 , 30 ]
const lowTolerance = 20
const highTolerance = 40
// Setup
await test . step ( ` Initial test setup ` , async ( ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
// verify modeling scene is loaded
await scene . expectPixelColor (
backgroundColor ,
standaloneChamferEdgeLocation ,
lowTolerance
)
2025-02-03 18:11:26 +01:00
2025-02-04 16:49:49 -05:00
// wait for stream to load
await scene . expectPixelColor ( bodyColor , bodyLocation , highTolerance )
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
// Test
await test . step ( 'Delete chamfer via feature tree selection' , async ( ) = > {
await test . step ( 'Open Feature Tree Pane' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
2025-05-10 18:53:05 +02:00
await scene . settled ( cmdBar )
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
await test . step ( 'Delete piped chamfer via feature tree selection' , async ( ) = > {
await test . step ( 'Verify all chamfers are present in the editor' , async ( ) = > {
2025-05-10 18:53:05 +02:00
await editor . expectEditor . toContain ( firstPipedChamferDeclaration )
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain ( secondPipedChamferDeclaration )
await editor . expectEditor . toContain (
2025-05-10 18:53:05 +02:00
standaloneAssignedChamferDeclaration
)
await editor . expectEditor . toContain (
standaloneUnassignedChamferDeclaration
2025-02-04 16:49:49 -05:00
)
} )
await test . step ( 'Verify test chamfers are present in the scene' , async ( ) = > {
await scene . expectPixelColor (
chamferColor ,
pipedChamferEdgeLocation ,
lowTolerance
)
await scene . expectPixelColor (
backgroundColor ,
standaloneChamferEdgeLocation ,
lowTolerance
)
} )
await test . step ( 'Delete piped chamfer' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Chamfer' ,
0
)
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-05-10 18:53:05 +02:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
} )
await test . step ( 'Verify piped chamfer is deleted but other chamfers are not (in the editor)' , async ( ) = > {
2025-05-10 18:53:05 +02:00
await editor . expectEditor . not . toContain ( firstPipedChamferDeclaration )
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain ( secondPipedChamferDeclaration )
await editor . expectEditor . toContain (
2025-05-10 18:53:05 +02:00
standaloneAssignedChamferDeclaration
)
await editor . expectEditor . toContain (
standaloneUnassignedChamferDeclaration
2025-02-04 16:49:49 -05:00
)
} )
await test . step ( 'Verify piped chamfer is deleted but non-piped is not (in the scene)' , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite , // you see edge color because chamfer is deleted
pipedChamferEdgeLocation ,
lowTolerance
)
await scene . expectPixelColor (
backgroundColor , // you see background color instead of edge because it's chamfered
standaloneChamferEdgeLocation ,
lowTolerance
)
} )
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
2025-05-10 18:53:05 +02:00
await test . step ( 'Delete standalone assigned chamfer via feature tree selection' , async ( ) = > {
await test . step ( 'Delete standalone assigned chamfer' , async ( ) = > {
2025-02-04 16:49:49 -05:00
const operationButton = await toolbar . getFeatureTreeOperation (
'Chamfer' ,
1
)
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-05-10 18:53:05 +02:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
} )
2025-05-10 18:53:05 +02:00
await test . step ( 'Verify standalone assigned chamfer is deleted but other two chamfers are not (in the editor)' , async ( ) = > {
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain ( secondPipedChamferDeclaration )
2025-05-10 18:53:05 +02:00
await editor . expectEditor . not . toContain (
standaloneAssignedChamferDeclaration
)
2025-02-04 16:49:49 -05:00
await editor . expectEditor . toContain (
2025-05-10 18:53:05 +02:00
standaloneUnassignedChamferDeclaration
)
} )
await test . step ( 'Verify standalone assigned chamfer is deleted but piped is not (in the scene)' , async ( ) = > {
await scene . expectPixelColor (
edgeColorWhite ,
standaloneChamferEdgeLocation ,
lowTolerance
)
} )
} )
await test . step ( 'Delete standalone unassigned chamfer via feature tree selection' , async ( ) = > {
await test . step ( 'Delete standalone unassigned chamfer' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Chamfer' ,
1
)
await operationButton . click ( { button : 'left' } )
await page . keyboard . press ( 'Delete' )
await scene . settled ( cmdBar )
} )
await test . step ( 'Verify standalone unassigned chamfer is deleted but piped chamfer is not (in the editor)' , async ( ) = > {
await editor . expectEditor . toContain ( secondPipedChamferDeclaration )
await editor . expectEditor . not . toContain (
standaloneUnassignedChamferDeclaration
2025-02-04 16:49:49 -05:00
)
} )
2025-05-10 18:53:05 +02:00
await test . step ( 'Verify standalone unassigned chamfer is deleted but piped is not (in the scene)' , async ( ) = > {
2025-02-04 16:49:49 -05:00
await scene . expectPixelColor (
edgeColorWhite ,
standaloneChamferEdgeLocation ,
lowTolerance
)
} )
2025-02-03 18:11:26 +01:00
} )
} )
2025-02-04 16:49:49 -05:00
} )
2025-02-03 18:11:26 +01:00
2025-02-04 16:49:49 -05:00
const shellPointAndClickCapCases = [
{ shouldPreselect : true } ,
{ shouldPreselect : false } ,
]
shellPointAndClickCapCases . forEach ( ( { shouldPreselect } ) = > {
test ( ` Shell point-and-click cap (preselected sketches: ${ shouldPreselect } ) ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
2025-03-31 10:56:03 -04:00
const initialCode = ` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( XZ )
2025-03-14 16:05:41 -04:00
| > circle ( center = [ 0 , 0 ] , radius = 30 )
extrude001 = extrude ( sketch001 , length = 30 )
2025-02-04 16:49:49 -05:00
`
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
2025-04-07 07:08:31 -04:00
2025-02-04 16:49:49 -05:00
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
2025-04-07 07:08:31 -04:00
2025-02-04 16:49:49 -05:00
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . connectionEstablished ( )
2025-02-04 16:49:49 -05:00
// One dumb hardcoded screen pixel value
const testPoint = { x : 575 , y : 200 }
const [ clickOnCap ] = scene . makeMouseHelpers ( testPoint . x , testPoint . y )
const shellDeclaration =
2025-04-14 20:37:45 +12:00
'shell001 = shell(extrude001, faces = [END], thickness = 5)'
2025-03-14 16:05:41 -04:00
const editedShellDeclaration =
2025-04-14 20:37:45 +12:00
'shell001 = shell(extrude001, faces = [END], thickness = 2)'
2025-02-04 16:49:49 -05:00
await test . step ( ` Look for the grey of the shape ` , async ( ) = > {
await scene . expectPixelColor ( [ 127 , 127 , 127 ] , testPoint , 15 )
2025-02-03 18:11:26 +01:00
} )
2025-02-04 16:49:49 -05:00
if ( ! shouldPreselect ) {
await test . step ( ` Go through the command bar flow without preselected faces ` , async ( ) = > {
await toolbar . shellButton . click ( )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Thickness : '' ,
} ,
highlightedHeaderArg : 'selection' ,
commandName : 'Shell' ,
} )
await clickOnCap ( )
await page . waitForTimeout ( 500 )
await cmdBar . progressCmdBar ( )
await page . waitForTimeout ( 500 )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Selection : '1 cap' ,
Thickness : '5' ,
} ,
commandName : 'Shell' ,
} )
await cmdBar . progressCmdBar ( )
} )
} else {
await test . step ( ` Preselect the cap ` , async ( ) = > {
await clickOnCap ( )
await page . waitForTimeout ( 500 )
} )
await test . step ( ` Go through the command bar flow with a preselected face (cap) ` , async ( ) = > {
await toolbar . shellButton . click ( )
await cmdBar . progressCmdBar ( )
2025-05-20 16:07:56 -04:00
await page . waitForTimeout ( 500 )
await cmdBar . progressCmdBar ( )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Selection : '1 cap' ,
Thickness : '5' ,
} ,
commandName : 'Shell' ,
} )
await cmdBar . progressCmdBar ( )
} )
}
await test . step ( ` Confirm code is added to the editor, scene has changed ` , async ( ) = > {
await editor . expectEditor . toContain ( shellDeclaration )
await editor . expectState ( {
diagnostics : [ ] ,
activeLines : [ shellDeclaration ] ,
highlightedCode : '' ,
} )
await scene . expectPixelColor ( [ 146 , 146 , 146 ] , testPoint , 15 )
2025-02-03 18:11:26 +01:00
} )
2025-03-14 16:05:41 -04:00
await test . step ( 'Edit shell via feature tree selection works' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
const operationButton = await toolbar . getFeatureTreeOperation (
'Shell' ,
0
)
await operationButton . dblclick ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'thickness' ,
currentArgValue : '5' ,
headerArguments : {
Thickness : '5' ,
} ,
highlightedHeaderArg : 'thickness' ,
commandName : 'Shell' ,
} )
await page . keyboard . insertText ( '2' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Thickness : '2' ,
} ,
commandName : 'Shell' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
await scene . expectPixelColor ( [ 150 , 150 , 150 ] , testPoint , 15 )
await editor . expectEditor . toContain ( editedShellDeclaration )
await editor . expectState ( {
diagnostics : [ ] ,
activeLines : [ editedShellDeclaration ] ,
highlightedCode : '' ,
} )
} )
2025-02-03 18:11:26 +01:00
} )
} )
2025-01-14 18:08:32 +01:00
2025-02-04 16:49:49 -05:00
test ( 'Shell point-and-click wall' , async ( {
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
context ,
page ,
homePage ,
2024-12-09 15:20:48 -05:00
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
2025-03-31 10:56:03 -04:00
const initialCode = ` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( XY )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 20 , 20 ] )
2025-03-07 22:07:16 -06:00
| > xLine ( length = 40 )
| > yLine ( length = - 60 )
| > xLine ( length = - 40 )
2025-02-04 16:49:49 -05:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
extrude001 = extrude ( sketch001 , length = 40 )
`
Move all tests over to electron (#4484)
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* One last try with window-16-cores
* Trigger CI
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Skip more win tests, add back all three oses
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores)
* Add two more fixmes
* 2 more fixmes
* skip segment overlays on win32
* Another fixme
* Trigger CI
* Trigger CI
* Quick clean up
* Move all tests over to electron
* Pass the correct param to playwright-electron.sh
* Add shebang to script and add macos-14-large as a target
* Get sketch-tests.spec.ts passing in electron
* Try out 4 workers
* Got testing-segment-overlays passing
* Pass testing-selections.spec.ts
* Go back to fix up sketch-tests test
* Pass various.spec.ts, by far the hardest one
* Pass can-sketch-on-all-planes... with ease
* Pass command bar tests
* fmt
* Completely fix code mirror text navigating for tests
* Pass debug pane tests
* Pass desktop export tests
* Pass editor tests
* Pass file tree tests
* Pass onboarding tests
* Corrected a fixme in file-tree.spec!
* Painfully fix hardcoded coordinates in point-click.spec
* Pass machine.spec tests
* Pass projects, fought hard with filechooser
* Pass regresion-tests.spec tests
* Pass network and connection tests
* Pass camera-movement.spec tests
* Extreme time eaten by gizmo test fixes. All passing now.
* Merge main (tests changed x_x) and pass all constraints.spec tests (pain)
* Pass another painful spec suite: testing-settings
* Pass perspective-toggle, interesting note
* Pass samples loading tests
* Pass app header tests
* Pass text-to-cad tests
* Pass segment-overlays (minor ache) and ability to switch to web if needed :)
* Fix a ton of syntax changes and deflake 2 more tests (pain)
* Correct all tsc errors
* Remove to-electron script
* Add an f-ton of shit because playwright doesnt want S P R E A D
* Try CI again
* Stop snapshots of exports (already test in e2e)
* Fix flake in double click editor
* Hopefully help CI flake
* Fixmes, fixmes everywhere
* One more fixme to settings
* Skip another code pane flake
* Port jess's projects.spec tests
* fixup
* Reuse electron window; difficult task
* Rebased and refixed
* Remove duplicate cases
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* Reduce the workers to something CI can handle
* Lower it further, we need to think about the others
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Update package.json
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Fix the last tests and tsc errors
* Timeout to 120 and windows-2022-16core
* Fix windows runner detection, enable concurrency temporarily
* Hopefully this time fix windows runner detection
* Comment out Vector, add back removed camera test code
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Fix camera tests again
* Massively deflake a whole class of tests
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large)
* Try new CI and fix small onboarding test
* Derp
* No github tuning
* Try mac
* Add back all the OS
* Lord, hallow be thy name
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores)
* Try AWS Windows runner
* Passing on windows locally with a few skips
* Trigger CI
* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)
* fmt, tsc, lint
* Enable two fixmes again
* Fix lint, codespell, fmt
* Fix lint
* Don't run e2e on draft, add back concurrency, clean up
* One last windows skip
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
2024-12-18 17:58:03 -05:00
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2024-12-09 15:20:48 -05:00
// One dumb hardcoded screen pixel value
2025-02-04 16:49:49 -05:00
const testPoint = { x : 580 , y : 180 }
2024-12-09 15:20:48 -05:00
const [ clickOnCap ] = scene . makeMouseHelpers ( testPoint . x , testPoint . y )
2025-02-04 16:49:49 -05:00
const [ clickOnWall ] = scene . makeMouseHelpers ( testPoint . x , testPoint . y + 70 )
2025-03-07 22:07:16 -06:00
const mutatedCode = 'xLine(length = -40, tag = $seg01)'
2024-12-09 15:20:48 -05:00
const shellDeclaration =
2025-04-14 20:37:45 +12:00
'shell001 = shell(extrude001, faces = [END, seg01], thickness = 5)'
2025-03-14 16:05:41 -04:00
const editedShellDeclaration =
2025-04-14 20:37:45 +12:00
'shell001 = shell(extrude001, faces = [END, seg01], thickness = 1)'
2024-12-09 15:20:48 -05:00
await test . step ( ` Look for the grey of the shape ` , async ( ) = > {
2025-02-04 16:49:49 -05:00
await scene . expectPixelColor ( [ 99 , 99 , 99 ] , testPoint , 15 )
} )
await test . step ( ` Go through the command bar flow, selecting a wall and keeping default thickness ` , async ( ) = > {
await toolbar . shellButton . click ( )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Thickness : '' ,
} ,
highlightedHeaderArg : 'selection' ,
commandName : 'Shell' ,
} )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2025-02-04 16:49:49 -05:00
await clickOnCap ( )
await page . keyboard . down ( 'Shift' )
await clickOnWall ( )
await page . waitForTimeout ( 500 )
await page . keyboard . up ( 'Shift' )
await cmdBar . progressCmdBar ( )
await page . waitForTimeout ( 500 )
await cmdBar . progressCmdBar ( )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 500 )
2025-02-04 16:49:49 -05:00
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Selection : '1 cap, 1 face' ,
Thickness : '5' ,
} ,
commandName : 'Shell' ,
} )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 500 )
2025-02-04 16:49:49 -05:00
await cmdBar . progressCmdBar ( )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 500 )
2025-02-04 16:49:49 -05:00
} )
await test . step ( ` Confirm code is added to the editor, scene has changed ` , async ( ) = > {
await editor . expectEditor . toContain ( mutatedCode )
await editor . expectEditor . toContain ( shellDeclaration )
await editor . expectState ( {
diagnostics : [ ] ,
2025-02-06 20:03:12 -06:00
activeLines : [ shellDeclaration ] ,
2025-02-04 16:49:49 -05:00
highlightedCode : '' ,
} )
await scene . expectPixelColor ( [ 49 , 49 , 49 ] , testPoint , 15 )
} )
2025-03-14 16:05:41 -04:00
await test . step ( 'Edit shell via feature tree selection works' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation ( 'Shell' , 0 )
await operationButton . dblclick ( { button : 'left' } )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'thickness' ,
currentArgValue : '5' ,
headerArguments : {
Thickness : '5' ,
} ,
highlightedHeaderArg : 'thickness' ,
commandName : 'Shell' ,
} )
await page . keyboard . insertText ( '1' )
await cmdBar . progressCmdBar ( )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 500 )
2025-03-14 16:05:41 -04:00
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Thickness : '1' ,
} ,
commandName : 'Shell' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
await scene . expectPixelColor ( [ 150 , 150 , 150 ] , testPoint , 15 )
await editor . expectEditor . toContain ( editedShellDeclaration )
await editor . expectState ( {
diagnostics : [ ] ,
activeLines : [ editedShellDeclaration ] ,
highlightedCode : '' ,
} )
} )
2025-02-04 16:49:49 -05:00
await test . step ( 'Delete shell via feature tree selection' , async ( ) = > {
await editor . closePane ( )
const operationButton = await toolbar . getFeatureTreeOperation ( 'Shell' , 0 )
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-02-04 16:49:49 -05:00
await scene . expectPixelColor ( [ 99 , 99 , 99 ] , testPoint , 15 )
2024-12-09 15:20:48 -05:00
} )
2025-02-04 16:49:49 -05:00
} )
const shellSketchOnFacesCases = [
2025-03-31 10:56:03 -04:00
` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( XZ )
2025-02-28 17:40:01 -08:00
| > circle ( center = [ 0 , 0 ] , radius = 100 )
2025-02-04 16:49:49 -05:00
| > extrude ( length = 100 )
2025-04-14 05:58:19 -04:00
sketch002 = startSketchOn ( sketch001 , face = 'END' )
2025-02-28 17:40:01 -08:00
| > circle ( center = [ 0 , 0 ] , radius = 50 )
2025-02-04 16:49:49 -05:00
| > extrude ( length = 50 )
` ,
2025-03-31 10:56:03 -04:00
` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( XZ )
2025-02-28 17:40:01 -08:00
| > circle ( center = [ 0 , 0 ] , radius = 100 )
2025-02-04 16:49:49 -05:00
extrude001 = extrude ( sketch001 , length = 100 )
2025-04-14 05:58:19 -04:00
sketch002 = startSketchOn ( extrude001 , face = 'END' )
2025-02-28 17:40:01 -08:00
| > circle ( center = [ 0 , 0 ] , radius = 50 )
2025-02-04 16:49:49 -05:00
extrude002 = extrude ( sketch002 , length = 50 )
` ,
]
shellSketchOnFacesCases . forEach ( ( initialCode , index ) = > {
const hasExtrudesInPipe = index === 0
test ( ` Shell point-and-click sketch on face (extrudes in pipes: ${ hasExtrudesInPipe } ) ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
2025-02-14 14:49:06 -06:00
await page . setBodyDimensions ( { width : 1200 , height : 500 } )
2025-02-04 16:49:49 -05:00
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
// One dumb hardcoded screen pixel value
2025-02-14 14:49:06 -06:00
const testPoint = { x : 580 , y : 320 }
2025-02-04 16:49:49 -05:00
const [ clickOnCap ] = scene . makeMouseHelpers ( testPoint . x , testPoint . y )
2025-02-06 20:03:12 -06:00
const shellTarget = hasExtrudesInPipe ? 'sketch002' : 'extrude002'
2025-04-14 20:37:45 +12:00
const shellDeclaration = ` shell001 = shell( ${ shellTarget } , faces = [END], thickness = 5) `
2025-02-04 16:49:49 -05:00
await test . step ( ` Look for the grey of the shape ` , async ( ) = > {
2025-02-14 14:49:06 -06:00
await scene . expectPixelColor ( [ 113 , 113 , 113 ] , testPoint , 15 )
2025-02-04 16:49:49 -05:00
} )
2024-12-09 15:20:48 -05:00
2025-02-04 16:49:49 -05:00
await test . step ( ` Go through the command bar flow, selecting a cap and keeping default thickness ` , async ( ) = > {
2024-12-09 15:20:48 -05:00
await toolbar . shellButton . click ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Thickness : '' ,
} ,
highlightedHeaderArg : 'selection' ,
commandName : 'Shell' ,
} )
2025-04-07 07:08:31 -04:00
await expect
. poll ( ( ) = > page . getByText ( 'Please select one' ) . count ( ) )
. toBe ( 1 )
2024-12-09 15:20:48 -05:00
await clickOnCap ( )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 1000 )
2024-12-09 15:20:48 -05:00
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Selection : '1 cap' ,
Thickness : '5' ,
} ,
commandName : 'Shell' ,
} )
await cmdBar . progressCmdBar ( )
} )
2025-02-04 16:49:49 -05:00
await test . step ( ` Confirm code is added to the editor, scene has changed ` , async ( ) = > {
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain ( shellDeclaration )
await editor . expectState ( {
diagnostics : [ ] ,
activeLines : [ shellDeclaration ] ,
highlightedCode : '' ,
} )
await toolbar . closePane ( 'code' )
2025-03-14 16:05:41 -04:00
await scene . expectPixelColor ( [ 80 , 80 , 80 ] , testPoint , 15 )
2024-12-09 15:20:48 -05:00
} )
} )
} )
2025-02-19 13:43:27 -05:00
const shellPointAndClickDeletionCases = [
{ shouldUseKeyboard : true } ,
{ shouldUseKeyboard : false } ,
]
shellPointAndClickDeletionCases . forEach ( ( { shouldUseKeyboard } ) = > {
test ( ` Shell point-and-click deletion (shouldUseKeyboard: ${ shouldUseKeyboard } ) ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
2025-03-21 22:39:12 +13:00
const sketchCode = ` sketch001 = startSketchOn(XY)
2025-04-25 16:01:35 -05:00
profile001 = startProfile ( sketch001 , at = [ - 20 , 20 ] )
2025-03-07 22:07:16 -06:00
| > xLine ( length = 40 )
| > yLine ( length = - 60 )
| > xLine ( length = - 40 )
2025-02-19 13:43:27 -05:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
`
const extrudeCode = ` extrude001 = extrude(profile001, length = 40)
`
2025-04-14 20:37:45 +12:00
const shellCode = ` shell001 = shell(extrude001, faces = [END], thickness = 5)
2025-02-19 13:43:27 -05:00
`
const initialCode = sketchCode + extrudeCode + shellCode
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-19 13:43:27 -05:00
await toolbar . openPane ( 'feature-tree' )
// One dumb hardcoded screen pixel value
const testPoint = { x : 590 , y : 400 }
const extrudeColor : [ number , number , number ] = [ 100 , 100 , 100 ]
const sketchColor : [ number , number , number ] = [ 140 , 140 , 140 ]
2025-05-01 12:42:44 -05:00
const defaultPlaneColor : [ number , number , number ] = [ 88 , 44 , 45 ]
2025-02-19 13:43:27 -05:00
const deleteOperation = async ( operationButton : Locator ) = > {
if ( shouldUseKeyboard ) {
await operationButton . click ( { button : 'left' } )
2025-02-25 09:41:25 -05:00
await page . keyboard . press ( 'Delete' )
2025-02-19 13:43:27 -05:00
} else {
await operationButton . click ( { button : 'right' } )
const editButton = page . getByTestId ( 'context-menu-delete' )
await editButton . click ( )
}
}
await test . step ( ` Look for the grey of the extrude shape ` , async ( ) = > {
await scene . expectPixelColor ( extrudeColor , testPoint , 20 )
} )
await test . step ( 'Delete shell and confirm deletion' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Shell' ,
0
)
await deleteOperation ( operationButton )
await scene . expectPixelColor ( extrudeColor , testPoint , 20 )
await editor . expectEditor . not . toContain ( shellCode )
} )
await test . step ( 'Delete extrude and confirm deletion' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Extrude' ,
0
)
await deleteOperation ( operationButton )
await editor . expectEditor . not . toContain ( extrudeCode )
await scene . expectPixelColor ( sketchColor , testPoint , 20 )
} )
await test . step ( 'Delete sketch and confirm empty scene' , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Sketch' ,
0
)
await deleteOperation ( operationButton )
await editor . expectEditor . toContain ( '' )
2025-05-01 12:42:44 -05:00
// Cannot use test point anymore because the camera's position has been
// reset and the rest of the test doesn't need to change just to check
// if the scene is cleared.
// Check that the scene is cleared
await scene . expectPixelColor ( defaultPlaneColor , { x : 574 , y : 342 } , 20 )
2025-02-19 13:43:27 -05:00
} )
} )
} )
2025-02-04 16:49:49 -05:00
test . describe ( 'Revolve point and click workflows' , ( ) = > {
test ( 'Base case workflow, auto spam continue in command bar' , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
const initialCode = `
2025-03-21 22:39:12 +13:00
sketch001 = startSketchOn ( XZ )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 100.0 , 100.0 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 0 , length = 200.0 , tag = $rectangleSegmentA001 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) - 90 , length = 200 , tag = $rectangleSegmentB001 )
| > angledLine (
angle = segAng ( rectangleSegmentA001 ) ,
length = - segLen ( rectangleSegmentA001 ) ,
tag = $rectangleSegmentC001 ,
)
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
extrude001 = extrude ( sketch001 , length = 200 )
2025-04-14 05:58:19 -04:00
sketch002 = startSketchOn ( extrude001 , face = rectangleSegmentA001 )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 66.77 , 84.81 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 180 , length = 27.08 , tag = $rectangleSegmentA002 )
| > angledLine (
angle = segAng ( rectangleSegmentA002 ) - 90 ,
length = 27.8 ,
tag = $rectangleSegmentB002 ,
)
| > angledLine (
angle = segAng ( rectangleSegmentA002 ) ,
length = - segLen ( rectangleSegmentA002 ) ,
tag = $rectangleSegmentC002 ,
)
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
2025-02-01 06:02:43 -05:00
`
2025-02-04 16:49:49 -05:00
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
// select line of code
2025-05-19 11:21:29 -04:00
const codeToSelection = ` startProfile(at = [-66.77, 84.81]) `
2025-02-04 16:49:49 -05:00
// revolve
2025-04-07 07:08:31 -04:00
await editor . scrollToText ( codeToSelection )
await page . getByText ( codeToSelection ) . click ( )
2025-02-04 16:49:49 -05:00
await toolbar . revolveButton . click ( )
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
2025-05-20 16:07:56 -04:00
await cmdBar . progressCmdBar ( )
2025-02-01 06:02:43 -05:00
2025-04-03 22:44:52 +13:00
const newCodeToFind = ` revolve001 = revolve(sketch002, angle = 360, axis = X) `
2025-02-04 16:49:49 -05:00
expect ( editor . expectEditor . toContain ( newCodeToFind ) ) . toBeTruthy ( )
2025-03-31 18:13:34 -04:00
// Edit flow
const newAngle = '90'
await toolbar . openPane ( 'feature-tree' )
const operationButton = await toolbar . getFeatureTreeOperation (
'Revolve' ,
0
)
await operationButton . dblclick ( { button : 'left' } )
await cmdBar . expectState ( {
commandName : 'Revolve' ,
currentArgKey : 'angle' ,
currentArgValue : '360' ,
headerArguments : {
Angle : '360' ,
} ,
highlightedHeaderArg : 'angle' ,
stage : 'arguments' ,
} )
await page . keyboard . insertText ( newAngle )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Angle : newAngle ,
} ,
commandName : 'Revolve' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
await editor . expectEditor . toContain (
newCodeToFind . replace ( 'angle = 360' , 'angle = ' + newAngle )
)
2025-02-04 16:49:49 -05:00
} )
test ( 'revolve surface around edge from an extruded solid2d' , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
2025-03-31 18:13:34 -04:00
const initialCode = ` sketch001 = startSketchOn(XZ)
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 102.57 , 101.72 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 0 , length = 202.6 , tag = $rectangleSegmentA001 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) - 90 , length = 202.6 , tag = $rectangleSegmentB001 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) , length = - segLen ( rectangleSegmentA001 ) , tag = $rectangleSegmentC001 )
2025-03-31 18:13:34 -04:00
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
extrude001 = extrude ( sketch001 , length = 50 )
2025-04-14 05:58:19 -04:00
sketch002 = startSketchOn ( extrude001 , face = rectangleSegmentA001 )
2025-03-31 18:13:34 -04:00
| > circle ( center = [ - 11.34 , 10.0 ] , radius = 8.69 )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
2025-02-01 06:02:43 -05:00
`
2025-02-04 16:49:49 -05:00
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . connectionEstablished ( )
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
// select line of code
2025-04-07 07:08:31 -04:00
const codeToSelection = ` center = [-11.34, 10.0] `
2025-02-04 16:49:49 -05:00
// revolve
2025-04-07 07:08:31 -04:00
await editor . scrollToText ( codeToSelection )
await page . getByText ( codeToSelection ) . click ( )
2025-02-04 16:49:49 -05:00
await toolbar . revolveButton . click ( )
2025-05-06 17:57:27 -04:00
await cmdBar . progressCmdBar ( )
2025-02-04 16:49:49 -05:00
await page . getByText ( 'Edge' , { exact : true } ) . click ( )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
const lineCodeToSelection = ` angledLine(angle = 0, length = 202.6, tag = $ rectangleSegmentA001) `
2025-02-04 16:49:49 -05:00
await page . getByText ( lineCodeToSelection ) . click ( )
await cmdBar . progressCmdBar ( )
2025-03-31 18:13:34 -04:00
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
2025-02-01 06:02:43 -05:00
2025-03-31 18:13:34 -04:00
const newCodeToFind = ` revolve001 = revolve(sketch002, angle = 360, axis = rectangleSegmentA001) `
await editor . expectEditor . toContain ( newCodeToFind )
// Edit flow
const newAngle = '180'
await toolbar . openPane ( 'feature-tree' )
const operationButton = await toolbar . getFeatureTreeOperation (
'Revolve' ,
0
)
await operationButton . dblclick ( { button : 'left' } )
await cmdBar . expectState ( {
commandName : 'Revolve' ,
currentArgKey : 'angle' ,
currentArgValue : '360' ,
headerArguments : {
Angle : '360' ,
} ,
highlightedHeaderArg : 'angle' ,
stage : 'arguments' ,
} )
await page . keyboard . insertText ( newAngle )
2025-06-12 10:58:07 -04:00
await cmdBar . variableCheckbox . click ( )
2025-03-31 18:13:34 -04:00
await expect ( page . getByPlaceholder ( 'Variable name' ) ) . toHaveValue (
'angle001'
)
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Angle : newAngle ,
} ,
commandName : 'Revolve' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
await editor . expectEditor . toContain ( 'angle001 = ' + newAngle )
await editor . expectEditor . toContain (
newCodeToFind . replace ( 'angle = 360' , 'angle = angle001' )
)
2025-04-07 07:08:31 -04:00
expect ( editor . expectEditor . toContain ( newCodeToFind ) ) . toBeTruthy ( )
2025-02-04 16:49:49 -05:00
} )
test ( 'revolve sketch circle around line segment from startProfileAt sketch' , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
const initialCode = `
sketch002 = startSketchOn ( XY )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 2.02 , 1.79 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > xLine ( length = 2.6 )
2025-04-30 17:13:11 +12:00
sketch001 = startSketchOn ( - XY )
2025-04-25 16:01:35 -05:00
| > startProfile ( at = [ - 0.48 , 1.25 ] )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > angledLine ( angle = 0 , length = 2.38 , tag = $rectangleSegmentA001 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) - 90 , length = 2.4 , tag = $rectangleSegmentB001 )
| > angledLine ( angle = segAng ( rectangleSegmentA001 ) , length = - segLen ( rectangleSegmentA001 ) , tag = $rectangleSegmentC001 )
| > line ( endAbsolute = [ profileStartX ( % ) , profileStartY ( % ) ] )
| > close ( )
extrude001 = extrude ( sketch001 , length = 5 )
2025-04-14 05:58:19 -04:00
sketch003 = startSketchOn ( extrude001 , face = 'START' )
KCL: Angled line should use keyword args (#5803)
We continue migrating KCL stdlib functions to use keyword arguments. Next up is the `angledLine` family of functions (except `angledLineThatIntersects, which will be a quick follow-up).
Before vs. after:
`angledLine({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, length = 3, tag = $edge)`
`angledLineOfXLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthX = 3, tag = $edge)`
`angledLineOfYLength({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, lengthY = 3, tag = $edge)`
`angledLineToX({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteX = 3, tag = $edge)`
`angledLineToY({angle = 90, length = 3}, %, $edge)`
=> `angledLine(angle = 90, endAbsoluteY = 3, tag = $edge)`
2025-04-09 14:55:15 -05:00
| > circle (
center = [ - 0.69 , 0.56 ] ,
radius = 0.28
)
2025-02-01 06:02:43 -05:00
`
2025-02-04 16:49:49 -05:00
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . connectionEstablished ( )
await scene . settled ( cmdBar )
2025-02-04 16:49:49 -05:00
// select line of code
2025-04-07 07:08:31 -04:00
const codeToSelection = ` center = [-0.69, 0.56] `
2025-02-04 16:49:49 -05:00
// revolve
await toolbar . revolveButton . click ( )
2025-04-07 07:08:31 -04:00
await page . waitForTimeout ( 1000 )
await editor . scrollToText ( codeToSelection )
await page . getByText ( codeToSelection ) . click ( )
2025-05-06 17:57:27 -04:00
await cmdBar . progressCmdBar ( )
2025-04-07 07:08:31 -04:00
await expect . poll ( ( ) = > page . getByText ( 'AxisOrEdge' ) . count ( ) ) . toBe ( 2 )
2025-02-04 16:49:49 -05:00
await page . getByText ( 'Edge' , { exact : true } ) . click ( )
2025-04-07 07:08:31 -04:00
const lineCodeToSelection = ` length = 2.6 `
await editor . scrollToText ( lineCodeToSelection )
2025-02-04 16:49:49 -05:00
await page . getByText ( lineCodeToSelection ) . click ( )
await cmdBar . progressCmdBar ( )
2025-03-31 18:13:34 -04:00
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
2025-02-01 06:02:43 -05:00
2025-03-18 20:34:44 -07:00
const newCodeToFind = ` revolve001 = revolve(sketch003, angle = 360, axis = seg01) `
2025-02-04 16:49:49 -05:00
expect ( editor . expectEditor . toContain ( newCodeToFind ) ) . toBeTruthy ( )
2025-03-31 18:13:34 -04:00
// Edit flow
const newAngle = '270'
2025-06-24 15:45:16 -04:00
const newAngle2 = '5'
const editedCodeToFind = ` revolve001 = revolve(sketch003, angle = ${ newAngle } , axis = seg01, bidirectionalAngle = ${ newAngle2 } , ) `
2025-03-31 18:13:34 -04:00
await toolbar . openPane ( 'feature-tree' )
const operationButton = await toolbar . getFeatureTreeOperation (
'Revolve' ,
0
)
await operationButton . dblclick ( { button : 'left' } )
await cmdBar . expectState ( {
commandName : 'Revolve' ,
currentArgKey : 'angle' ,
currentArgValue : '360' ,
headerArguments : {
Angle : '360' ,
} ,
highlightedHeaderArg : 'angle' ,
stage : 'arguments' ,
} )
await page . keyboard . insertText ( newAngle )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Angle : newAngle ,
} ,
commandName : 'Revolve' ,
} )
2025-06-24 15:45:16 -04:00
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 )
2025-03-31 18:13:34 -04:00
await cmdBar . progressCmdBar ( )
2025-06-24 15:45:16 -04:00
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Angle : newAngle ,
BidirectionalAngle : newAngle2 ,
} ,
commandName : 'Revolve' ,
} )
await cmdBar . submit ( )
2025-03-31 18:13:34 -04:00
await toolbar . closePane ( 'feature-tree' )
2025-06-24 15:45:16 -04:00
await editor . expectEditor . toContain ( editedCodeToFind , {
shouldNormalise : true ,
} )
2025-02-04 16:49:49 -05:00
} )
2025-02-01 06:02:43 -05:00
} )
2025-02-22 08:09:54 -05:00
test ( ` Set appearance ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
2025-03-31 10:56:03 -04:00
const initialCode = ` @settings(defaultLengthUnit = in)
sketch001 = startSketchOn ( XZ )
2025-02-28 17:40:01 -08:00
profile001 = circle (
sketch001 ,
2025-02-22 08:09:54 -05:00
center = [ 0 , 0 ] ,
radius = 100
2025-02-28 17:40:01 -08:00
)
2025-02-22 08:09:54 -05:00
extrude001 = extrude ( profile001 , length = 100 )
`
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , initialCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
2025-04-07 07:08:31 -04:00
await scene . settled ( cmdBar )
2025-02-22 08:09:54 -05:00
// One dumb hardcoded screen pixel value
const testPoint = { x : 500 , y : 250 }
2025-02-28 15:37:25 -06:00
const initialColor : [ number , number , number ] = [ 123 , 123 , 123 ]
2025-04-07 07:08:31 -04:00
const tolerance = 50
2025-02-22 08:09:54 -05:00
await test . step ( ` Confirm extrude exists with default appearance ` , async ( ) = > {
await toolbar . closePane ( 'code' )
2025-04-07 07:08:31 -04:00
await scene . expectPixelColor ( initialColor , testPoint , tolerance )
2025-02-22 08:09:54 -05:00
} )
2025-05-07 12:48:23 -05:00
async function setAppearanceAndCheck (
2025-02-22 08:09:54 -05:00
option : string ,
hex : string ,
2025-04-07 07:08:31 -04:00
shapeColor ? : [ number , number , number ]
2025-02-22 08:09:54 -05:00
) {
await toolbar . openPane ( 'feature-tree' )
2025-02-28 18:00:29 -05:00
const enterAppearanceFlow = async ( stepName : string ) = >
test . step ( stepName , async ( ) = > {
const operationButton = await toolbar . getFeatureTreeOperation (
'Extrude' ,
0
)
await operationButton . click ( { button : 'right' } )
const menuButton = page . getByTestId ( 'context-menu-set-appearance' )
await menuButton . click ( )
await cmdBar . expectState ( {
commandName : 'Appearance' ,
currentArgKey : 'color' ,
currentArgValue : '' ,
headerArguments : {
Color : '' ,
} ,
highlightedHeaderArg : 'color' ,
stage : 'arguments' ,
} )
} )
await enterAppearanceFlow ( ` Open Set Appearance flow ` )
await test . step ( ` Validate hidden argument "nodeToEdit" can't be reached with Backspace ` , async ( ) = > {
2025-03-05 17:57:47 -05:00
await page . keyboard . press ( 'Shift+Backspace' )
2025-02-28 18:00:29 -05:00
await cmdBar . expectState ( {
stage : 'pickCommand' ,
} )
await page . keyboard . press ( 'Escape' )
await cmdBar . expectState ( {
stage : 'commandBarClosed' ,
} )
2025-02-22 08:09:54 -05:00
} )
2025-02-28 18:00:29 -05:00
await enterAppearanceFlow ( ` Restart Appearance flow ` )
2025-02-22 08:09:54 -05:00
const item = page . getByText ( option , { exact : true } )
await item . click ( )
await cmdBar . expectState ( {
commandName : 'Appearance' ,
headerArguments : {
Color : hex ,
} ,
stage : 'review' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
2025-04-07 07:08:31 -04:00
if ( shapeColor ) {
await scene . expectPixelColor ( shapeColor , testPoint , tolerance )
}
2025-02-22 08:09:54 -05:00
await toolbar . openPane ( 'code' )
if ( hex === 'default' ) {
const anyAppearanceDeclaration = ` |> appearance( `
await editor . expectEditor . not . toContain ( anyAppearanceDeclaration )
} else {
const declaration = ` |> appearance(%, color = ' ${ hex } ') `
await editor . expectEditor . toContain ( declaration )
// TODO: fix selection range after appearance update
// await editor.expectState({
// diagnostics: [],
// activeLines: [declaration],
// highlightedCode: '',
// })
}
await toolbar . closePane ( 'code' )
}
await test . step ( ` Go through the Set Appearance flow for all options ` , async ( ) = > {
2025-05-07 12:48:23 -05:00
await setAppearanceAndCheck ( 'Red' , '#FF0000' , [ 180 , 30 , 30 ] )
2025-04-07 07:08:31 -04:00
// Not checking the scene color every time cause that's not really deterministic. Red seems reliable though
2025-05-07 12:48:23 -05:00
await setAppearanceAndCheck ( 'Green' , '#00FF00' )
await setAppearanceAndCheck ( 'Blue' , '#0000FF' )
await setAppearanceAndCheck ( 'Turquoise' , '#00FFFF' )
await setAppearanceAndCheck ( 'Purple' , '#FF00FF' )
await setAppearanceAndCheck ( 'Yellow' , '#FFFF00' )
await setAppearanceAndCheck ( 'Black' , '#000000' )
await setAppearanceAndCheck ( 'Dark Grey' , '#080808' )
await setAppearanceAndCheck ( 'Light Grey' , '#D3D3D3' )
await setAppearanceAndCheck ( 'White' , '#FFFFFF' )
await setAppearanceAndCheck (
2025-02-22 08:09:54 -05:00
'Default (clear appearance)' ,
'default' ,
initialColor
)
} )
} )
2025-04-17 11:44:31 -04:00
const translateExtrudeCases : { variables : boolean } [ ] = [
{
variables : false ,
} ,
{
variables : true ,
} ,
]
translateExtrudeCases . map ( ( { variables } ) = > {
test ( ` Set translate on extrude through right-click menu (variables: ${ variables } ) ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
const initialCode = ` sketch001 = startSketchOn(XZ)
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
`
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 midPoint = { x : 500 , y : 250 }
const moreToTheRightPoint = { x : 800 , y : 250 }
const bgColor : [ number , number , number ] = [ 50 , 50 , 50 ]
const partColor : [ number , number , number ] = [ 150 , 150 , 150 ]
const tolerance = 50
await test . step ( 'Confirm extrude exists with default appearance' , async ( ) = > {
await toolbar . closePane ( 'code' )
await scene . expectPixelColor ( partColor , midPoint , tolerance )
await scene . expectPixelColor ( bgColor , moreToTheRightPoint , tolerance )
} )
await test . step ( 'Set translate through command bar flow' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
const op = await toolbar . getFeatureTreeOperation ( 'Extrude' , 0 )
await op . click ( { button : 'right' } )
await page . getByTestId ( 'context-menu-set-translate' ) . click ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'x' ,
currentArgValue : '0' ,
headerArguments : {
X : '' ,
Y : '' ,
Z : '' ,
} ,
highlightedHeaderArg : 'x' ,
commandName : 'Translate' ,
} )
await page . keyboard . insertText ( '3' )
if ( variables ) {
await cmdBar . createNewVariable ( )
}
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '0.1' )
if ( variables ) {
await cmdBar . createNewVariable ( )
}
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '0.2' )
if ( variables ) {
await cmdBar . createNewVariable ( )
}
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
X : '3' ,
Y : '0.1' ,
Z : '0.2' ,
} ,
commandName : 'Translate' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
} )
await test . step ( 'Confirm code and scene have changed' , async ( ) = > {
await toolbar . openPane ( 'code' )
if ( variables ) {
await editor . expectEditor . toContain (
`
z001 = 0.2
y001 = 0.1
x001 = 3
sketch001 = startSketchOn ( XZ )
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
| > translate ( x = x001 , y = y001 , z = z001 )
` ,
{ shouldNormalise : true }
)
} else {
await editor . expectEditor . toContain (
`
sketch001 = startSketchOn ( XZ )
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
| > translate ( x = 3 , y = 0.1 , z = 0.2 )
` ,
{ shouldNormalise : true }
)
}
await scene . expectPixelColor ( bgColor , midPoint , tolerance )
await scene . expectPixelColor ( partColor , moreToTheRightPoint , tolerance )
} )
await test . step ( 'Edit translate' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
const op = await toolbar . getFeatureTreeOperation ( 'Extrude' , 0 )
await op . click ( { button : 'right' } )
await page . getByTestId ( 'context-menu-set-translate' ) . click ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'z' ,
currentArgValue : variables ? 'z001' : '0.2' ,
headerArguments : {
X : '3' ,
Y : '0.1' ,
Z : '0.2' ,
} ,
highlightedHeaderArg : 'z' ,
commandName : 'Translate' ,
} )
await page . keyboard . insertText ( '0.3' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
X : '3' ,
Y : '0.1' ,
Z : '0.3' ,
} ,
commandName : 'Translate' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain ( ` z = 0.3 ` )
// Expect almost no change in scene
await scene . expectPixelColor ( bgColor , midPoint , tolerance )
await scene . expectPixelColor ( partColor , moreToTheRightPoint , tolerance )
} )
} )
} )
const rotateExtrudeCases : { variables : boolean } [ ] = [
{
variables : false ,
} ,
{
variables : true ,
} ,
]
rotateExtrudeCases . map ( ( { variables } ) = > {
test ( ` Set rotate on extrude through right-click menu (variables: ${ variables } ) ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
const initialCode = ` sketch001 = startSketchOn(XZ)
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
`
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 ( 'Set rotate through command bar flow' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
const op = await toolbar . getFeatureTreeOperation ( 'Extrude' , 0 )
await op . click ( { button : 'right' } )
await page . getByTestId ( 'context-menu-set-rotate' ) . click ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'roll' ,
currentArgValue : '0' ,
headerArguments : {
Roll : '' ,
Pitch : '' ,
Yaw : '' ,
} ,
highlightedHeaderArg : 'roll' ,
commandName : 'Rotate' ,
} )
await page . keyboard . insertText ( '1.1' )
if ( variables ) {
await cmdBar . createNewVariable ( )
}
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '1.2' )
if ( variables ) {
await cmdBar . createNewVariable ( )
}
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '1.3' )
if ( variables ) {
await cmdBar . createNewVariable ( )
}
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Roll : '1.1' ,
Pitch : '1.2' ,
Yaw : '1.3' ,
} ,
commandName : 'Rotate' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
} )
await test . step ( 'Confirm code and scene have changed' , async ( ) = > {
await toolbar . openPane ( 'code' )
if ( variables ) {
await editor . expectEditor . toContain (
`
yaw001 = 1.3
pitch001 = 1.2
roll001 = 1.1
sketch001 = startSketchOn ( XZ )
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
| > rotate ( roll = roll001 , pitch = pitch001 , yaw = yaw001 )
` ,
{ shouldNormalise : true }
)
} else {
await editor . expectEditor . toContain (
`
sketch001 = startSketchOn ( XZ )
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
| > rotate ( roll = 1.1 , pitch = 1.2 , yaw = 1.3 )
` ,
{ shouldNormalise : true }
)
}
} )
await test . step ( 'Edit rotate' , async ( ) = > {
await toolbar . openPane ( 'feature-tree' )
const op = await toolbar . getFeatureTreeOperation ( 'Extrude' , 0 )
await op . click ( { button : 'right' } )
await page . getByTestId ( 'context-menu-set-rotate' ) . click ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'yaw' ,
currentArgValue : variables ? 'yaw001' : '1.3' ,
headerArguments : {
Roll : '1.1' ,
Pitch : '1.2' ,
Yaw : '1.3' ,
} ,
highlightedHeaderArg : 'yaw' ,
commandName : 'Rotate' ,
} )
await page . keyboard . insertText ( '13' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Roll : '1.1' ,
Pitch : '1.2' ,
Yaw : '13' ,
} ,
commandName : 'Rotate' ,
} )
await cmdBar . progressCmdBar ( )
await toolbar . closePane ( 'feature-tree' )
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain ( ` yaw = 13 ` )
} )
} )
} )
test ( ` Set translate and rotate on extrude through selection ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
const initialCode = ` sketch001 = startSketchOn(XZ)
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
`
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 midPoint = { x : 500 , y : 250 }
const moreToTheRightPoint = { x : 800 , y : 250 }
const bgColor : [ number , number , number ] = [ 50 , 50 , 50 ]
const partColor : [ number , number , number ] = [ 150 , 150 , 150 ]
const tolerance = 50
const [ clickMidPoint ] = scene . makeMouseHelpers ( midPoint . x , midPoint . y )
const [ clickMoreToTheRightPoint ] = scene . makeMouseHelpers (
moreToTheRightPoint . x ,
moreToTheRightPoint . y
)
await test . step ( 'Confirm extrude exists with default appearance' , async ( ) = > {
await toolbar . closePane ( 'code' )
await scene . expectPixelColor ( partColor , midPoint , tolerance )
await scene . expectPixelColor ( bgColor , moreToTheRightPoint , tolerance )
} )
await test . step ( 'Set translate through command bar flow' , async ( ) = > {
await cmdBar . openCmdBar ( )
await cmdBar . chooseCommand ( 'Translate' )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
X : '' ,
Y : '' ,
Z : '' ,
} ,
highlightedHeaderArg : 'selection' ,
commandName : 'Translate' ,
} )
await clickMidPoint ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'x' ,
currentArgValue : '0' ,
headerArguments : {
Selection : '1 path' ,
X : '' ,
Y : '' ,
Z : '' ,
} ,
highlightedHeaderArg : 'x' ,
commandName : 'Translate' ,
} )
await page . keyboard . insertText ( '2' )
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Selection : '1 path' ,
X : '2' ,
Y : '0' ,
Z : '0' ,
} ,
commandName : 'Translate' ,
} )
await cmdBar . progressCmdBar ( )
} )
await test . step ( 'Confirm code and scene have changed' , async ( ) = > {
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain (
`
sketch001 = startSketchOn ( XZ )
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
| > translate ( x = 2 , y = 0 , z = 0 )
` ,
{ shouldNormalise : true }
)
await scene . expectPixelColor ( bgColor , midPoint , tolerance )
await scene . expectPixelColor ( partColor , moreToTheRightPoint , tolerance )
} )
await test . step ( 'Set rotate through command bar flow' , async ( ) = > {
// clear selection
await clickMidPoint ( )
await cmdBar . openCmdBar ( )
await cmdBar . chooseCommand ( 'Rotate' )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
Roll : '' ,
Pitch : '' ,
Yaw : '' ,
} ,
highlightedHeaderArg : 'selection' ,
commandName : 'Rotate' ,
} )
await clickMoreToTheRightPoint ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'roll' ,
currentArgValue : '0' ,
headerArguments : {
Selection : '1 path' ,
Roll : '' ,
Pitch : '' ,
Yaw : '' ,
} ,
highlightedHeaderArg : 'roll' ,
commandName : 'Rotate' ,
} )
await page . keyboard . insertText ( '0.1' )
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '0.2' )
await cmdBar . progressCmdBar ( )
await page . keyboard . insertText ( '0.3' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Selection : '1 path' ,
Roll : '0.1' ,
Pitch : '0.2' ,
Yaw : '0.3' ,
} ,
commandName : 'Rotate' ,
} )
await cmdBar . progressCmdBar ( )
} )
await test . step ( 'Confirm code has changed' , async ( ) = > {
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain (
`
sketch001 = startSketchOn ( XZ )
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
| > translate ( x = 2 , y = 0 , z = 0 )
| > rotate ( roll = 0.1 , pitch = 0.2 , yaw = 0.3 )
` ,
{ shouldNormalise : true }
)
// No change here since the angles are super small
await scene . expectPixelColor ( bgColor , midPoint , tolerance )
await scene . expectPixelColor ( partColor , moreToTheRightPoint , tolerance )
} )
} )
2025-04-26 18:26:39 -04:00
test ( 'Point-and-click Clone extrude through selection' , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
const initialCode = ` sketch001 = startSketchOn(XZ)
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
`
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 midPoint = { x : 500 , y : 250 }
const [ clickMidPoint ] = scene . makeMouseHelpers ( midPoint . x , midPoint . y )
await test . step ( 'Clone through command bar flow' , async ( ) = > {
await toolbar . closePane ( 'code' )
await cmdBar . openCmdBar ( )
await cmdBar . chooseCommand ( 'Clone a solid or sketch' )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'selection' ,
currentArgValue : '' ,
headerArguments : {
Selection : '' ,
VariableName : '' ,
} ,
highlightedHeaderArg : 'selection' ,
commandName : 'Clone' ,
} )
await clickMidPoint ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'variableName' ,
currentArgValue : '' ,
headerArguments : {
Selection : '1 path' ,
VariableName : '' ,
} ,
highlightedHeaderArg : 'variableName' ,
commandName : 'Clone' ,
} )
await page . keyboard . insertText ( 'yoyoyo' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
Selection : '1 path' ,
VariableName : 'yoyoyo' ,
} ,
commandName : 'Clone' ,
} )
await cmdBar . progressCmdBar ( )
// Expect changes
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain (
`
sketch001 = startSketchOn ( XZ )
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 , length = 1 )
yoyoyo = clone ( extrude001 )
` ,
{ shouldNormalise : true }
)
} )
} )
2025-05-06 17:57:27 -04:00
const multiProfileSweepsCode = ` sketch001 = startSketchOn(XY)
profile001 = circle ( sketch001 , center = [ 3 , 0 ] , radius = 1 )
profile002 = circle ( sketch001 , center = [ 6 , 0 ] , radius = 1 )
path001 = startProfile ( sketch001 , at = [ 0 , 0 ] )
| > yLine ( length = 2 )
`
const profile001Point = { x : 470 , y : 270 }
const profile002Point = { x : 670 , y : 270 }
test ( 'Point-and-click multi-profile sweeps: extrude' , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , multiProfileSweepsCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await scene . settled ( cmdBar )
await test . step ( 'Select through scene' , async ( ) = > {
// Unfortunately can't select thru code for multi profile yet
const [ clickProfile001Point ] = scene . makeMouseHelpers (
profile001Point . x ,
profile001Point . y
)
const [ clickProfile002Point ] = scene . makeMouseHelpers (
profile002Point . x ,
profile002Point . y
)
await toolbar . closePane ( 'code' )
await clickProfile001Point ( )
await page . keyboard . down ( 'Shift' )
await clickProfile002Point ( )
await page . waitForTimeout ( 500 )
await page . keyboard . up ( 'Shift' )
} )
await test . step ( 'Go through command bar flow' , async ( ) = > {
await toolbar . extrudeButton . click ( )
2025-05-20 16:07:56 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'sketches' ,
currentArgValue : '' ,
headerArguments : {
Profiles : '' ,
Length : '' ,
} ,
highlightedHeaderArg : 'Profiles' ,
commandName : 'Extrude' ,
} )
await cmdBar . progressCmdBar ( )
2025-05-06 17:57:27 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'length' ,
currentArgValue : '5' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '2 profiles' ,
2025-05-06 17:57:27 -04:00
Length : '' ,
} ,
highlightedHeaderArg : 'length' ,
commandName : 'Extrude' ,
} )
await page . keyboard . insertText ( '1' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '2 profiles' ,
2025-05-06 17:57:27 -04:00
Length : '1' ,
} ,
commandName : 'Extrude' ,
} )
await cmdBar . progressCmdBar ( )
await scene . settled ( cmdBar )
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain (
` extrude001 = extrude([profile001, profile002], length = 1) ` ,
{ shouldNormalise : true }
)
await editor . closePane ( )
} )
await test . step ( 'Delete extrude via feature tree selection' , async ( ) = > {
const op = await toolbar . getFeatureTreeOperation ( 'Extrude' , 0 )
await op . click ( { button : 'right' } )
await page . getByTestId ( 'context-menu-delete' ) . click ( )
await scene . settled ( cmdBar )
await toolbar . closePane ( 'feature-tree' )
await toolbar . openPane ( 'code' )
await editor . expectEditor . not . toContain (
` extrude001 = extrude([profile001, profile002], length = 1) ` ,
{ shouldNormalise : true }
)
} )
} )
test ( 'Point-and-click multi-profile sweeps: sweep' , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , multiProfileSweepsCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await scene . settled ( cmdBar )
await test . step ( 'Select through scene' , async ( ) = > {
// Unfortunately can't select thru code for multi profile yet
const [ clickProfile001Point ] = scene . makeMouseHelpers (
profile001Point . x ,
profile001Point . y
)
const [ clickProfile002Point ] = scene . makeMouseHelpers (
profile002Point . x ,
profile002Point . y
)
await toolbar . closePane ( 'code' )
await clickProfile001Point ( )
await page . keyboard . down ( 'Shift' )
await clickProfile002Point ( )
await page . waitForTimeout ( 500 )
await page . keyboard . up ( 'Shift' )
} )
await test . step ( 'Go through command bar flow' , async ( ) = > {
await toolbar . sweepButton . click ( )
2025-05-20 16:07:56 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'sketches' ,
currentArgValue : '' ,
headerArguments : {
Profiles : '' ,
Path : '' ,
} ,
highlightedHeaderArg : 'Profiles' ,
commandName : 'Sweep' ,
} )
await cmdBar . progressCmdBar ( )
2025-05-06 17:57:27 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'path' ,
currentArgValue : '' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '2 profiles' ,
2025-05-06 17:57:27 -04:00
Path : '' ,
} ,
highlightedHeaderArg : 'path' ,
commandName : 'Sweep' ,
} )
await toolbar . openPane ( 'code' )
await page . getByText ( 'yLine(length = 2)' ) . click ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '2 profiles' ,
2025-05-06 17:57:27 -04:00
Path : '1 segment' ,
} ,
commandName : 'Sweep' ,
} )
await cmdBar . progressCmdBar ( )
await scene . settled ( cmdBar )
await toolbar . openPane ( 'code' )
await editor . expectEditor . toContain (
` sweep001 = sweep([profile001, profile002], path = path001) ` ,
{ shouldNormalise : true }
)
} )
await test . step ( 'Delete sweep via feature tree selection' , async ( ) = > {
await editor . closePane ( )
const op = await toolbar . getFeatureTreeOperation ( 'Sweep' , 0 )
await op . click ( { button : 'right' } )
await page . getByTestId ( 'context-menu-delete' ) . click ( )
await scene . settled ( cmdBar )
await editor . expectEditor . not . toContain (
` sweep001 = sweep([profile001, profile002], path = path001) ` ,
{ shouldNormalise : true }
)
} )
} )
test ( 'Point-and-click multi-profile sweeps: revolve' , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , multiProfileSweepsCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await scene . settled ( cmdBar )
await test . step ( 'Select through scene' , async ( ) = > {
// Unfortunately can't select thru code for multi profile yet
const [ clickProfile001Point ] = scene . makeMouseHelpers (
profile001Point . x ,
profile001Point . y
)
const [ clickProfile002Point ] = scene . makeMouseHelpers (
profile002Point . x ,
profile002Point . y
)
await toolbar . closePane ( 'code' )
await clickProfile001Point ( )
await page . keyboard . down ( 'Shift' )
await clickProfile002Point ( )
await page . waitForTimeout ( 500 )
await page . keyboard . up ( 'Shift' )
} )
await test . step ( 'Go through command bar flow' , async ( ) = > {
await toolbar . closePane ( 'code' )
await toolbar . revolveButton . click ( )
2025-05-20 16:07:56 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'sketches' ,
currentArgValue : '' ,
headerArguments : {
Profiles : '' ,
AxisOrEdge : '' ,
Angle : '' ,
} ,
highlightedHeaderArg : 'Profiles' ,
commandName : 'Revolve' ,
} )
await cmdBar . progressCmdBar ( )
2025-05-06 17:57:27 -04:00
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'axisOrEdge' ,
currentArgValue : '' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '2 profiles' ,
2025-05-06 17:57:27 -04:00
AxisOrEdge : '' ,
Angle : '' ,
} ,
highlightedHeaderArg : 'axisOrEdge' ,
commandName : 'Revolve' ,
} )
await cmdBar . selectOption ( { name : 'Edge' } ) . click ( )
await toolbar . openPane ( 'code' )
await page . getByText ( 'yLine(length = 2)' ) . click ( )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'arguments' ,
currentArgKey : 'angle' ,
currentArgValue : '360' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '2 profiles' ,
2025-05-06 17:57:27 -04:00
AxisOrEdge : 'Edge' ,
Edge : '1 segment' ,
Angle : '' ,
} ,
highlightedHeaderArg : 'angle' ,
commandName : 'Revolve' ,
} )
await page . keyboard . insertText ( '180' )
await cmdBar . progressCmdBar ( )
await cmdBar . expectState ( {
stage : 'review' ,
headerArguments : {
2025-05-19 11:21:29 -04:00
Profiles : '2 profiles' ,
2025-05-06 17:57:27 -04:00
AxisOrEdge : 'Edge' ,
Edge : '1 segment' ,
Angle : '180' ,
} ,
commandName : 'Revolve' ,
} )
await cmdBar . progressCmdBar ( )
await scene . settled ( cmdBar )
await editor . expectEditor . toContain ( ` yLine(length = 2, tag = $ seg01) ` , {
shouldNormalise : true ,
} )
await editor . expectEditor . toContain (
` revolve001 = revolve([profile001, profile002], angle=180, axis=seg01) ` ,
{ shouldNormalise : true }
)
} )
await test . step ( 'Delete revolve via feature tree selection' , async ( ) = > {
await editor . closePane ( )
const op = await toolbar . getFeatureTreeOperation ( 'Revolve' , 0 )
await op . click ( { button : 'right' } )
await page . getByTestId ( 'context-menu-delete' ) . click ( )
await scene . settled ( cmdBar )
await editor . expectEditor . not . toContain (
` revolve001 = revolve([profile001, profile002], axis = XY, angle = 180) ` ,
{ shouldNormalise : true }
)
} )
} )
2025-05-15 12:26:20 -04:00
test ( ` Point and click codemods can't run on KCL errors ` , async ( {
context ,
page ,
homePage ,
scene ,
editor ,
toolbar ,
cmdBar ,
} ) = > {
const badCode = ` sketch001 = startSketchOn(XZ)
profile001 = circle ( sketch001 , center = [ 0 , 0 ] , radius = 1 )
extrude001 = extrude ( profile001 length = 1 ) `
await context . addInitScript ( ( initialCode ) = > {
localStorage . setItem ( 'persistCode' , initialCode )
} , badCode )
await page . setBodyDimensions ( { width : 1000 , height : 500 } )
await homePage . goToModelingScene ( )
await scene . connectionEstablished ( )
await test . step ( ` Start Sketch is disabled ` , async ( ) = > {
await expect ( toolbar . startSketchBtn ) . not . toBeEnabled ( )
await editor . expectEditor . toContain ( badCode , { shouldNormalise : true } )
} )
await test . step ( ` Helix is disabled ` , async ( ) = > {
await expect ( toolbar . helixButton ) . not . toBeEnabled ( )
await editor . expectEditor . toContain ( badCode , { shouldNormalise : true } )
} )
} )
2025-06-23 10:53:01 -04:00
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 }
)
} )
} )
2025-02-01 06:02:43 -05:00
} )