Compare commits

...

78 Commits

Author SHA1 Message Date
3504b9246f Merge remote-tracking branch 'origin/main' into paultag/import 2025-04-03 10:15:28 -04:00
aad583be2e Move axes to std constants; move helix, revolve, and mirror2d to be declared in KCL (#6105)
Move axes to std constants; move helix, revolve, and mirror2d to be declated in KCL

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-04-03 09:44:52 +00:00
3e4505e2e3 [refactor] remove 6 floating-promise ignores (#5985)
* Remove trivial floating promise in authMachine

* Add catch statement so LSP promise is considered non-floating

* Remove trivial float in AllSettingsFields

* Add error reporting for ensureWasmInit

* Remove pointless floating promise in Modeling

* Add comment and reportRejection to floating promise in "set selection"

* Read comment, put back await that should be there

* Fix dumb imports rebase botch

* Missed an import

---------

Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2025-04-03 02:53:10 +00:00
1fe1cfb397 Syntax sugar booleans (+ and -) which is intuitive for MEs (#6124)
* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-03 02:13:03 +00:00
2f721c84ed Bump vite from 5.4.12 to 5.4.16 in the security group (#6118)
Bumps the security group with 1 update: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 5.4.12 to 5.4.16
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.16/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.16/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 22:46:30 +00:00
9112ff8c0a Bump vite from 5.4.14 to 5.4.16 in /packages/codemirror-lang-kcl in the security group (#6117)
Bump vite in /packages/codemirror-lang-kcl in the security group

Bumps the security group in /packages/codemirror-lang-kcl with 1 update: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 5.4.14 to 5.4.16
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.16/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.16/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: indirect
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 22:22:17 +00:00
96e12b5aba update transform samples with mesh moving (#6080)
* update transform samples with mesh moving

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* chjanges

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 15:11:06 -07:00
bec3ba71cd More circular deps fixed (#6121)
* 23

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 22

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 21

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix known

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 20

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 11

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 11

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 15:10:57 -07:00
c6766d2a73 bump kcl and friends (#6122)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 14:28:32 -07:00
befac6ad87 Move diff-circular-deps to dedicated script (#6123)
* Move diff-circular-deps to dedicated script

* Update package.json

Co-authored-by: Jace Browning <jacebrowning@gmail.com>

* Fix ci

---------

Co-authored-by: Jace Browning <jacebrowning@gmail.com>
2025-04-02 17:23:23 -04:00
60bc38559b fix sketch mode scale issue (#6107)
* fix sketch mode scale issue

* fmt

* Fix snapshot tests in kurt-5621-scale-issue (#6111)

* Change test function to share units with settings (#6114)

* Change test function to share units with settings

* Consolidate to the same module

---------

Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2025-04-02 16:31:18 -04:00
2a56155587 add circular deps to PRs (#6116)
* add to ci

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 12:43:11 -07:00
87c3673a71 Fix length unit in import transform test (#6108)
Fix length unit of import_transform file

Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2025-04-02 19:32:17 +00:00
21889162ff Map out dependencies between Windows scripts (#6112)
* Map dependencies between Windows scripts

* Skip unix-specific command on Windows

* Handle missing directory

* Explicitly run with PowerShell

This makes the scripts with work CMD out-of-the-box.
2025-04-02 19:07:18 +00:00
f1cccc22cd roll pitch yaw optional, can provide only 1 (#6115)
* roll pitch yaw optional, can provide only 1

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 18:52:28 +00:00
a035f7879b Merge remote-tracking branch 'origin/main' into paultag/import 2025-04-02 11:36:59 -04:00
10c1f3a849 Prevent double-click to constrain length on unsupported lines (#5938)
* WIP: Prevent length constraint creation on endAbsolute lines
Fixes #5937

* Typo

Thanks @franknoirot

Co-authored-by: Frank Noirot <frank@zoo.dev>

* length constraint stuff from @lrev-Dev

* Clean up

* Lint

* Add regression test for double click after sketch constraint

---------

Co-authored-by: Frank Noirot <frank@zoo.dev>
Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
2025-04-02 14:52:36 +00:00
d168ef94e9 Sort imports (#6101)
* add package.json

Signed-off-by: Jess Frazelle <github@jessfraz.com>

initial run;

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

more fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

clientsidescne

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

paths

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix styles

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

combine

Signed-off-by: Jess Frazelle <github@jessfraz.com>

eslint rule

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

my ocd

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

constants file

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

no more import sceneInfra

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

try fix circular import

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 06:54:26 +00:00
29f8b05f56 Fix to not track operations when loading modules (#6083) 2025-04-02 00:34:25 -04:00
af482c30bd save as bw compatible (#6088)
* save as bw compatible

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* js side only for bw compatibility changes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* failure for doing wrong thing

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* remove from ts side

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 03:39:55 +00:00
4e36e398ee Display the next version using native git commands (#6091) 2025-04-02 03:06:38 +00:00
b5f81b9384 Use new Point3d for named views (#6102)
* Use new Point3d for named views

* Wait a bit for the file menu to be created

---------

Co-authored-by: Jace Browning <jacebrowning@gmail.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2025-04-02 02:00:46 +00:00
879b471aed Revert "sort imports" (#6100)
Revert "sort imports (#6094)"

This reverts commit 2fc8cb5376.
2025-04-01 15:31:19 -07:00
964d81dc0e transform w optional args (#6095)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-01 14:23:36 -07:00
443f7cd5fd try to make wheels smaller (#6098)
* try to make wheels smaller

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* target

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-01 14:22:33 -07:00
2fc8cb5376 sort imports (#6094)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-01 14:20:42 -07:00
d122d7a224 fix rebase add feature flag
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-01 12:34:42 -07:00
198e7c4bd2 Merge remote-tracking branch 'origin/main' into paultag/import 2025-04-01 15:18:23 -04:00
14d8903acc man this is bad 2025-04-01 15:16:59 -04:00
ee20a09e7e Update main.kcl (#6087)
* Update main.kcl

Finally making this bracket smarter
correcting fillet issues
single body w/ SSI extruded cuts
it even works as a sendcutsend upload now

* Update kcl-samples simulation test output

* Update main.kcl

descriptive variable names

* Update kcl-samples simulation test output

* Update main.kcl

spelling corrections

* Update kcl-samples simulation test output

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Josh Gomez <114548659+jgomez720@users.noreply.github.com>
2025-04-01 11:28:09 -07:00
275c23f294 chip away more 2025-04-01 13:35:50 -04:00
f4e801351c Add more TS lints (#6084)
* Fix to not call onMouseLeave with no selected object

* Add no this alias lint

* Add more lints and fix JSON formatting

* Fix to use lower-case string type

* Add another namespace lint

* Fix to not use plus on possibly non-string values
2025-04-01 10:21:31 -07:00
7329753211 Bump kcl versions (#6089) 2025-04-01 12:43:27 -04:00
7d46e7e271 fix api for edge cuts (#6086)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-01 12:42:11 -04:00
0ac9ac3896 Reapply "this was a bad idea"
This reverts commit fafdf41093.
2025-04-01 11:56:36 -04:00
0220d0f9de ok 2025-04-01 11:55:08 -04:00
4523dc209b Merge remote-tracking branch 'origin/main' into paultag/import 2025-04-01 11:55:02 -04:00
0583eb07d5 Remove unused test code to fix console error (#6073) 2025-04-01 03:08:04 +00:00
73694563cf change TyF64 to f64 according to JsonSchema and cleanup docs code (#6081)
* cleanup gen_std

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix table

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-01 01:02:48 +00:00
bb4ed59191 Fix patterning in module to not fail when importing function from the module (#6082)
* Add failing test

* Update output to show execution error

* Fix circular pattern to not error in isolated or mock mode

* Update output after fix

* Add failing test for pattern linear 2D

* Add failing output

* Fix isolated execution in linear patterns

* Update output after linear fix
2025-03-31 23:46:29 +00:00
566143757f Fix 404 when clicking on the car wheel sample (#6079)
Fixes #6078
2025-03-31 23:09:59 +00:00
822f2ffc73 Add edit flow for Revolve point-and-click (#5951)
* WIP: Add edge and segment selection in point-and-click Helix flow
Fixes #5393

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Working edge based helix edit

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Add utility function for shared code between revolve and helix

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Use updateModelingState in codemod

* A snapshot a day keeps the bugs away! 📷🐛

* Add skip: true for edge helix to be consistent with axis as options

* A snapshot a day keeps the bugs away! 📷🐛

* Add support for sweepEdge and tests

* Lint

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Clean up snapshots

* WIP: Add edit flow for Revolve
Fixes #5504

* A snapshot a day keeps the bugs away! 📷🐛

* Clean up, add edit steps to three e2e tests

* Fix up tests after ccw change

* Use displayName: 'CounterClockWise' cause ccw not cutting it

* Fix tsc

* Remove uneeded return

* Update 2020 snapshots after helix change

* Update 2020 snapshots after helix change

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Another one :djkhaled:

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Move to fromPromise actor, fix test

* A snapshot a day keeps the bugs away! 📷🐛

* Clean up

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* Lint

* Fix third test

* A snapshot a day keeps the bugs away! 📷🐛

* Lint

* Fix edit insert order

* Fix axis, edge cases with new var, edit new var

* Add test case for new variable creation

* Clean up addRevolve with getSafeInsertIndex

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-31 22:13:34 +00:00
ea73eb011c :( 2025-03-31 16:51:46 -04:00
0aa2824c20 yike 2025-03-31 16:20:29 -04:00
e66893c5d0 poop 2025-03-31 16:17:35 -04:00
60274127df error 2025-03-31 15:57:13 -04:00
a0d1750829 prepare prelude before spawning 2025-03-31 15:54:35 -04:00
00ffa8c0bf Merge remote-tracking branch 'origin/main' into paultag/import 2025-03-31 15:46:26 -04:00
eb3ceba497 Minor design tweaks to log in page (#6071)
Bump subheadings, make link buttons primary colored
2025-03-31 15:33:27 -04:00
2c6d0621c9 Add test for #4236: "Fix corner rect panning bug" (#6018)
* add test for rect panning bug

* tweak timeouts

* cleanups, handle both center and corner rectangle

* revert regression that was used for the test

* apply PR feedback
2025-03-31 15:31:22 -04:00
d8e84cb5e3 Change default tolerance value to not depend on units (#6055) 2025-03-31 19:28:15 +00:00
0b1e79871f Bump the patch group across 1 directory with 16 updates (#6068)
Bumps the patch group with 16 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@codemirror/commands](https://github.com/codemirror/commands) | `6.8.0` | `6.8.1` |
| [@codemirror/lint](https://github.com/codemirror/lint) | `6.8.4` | `6.8.5` |
| [@codemirror/state](https://github.com/codemirror/state) | `6.5.0` | `6.5.2` |
| [@csstools/postcss-oklab-function](https://github.com/csstools/postcss-plugins/tree/HEAD/plugins/postcss-oklab-function) | `4.0.7` | `4.0.8` |
| [@headlessui/tailwindcss](https://github.com/tailwindlabs/headlessui/tree/HEAD/packages/@headlessui-tailwindcss) | `0.2.1` | `0.2.2` |
| [@kittycad/lib](https://github.com/KittyCAD/kittycad.ts) | `2.0.21` | `2.0.23` |
| [chokidar](https://github.com/paulmillr/chokidar) | `4.0.1` | `4.0.3` |
| [electron-updater](https://github.com/electron-userland/electron-builder/tree/HEAD/packages/electron-updater) | `6.6.0` | `6.6.2` |
| [@playwright/test](https://github.com/microsoft/playwright) | `1.51.0` | `1.51.1` |
| [@types/diff](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/diff) | `7.0.1` | `7.0.2` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.13.9` | `22.13.14` |
| [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `4.3.1` | `4.3.4` |
| [autoprefixer](https://github.com/postcss/autoprefixer) | `10.4.19` | `10.4.21` |
| [electron-builder](https://github.com/electron-userland/electron-builder/tree/HEAD/packages/electron-builder) | `26.0.7` | `26.0.12` |
| [ws](https://github.com/websockets/ws) | `8.18.0` | `8.18.1` |
| [@types/ws](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ws) | `8.5.13` | `8.18.0` |



Updates `@codemirror/commands` from 6.8.0 to 6.8.1
- [Changelog](https://github.com/codemirror/commands/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/commands/compare/6.8.0...6.8.1)

Updates `@codemirror/lint` from 6.8.4 to 6.8.5
- [Changelog](https://github.com/codemirror/lint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lint/compare/6.8.4...6.8.5)

Updates `@codemirror/state` from 6.5.0 to 6.5.2
- [Changelog](https://github.com/codemirror/state/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/state/compare/6.5.0...6.5.2)

Updates `@csstools/postcss-oklab-function` from 4.0.7 to 4.0.8
- [Changelog](https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-oklab-function/CHANGELOG.md)
- [Commits](https://github.com/csstools/postcss-plugins/commits/HEAD/plugins/postcss-oklab-function)

Updates `@headlessui/tailwindcss` from 0.2.1 to 0.2.2
- [Release notes](https://github.com/tailwindlabs/headlessui/releases)
- [Changelog](https://github.com/tailwindlabs/headlessui/blob/main/packages/@headlessui-tailwindcss/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/headlessui/commits/@headlessui/tailwindcss@v0.2.2/packages/@headlessui-tailwindcss)

Updates `@kittycad/lib` from 2.0.21 to 2.0.23
- [Release notes](https://github.com/KittyCAD/kittycad.ts/releases)
- [Commits](https://github.com/KittyCAD/kittycad.ts/compare/v2.0.21...v2.0.23)

Updates `chokidar` from 4.0.1 to 4.0.3
- [Release notes](https://github.com/paulmillr/chokidar/releases)
- [Commits](https://github.com/paulmillr/chokidar/compare/4.0.1...4.0.3)

Updates `electron-updater` from 6.6.0 to 6.6.2
- [Release notes](https://github.com/electron-userland/electron-builder/releases)
- [Changelog](https://github.com/electron-userland/electron-builder/blob/master/packages/electron-updater/CHANGELOG.md)
- [Commits](https://github.com/electron-userland/electron-builder/commits/electron-updater@6.6.2/packages/electron-updater)

Updates `@playwright/test` from 1.51.0 to 1.51.1
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.51.0...v1.51.1)

Updates `@types/diff` from 7.0.1 to 7.0.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/diff)

Updates `@types/node` from 22.13.9 to 22.13.14
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitejs/plugin-react` from 4.3.1 to 4.3.4
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/v4.3.4/packages/plugin-react)

Updates `autoprefixer` from 10.4.19 to 10.4.21
- [Release notes](https://github.com/postcss/autoprefixer/releases)
- [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/autoprefixer/compare/10.4.19...10.4.21)

Updates `electron-builder` from 26.0.7 to 26.0.12
- [Release notes](https://github.com/electron-userland/electron-builder/releases)
- [Changelog](https://github.com/electron-userland/electron-builder/blob/master/packages/electron-builder/CHANGELOG.md)
- [Commits](https://github.com/electron-userland/electron-builder/commits/v26.0.12/packages/electron-builder)

Updates `ws` from 8.18.0 to 8.18.1
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.18.0...8.18.1)

Updates `@types/ws` from 8.5.13 to 8.18.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ws)

---
updated-dependencies:
- dependency-name: "@codemirror/commands"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@codemirror/lint"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@codemirror/state"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@csstools/postcss-oklab-function"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@headlessui/tailwindcss"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@kittycad/lib"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: chokidar
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: electron-updater
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@playwright/test"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@types/diff"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@vitejs/plugin-react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: autoprefixer
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: electron-builder
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: ws
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patch
- dependency-name: "@types/ws"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 18:56:37 +00:00
954fddf578 Show a toast if the user tries to save their work (#6051)
* Show a toast if the user tries to save their work

And store the fact that they've seen it in localStorage so we don't spam
them every time they hit it after they see it.

* Remove any localStorage logic, toast every time
2025-03-31 14:37:04 -04:00
f94f748339 Use waitForExecutionDone in lint errors test (#6070) 2025-03-31 13:43:43 -04:00
e2b7b22ca9 ctx.close in tests when error on execution (#6075)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-31 10:24:42 -07:00
efc8c82d8b BREAKING: KCL @settings are the source of truth for units (#5808) 2025-03-31 10:56:03 -04:00
eac5abba79 Clean up env vars in e2e-tests.yml (#6045)
* pierremtb/adhoc/clean-up-e2e-env-vars-ci

* Add back           VITE_KC_SKIP_AUTH: true for snaps

* Remove VITE_KC_SKIP_AUTH: true, add back token
2025-03-31 09:18:23 -04:00
1956c14b8a auto format kcl samples (#6065)
* recast kcl samples;

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* auto format the kcl-samples

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-30 17:06:36 +00:00
017fac7041 use deterministic ids in more places (#6064)
* dont redact the ids now that they are deterministic

Signed-off-by: Jess Frazelle <github@jessfraz.com>

pass arouund id generator more

Signed-off-by: Jess Frazelle <github@jessfraz.com>

change the anme space

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates and re-run

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixups

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup old files

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup old files

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-30 04:23:11 +00:00
0bdc50c78f bump kcl-lib and friends (#6063)
* bump kcl-lib and friends

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* expose

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* relevant files

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* udpates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-29 19:26:20 -07:00
57d78b6094 Move artifact graph out of engine connection (#6062)
* cleanups

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanups

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fmt

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-29 20:25:26 -04:00
db5ce7ba85 Move turns to a submodule of std (#6039)
* Move turns to a submodule of std

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Cache module infos as well as memory; fix a bug with deprecated constants

Signed-off-by: Nick Cameron <nrc@ncameron.org>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-30 11:10:44 +13:00
51c16d0048 only rust changes reset scene (#6060)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-29 11:43:42 -07:00
6532b23f1c Bump tar-fs from 2.1.1 to 2.1.2 in /rust/kcl-language-server in the security group (#6056) 2025-03-29 16:35:45 +00:00
49304b9ecd fix context closes (#6058)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-03-28 20:31:44 -07:00
fafdf41093 Revert "this was a bad idea"
This reverts commit a2092e7ed6.
2025-03-28 17:07:29 -04:00
a2092e7ed6 this was a bad idea 2025-03-28 15:03:13 -04:00
aa103d299c Merge branch 'main' into paultag/import 2025-03-28 14:40:34 -04:00
aaaab495bc Merge remote-tracking branch 'origin' into paultag/import 2025-03-18 16:24:05 -04:00
364e38fda2 Merge remote-tracking branch 'origin' into paultag/import 2025-03-18 09:17:51 -04:00
b085af139b lock start things 2025-03-13 14:58:24 -04:00
ec537cd8dc Merge remote-tracking branch 'origin/main' into paultag/import 2025-03-13 11:17:34 -04:00
8debbc5241 wip 2025-03-13 11:17:22 -04:00
a590ed99cf Merge branch 'main' of github.com:KittyCAD/modeling-app into paultag/import 2025-03-12 12:00:46 -04:00
a002bb60a0 Merge remote-tracking branch 'origin/main' into paultag/import 2025-03-11 16:18:58 -04:00
6ba01b8dfa sketch a bit more; going to pull this out of tests next 2025-03-10 15:43:43 -04:00
ca9e6e0944 Merge remote-tracking branch 'origin/main' into paultag/import 2025-03-10 12:27:50 -04:00
e85e54215c wip 2025-03-10 12:27:47 -04:00
909 changed files with 43558 additions and 59921 deletions

View File

@ -1,91 +0,0 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": [
"react-perf",
"css-modules",
"jest",
"jsx-a11y",
"react",
"react-hooks",
"suggest-no-throw",
"testing-library",
"@typescript-eslint"
],
"extends": [
"plugin:css-modules/recommended",
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended"
],
"rules": {
"no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-array-constructor": "error",
"@typescript-eslint/no-array-delete": "error",
"@typescript-eslint/no-duplicate-enum-values": "error",
"@typescript-eslint/no-duplicate-type-constituents": "error",
"@typescript-eslint/no-empty-object-type": "error",
"@typescript-eslint/no-floating-promises": "error",
"no-implied-eval": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-implied-eval": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-unnecessary-type-constraint": "error",
"no-unused-vars": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-unused-vars": ["error", {
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_",
"ignoreRestSiblings": true,
"vars": "all",
"args": "none"
}],
"@typescript-eslint/prefer-as-const": "warn",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",
"no-restricted-globals": [
"error",
{
"name": "isNaN",
"message": "Use Number.isNaN() instead."
},
],
"no-restricted-syntax": [
"error",
{
"selector": "CallExpression[callee.object.name='Array'][callee.property.name='isArray']",
"message": "Use isArray() in lib/utils.ts instead of Array.isArray()."
}
],
"semi": [
"error",
"never"
],
"react-hooks/exhaustive-deps": "off",
"suggest-no-throw/suggest-no-throw": "warn",
},
"overrides": [
{
"files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
"extends": [
"plugin:testing-library/react"
],
"rules": {
"suggest-no-throw/suggest-no-throw": "off",
"testing-library/prefer-screen-queries": "off",
"jest/valid-expect": "off"
}
},
{
"files": ["src/**/*.test.ts"],
"extends": [
"plugin:testing-library/react"
],
"rules": {
"suggest-no-throw/suggest-no-throw": "off",
}
}
]
}

127
.eslintrc.json Normal file
View File

@ -0,0 +1,127 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": [
"react-perf",
"css-modules",
"jest",
"jsx-a11y",
"react",
"react-hooks",
"suggest-no-throw",
"testing-library",
"@typescript-eslint"
],
"extends": [
"plugin:css-modules/recommended",
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended"
],
"rules": {
"no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-array-constructor": "error",
"@typescript-eslint/no-array-delete": "error",
"@typescript-eslint/no-duplicate-enum-values": "error",
"@typescript-eslint/no-duplicate-type-constituents": "error",
"@typescript-eslint/no-empty-object-type": "error",
"@typescript-eslint/no-extra-non-null-assertion": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-for-in-array": "error",
"no-implied-eval": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-implied-eval": "error",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
"@typescript-eslint/no-redundant-type-constituents": "error",
"@typescript-eslint/no-this-alias": "warn",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-unnecessary-type-constraint": "error",
"no-unused-vars": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-unused-vars": [
"error",
{
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_",
"ignoreRestSiblings": true,
"vars": "all",
"args": "none"
}
],
"@typescript-eslint/no-unsafe-unary-minus": "error",
"@typescript-eslint/no-wrapper-object-types": "error",
"no-throw-literal": "off", // Use @typescript-eslint/only-throw-error instead.
"@typescript-eslint/only-throw-error": "error",
"@typescript-eslint/prefer-as-const": "warn",
"@typescript-eslint/prefer-namespace-keyword": "error",
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",
"no-restricted-globals": [
"error",
{
"name": "isNaN",
"message": "Use Number.isNaN() instead."
}
],
"no-restricted-syntax": [
"error",
{
"selector": "CallExpression[callee.object.name='Array'][callee.property.name='isArray']",
"message": "Use isArray() in lib/utils.ts instead of Array.isArray()."
},
{
"selector": "CallExpression[callee.object.name='TOML'][callee.property.name='stringify']",
"message": "Do not use TOML.stringify directly. Use the wrappers in test-utils instead like settingsToToml."
},
{
"selector": "CallExpression[callee.object.name='TOML'][callee.property.name='parse']",
"message": "Do not use TOML.parse directly. Use the wrappers in test-utils instead like tomlToSettings."
}
],
"no-restricted-imports": [
"error",
{
"patterns": [
// Restrict all relative imports except for .css files.
{
"group": ["./*", "../*", "!./*.css", "!../*.css"],
"message": "Use absolute imports instead."
}
]
}
],
"semi": ["error", "never"],
"react-hooks/exhaustive-deps": "off",
"suggest-no-throw/suggest-no-throw": "error"
},
"overrides": [
{
"files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
"extends": ["plugin:testing-library/react"],
"rules": {
"suggest-no-throw/suggest-no-throw": "off",
"testing-library/prefer-screen-queries": "off",
"jest/valid-expect": "off"
}
},
{
"files": ["src/**/*.test.ts"],
"extends": ["plugin:testing-library/react"],
"rules": {
"suggest-no-throw/suggest-no-throw": "off"
}
},
{
"files": ["packages/**/*.ts", "rust/**/*.ts"],
"extends": [],
"rules": {
"no-restricted-imports": "off"
}
}
]
}

View File

@ -229,10 +229,6 @@ jobs:
timeout_minutes: 30
max_attempts: 3
env:
CI: true
NODE_ENV: development
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
VITE_KC_SKIP_AUTH: true
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
snapshottoken: ${{ secrets.KITTYCAD_API_TOKEN }}
@ -377,11 +373,7 @@ jobs:
timeout_minutes: 45
max_attempts: 15
env:
CI: true
FAIL_ON_CONSOLE_ERRORS: true
NODE_ENV: development
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
VITE_KC_SKIP_AUTH: true
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
- uses: actions/upload-artifact@v4

View File

@ -136,6 +136,36 @@ jobs:
- run: yarn lint
yarn-circular-dependencies:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn circular-deps:diff
python-codespell:
runs-on: ubuntu-22.04
steps:

View File

@ -4,18 +4,38 @@ all: install build check
###############################################################################
# INSTALL
WASM_PACK ?= ~/.cargo/bin/wasm-pack
ifeq ($(OS),Windows_NT)
CARGO ?= ~/.cargo/bin/cargo.exe
WASM_PACK ?= ~/.cargo/bin/wasm-pack.exe
else
CARGO ?= ~/.cargo/bin/cargo
WASM_PACK ?= ~/.cargo/bin/wasm-pack
endif
.PHONY: install
install: node_modules/.yarn-integrity $(WASM_PACK) ## Install dependencies
install: node_modules/.yarn-integrity $(CARGO) $(WASM_PACK) ## Install dependencies
node_modules/.yarn-integrity: package.json yarn.lock
yarn install
ifeq ($(OS),Windows_NT)
@ type nul > $@
else
@ touch $@
endif
$(CARGO):
ifeq ($(OS),Windows_NT)
yarn install:rust:windows
else
yarn install:rust
endif
$(WASM_PACK):
yarn install:rust
ifeq ($(OS),Windows_NT)
yarn install:wasm-pack:cargo
else
yarn install:wasm-pack:sh
endif
###############################################################################
# BUILD
@ -31,13 +51,17 @@ VITE_SOURCES := $(wildcard vite.*) $(wildcard vite/**/*.tsx)
build: build-web build-desktop
.PHONY: build-web
build-web: public/kcl_wasm_lib_bg.wasm build/index.html
build-web: install public/kcl_wasm_lib_bg.wasm build/index.html
.PHONY: build-desktop
build-desktop: public/kcl_wasm_lib_bg.wasm .vite/build/main.js
build-desktop: install public/kcl_wasm_lib_bg.wasm .vite/build/main.js
public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES)$(RUST_SOURCES)
public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES) $(RUST_SOURCES)
ifeq ($(OS),Windows_NT)
yarn build:wasm:dev:windows
else
yarn build:wasm:dev
endif
build/index.html: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES)
yarn build:local
@ -63,8 +87,10 @@ lint: install ## Lint the code
###############################################################################
# RUN
TARGET ?= web
.PHONY: run
run: run-web
run: run-$(TARGET)
.PHONY: run-web
run-web: install build-web ## Start the web app
@ -90,7 +116,7 @@ test-unit: install ## Run the unit tests
yarn test:unit
.PHONY: test-e2e
test-e2e: test-e2e-desktop
test-e2e: test-e2e-$(TARGET)
.PHONY: test-e2e-web
test-e2e-web: install build-web ## Run the web e2e tests
@ -106,15 +132,23 @@ test-e2e-desktop: install build-desktop ## Run the desktop e2e tests
.PHONY: clean
clean: ## Delete all artifacts
ifeq ($(OS),Windows_NT)
git clean --force -d -X
else
rm -rf .vite/ build/
rm -rf trace.zip playwright-report/ test-results/
rm -rf public/kcl_wasm_lib_bg.wasm
rm -rf rust/*/bindings/ rust/*/pkg/ rust/target/
rm -rf node_modules/ rust/*/node_modules/
endif
.PHONY: help
help: install
ifeq ($(OS),Windows_NT)
@ powershell -Command "Get-Content $(MAKEFILE_LIST) | Select-String -Pattern '^[^\s]+:.*##\s.*$$' | ForEach-Object { $$line = $$_.Line -split ':.*?##\s+'; Write-Host -NoNewline $$line[0].PadRight(30) -ForegroundColor Cyan; Write-Host $$line[1] }"
else
@ grep -E '^[^[:space:]]+:.*## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
endif
.DEFAULT_GOAL := help

View File

@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 5)
// Add color to a revolved solid.
sketch001 = startSketchOn(XY)
|> circle(center = [15, 0], radius = 5)
|> revolve(angle = 360, axis = 'y')
|> revolve(angle = 360, axis = Y)
|> appearance(color = '#ff0000', metalness = 90, roughness = 90)
```

View File

@ -9,13 +9,12 @@ layout: manual
### `std`
- [`HALF_TURN`](/docs/kcl/consts/std-HALF_TURN)
- [`QUARTER_TURN`](/docs/kcl/consts/std-QUARTER_TURN)
- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-THREE_QUARTER_TURN)
- [`X`](/docs/kcl/consts/std-X)
- [`XY`](/docs/kcl/consts/std-XY)
- [`XZ`](/docs/kcl/consts/std-XZ)
- [`Y`](/docs/kcl/consts/std-Y)
- [`YZ`](/docs/kcl/consts/std-YZ)
- [`ZERO`](/docs/kcl/consts/std-ZERO)
- [`Z`](/docs/kcl/consts/std-Z)
### `std::math`
@ -23,3 +22,10 @@ layout: manual
- [`PI`](/docs/kcl/consts/std-math-PI)
- [`TAU`](/docs/kcl/consts/std-math-TAU)
### `std::turns`
- [`HALF_TURN`](/docs/kcl/consts/std-turns-HALF_TURN)
- [`QUARTER_TURN`](/docs/kcl/consts/std-turns-QUARTER_TURN)
- [`THREE_QUARTER_TURN`](/docs/kcl/consts/std-turns-THREE_QUARTER_TURN)
- [`ZERO`](/docs/kcl/consts/std-turns-ZERO)

View File

@ -1,15 +0,0 @@
---
title: "std::HALF_TURN"
excerpt: ""
layout: manual
---
```js
std::HALF_TURN: number(deg) = 180deg
```

View File

@ -1,15 +0,0 @@
---
title: "std::QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::QUARTER_TURN: number(deg) = 90deg
```

View File

@ -1,15 +0,0 @@
---
title: "std::THREE_QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -1,5 +1,5 @@
---
title: "std::ZERO"
title: "std::X"
excerpt: ""
layout: manual
---
@ -9,7 +9,7 @@ layout: manual
```js
std::ZERO: number = 0
std::X
```

15
docs/kcl/consts/std-Y.md Normal file
View File

@ -0,0 +1,15 @@
---
title: "std::Y"
excerpt: ""
layout: manual
---
```js
std::Y
```

15
docs/kcl/consts/std-Z.md Normal file
View File

@ -0,0 +1,15 @@
---
title: "std::Z"
excerpt: ""
layout: manual
---
```js
std::Z
```

View File

@ -0,0 +1,15 @@
---
title: "std::turns::HALF_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::HALF_TURN: number(deg) = 180deg
```

View File

@ -0,0 +1,15 @@
---
title: "std::turns::QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::QUARTER_TURN: number(deg) = 90deg
```

View File

@ -0,0 +1,15 @@
---
title: "std::turns::THREE_QUARTER_TURN"
excerpt: ""
layout: manual
---
```js
std::turns::THREE_QUARTER_TURN: number(deg) = 270deg
```

View File

@ -0,0 +1,15 @@
---
title: "std::turns::ZERO"
excerpt: ""
layout: manual
---
```js
std::turns::ZERO: number = 0
```

File diff suppressed because one or more lines are too long

View File

@ -22,20 +22,22 @@ layout: manual
* [`string`](kcl/types/string)
* [`tag`](kcl/types/tag)
* **std**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`HALF_TURN`](kcl/consts/std-HALF_TURN)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`QUARTER_TURN`](kcl/consts/std-QUARTER_TURN)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)
* [`THREE_QUARTER_TURN`](kcl/consts/std-THREE_QUARTER_TURN)
* [`X`](kcl/consts/std-X)
* [`XY`](kcl/consts/std-XY)
* [`XZ`](kcl/consts/std-XZ)
* [`Y`](kcl/consts/std-Y)
* [`YZ`](kcl/consts/std-YZ)
* [`ZERO`](kcl/consts/std-ZERO)
* [`Z`](kcl/consts/std-Z)
* [`abs`](kcl/abs)
* [`acos`](kcl/acos)
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
@ -72,7 +74,7 @@ layout: manual
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/helix)
* [`helix`](kcl/std-helix)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`inch`](kcl/inch)
@ -91,7 +93,6 @@ layout: manual
* [`map`](kcl/map)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`mirror2d`](kcl/mirror2d)
* [`mm`](kcl/mm)
* [`offsetPlane`](kcl/offsetPlane)
* [`patternCircular2d`](kcl/patternCircular2d)
@ -110,7 +111,7 @@ layout: manual
* [`push`](kcl/push)
* [`reduce`](kcl/reduce)
* [`rem`](kcl/rem)
* [`revolve`](kcl/revolve)
* [`revolve`](kcl/std-revolve)
* [`rotate`](kcl/rotate)
* [`round`](kcl/round)
* [`scale`](kcl/scale)
@ -146,3 +147,9 @@ layout: manual
* [`tan`](kcl/std-math-tan)
* **std::sketch**
* [`circle`](kcl/std-sketch-circle)
* [`mirror2d`](kcl/std-sketch-mirror2d)
* **std::turns**
* [`turns::HALF_TURN`](kcl/consts/std-turns-HALF_TURN)
* [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN)
* [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN)
* [`turns::ZERO`](kcl/consts/std-turns-ZERO)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -146,7 +146,7 @@ exampleSketch = startSketchOn(XY)
|> line(end = [-2, 0])
|> close()
example = revolve(exampleSketch, axis = 'y', angle = 180)
example = revolve(exampleSketch, axis = Y, angle = 180)
exampleSketch002 = startSketchOn(example, 'end')
|> startProfileAt([4.5, -5], %)
@ -177,7 +177,7 @@ exampleSketch = startSketchOn(XY)
example = revolve(
exampleSketch,
axis = 'y',
axis = Y,
angle = 180,
tagEnd = $end01,
)

116
docs/kcl/std-helix.md Normal file

File diff suppressed because one or more lines are too long

246
docs/kcl/std-revolve.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@ circle(@sketch_or_surface: Sketch | Plane | Face, center: Point2d, radius: numbe
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch_or_surface` | [`Sketch`](/docs/kcl/types/Sketch) `|` [`Plane`](/docs/kcl/types/Face) `|` [`Plane`](/docs/kcl/types/Face) | Sketch to extend, or plane or surface to sketch on. | Yes |
| `sketch_or_surface` | [`Sketch`](/docs/kcl/types/Sketch) OR [`Plane`](/docs/kcl/types/Plane) OR [`Face`](/docs/kcl/types/Face) | Sketch to extend, or plane or surface to sketch on. | Yes |
| `center` | [`Point2d`](/docs/kcl/types/Point2d) | The center of the circle. | Yes |
| `radius` | [`number`](/docs/kcl/types/number) | The radius of the circle. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`tag`](/docs/kcl/types/tag) | Create a new tag which refers to this circle. | No |

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -74,7 +74,7 @@ helixPath = helix(
revolutions = 4,
length = 10,
radius = 5,
axis = 'Z',
axis = Z,
)
// Create a spring by sweeping around the helix path.

File diff suppressed because one or more lines are too long

12
docs/kcl/types/Axis2d.md Normal file
View File

@ -0,0 +1,12 @@
---
title: "std::Axis2d"
excerpt: "An infinite line in 2d space."
layout: manual
---
An infinite line in 2d space.

12
docs/kcl/types/Axis3d.md Normal file
View File

@ -0,0 +1,12 @@
---
title: "std::Axis3d"
excerpt: "An infinite line in 3d space."
layout: manual
---
An infinite line in 3d space.

12
docs/kcl/types/Edge.md Normal file
View File

@ -0,0 +1,12 @@
---
title: "std::Edge"
excerpt: "The edge of a solid."
layout: manual
---
The edge of a solid.

View File

@ -28,7 +28,7 @@ An extrude plane.
| `faceId` |[`string`](/docs/kcl/types/string)| The face id for the extrude plane. | No |
| [`tag`](/docs/kcl/types/tag) |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the geometry. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
| `sourceRange` |`[integer, integer, integer]`| The source range. | No |
----
@ -48,7 +48,7 @@ An extruded arc.
| `faceId` |[`string`](/docs/kcl/types/string)| The face id for the extrude plane. | No |
| [`tag`](/docs/kcl/types/tag) |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the geometry. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
| `sourceRange` |`[integer, integer, integer]`| The source range. | No |
----
@ -68,7 +68,7 @@ Geometry metadata.
| `faceId` |[`string`](/docs/kcl/types/string)| The id for the chamfer surface. | No |
| [`tag`](/docs/kcl/types/tag) |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the geometry. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
| `sourceRange` |`[integer, integer, integer]`| The source range. | No |
----
@ -88,7 +88,7 @@ Geometry metadata.
| `faceId` |[`string`](/docs/kcl/types/string)| The id for the fillet surface. | No |
| [`tag`](/docs/kcl/types/tag) |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the geometry. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
| `sourceRange` |`[integer, integer, integer]`| The source range. | No |
----

View File

@ -17,6 +17,6 @@ Geometry metadata.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `id` |[`string`](/docs/kcl/types/string)| The id of the geometry. | No |
| `sourceRange` |[`SourceRange`](/docs/kcl/types/SourceRange)| The source range. | No |
| `sourceRange` |`[integer, integer, integer]`| The source range. | No |

View File

@ -17,7 +17,7 @@ A helix.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `value` |[`string`](/docs/kcl/types/string)| The id of the helix. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `artifactId` |[`string`](/docs/kcl/types/string)| The artifact ID. | No |
| `revolutions` |[`number`](/docs/kcl/types/number)| Number of revolutions. | No |
| `angleStart` |[`number`](/docs/kcl/types/number)| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |

View File

@ -285,7 +285,7 @@ Data for an imported geometry.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `type` |enum: `Module`| | No |
| `value` |[`ModuleId`](/docs/kcl/types/ModuleId)| Identifier of a source file. Uses a u32 to keep the size small. | No |
| `value` |`integer`| Identifier of a source file. Uses a u32 to keep the size small. | No |
----

View File

@ -17,6 +17,6 @@ Data for polar coordinates.
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `angle` |[`number`](/docs/kcl/types/number)| The angle of the line (in degrees). | No |
| `length` |[`TyF64`](/docs/kcl/types/TyF64)| The length of the line. | No |
| `length` |[`number`](/docs/kcl/types/number)| The length of the line. | No |

View File

@ -25,7 +25,7 @@ A sketch type.
|----------|------|-------------|----------|
| `type` |enum: `plane`| | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the plane. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `artifactId` |[`string`](/docs/kcl/types/string)| The artifact ID. | No |
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| Type for a plane. | No |
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane's X axis be? | No |
@ -49,7 +49,7 @@ A face.
|----------|------|-------------|----------|
| `type` |enum: `face`| | No |
| `id` |[`string`](/docs/kcl/types/string)| The id of the face. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `artifactId` |[`string`](/docs/kcl/types/string)| The artifact ID. | No |
| `value` |[`string`](/docs/kcl/types/string)| The tag of the face. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No |

View File

@ -1,15 +0,0 @@
---
title: "SourceRange"
excerpt: ""
layout: manual
---
**Type:** `integer` (`uint`)

View File

@ -5,17 +5,11 @@ layout: manual
---
**Type:** `object`
**Type:** [`number`](/docs/kcl/types/number) (`double`)
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `n` |[`number`](/docs/kcl/types/number)| | No |
| `ty` |[`NumericType`](/docs/kcl/types/NumericType)| | No |

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import { test, expect } from './zoo-test'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Electron app header tests', () => {
test(

View File

@ -1,13 +1,14 @@
import { Page } from '@playwright/test'
import { test, expect } from './zoo-test'
import type { Page } from '@playwright/test'
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
import {
getUtils,
PERSIST_MODELING_CONTEXT,
TEST_COLORS,
commonPoints,
PERSIST_MODELING_CONTEXT,
getUtils,
orRunWhenFullSuiteEnabled,
} from './test-utils'
import { HomePageFixture } from './fixtures/homePageFixture'
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.setTimeout(120000)
@ -85,7 +86,7 @@ async function doBasicSketch(
await page.mouse.click(startXPx, 500 - PUR * 20)
if (openPanes.includes('code')) {
await expect(u.codeLocator)
.toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${
.toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(length = ${commonPoints.num1})
@ -119,10 +120,7 @@ async function doBasicSketch(
await page.waitForTimeout(100)
if (openPanes.includes('code')) {
await expect(
await u.getGreatestPixDiff(line1, TEST_COLORS.BLUE)
).toBeLessThan(3)
await expect(await u.getGreatestPixDiff(line1, [0, 0, 255])).toBeLessThan(3)
expect(await u.getGreatestPixDiff(line1, TEST_COLORS.BLUE)).toBeLessThan(3)
}
// hold down shift
@ -145,7 +143,7 @@ async function doBasicSketch(
// Open the code pane.
await u.openKclCodePanel()
await expect(u.codeLocator)
.toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${
.toHaveText(`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${
commonPoints.startAt
}, sketch001)
|> xLine(length = ${commonPoints.num1}, tag = $seg01)

View File

@ -1,7 +1,8 @@
import { test, expect } from './zoo-test'
import fs from 'node:fs/promises'
import path from 'node:path'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Point and click for boolean workflows', () => {
// Boolean operations to test
const booleanOperations = [

View File

@ -1,10 +1,11 @@
import { Page } from '@playwright/test'
import { test, expect } from './zoo-test'
import { HomePageFixture } from './fixtures/homePageFixture'
import { getUtils } from './test-utils'
import { EngineCommand } from 'lang/std/artifactGraph'
import { uuidv4 } from 'lib/utils'
import { SceneFixture } from './fixtures/sceneFixture'
import type { Page } from '@playwright/test'
import type { EngineCommand } from '@src/lang/std/artifactGraph'
import { uuidv4 } from '@src/lib/utils'
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
import { getUtils } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe(
'Can create sketches on all planes and their back sides',
@ -46,7 +47,7 @@ test.describe(
},
}
const code = `sketch001 = startSketchOn(${plane})profile001 = startProfileAt([0.91, -1.22], sketch001)`
const code = `@settings(defaultLengthUnit = in)sketch001 = startSketchOn(${plane})profile001 = startProfileAt([0.91, -1.22], sketch001)`
await u.openDebugPanel()

View File

@ -1,13 +1,14 @@
import { test, expect } from './zoo-test'
import {
orRunWhenFullSuiteEnabled,
getUtils,
executorInputPath,
} from './test-utils'
import { join } from 'path'
import { bracket } from 'lib/exampleKcl'
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates'
import { bracket } from '@src/lib/exampleKcl'
import fsp from 'fs/promises'
import { join } from 'path'
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from '@e2e/playwright/storageStates'
import {
executorInputPath,
getUtils,
orRunWhenFullSuiteEnabled,
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
test('Typing KCL errors induces a badge on the code pane button', async ({
@ -251,11 +252,11 @@ test(
])
await Promise.all([
fsp.copyFile(
executorInputPath('router-template-slate.kcl'),
executorInputPath('cylinder-inches.kcl'),
join(routerTemplateDir, 'main.kcl')
),
fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('e2e-can-sketch-on-chamfer.kcl'),
join(bracketDir, 'main.kcl')
),
])

View File

@ -1,12 +1,13 @@
import { test, expect } from './zoo-test'
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
import * as fsp from 'fs/promises'
import path, { join } from 'path'
import {
executorInputPath,
getUtils,
orRunWhenFullSuiteEnabled,
} from './test-utils'
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
import path, { join } from 'path'
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
test('Extrude from command bar selects extrude line after', async ({

View File

@ -1,5 +1,5 @@
import { test, expect } from './zoo-test'
import { getUtils } from './test-utils'
import { getUtils } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Copilot ghost text', () => {
// eslint-disable-next-line jest/valid-title

View File

@ -1,6 +1,5 @@
import { test, expect } from './zoo-test'
import { getUtils } from './test-utils'
import { getUtils } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
function countNewlines(input: string): number {
let count = 0

View File

@ -1,11 +1,12 @@
import { test, expect } from './zoo-test'
import fsp from 'fs/promises'
import path from 'path'
import {
getUtils,
executorInputPath,
getPlaywrightDownloadDir,
} from './test-utils'
import fsp from 'fs/promises'
getUtils,
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test(
'export works on the first try',
@ -20,11 +21,11 @@ test(
await Promise.all([fsp.mkdir(bracketDir, { recursive: true })])
await Promise.all([
fsp.copyFile(
executorInputPath('router-template-slate.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'other.kcl')
),
fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('e2e-can-sketch-on-chamfer.kcl'),
path.join(bracketDir, 'main.kcl')
),
])
@ -107,7 +108,7 @@ test(
},
{ timeout: 15_000 }
)
.toBeGreaterThan(300_000)
.toBeGreaterThan(30_000)
})
})
@ -187,7 +188,7 @@ test(
},
{ timeout: 15_000 }
)
.toBeGreaterThan(70_000)
.toBeGreaterThan(50_000)
})
})
}

View File

@ -1,14 +1,14 @@
import { test, expect } from './zoo-test'
import { uuidv4 } from '@src/lib/utils'
import fsp from 'fs/promises'
import { uuidv4 } from 'lib/utils'
import { join } from 'path'
import {
TEST_COLORS,
executorInputPath,
getUtils,
orRunWhenFullSuiteEnabled,
TEST_COLORS,
} from './test-utils'
import { join } from 'path'
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
test('can comment out code with ctrl+/', async ({ page, homePage }) => {
@ -32,26 +32,30 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('/')
await page.keyboard.up('ControlOrMeta')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XY)
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> line(end = [-20, 0])
// |> close()`)
// |> close()`.replaceAll('\n', '')
)
// uncomment the code
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('/')
await page.keyboard.up('ControlOrMeta')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XY)
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> line(end = [-20, 0])
|> close()`)
|> close()`.replaceAll('\n', '')
)
})
test('ensure we use the cache, and do not re-execute', async ({
@ -178,13 +182,15 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.locator('#code-pane button:first-child').click()
await page.locator('button:has-text("Format code")').click()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XY)
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> line(end = [-20, 0])
|> close()`)
|> close()`.replaceAll('\n', '')
)
})
test('if you click the format button it formats your code and executes so lints are still there', async ({
@ -227,13 +233,15 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch_001 = startSketchOn(XY)
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch_001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
|> line(end = [-20, 0])
|> close()`)
|> close()`.replaceAll('\n', '')
)
// error in guter
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
@ -471,6 +479,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
test('if you write kcl with lint errors you get lints', async ({
page,
homePage,
scene,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1000, height: 500 })
@ -490,10 +499,7 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.press('ArrowLeft')
await page.keyboard.press('ArrowRight')
// FIXME: lsp errors do not propagate to the frontend until engine is connected and code is executed
// This timeout is to wait for engine connection. LSP and code execution errors should be handled differently
// LSP can emit errors as fast as it waits and show them in the editor
await page.waitForTimeout(10000)
await scene.waitForExecutionDone()
// error in guter
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
@ -815,10 +821,12 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
// there shouldn't be any auto complete options for 'lin' in the comment
await expect(page.locator('.cm-completionLabel')).not.toBeVisible()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XZ)
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> startProfileAt([3.14, 12], %)
|> xLine(%, length = 5) // lin`)
|> xLine(%, length = 5) // lin`.replaceAll('\n', '')
)
// expect there to be no KCL errors
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(0)
@ -888,10 +896,12 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
// there shouldn't be any auto complete options for 'lin' in the comment
await expect(page.locator('.cm-completionLabel')).not.toBeVisible()
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XZ)
await expect(page.locator('.cm-content')).toHaveText(
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> startProfileAt([3.14, 12], %)
|> xLine(%, length = 5) // lin`)
|> xLine(%, length = 5) // lin`.replaceAll('\n', '')
)
})
})
test('Can undo a click and point extrude with ctrl+z', async ({
@ -975,12 +985,13 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
test(
'Can undo a sketch modification with ctrl+z',
{ tag: ['@skipWin'] },
async ({ page, homePage }) => {
async ({ page, homePage, editor }) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit=in)
sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -10.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -0.38], %)
@ -1070,41 +1081,45 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XZ)
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [15.4, -2.78])
|> tangentialArcTo([27.6, -3.05], %)
|> close()
|> extrude(length = 5)
`)
|> extrude(length = 5)`,
{ shouldNormalise: true }
)
// Hit undo
await page.keyboard.down('Control')
await page.keyboard.press('KeyZ')
await page.keyboard.up('Control')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XZ)
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [15.4, -2.78])
|> tangentialArcTo([24.95, -0.38], %)
|> close()
|> extrude(length = 5)`)
|> extrude(length = 5)`,
{ shouldNormalise: true }
)
// Hit undo again.
await page.keyboard.down('Control')
await page.keyboard.press('KeyZ')
await page.keyboard.up('Control')
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XZ)
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
|> startProfileAt([2.71, -2.71], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -0.38], %)
|> close()
|> extrude(length = 5)
`)
|> extrude(length = 5)`,
{ shouldNormalise: true }
)
// Hit undo again.
await page.keyboard.down('Control')
@ -1112,13 +1127,15 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
await page.keyboard.up('Control')
await page.waitForTimeout(100)
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -10.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -0.38], %)
|> close()
|> extrude(length = 5)`)
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -10.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -0.38], %)
|> close()
|> extrude(length = 5)`,
{ shouldNormalise: true }
)
}
)
@ -1206,4 +1223,55 @@ test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
})
}
)
test('Rectangle tool panning with middle click', async ({
page,
homePage,
toolbar,
scene,
cmdBar,
editor,
}) => {
await page.setBodyDimensions({ width: 1200, height: 900 })
await homePage.goToModelingScene()
// wait until scene is ready to be interacted with
await scene.connectionEstablished()
await scene.settled(cmdBar)
await page.getByRole('button', { name: 'Start Sketch' }).click()
// select an axis plane
await page.mouse.click(700, 200)
// Needed as we don't yet have a way to get a signal from the engine that the camera has animated to the sketch plane
await page.waitForTimeout(1000)
const middleMousePan = async (
startX: number,
startY: number,
endX: number,
endY: number
) => {
const initialCode = await editor.getCurrentCode()
await page.mouse.click(startX, startY, { button: 'middle' })
await page.mouse.move(endX, endY, {
steps: 10,
})
// We expect the code to be the same, middle mouse click should not modify the code, only do panning
await editor.expectEditor.toBe(initialCode)
}
await test.step(`Verify corner rectangle panning`, async () => {
await page.getByTestId('corner-rectangle').click()
await middleMousePan(800, 500, 900, 600)
})
await test.step(`Verify center rectangle panning`, async () => {
await toolbar.selectCenterRectangle()
await middleMousePan(800, 200, 900, 300)
})
})
})

View File

@ -1,7 +1,8 @@
import { test, expect } from './zoo-test'
import * as fsp from 'fs/promises'
import { join } from 'path'
import { expect, test } from '@e2e/playwright/zoo-test'
const FEATURE_TREE_EXAMPLE_CODE = `export fn timesFive(x) {
return 5 * x
}
@ -21,7 +22,7 @@ sketch001 = startSketchOn(XZ)
|> angledLine([-45, length001], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
revolve001 = revolve(sketch001, axis = "X")
revolve001 = revolve(sketch001, axis = X)
triangle()
|> extrude(length = 30)
plane001 = offsetPlane(XY, offset = 10)
@ -126,7 +127,7 @@ test.describe('Feature Tree pane', () => {
await testViewSource({
operationName: 'Revolve',
operationIndex: 0,
expectedActiveLine: 'revolve001 = revolve(sketch001, axis = "X")',
expectedActiveLine: 'revolve001 = revolve(sketch001, axis = X)',
})
await testViewSource({
operationName: 'Triangle',

View File

@ -1,15 +1,16 @@
import { test, expect } from './zoo-test'
import * as fsp from 'fs/promises'
import { FILE_EXT } from '@src/lib/constants'
import * as fs from 'fs'
import * as fsp from 'fs/promises'
import { join } from 'path'
import {
createProject,
executorInputPath,
getUtils,
orRunWhenFullSuiteEnabled,
runningOnWindows,
} from './test-utils'
import { join } from 'path'
import { FILE_EXT } from 'lib/constants'
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('integrations tests', () => {
test(

View File

@ -1,5 +1,5 @@
import type { Page, Locator, Route, Request } from '@playwright/test'
import { expect, TestInfo } from '@playwright/test'
import type { Locator, Page, Request, Route, TestInfo } from '@playwright/test'
import { expect } from '@playwright/test'
import * as fs from 'fs'
import * as path from 'path'

View File

@ -1,11 +1,12 @@
import type { Page, Locator } from '@playwright/test'
import type { Locator, Page } from '@playwright/test'
import { expect } from '@playwright/test'
import {
closePane,
checkIfPaneIsOpen,
closePane,
openPane,
sansWhitespace,
} from '../test-utils'
} from '@e2e/playwright/test-utils'
interface EditorState {
activeLines: Array<string>
@ -81,6 +82,13 @@ export class EditorFixture {
expectEditor = {
toContain: this._expectEditorToContain(),
not: { toContain: this._expectEditorToContain(true) },
toBe: async (code: string) => {
const currentCode = await this.getCurrentCode()
return expect(currentCode).toBe(code)
},
}
getCurrentCode = async () => {
return await this.codeContent.innerText()
}
snapshot = async (options?: { timeout?: number; name?: string }) => {
const wasPaneOpen = await this.checkIfPaneIsOpen()

View File

@ -1,28 +1,28 @@
/* eslint-disable react-hooks/rules-of-hooks */
import type {
BrowserContext,
ElectronApplication,
TestInfo,
Page,
TestInfo,
} from '@playwright/test'
import { _electron as electron } from '@playwright/test'
import * as TOML from '@iarna/toml'
import { TEST_SETTINGS } from '../storageStates'
import { SETTINGS_FILE_NAME } from 'lib/constants'
import { getUtils, setup } from '../test-utils'
import { SETTINGS_FILE_NAME } from '@src/lib/constants'
import type { DeepPartial } from '@src/lib/types'
import fsp from 'fs/promises'
import fs from 'node:fs'
import path from 'path'
import { CmdBarFixture } from './cmdBarFixture'
import { EditorFixture } from './editorFixture'
import { ToolbarFixture } from './toolbarFixture'
import { SceneFixture } from './sceneFixture'
import { HomePageFixture } from './homePageFixture'
import { DeepPartial } from 'lib/types'
import { Settings } from '@rust/kcl-lib/bindings/Settings'
import type { Settings } from '@rust/kcl-lib/bindings/Settings'
import { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
import { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
import { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
import { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
import { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
import { TEST_SETTINGS } from '@e2e/playwright/storageStates'
import { getUtils, settingsToToml, setup } from '@e2e/playwright/test-utils'
export class AuthenticatedApp {
public readonly page: Page
@ -124,6 +124,7 @@ export class ElectronZoo {
// We need to expose this in order for some tests that require folder
// creation and some code below.
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this
const options = {
@ -286,26 +287,30 @@ export class ElectronZoo {
let settingsOverridesToml = ''
if (appSettings) {
settingsOverridesToml = TOML.stringify({
// @ts-expect-error
settingsOverridesToml = settingsToToml({
settings: {
...TEST_SETTINGS,
...appSettings,
app: {
...TEST_SETTINGS.app,
project_directory: this.projectDirName,
...appSettings.app,
},
project: {
...TEST_SETTINGS.project,
directory: this.projectDirName,
},
},
})
} else {
settingsOverridesToml = TOML.stringify({
// @ts-expect-error
settingsOverridesToml = settingsToToml({
settings: {
...TEST_SETTINGS,
app: {
...TEST_SETTINGS.app,
project_directory: this.projectDirName,
},
project: {
...TEST_SETTINGS.project,
directory: this.projectDirName,
},
},
})

View File

@ -1,4 +1,4 @@
import type { Page, Locator } from '@playwright/test'
import type { Locator, Page } from '@playwright/test'
import { expect } from '@playwright/test'
interface ProjectCardState {

View File

@ -1,15 +1,17 @@
import type { Page, Locator } from '@playwright/test'
import { expect } from '../zoo-test'
import { isArray, uuidv4 } from 'lib/utils'
import { CmdBarFixture } from './cmdBarFixture'
import type { Locator, Page } from '@playwright/test'
import { isArray, uuidv4 } from '@src/lib/utils'
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
import {
closeDebugPanel,
doAndWaitForImageDiff,
getPixelRGBs,
getUtils,
openAndClearDebugPanel,
sendCustomCmd,
getUtils,
} from '../test-utils'
} from '@e2e/playwright/test-utils'
import { expect } from '@e2e/playwright/zoo-test'
type MouseParams = {
pixelDiff?: number
@ -310,7 +312,9 @@ export async function expectPixelColor(
.toBeTruthy()
.catch((cause) => {
throw new Error(
`ExpectPixelColor: expecting ${colour} got ${finalValue}`,
`ExpectPixelColor: point ${JSON.stringify(
coords
)} was expecting ${colour} but got ${finalValue}`,
{ cause }
)
})

View File

@ -1,14 +1,18 @@
import { type Page, type Locator, test } from '@playwright/test'
import { expect } from '../zoo-test'
import { type Locator, type Page, test } from '@playwright/test'
import type { SidebarType } from '@src/components/ModelingSidebar/ModelingPanes'
import { SIDEBAR_BUTTON_SUFFIX } from '@src/lib/constants'
import type { ToolbarModeName } from '@src/lib/toolbar'
import {
checkIfPaneIsOpen,
closePane,
doAndWaitForImageDiff,
openPane,
} from '../test-utils'
import { SidebarType } from 'components/ModelingSidebar/ModelingPanes'
import { SIDEBAR_BUTTON_SUFFIX } from 'lib/constants'
import { ToolbarModeName } from 'lib/toolbar'
} from '@e2e/playwright/test-utils'
import { expect } from '@e2e/playwright/zoo-test'
import { type baseUnitLabels } from '@src/lib/settings/settingsTypes'
type LengthUnitLabel = (typeof baseUnitLabels)[keyof typeof baseUnitLabels]
export class ToolbarFixture {
public page: Page
@ -235,6 +239,12 @@ export class ToolbarFixture {
async checkIfFeatureTreePaneIsOpen() {
return this.checkIfPaneIsOpen(this.featureTreeId)
}
async selectUnit(unit: LengthUnitLabel) {
await this.page.getByTestId('units-menu').click()
const optionLocator = this.page.getByRole('button', { name: unit })
await expect(optionLocator).toBeVisible()
await optionLocator.click()
}
/**
* Get a specific operation button from the Feature Tree pane.

View File

@ -272,14 +272,6 @@ export const isErrorWhitelisted = (exception: Error) => {
project: 'Google Chrome',
foundInSpec: 'e2e/playwright/snapshot-tests.spec.ts',
},
// TODO: fix this error in the code
{
name: 'ReferenceError',
message: 'createNewVariableCheckbox is not defined',
stack: '',
project: 'Google Chrome',
foundInSpec: 'e2e/playwright/testing-constraints.spec.ts',
},
{
name: 'Error',
message: 'The "path" argument must be of type string. Received undefined',

View File

@ -1,7 +1,8 @@
import { test, expect } from './zoo-test'
import { executorInputPath } from './test-utils'
import { join } from 'path'
import fsp from 'fs/promises'
import { join } from 'path'
import { executorInputPath } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test(
'When machine-api server not found butt is disabled and shows the reason',
@ -11,7 +12,7 @@ test(
const bracketDir = join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
join(bracketDir, 'main.kcl')
)
})
@ -51,7 +52,7 @@ test(
const bracketDir = join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
join(bracketDir, 'main.kcl')
)
})

View File

@ -1,13 +1,15 @@
import { test, expect } from './zoo-test'
import { PROJECT_SETTINGS_FILE_NAME } from 'lib/constants'
import { PROJECT_SETTINGS_FILE_NAME } from '@src/lib/constants'
import * as fsp from 'fs/promises'
import { join } from 'path'
import type { NamedView } from '@rust/kcl-lib/bindings/NamedView'
import {
createProject,
tomlToPerProjectSettings,
perProjectsettingsToToml,
} from './test-utils'
import { NamedView } from '@rust/kcl-lib/bindings/NamedView'
tomlToPerProjectSettings,
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
// Helper function to determine if the file path on disk exists
// Specifically this is used to check if project.toml exists on disk

View File

@ -1,4 +1,4 @@
import { test, expect } from './zoo-test'
import { expect, test } from '@e2e/playwright/zoo-test'
/**
* Not all menu actions are tested. Some are default electron menu actions.
@ -10,6 +10,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('File.Create project', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const newProject =
@ -29,6 +30,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('File.Open project', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const openProject =
@ -52,6 +54,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
}) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const userSettings = app.applicationMenu.getMenuItemById(
@ -75,6 +78,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
}) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const keybindings = app.applicationMenu.getMenuItemById(
@ -96,6 +100,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
}) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -112,6 +117,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('File.Preferences.Theme', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -136,6 +142,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
}) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -152,6 +159,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('File.Preferences.Sign out', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById('File.Sign out')
@ -170,6 +178,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('Edit.Rename project', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -188,6 +197,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('Edit.Delete project', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -210,6 +220,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
}) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -228,6 +239,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('View.Command Palette...', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -245,6 +257,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('Help.Show all commands', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -260,6 +273,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('Help.KCL code samples', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -275,6 +289,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
}) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(
@ -293,6 +308,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
test('Help.Reset onboarding', async ({ tronApp, cmdBar, page }) => {
if (!tronApp) fail()
// Run electron snippet to find the Menu!
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
await tronApp.electron.evaluate(async ({ app }) => {
if (!app || !app.applicationMenu) fail()
const menu = app.applicationMenu.getMenuItemById(

View File

@ -2,8 +2,7 @@
// application, check it can make it to the project pane, and nothing more.
// It also tests our test wrappers are working.
// Additionally this serves as a nice minimal example.
import { test, expect } from './zoo-test'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Open the application', () => {
test('see the project view', async ({ page, context }) => {

View File

@ -1,22 +1,23 @@
import { test, expect } from './zoo-test'
import { join } from 'path'
import { bracket } from '@src/lib/exampleKcl'
import { onboardingPaths } from '@src/routes/Onboarding/paths'
import fsp from 'fs/promises'
import {
getUtils,
executorInputPath,
createProject,
settingsToToml,
orRunWhenFullSuiteEnabled,
} from './test-utils'
import { bracket } from 'lib/exampleKcl'
import { onboardingPaths } from 'routes/Onboarding/paths'
import { join } from 'path'
import { expectPixelColor } from '@e2e/playwright/fixtures/sceneFixture'
import {
TEST_SETTINGS_KEY,
TEST_SETTINGS_ONBOARDING_START,
TEST_SETTINGS_ONBOARDING_EXPORT,
TEST_SETTINGS_ONBOARDING_START,
TEST_SETTINGS_ONBOARDING_USER_MENU,
} from './storageStates'
import { expectPixelColor } from './fixtures/sceneFixture'
} from '@e2e/playwright/storageStates'
import {
createProject,
executorInputPath,
getUtils,
orRunWhenFullSuiteEnabled,
settingsToToml,
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
// Because our default test settings have the onboardingStatus set to 'dismissed',
// we must set it to empty for the tests where we want to see the onboarding immediately.

View File

@ -1,4 +1,4 @@
import { test, expect } from '@playwright/test'
import { expect, test } from '@playwright/test'
/** @deprecated, import from ./fixtureSetup.ts instead */
export const _test = test

View File

@ -1,12 +1,12 @@
import { Page } from '@playwright/test'
import { test, expect } from './zoo-test'
import { EditorFixture } from './fixtures/editorFixture'
import { SceneFixture } from './fixtures/sceneFixture'
import { ToolbarFixture } from './fixtures/toolbarFixture'
import type { Locator, Page } from '@playwright/test'
import fs from 'node:fs/promises'
import path from 'node:path'
import { getUtils, orRunWhenFullSuiteEnabled } from './test-utils'
import { Locator } from '@playwright/test'
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 { getUtils, orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
// test file is for testing point an click code gen functionality that's not sketch mode related
@ -137,7 +137,7 @@ test.describe('Point-and-click tests', () => {
await scene.moveCameraTo(cameraPos, cameraTarget)
await test.step('check chamfer selection changes cursor positon', async () => {
await test.step('check chamfer selection changes cursor position', async () => {
await expect(async () => {
// sometimes initial click doesn't register
await clickChamfer()
@ -173,7 +173,7 @@ test.describe('Point-and-click tests', () => {
})
await test.step('Check there is no errors after code created in previous steps executes', async () => {
await editor.expectState({
activeLines: ['sketch001 = startSketchOn(XZ)'],
activeLines: ['@settings(defaultLengthUnit = in)'],
highlightedCode: '',
diagnostics: [],
})
@ -299,7 +299,8 @@ test.describe('Point-and-click tests', () => {
await test.step('verify at the end of the test that final code is what is expected', async () => {
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag]
|> angledLine([0, 268.43], %, $rectangleSegmentA001)
|> angledLine([
@ -369,7 +370,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
})
})
test('Works on chamfers that are non in a pipeExpression can break up multi edges in a chamfer array', async ({
test('Works on chamfers that are not in a pipeExpression can break up multi edges in a chamfer array', async ({
context,
page,
homePage,
@ -418,7 +419,8 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|>close()`,
})
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> startProfileAt([75.8, 317.2], %)
|> angledLine([0, 268.43], %, $rectangleSegmentA001)
|> angledLine([
@ -1082,8 +1084,8 @@ openSketch = startSketchOn(XY)
}) => {
// One dumb hardcoded screen pixel value
const testPoint = { x: 620, y: 257 }
const expectedOutput = `helix001 = helix( axis = 'X', radius = 5, length = 5, revolutions = 1, angleStart = 360, ccw = false,)`
const expectedLine = `axis='X',`
const expectedOutput = `helix001 = helix( axis = X, radius = 5, length = 5, revolutions = 1, angleStart = 360, ccw = false,)`
const expectedLine = `axis=X,`
await homePage.goToModelingScene()
@ -1215,7 +1217,7 @@ openSketch = startSketchOn(XY)
cmdBar,
}) => {
page.on('console', console.log)
const initialCode = `sketch001 = startSketchOn('XZ')
const initialCode = `sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([0, 0], sketch001)
|> yLine(length = 100)
|> line(endAbsolute = [100, 0])
@ -1639,9 +1641,10 @@ loft001 = loft([sketch001, sketch002])
{
targetType: 'circle',
testPoint: { x: 700, y: 250 },
initialCode: `sketch001 = startSketchOn('YZ')
initialCode: `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(YZ)
profile001 = circle(sketch001, center = [0, 0], radius = 500)
sketch002 = startSketchOn('XZ')
sketch002 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> xLine(length = -500)
|> tangentialArcTo([-2000, 500], %)`,
@ -1649,7 +1652,8 @@ sketch002 = startSketchOn('XZ')
{
targetType: 'rectangle',
testPoint: { x: 710, y: 255 },
initialCode: `sketch001 = startSketchOn('YZ')
initialCode: `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(YZ)
profile001 = startProfileAt([-400, -400], sketch001)
|> angledLine([0, 800], %, $rectangleSegmentA001)
|> angledLine([
@ -1662,7 +1666,7 @@ profile001 = startProfileAt([-400, -400], sketch001)
], %)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
sketch002 = startSketchOn('XZ')
sketch002 = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> xLine(length = -500)
|> tangentialArcTo([-2000, 500], %)`,
@ -1806,7 +1810,8 @@ sketch002 = startSketchOn('XZ')
toolbar,
cmdBar,
}) => {
const initialCode = `sketch001 = startSketchOn(YZ)
const initialCode = `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(YZ)
|> circle(
center = [0, 0],
radius = 500
@ -2475,7 +2480,8 @@ extrude001 = extrude(profile001, length = 5)
cmdBar,
}) => {
// Code samples
const initialCode = `sketch001 = startSketchOn(XY)
const initialCode = `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XY)
|> startProfileAt([-12, -6], %)
|> line(end = [0, 12])
|> line(end = [24, 0])
@ -2767,7 +2773,8 @@ extrude001 = extrude(sketch001, length = -12)
toolbar,
}) => {
// Code samples
const initialCode = `sketch001 = startSketchOn(XY)
const initialCode = `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XY)
|> startProfileAt([-12, -6], %)
|> line(end = [0, 12])
|> line(end = [24, 0], tag = $seg02)
@ -2921,7 +2928,8 @@ chamfer04 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)])
toolbar,
cmdBar,
}) => {
const initialCode = `sketch001 = startSketchOn(XZ)
const initialCode = `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 30)
extrude001 = extrude(sketch001, length = 30)
`
@ -3056,7 +3064,8 @@ extrude001 = extrude(sketch001, length = 30)
toolbar,
cmdBar,
}) => {
const initialCode = `sketch001 = startSketchOn(XY)
const initialCode = `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XY)
|> startProfileAt([-20, 20], %)
|> xLine(length = 40)
|> yLine(length = -60)
@ -3174,7 +3183,8 @@ extrude001 = extrude(sketch001, length = 40)
})
const shellSketchOnFacesCases = [
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 100)
|> extrude(length = 100)
@ -3182,7 +3192,8 @@ sketch002 = startSketchOn(sketch001, 'END')
|> circle(center = [0, 0], radius = 50)
|> extrude(length = 50)
`,
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> circle(center = [0, 0], radius = 100)
extrude001 = extrude(sketch001, length = 100)
@ -3463,8 +3474,41 @@ segAng(rectangleSegmentA002),
await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar()
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = 'X')`
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)`
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
// 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)
)
})
test('revolve surface around edge from an extruded solid2d', async ({
context,
@ -3475,26 +3519,22 @@ segAng(rectangleSegmentA002),
toolbar,
cmdBar,
}) => {
const initialCode = `
sketch001 = startSketchOn(XZ)
|> startProfileAt([-102.57, 101.72], %)
|> angledLine([0, 202.6], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
202.6
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
const initialCode = `sketch001 = startSketchOn(XZ)
|> startProfileAt([-102.57, 101.72], %)
|> angledLine([0, 202.6], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001) - 90,
202.6
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude001 = extrude(sketch001, length = 50)
sketch002 = startSketchOn(extrude001, rectangleSegmentA001)
|> circle(
center = [-11.34, 10.0],
radius = 8.69
)
|> circle(center = [-11.34, 10.0], radius = 8.69)
`
await context.addInitScript((initialCode) => {
localStorage.setItem('persistCode', initialCode)
@ -3512,9 +3552,49 @@ radius = 8.69
const lineCodeToSelection = `|> angledLine([0, 202.6], %, $rectangleSegmentA001)`
await page.getByText(lineCodeToSelection).click()
await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar()
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = getOppositeEdge(rectangleSegmentA001)) `
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
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)
await page.getByRole('button', { name: 'Create new variable' }).click()
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')
)
})
test('revolve sketch circle around line segment from startProfileAt sketch', async ({
context,
@ -3525,26 +3605,22 @@ radius = 8.69
toolbar,
cmdBar,
}) => {
const initialCode = `
sketch002 = startSketchOn(XY)
|> startProfileAt([-2.02, 1.79], %)
|> xLine(length = 2.6)
sketch001 = startSketchOn('-XY')
|> startProfileAt([-0.48, 1.25], %)
|> angledLine([0, 2.38], %, $rectangleSegmentA001)
|> angledLine([segAng(rectangleSegmentA001) - 90, 2.4], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude001 = extrude(sketch001, length = 5)
sketch003 = startSketchOn(extrude001, 'START')
|> circle(
center = [-0.69, 0.56],
radius = 0.28
)
const initialCode = `sketch002 = startSketchOn(XY)
|> startProfileAt([-2.02, 1.79], %)
|> xLine(length = 2.6)
sketch001 = startSketchOn(-XY)
|> startProfileAt([-0.48, 1.25], %)
|> angledLine([0, 2.38], %, $rectangleSegmentA001)
|> angledLine([segAng(rectangleSegmentA001) - 90, 2.4], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $rectangleSegmentC001)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
extrude001 = extrude(sketch001, length = 5)
sketch003 = startSketchOn(extrude001, 'START')
|> circle(center = [-0.69, 0.56], radius = 0.28)
`
await context.addInitScript((initialCode) => {
@ -3563,9 +3639,44 @@ radius = 8.69
const lineCodeToSelection = `|> xLine(length = 2.6)`
await page.getByText(lineCodeToSelection).click()
await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar()
await cmdBar.progressCmdBar()
const newCodeToFind = `revolve001 = revolve(sketch003, angle = 360, axis = seg01)`
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
// Edit flow
const newAngle = '270'
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)
)
})
})
@ -3578,7 +3689,8 @@ radius = 8.69
toolbar,
cmdBar,
}) => {
const initialCode = `sketch001 = startSketchOn(XZ)
const initialCode = `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
profile001 = circle(
sketch001,
center = [0, 0],

View File

@ -1,19 +1,20 @@
import { test, expect } from './zoo-test'
import { DEFAULT_PROJECT_KCL_FILE } from '@src/lib/constants'
import fs from 'fs'
import fsp from 'fs/promises'
import path from 'path'
import type { Paths } from '@e2e/playwright/test-utils'
import {
createProject,
doExport,
executorInputPath,
getPlaywrightDownloadDir,
getUtils,
isOutOfViewInScrollContainer,
Paths,
createProject,
getPlaywrightDownloadDir,
orRunWhenFullSuiteEnabled,
runningOnWindows,
} from './test-utils'
import fsp from 'fs/promises'
import fs from 'fs'
import path from 'path'
import { DEFAULT_PROJECT_KCL_FILE } from 'lib/constants'
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test(
'projects reload if a new one is created, deleted, or renamed externally',
@ -87,7 +88,7 @@ test(
const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'main.kcl')
)
})
@ -124,7 +125,7 @@ test(
const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'main.kcl')
)
const errorDir = path.join(dir, 'broken-code')
@ -162,7 +163,7 @@ test(
// gray at this pixel means the stream has loaded in the most
// user way we can verify it (pixel color)
await expect
.poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), {
.poll(() => u.getGreatestPixDiff(pointOnModel, [110, 110, 110]), {
timeout: 10_000,
})
.toBeLessThan(20)
@ -213,7 +214,7 @@ test(
const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'main.kcl')
)
const emptyDir = path.join(dir, 'empty')
@ -248,7 +249,7 @@ test(
// gray at this pixel means the stream has loaded in the most
// user way we can verify it (pixel color)
await expect
.poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), {
.poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), {
timeout: 10_000,
})
.toBeLessThan(15)
@ -290,7 +291,7 @@ test(
const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'main.kcl')
)
@ -319,7 +320,7 @@ test(
// gray at this pixel means the stream has loaded in the most
// user way we can verify it (pixel color)
await expect
.poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), {
.poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), {
timeout: 10_000,
})
.toBeLessThan(15)
@ -359,7 +360,7 @@ test(
const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'main.kcl')
)
await fsp.copyFile(
@ -393,7 +394,7 @@ test(
// gray at this pixel means the stream has loaded in the most
// user way we can verify it (pixel color)
await expect
.poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), {
.poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), {
timeout: 10_000,
})
.toBeLessThan(15)
@ -443,7 +444,6 @@ test(
await page.getByText('broken-code').click()
// Gotcha: You can not use scene.waitForExecutionDone() since the KCL code is going to fail
await expect(page.getByTestId('loading')).toBeAttached()
await expect(page.getByTestId('loading')).not.toBeAttached({
timeout: 20_000,
})
@ -481,7 +481,7 @@ test.describe('Can export from electron app', () => {
const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'main.kcl')
)
})
@ -513,7 +513,7 @@ test.describe('Can export from electron app', () => {
// gray at this pixel means the stream has loaded in the most
// user way we can verify it (pixel color)
await expect
.poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), {
.poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), {
timeout: 10_000,
})
.toBeLessThan(15)
@ -554,7 +554,7 @@ test.describe('Can export from electron app', () => {
},
{ timeout: 15_000 }
)
.toBeGreaterThan(300_000)
.toBeGreaterThan(50_000)
// clean up exported file
await fsp.rm(filepath)
@ -1507,7 +1507,12 @@ test(
await u.waitForPageLoad()
await page.locator('.cm-content').fill(`sketch001 = startSketchOn(XZ)
// The file should be prepopulated with the user's unit settings.
await expect(page.locator('.cm-content')).toHaveText(
'@settings(defaultLengthUnit = in)'
)
await page.locator('.cm-content').fill(`sketch001 = startSketchOn('XZ')
|> startProfileAt([-87.4, 282.92], %)
|> line(end = [324.07, 27.199], tag = $seg01)
|> line(end = [118.328, -291.754])

View File

@ -1,4 +1,5 @@
import { test, expect } from './zoo-test'
import { expect, test } from '@e2e/playwright/zoo-test'
/* eslint-disable jest/no-conditional-expect */
/**

View File

@ -1,5 +1,5 @@
import { test, expect } from './zoo-test'
import { orRunWhenFullSuiteEnabled } from './test-utils'
import { orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
/* eslint-disable jest/no-conditional-expect */

View File

@ -1,17 +1,18 @@
import { Page } from '@playwright/test'
import { test, expect } from './zoo-test'
import path from 'path'
import type { Page } from '@playwright/test'
import { bracket } from '@src/lib/exampleKcl'
import { reportRejection } from '@src/lib/trap'
import * as fsp from 'fs/promises'
import path from 'path'
import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from '@e2e/playwright/storageStates'
import type { TestColor } from '@e2e/playwright/test-utils'
import {
getUtils,
executorInputPath,
TEST_COLORS,
TestColor,
executorInputPath,
getUtils,
orRunWhenFullSuiteEnabled,
} from './test-utils'
import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from './storageStates'
import { bracket } from 'lib/exampleKcl'
import { reportRejection } from 'lib/trap'
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Regression tests', { tag: ['@skipWin'] }, () => {
// bugs we found that don't fit neatly into other categories
@ -331,7 +332,7 @@ extrude001 = extrude(sketch001, length = 50)
localStorage.setItem(
'persistCode',
`@settings(defaultLengthUnit = mm)
sketch002 = startSketchOn('XY')
sketch002 = startSketchOn(XY)
profile002 = startProfileAt([72.24, -52.05], sketch002)
|> angledLine([0, 181.26], %, $rectangleSegmentA001)
|> angledLine([
@ -582,7 +583,7 @@ extrude002 = extrude(profile002, length = 150)
const bracketDir = path.join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
executorInputPath('cylinder-inches.kcl'),
path.join(bracketDir, 'main.kcl')
)
})
@ -619,6 +620,7 @@ extrude002 = extrude(profile002, length = 150)
test(`View gizmo stays visible even when zoomed out all the way`, async ({
page,
homePage,
scene,
}) => {
const u = await getUtils(page)
@ -632,7 +634,7 @@ extrude002 = extrude(profile002, length = 150)
await test.step(`Load an empty file`, async () => {
await page.addInitScript(async () => {
localStorage.setItem('persistCode', '')
localStorage.setItem('persistCode', '@settings(defaultLengthUnit = in)')
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
@ -646,22 +648,31 @@ extrude002 = extrude(profile002, length = 150)
timeout: 5000,
message: 'Plane color is visible',
})
.toBeLessThanOrEqual(15)
.toBeLessThanOrEqual(20)
await expect(scene.startEditSketchBtn).toBeEnabled()
let maxZoomOuts = 10
let middlePixelIsBackgroundColor =
(await middlePixelIsColor(bgColor)) < 10
console.time('pressing control')
await page.keyboard.down('Control')
while (!middlePixelIsBackgroundColor && maxZoomOuts > 0) {
await page.keyboard.down('Control')
await page.mouse.move(600, 460)
await page.mouse.down({ button: 'right' })
await page.mouse.move(600, 50, { steps: 20 })
await page.mouse.up({ button: 'right' })
await page.keyboard.up('Control')
await page.waitForTimeout(100)
await page.mouse.move(650, 460)
console.time('moved to start point')
await page.mouse.down({ button: 'right' })
console.time('moused down')
await page.mouse.move(650, 50, { steps: 20 })
console.time('moved to end point')
await page.waitForTimeout(100)
await page.mouse.up({ button: 'right' })
console.time('moused up')
maxZoomOuts--
middlePixelIsBackgroundColor = (await middlePixelIsColor(bgColor)) < 10
middlePixelIsBackgroundColor = (await middlePixelIsColor(bgColor)) < 15
}
await page.keyboard.up('Control')
expect(middlePixelIsBackgroundColor, {
message: 'We should not see the default planes',
@ -678,13 +689,12 @@ extrude002 = extrude(profile002, length = 150)
homePage,
scene,
toolbar,
viewport,
}) => {
await context.folderSetupFn(async (dir) => {
const legoDir = path.join(dir, 'lego')
await fsp.mkdir(legoDir, { recursive: true })
await fsp.copyFile(
executorInputPath('lego.kcl'),
executorInputPath('e2e-can-sketch-on-chamfer.kcl'),
path.join(legoDir, 'main.kcl')
)
})
@ -697,11 +707,8 @@ extrude002 = extrude(profile002, length = 150)
await scene.loadingIndicator.waitFor({ state: 'detached' })
})
await test.step(`The part should start loading quickly, not waiting until execution is complete`, async () => {
await scene.expectPixelColor(
[143, 143, 143],
{ x: (viewport?.width ?? 1200) / 2, y: (viewport?.height ?? 500) / 2 },
15
)
// TODO: use the viewport size to pick the center point, but the `viewport` fixture's values were wrong.
await scene.expectPixelColor([116, 116, 116], { x: 500, y: 250 }, 15)
})
})
@ -791,6 +798,74 @@ plane002 = offsetPlane(XZ, offset = -2 * x)`
await page.getByTestId('custom-cmd-send-button').click()
}
)
test('scale other than default works with sketch mode', async ({
page,
homePage,
toolbar,
editor,
scene,
}) => {
await test.step('Load the washer code', async () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`@settings(defaultLengthUnit = in)
innerDiameter = 0.203
outerDiameter = 0.438
thicknessMax = 0.038
thicknessMin = 0.024
washerSketch = startSketchOn(XY)
|> circle(center = [0, 0], radius = outerDiameter / 2)
washer = extrude(washerSketch, length = thicknessMax)`
)
})
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
})
const [circleCenterClick] = scene.makeMouseHelpers(650, 300)
const [circleRadiusClick] = scene.makeMouseHelpers(800, 320)
const [washerFaceClick] = scene.makeMouseHelpers(657, 286)
await page.waitForTimeout(100)
await test.step('Start sketching on the washer face', async () => {
await toolbar.startSketchPlaneSelection()
await washerFaceClick()
await page.waitForTimeout(600) // engine animation
await toolbar.expectToolbarMode.toBe('sketching')
})
await test.step('Draw a circle and verify code', async () => {
// select circle tool
await expect
.poll(async () => {
await toolbar.circleBtn.click()
return toolbar.circleBtn.getAttribute('aria-pressed')
})
.toBe('true')
await page.waitForTimeout(100)
await circleCenterClick()
// this number will be different if the scale is not set correctly for inches
await editor.expectEditor.toContain(
'circle(sketch001, center = [0.06, -0.06]'
)
await circleRadiusClick()
await editor.expectEditor.toContain(
'circle(sketch001, center = [0.06, -0.06], radius = 0.18'
)
})
await test.step('Exit sketch mode', async () => {
await toolbar.exitSketch()
await toolbar.expectToolbarMode.toBe('modeling')
await toolbar.selectUnit('Yards')
await editor.expectEditor.toContain('@settings(defaultLengthUnit = yd)')
})
})
})
async function clickExportButton(page: Page) {

View File

@ -1,20 +1,20 @@
import { Page } from '@playwright/test'
import { test, expect } from './zoo-test'
import type { Page } from '@playwright/test'
import { roundOff, uuidv4 } from '@src/lib/utils'
import fs from 'node:fs/promises'
import path from 'node:path'
import { HomePageFixture } from './fixtures/homePageFixture'
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
import {
getMovementUtils,
getUtils,
PERSIST_MODELING_CONTEXT,
TEST_COLORS,
getMovementUtils,
getUtils,
orRunWhenFullSuiteEnabled,
} from './test-utils'
import { uuidv4, roundOff } from 'lib/utils'
import { SceneFixture } from './fixtures/sceneFixture'
import { ToolbarFixture } from './fixtures/toolbarFixture'
import { CmdBarFixture } from './fixtures/cmdBarFixture'
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
test('multi-sketch file shows multiple Edit Sketch buttons', async ({
@ -113,7 +113,8 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
|> startProfileAt([2.61, -4.01], %)
|> xLine(length = 8.73)
|> tangentialArcTo([8.33, -1.31], %)`
@ -159,7 +160,10 @@ test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
await page.mouse.click(700, 200)
await expect.poll(u.normalisedEditorCode, { timeout: 1000 })
.toBe(`sketch002 = startSketchOn(XZ)
.toBe(`@settings(defaultLengthUnit = in)
sketch002 = startSketchOn(XZ)
sketch001 = startProfileAt([12.34, -12.34], sketch002)
|> yLine(length = 12.34)
@ -475,7 +479,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit=in)
sketch001 = startSketchOn(XZ)
|> circle(center = [4.61, -5.01], radius = 8)`
)
})
@ -560,12 +565,14 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
test('Can edit a sketch that has been extruded in the same pipe', async ({
page,
homePage,
editor,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit=in)
sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -10.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -0.38], %)
@ -650,31 +657,34 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XZ)
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
|> startProfileAt([7.12, -12.68], %)
|> line(end = [12.68, -1.09])
|> tangentialArcTo([24.89, 0.68], %)
|> close()
|> extrude(length = 5)
`)
|> extrude(length = 5)`,
{ shouldNormalise: true }
)
})
test('Can edit a sketch that has been revolved in the same pipe', async ({
page,
homePage,
scene,
editor,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit=in)
sketch001 = startSketchOn(XZ)
|> startProfileAt([4.61, -14.01], %)
|> line(end = [12.73, -0.09])
|> tangentialArcTo([24.95, -5.38], %)
|> close()
|> revolve(axis = "X")`
|> revolve(axis = X)`
)
})
@ -754,14 +764,16 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`sketch001 = startSketchOn(XZ)
await editor.expectEditor.toContain(
`sketch001 = startSketchOn(XZ)
|> startProfileAt([6.44, -12.07], %)
|> line(end = [14.72, 1.97])
|> tangentialArcTo([24.95, -5.38], %)
|> line(end = [1.97, 2.06])
|> close()
|> revolve(axis = "X")`)
|> revolve(axis = X)`,
{ shouldNormalise: true }
)
})
test('Can add multiple sketches', async ({ page, homePage }) => {
const u = await getUtils(page)
@ -789,7 +801,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
200
)
let codeStr = 'sketch001 = startSketchOn(XY)'
let codeStr =
'@settings(defaultLengthUnit = in)sketch001 = startSketchOn(XY)'
await page.mouse.click(center.x, viewportSize.height * 0.55)
await expect(u.codeLocator).toHaveText(codeStr)
@ -868,7 +881,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002)
await u.openDebugPanel()
const code = `sketch001 = startSketchOn(-XZ)
const code = `@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(-XZ)
profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
scale * 34.8
)}], sketch001)
@ -898,7 +912,7 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
await page.mouse.move(700, 200, { steps: 10 })
await page.mouse.click(700, 200, { delay: 200 })
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn(-XZ)`
`@settings(defaultLengthUnit = in)sketch001 = startSketchOn(-XZ)`
)
let prevContent = await page.locator('.cm-content').innerText()
@ -1209,7 +1223,7 @@ profile001 = startProfileAt([${roundOff(scale * 69.6)}, ${roundOff(
|> xLine(endAbsolute = 0 + .001)
|> yLine(endAbsolute = 0)
|> close()
|> revolve(axis = "Y")
|> revolve(axis = Y)
return lugSketch
}
@ -1426,7 +1440,8 @@ test.describe(`Sketching with offset planes`, () => {
await context.addInitScript(() => {
localStorage.setItem(
'persistCode',
`offsetPlane001 = offsetPlane(XY, offset = 10)`
`@settings(defaultLengthUnit = in)
offsetPlane001 = offsetPlane(XY, offset = 10)`
)
})
@ -1440,7 +1455,7 @@ test.describe(`Sketching with offset planes`, () => {
await test.step(`Hovering should highlight code`, async () => {
await planeHover()
await editor.expectState({
activeLines: [`offsetPlane001=offsetPlane(XY,offset=10)`],
activeLines: [`@settings(defaultLengthUnit = in)`],
diagnostics: [],
highlightedCode: 'offsetPlane(XY, offset = 10)',
})
@ -1453,7 +1468,7 @@ test.describe(`Sketching with offset planes`, () => {
await expect(toolbar.lineBtn).toBeEnabled()
await editor.expectEditor.toContain('startSketchOn(offsetPlane001)')
await editor.expectState({
activeLines: [`offsetPlane001=offsetPlane(XY,offset=10)`],
activeLines: [`@settings(defaultLengthUnit = in)`],
diagnostics: [],
highlightedCode: '',
})
@ -1604,7 +1619,8 @@ profile002 = startProfileAt([117.2, 56.08], sketch001)
await context.addInitScript(() => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
profile002 = startProfileAt([40.68, 87.67], sketch001)
|> xLine(length = 239.17)
profile003 = startProfileAt([206.63, -56.73], sketch001)
@ -2172,7 +2188,8 @@ profile003 = startProfileAt([206.63, -56.73], sketch001)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([6.24, 4.54], sketch001)
|> line(end = [-0.41, 6.99])
|> line(end = [8.61, 0.74])
@ -2317,7 +2334,8 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07]
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([6.24, 4.54], sketch001)
|> line(end = [-0.41, 6.99])
|> line(end = [8.61, 0.74])
@ -2422,7 +2440,8 @@ profile003 = circle(sketch001, center = [6.92, -4.2], radius = 3.16)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([-63.43, 193.08], sketch001)
|> line(end = [168.52, 149.87])
|> line(end = [190.29, -39.18])
@ -2486,7 +2505,11 @@ extrude001 = extrude(profile003, length = 5)
page,
}) => {
await page.addInitScript(async () => {
localStorage.setItem('persistCode', `myVar = 5`)
localStorage.setItem(
'persistCode',
`@settings(defaultLengthUnit = in)
myVar = 5`
)
})
await page.setBodyDimensions({ width: 1000, height: 500 })
@ -2533,7 +2556,8 @@ extrude001 = extrude(profile003, length = 5)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([85.19, 338.59], sketch001)
|> line(end = [213.3, -94.52])
|> line(end = [-230.09, -55.34])
@ -2575,7 +2599,8 @@ profile002 = startProfileAt([85.81, 52.55], sketch002)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`thePart = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
thePart = startSketchOn(XZ)
|> startProfileAt([7.53, 10.51], %)
|> line(end = [12.54, 1.83])
|> line(end = [6.65, -6.91])
@ -2636,7 +2661,8 @@ extrude001 = extrude(thePart, length = 75)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([6.71, -3.66], sketch001)
|> line(end = [2.65, 9.02], tag = $seg02)
|> line(end = [3.73, -9.36], tag = $seg01)
@ -2809,7 +2835,8 @@ extrude003 = extrude(profile011, length = 2.5)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`sketch001 = startSketchOn(XZ)
`@settings(defaultLengthUnit = in)
sketch001 = startSketchOn(XZ)
profile001 = startProfileAt([34, 42.66], sketch001)
|> line(end = [102.65, 151.99])
|> line(end = [76, -138.66])

View File

@ -1,21 +1,22 @@
import { test, expect } from './zoo-test'
import { secrets } from './secrets'
import {
Paths,
doExport,
getUtils,
settingsToToml,
orRunWhenFullSuiteEnabled,
} from './test-utils'
import { Models } from '@kittycad/lib'
import fsp from 'fs/promises'
import type { Models } from '@kittycad/lib'
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
import { spawn } from 'child_process'
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
import fsp from 'fs/promises'
import JSZip from 'jszip'
import path from 'path'
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from './storageStates'
import { SceneFixture } from './fixtures/sceneFixture'
import { CmdBarFixture } from './fixtures/cmdBarFixture'
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
import { secrets } from '@e2e/playwright/secrets'
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
import type { Paths } from '@e2e/playwright/test-utils'
import {
doExport,
getUtils,
orRunWhenFullSuiteEnabled,
settingsToToml,
} from '@e2e/playwright/test-utils'
import { expect, test } from '@e2e/playwright/zoo-test'
test.beforeEach(async ({ page, context }) => {
// Make the user avatar image always 404
@ -76,11 +77,11 @@ part001 = startSketchOn(-XZ)
|> xLine(endAbsolute = totalLen, tag = $seg03)
|> yLine(length = -armThick, tag = $seg01)
|> angledLineThatIntersects({
angle = HALF_TURN,
angle = turns::HALF_TURN,
offset = -armThick,
intersectTag = seg04
}, %)
|> angledLineToY([segAng(seg04, %) + 180, ZERO], %)
|> angledLineToY([segAng(seg04, %) + 180, turns::ZERO], %)
|> angledLineToY({
angle = -bottomAng,
to = -totalHeightHalf - armThick,
@ -88,12 +89,12 @@ part001 = startSketchOn(-XZ)
|> xLine(length = endAbsolute = segEndX(seg03) + 0)
|> yLine(length = -segLen(seg01, %))
|> angledLineThatIntersects({
angle = HALF_TURN,
angle = turns::HALF_TURN,
offset = -armThick,
intersectTag = seg02
}, %)
|> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %)
|> xLine(endAbsolute = ZERO)
|> xLine(endAbsolute = turns::ZERO)
|> close()
|> extrude(length = 4)`
)
@ -345,7 +346,9 @@ const extrudeDefaultPlane = async (
app: {
onboarding_status: 'dismissed',
show_debug_panel: true,
theme: 'dark',
appearance: {
theme: 'dark',
},
},
project: {
default_project_name: 'project-$nnn',
@ -452,7 +455,7 @@ test(
await page.waitForTimeout(700) // TODO detect animation ending, or disable animation
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
code += `profile001 = startProfileAt([7.19, -9.7], sketch001)`
code += `profile001 = startProfileAt([182.59, -246.32], sketch001)`
await expect(page.locator('.cm-content')).toHaveText(code)
await page.waitForTimeout(100)
@ -470,7 +473,7 @@ test(
await page.waitForTimeout(500)
code += `
|> xLine(length = 7.25)`
|> xLine(length = 184.3)`
await expect(page.locator('.cm-content')).toHaveText(code)
await page
@ -628,7 +631,7 @@ test(
mask: [page.getByTestId('model-state-indicator')],
})
await expect(page.locator('.cm-content')).toHaveText(
`sketch001 = startSketchOn(XZ)profile001 = circle(sketch001, center = [14.44, -2.44], radius = 1)`
`sketch001 = startSketchOn(XZ)profile001 = circle(sketch001, center = [366.89, -62.01], radius = 1)`
)
}
)
@ -665,7 +668,7 @@ test.describe(
const startXPx = 600
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
code += `profile001 = startProfileAt([7.19, -9.7], sketch001)`
code += `profile001 = startProfileAt([182.59, -246.32], sketch001)`
await expect(u.codeLocator).toHaveText(code)
await page.waitForTimeout(100)
@ -673,7 +676,7 @@ test.describe(
await page.waitForTimeout(100)
code += `
|> xLine(length = 7.25)`
|> xLine(length = 184.3)`
await expect(u.codeLocator).toHaveText(code)
await page
@ -688,7 +691,7 @@ test.describe(
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
code += `
|> tangentialArcTo([21.7, -2.44], %)`
|> tangentialArcTo([551.2, -62.01], %)`
await expect(u.codeLocator).toHaveText(code)
// click tangential arc tool again to unequip it

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 70 KiB

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