Compare commits

..

132 Commits

Author SHA1 Message Date
49c8fc4c97 Update bracket example code and some test colors that broke 2024-09-03 18:35:09 -04:00
3cbda10eab Update next/prev adjacency + tests to match engine (#3706)
* update next/prev adjacency + tests to match engine

* quick tests fix post engine merge
2024-09-03 13:34:31 -07:00
0f3432b5a0 fix frame on non macs (#3751)
* fix frame on non macs

* fixes

* fmt

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jessie Frazelle <jess@zoo.dev>
2024-09-03 12:11:29 -07:00
f11dc07f0b internal: Remove unused wait-on dependency (#3749)
Remove unused wait-on dependency
2024-09-03 14:30:57 -04:00
e49beb6609 Package with electron-builder and enable auto-updates (#3717)
* WIP: enable build releases
Will eventually fix #3528

* Build on all branches

* WIP: electron-forge publish to gcs

* WIP env var

* WIP windows

* WIP checkout in publish

* Back to matrix for build-apps and upstream wasm build

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP clean up out upload with all dry runs

* WIP macos

* Clean up

* Add update-electron-app

* Bump version down to 0.24.11

* Explicit NODE_ENV=production

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* Push dummy version 0.99.99

* Undo

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* Trigger CI

* Lint

* Experiment with DMG and MSI

* Split up artifacts

* Executable name to Zoo Modeling App

* Linux kebab-case exe, autoUpdate on wix

* Experiment with electron-builder

* WIP

* fail-fast false

* tronb:vite

* DMG and NSIS

* Typo

* Disable updater for electron-builder tests, quick fix

* WIP macOS sign and notarize

* WIP Win signing

* CSC_FOR_PULL_REQUEST

* Comment out signingHashAlgorithms

* APPLE_APP_SPECIFIC_PASSWORD and move scripts

* notarize: true and change script link

* mac.notarize.teamid

* Clean up and first steps on auto updater

* Lint

* Add logs

* Work on nsis config

* More extensive configs

* Clean up

* Test push updater

* Push again; Fix lint

* Bump down to 0.24.11 to test, disable publish

* WIP mac updater

* Back to .12 to push zips

* Back to .11 to test

* Back to .12 to push to same dir

* Fix windows and names

* Back to .11 to test, no publish

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* Push again .12

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* Add publisherName as in certificate

* Back to 11 build

* Add msi target

* MSI params

* perMarchine: false

* .12 msi push

* WIP tauri bundle generation (macOS)

* Typo

* Universal build mac

* Test last_update tauri gen for macOS

* VERSION fix

* Add v to VERSION

* Add v to VERSION part 2

* Fix tar

* WIP windows updater

* WIP windows

* Change Compress-Archive to 7z on Windows

* 7z change

* Fix flag

* -mm Deflate

* -mm Copy and version .99

* perMachine true

* perMachine true

* Manual autoUpdater.quitAndInstall

* Test NSIS for tauri transition

* WIP

* No more universal for mac, last_download.json endpoint

* Typo in json

* Tweaks

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* Fix typo in download.json

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)"

This reverts commit 0d6d67ec2c.

* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)"

This reverts commit b01bc589ab.

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)"

This reverts commit 5deff7614f.

* Fix tauri update json for universal to arch specified

* Fix tauri update json for universal to arch specified part 2

* Fix tauri update json for universal to arch specified part 3

* Back to checkUpdateAndNotify, frames on window

* Clean up

* Default prod env values

* CI clean up

* More clean up

* Override if forge env not set

* Make basic-sketch test more robust

* Fix env vars set

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: 49lf <ircsurfer33@gmail.com>
2024-09-03 12:30:14 -04:00
b8f27b77a8 Bump async-trait from 0.1.81 to 0.1.82 in /src/wasm-lib (#3747)
Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.81 to 0.1.82.
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.81...0.1.82)

---
updated-dependencies:
- dependency-name: async-trait
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-03 09:15:03 -07:00
fa7e31223d Bump postcss from 8.4.41 to 8.4.43 (#3740)
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.41 to 8.4.43.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.41...8.4.43)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-02 14:32:32 -07:00
f04c4588df Update .gitignore 2024-09-02 14:16:08 -07:00
c95812efa6 Bump kittycad from 0.3.17 to 0.3.18 in /src/wasm-lib (#3674)
Bumps [kittycad](https://github.com/KittyCAD/kittycad.rs) from 0.3.17 to 0.3.18.
- [Release notes](https://github.com/KittyCAD/kittycad.rs/releases)
- [Commits](https://github.com/KittyCAD/kittycad.rs/compare/v0.3.17...v0.3.18)

---
updated-dependencies:
- dependency-name: kittycad
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-02 12:38:50 -07:00
96385cd5ee Bump syn from 2.0.76 to 2.0.77 in /src/wasm-lib (#3743)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.76 to 2.0.77.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.76...2.0.77)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-02 11:46:07 -07:00
64707edaad Bump tokio from 1.39.3 to 1.40.0 in /src/wasm-lib (#3742)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.39.3 to 1.40.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.39.3...tokio-1.40.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-02 11:45:58 -07:00
27baf135e7 Parse multi-line comments in |> expressions (#3731)
Fixes #3708, ty @mlfarrell for reporting!
2024-08-30 21:12:00 -05:00
a4cf68c661 replace tanArc(to) with tanArcToRelative (#3729)
* replace tanArc(to) with tanArcToRelative

Closes #3319

* Handle invalid tanArcs
2024-08-30 13:44:20 -05:00
403e074249 Nadro/3686/file swapping while executing (#3703)
* chore: Implemented a executeAst interrupt to stop processing a KCL program

* fix: added a catch since this promise was not being caught

* fix: fmt formatting, need to fix some tsc errors next.

* fix: fixing tsc errors

* fix: cleaning up comment

* fix: only rejecting pending modeling commands

* fix: adding constant for rejection message, adding rejection in WASM send command

* fix: tsc, lint, fmt checks

* fix circ dependency

---------

Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
2024-08-30 10:14:24 +00:00
50259aa052 add edges to Artifact Graph (Fillet UI related) (#3675)
* add edges to artifact graph

* update graph snapshot sizes (too cluttered

* fix adjencent reverse issue

* add comments

* remove log

* Look at this (photo)Graph *in the voice of Nickelback*

* remove log

* remove silly debug

* make wasm-prep windows friendly

* don't swallow error

* more rust tweaks

* Increase test timeout

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2024-08-30 19:46:48 +10:00
1739f3dafe new snapshots (#3725)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-29 15:58:38 -07:00
7ceb518446 Fix tests for upcoming PR (#3723)
fix tests for upcoming PR
2024-08-29 15:27:00 -07:00
36a6b8c0ea KCL None needs more specific serialization (#3720)
Previously, many KCL values could be deserialized as KCL None values.
This isn't good -- the only thing you should be able to possibly
deserialize as KCL None is KCL None.

Solution was to add a private field in KCL None, serialize it with a
special magic number value, and then check for that magic number when
deserializing
2024-08-29 13:41:32 -05:00
bbdca7421e New sign-in page and signed-in on-load animation (#3684)
* Basic sign-in page layout

* Better responsive styling

* Add wipe animation

* Fix mobile button styling

* Add juicy on-load animation to logo in app header

* Make video card a link to the sample's code

* Fix video URL on bundled desktop app, add "open default browser" behavior to links

* Revert "Add juicy on-load animation to logo in app header"

This reverts commit c167569d7e.

---------

Co-authored-by: 49fl <ircsurfer33@gmail.com>
2024-08-29 14:21:42 -04:00
03c6f6d60e Fix extrude button (#3718)
* Fix: regression on command bar buttons (remove drag)

* Revert "Fix: regression on command bar buttons (remove drag)"

This reverts commit 2404bcdf31.

* Make all elements opt-out of drag behavior by default, add comments around drag attribute

* Add vendor-specific user-select

* It won't do to make all elements opt-out, it ends up swallowing the drag events themselves!

* Sneaking in this email truncation nit that's bothered me

* Gotta remove that one more attempt at a generic "we made this clickable" element

* Make orbit continue to work when dragging over the AppHeader

---------

Co-authored-by: Frank Noirot <frank@kittycad.io>
2024-08-29 10:38:13 -04:00
18c7e7934a remove electron test console noise (#3713) 2024-08-29 07:55:27 +00:00
bf650fd129 Fix Stream shows the inside of sketch after extrude (#3711)
Fix Stream shows the inside of sketch after extrude 2998
2024-08-29 16:45:46 +10:00
81ccb65f15 remove double zoom to fit (#3710)
remove double zoom to fit 3217
2024-08-29 16:28:57 +10:00
335b5100ae Fix playwright artifact paths to be unique (#3704) 2024-08-28 17:30:20 -04:00
1162ff3b03 Update machine-api for modified api schema (#3572)
update to new machine-api format
2024-08-28 15:15:37 -04:00
5e8227ead8 File tree stuff (#3679)
* Fix and test file tree operations

* fmt

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

* Make tsc happy

* I've been lied to

* Fix navigating to deleted file

* tsc

* Remove debugger statement

* Fix test

* All tests fixed

* Remove old config and remove slowmo

* fmt

* Remove unintentional changelog in readme (#3678)

* lint

* fmt

* Increase test timeout

* Fix the damn test

* fix web app

* fmt

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
2024-08-28 06:38:14 -04:00
max
ed339a6b9a Bug: Fillet Button - selecting edge without tag caused an Error rev2 (#3690)
* typos

* typos2

* trigger ci
2024-08-28 01:53:33 +02:00
1d19fc6b7e Fix platform detection in Vite (#3689) 2024-08-27 19:02:49 -04:00
max
5b5355376f Revert "Bug: Fillet Button - selecting edge without tag caused an Error" (#3687)
Revert "Bug: Fillet Button - selecting edge without tag caused an Error (#3685)"

This reverts commit 5c90f72c91.
2024-08-28 00:20:50 +02:00
max
5c90f72c91 Bug: Fillet Button - selecting edge without tag caused an Error (#3685)
fixed
2024-08-27 21:49:46 +00:00
026a8d19cb Remove unintentional changelog in readme (#3678) 2024-08-27 17:27:41 +00:00
6dd0981709 make wasm-build windows safe (#3676)
make wasm-prep windows safe
2024-08-27 11:26:52 +00:00
b231a26115 more conclusive text to cad playwright tests (#3672) 2024-08-27 06:36:05 +00:00
3f47486fb5 fix electron playwright reports/traces (#3670)
add matricx to playwright reports
2024-08-27 02:04:34 +00:00
57e97d16d0 integrate wasm-prep (#3671)
* integrate wasm-prep

* update readme
2024-08-27 01:35:11 +00:00
dbdc7e5c8b add maker wix (#3668)
* add maker wix

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>
2024-08-26 13:54:18 -07:00
f6bb10170d Ensure auth device token is saved to a file so it persists upgrades and reinstalls (#3640)
* ensure auth device token is saved to a file so it persists upgrades and reinstalls
#3639

* write file on check log in

* write file on check log in

* clean up
2024-08-27 05:59:25 +10:00
972dca8743 Change mouse controls display to be easier to understand (#3648)
* Change mouse controls display to be easier to understand

* Fix to not duplicate default camera controls

* Change "Scroll wheel" to "Scroll" on all platforms
2024-08-26 15:05:33 -04:00
e9e933eecd remove priviledged schemes (#3666)
updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-26 18:27:20 +00:00
2b1315423f Bump serde_json from 1.0.125 to 1.0.127 in /src/wasm-lib (#3662)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.125 to 1.0.127.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/1.0.125...1.0.127)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 10:03:11 -07:00
bd4c24bc04 Remove references to src-tauri (#3663)
* Remove references to src-tauri

* Remove more ignores from the electron migration
2024-08-26 16:31:28 +00:00
50cc88977c Bump micromatch from 4.0.7 to 4.0.8 (#3649)
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.7 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/4.0.8/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.7...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 16:16:23 +00:00
bea9a1c3ec Bump syn from 2.0.75 to 2.0.76 in /src/wasm-lib (#3659)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.75 to 2.0.76.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.75...2.0.76)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 08:56:37 -07:00
f43411fdb4 Bump serde from 1.0.208 to 1.0.209 in /src/wasm-lib (#3661)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.208 to 1.0.209.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.208...v1.0.209)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 08:55:52 -07:00
max
c2e9d18f92 3036 tests add fillet (#3530)
* addFillet.ts - refactor existing code

* move logic from modelingMachine to addFillet

* rename getPathForSelection into getPathToExtrudeForSegmentSelection

* stuck with kclManager

* stuck 2

* remove engineless exe from fillet test

* pathToExtrudeNode properly tested

* resolve conflicts

* engine initialization update

* cleanup comments

* passed ExecuteArgs instead of Program to executeAst

* afterAll engineCommandManager.tearDown

* resolve conflicts

* mutateAstForRadiusInsertion

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* save banner from hulk mutations

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* sweet errors

* purging the as

* make type of getNodeFromPath safe again

* as cleaning part 2

* cleared mutation logic

* last bits

* make the linter happy

---------

Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-26 08:07:20 +02:00
199722c505 fix and tests (#3656)
* fix and tests

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>
2024-08-25 22:14:38 +00:00
f9699d174c header changes and open new window for double click in finder macos (#3652)
* header changes and open new window for double click in finder macos

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

* cleanup

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

* add protocols

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

* updates

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

* extend with info.plist

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>
2024-08-25 19:56:11 +00:00
590a6479e0 double-click to open / open from cli (#3643)
* fixes

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

* add tests

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

* updates

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

* Look at this (photo)Graph *in the voice of Nickelback*

* remove unneeded rust

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

* remove dep on clap

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

* fixups for imports

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

* updates

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

* fix types

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

* bump

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-25 00:47:09 +00:00
fbf0d3d953 Nadro/3581/change base unit test (#3621)
* fix: Updating the playwright tests section

* fix: cleaning up formatting for playwright test markdown

* fix: autocomplete put a 3rd *

* chore: e2e playwright for change of base unit in multiple scenarios

* fix: fmt auto format

* fix: fmt and clean up for PR

* fix: removing typo

* fix: added the ) formatting back

* fix: linting errors + formatting

* fix: removing unused testing code from previous logic

---------

Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-24 23:51:50 +00:00
3dd66bc8d2 Add test for not creating main.kcl when there are nested directories (#3647)
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-24 23:51:36 +00:00
a928b8fbd0 Update README.md to add updating upstreams for kcl-lib (#3650)
Update README.md
2024-08-24 16:33:01 -07:00
d2349bec2b chore: implemented e2e tests for text-to-cad file workflows (#3645) 2024-08-24 15:31:27 -07:00
6e10f75ff6 KCL executor: accept and send 'replay' flag, track session data (#3646)
Part of https://github.com/KittyCAD/engine/issues/2504:

The engine accepts this 'replay' flag now, so, accept it too and send it up to the engine.

Part of https://github.com/KittyCAD/cli/issues/847

The engine sends 'session data' now (like the API Call ID). The CLI executes KCL using this executor, and would like to get the session data after execution.
2024-08-23 17:40:30 -05:00
03e289af20 Fix Commands button to show correct shortcut on Windows and Linux (#3625)
* Fix Commands button to show correct shortcut

* Fix onboarding to use the same shortcut reference

* Rename test file to be more general

* Add test for commands button text

* Remove outdated reference to Ctrl+/

* Change shortcut separator to be + and no spaces

* Add JSDocs and improve comments

* Add unit tests

* Change control modifier to regular ASCII caret

* Add browser test and fix platform detection

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* Add useful debug info to the error message

* Fix to display metaKey as Super on Linux

* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)"

This reverts commit f8da90d5d2.

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* Approve snapshots

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-23 16:20:22 -04:00
efc140abbf Test: Can load a file with CRLF line endings (#3636)
* Test: Can load a file with CRLF line endings #3616

* first arg stuff??

* Fix paths in playwright for windows

* Fix line ending replace on windows

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

---------

Co-authored-by: Adam Sunderland <iterion@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Co-authored-by: Adam Sunderland <adam@kittycad.io>
2024-08-23 13:51:30 -04:00
4dfad19b7e add hollow (#3642)
* add hollow

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>
2024-08-23 16:57:02 +00:00
e56c634b35 Fix existing: Zoom should be consistent when exiting or entering sketches (#3638)
#3637
2024-08-23 16:10:46 +00:00
00292abc98 Bump @babel/preset-env from 7.25.3 to 7.25.4 (#3630)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.25.3 to 7.25.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.4/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-23 09:00:56 -07:00
483d6903d6 Bump @kittycad/lib from 2.0.0 to 2.0.1 (#3631)
Bumps [@kittycad/lib](https://github.com/KittyCAD/kittycad.ts) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/KittyCAD/kittycad.ts/releases)
- [Commits](https://github.com/KittyCAD/kittycad.ts/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: "@kittycad/lib"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-23 09:00:48 -07:00
3780996374 Fix opening bottom right version link in external browser (#3633) 2024-08-23 09:00:18 -07:00
2fde71228a Bump quote from 1.0.36 to 1.0.37 in /src/wasm-lib (#3628)
Bumps [quote](https://github.com/dtolnay/quote) from 1.0.36 to 1.0.37.
- [Release notes](https://github.com/dtolnay/quote/releases)
- [Commits](https://github.com/dtolnay/quote/compare/1.0.36...1.0.37)

---
updated-dependencies:
- dependency-name: quote
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-23 08:48:53 -07:00
5cd8ab3812 Enable all disabled win32 tests (#3618)
* Enable all disabled win32 tests

* Skip one test
2024-08-23 10:50:40 -04:00
9a385fb474 Release kcl-lib 0.2.7 (#3641) 2024-08-23 08:11:37 -05:00
b740d25bbd Bump kittycad to 0.3.16 (#3626)
Bump kittycad
2024-08-23 07:50:30 -05:00
ef350b020b file in the file tree open with a single click [fix me remove] (#3635) 2024-08-23 10:29:12 +00:00
4d2375faac tests for file manager the stuff that should happen on disk (#3634)
tests for file manager the stuff that should happen on disk #3587
2024-08-23 17:11:17 +10:00
22a9f44916 fix coredump home page (#3624)
updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-22 17:18:29 -07:00
713a30ed72 Fix initial default app settings behavior when the user has no settings yet (#3601)
Fix initial default app settings behavior when the user has no settings yet.

Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-22 16:51:26 -07:00
ebed10bc76 Franknoirot/fix file deletion (#3569)
* Don't chop off file name from file path

* Add a test to confirm file deletion works (as long as you have a main.kcl)

* Add TODO test for when main.kcl doesn't exist

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* Make the bad prompt test generate a new prompt each run

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: 49fl <ircsurfer33@gmail.com>
2024-08-22 19:42:21 -04:00
acbe92d717 Fix keyboard shortcuts to use Control on Windows and Linux (#3620)
* Fix keyboard shortcuts to use Control instead of Meta on Windows and Linux

* Convert more tests to use Playwright built-in
2024-08-22 16:13:27 -07:00
e624c9b124 fix failing tests from chalmers pr (#3619)
* fix failing tests from chalmers pr

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

* fix memory pane

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-22 15:00:20 -07:00
877eb3ec5e Lock the rust toolchain version (#3617) 2024-08-22 13:09:28 -07:00
64500d055a Add safer isArray function (#3606)
* Add safer isArray function

* Fix formatting
2024-08-22 13:08:49 -07:00
5df996d877 Bump @types/node from 22.4.2 to 22.5.0 (#3611)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.4.2 to 22.5.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 13:03:44 -07:00
84d70751af Bump husky from 9.1.4 to 9.1.5 (#3592)
Bumps [husky](https://github.com/typicode/husky) from 9.1.4 to 9.1.5.
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](https://github.com/typicode/husky/compare/v9.1.4...v9.1.5)

---
updated-dependencies:
- dependency-name: husky
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 13:03:29 -07:00
3899999465 Bump vite from 5.3.5 to 5.4.2 (#3591)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.3.5 to 5.4.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 13:03:16 -07:00
9f370fbb56 default to production when no NODE_ENV (#3614)
* default to production when no NODE_ENV

* tweak message

---------

Co-authored-by: 49fl <ircsurfer33@gmail.com>
2024-08-22 13:02:23 -07:00
f750c4ea8b Nadro/3394/project name regression (#3609)
* exporting createProjectAndRenameIt, going to be used for a third time

* feat: added e2e test to test project name retention after onboarding plays

* fix: formatting, adding Page type

* fix: resolved linter warnings, wrong syntax and function name typo
2024-08-22 13:00:13 -07:00
e16ecc28a3 KCL parser: Allow comments in multi-line object expression (#3607)
Like my previous PR to array expressions (https://github.com/KittyCAD/modeling-app/pull/3539), but for object expressions. Closes https://github.com/KittyCAD/modeling-app/issues/1528
2024-08-22 13:54:59 -05:00
a2d8c5a714 Fix path splitting issues on windows (#3565)
* Fix path splitting issues on windows

* Fix path splitting issue on routeLoaders

* Enable some e2e tests

* Swap enabled e2e tests

* Working bare-min project parse

* Make tsc happy

* Clean up & enable more tests

* Fix paths in browser

* Fix tests for windows

fmt

* Clean up wasm side

* Make build:wasm windows compatible

* More paths cleanup & some tests

* Remove sleep

* Use new config sturcture in parseroute

* Clean up debugger

* Fix: on settings close go back to the same file (#3549)

* Fix: on settings close go back to the same file

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* shit aint working yo

* Get that page a-loading

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>

* Fmt

* Comment out currently failing win32 tests

* Ignore tsc for electron monkey-patch

* Force line-endings to only

* Fix tsc

* Enable more tests

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* Avoid modifying global for tests

---------

Co-authored-by: 49fl <ircsurfer33@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-22 13:38:53 -04:00
0bb4586e6d enable Playwright list reporter (#3411)
enable list reporter

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
2024-08-22 20:51:43 +10:00
bbabf04ba6 electron icons (#3613)
* Add back in app icons that got wiped from Tauri version of the app
#3526

* linux

* windows icon size

* clean up
2024-08-22 17:51:18 +10:00
37a1208924 Fix existing: Extrude from command bar selects extrude line after (#3547)
* Fix existing: Extrude from command bar selects extrude line after #3545

* remove as

---------

Co-authored-by: Frank Noirot <frank@zoo.dev>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-22 16:13:08 +10:00
682099c1ad Bump phonenumber in fuzz (#3610) 2024-08-21 16:01:49 -05:00
8f3ad0d43c Bump phonenumber (#3608)
but then who bumped phone????
2024-08-21 14:52:15 -05:00
be047f5111 add unit functions (#3604)
* add unit functions

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

* add tests

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

* update docs

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

* updates

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* empty

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-21 12:12:56 -07:00
d656a389f8 Remove KclValue::SketchGroup variant (#3446)
We can store Rust types like `SketchGroup` as their own variant of `KclValue`, or as `KclValue::UserVal`. Sometimes we store in one and try to read from the other, which fails. This causes bugs, like #3338.

Instead, we should use either ::SketchGroup or ::UserVal, and stop using the other. If we stopped using ::UserVal, we'd need a new variant for every Rust type we wanted to build, including user-defined types. So I don't think that's practical.

Instead, we should store every KCL value by de/serializing it into UserVal. This is a first step along that path, removing just the SketchGroup variants. If it goes well, we can remove the other specialized variants too.

My only concern is there might be performance implications from how frequently we convert between serde_json::Value and Rust types via Serde. But I'm not too worried -- there's no parsing JSON strings, just traversing serde_json::Value trees. This isn't great for performance but I think it'll probably be miniscule in comparison to doing all the API calls.
2024-08-21 11:06:48 -05:00
682590deea KCL parser: allow comments in multi-line arrays (#3539)
KCL parser: allow noncode (e.g. comments) in arrays

Part of #1528
2024-08-21 09:54:15 -05:00
925f5cc2c2 windows doesn't like cp, in build wasm script (#3599) 2024-08-21 15:55:59 +10:00
a167c174f9 add another skip to make windows tron happy (#3597)
add another skip to make windows happy
2024-08-21 15:23:01 +10:00
7f297c13fd Test for reconnect and theme (#3264)
add test
2024-08-21 15:02:54 +10:00
a7e3d83297 Test for 3 export paths (#3596)
test for 3 export paths #3582
2024-08-21 15:02:39 +10:00
f74c12aa99 Bump @types/react from 18.3.3 to 18.3.4 (#3595)
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.3.3 to 18.3.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 21:15:00 -07:00
5df9965795 Bump @types/node from 22.4.1 to 22.4.2 (#3594)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.4.1 to 22.4.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 21:14:45 -07:00
50d80eb0b6 Bump electron from 31.4.0 to 32.0.1 (#3593)
Bumps [electron](https://github.com/electron/electron) from 31.4.0 to 32.0.1.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v31.4.0...v32.0.1)

---
updated-dependencies:
- dependency-name: electron
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 21:14:32 -07:00
96d24065d6 Bump google-github-actions/auth from 2.1.3 to 2.1.5 (#3589)
Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2.1.3 to 2.1.5.
- [Release notes](https://github.com/google-github-actions/auth/releases)
- [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/auth/compare/v2.1.3...v2.1.5)

---
updated-dependencies:
- dependency-name: google-github-actions/auth
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 21:12:46 -07:00
61dc94b1ee Show the SketchGroup can be found even if it's deeper in an object (#3462)
* Show the SketchGroup can be found even if it's deeper in an object

* trigger rust

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
2024-08-20 21:12:38 -07:00
f14c27e1c4 Add the unexpected token to the error message (#3430)
* Add the unexpected token to the error message

This is helpful during development where there's nothing to point at
the character index.

* Update more tests
2024-08-20 20:49:19 -07:00
c09775f5eb Fix existing: file renaming (and more things that spin out of settings file path parsing) (#3584)
* Fix the behavior so that we navigate to the new file path

* This change is done in other PRs but is also necessary here

* Add an Electron Playwright test for renaming a file

* Add tests for renaming dir, one is failing

* Don't need that console.warn

* Add DeepPartial utility type

* Fix settings parsing so that project path parsing is fixed

* Move URL check after DOM checks

* Revert this fallback behavior from https://github.com/KittyCAD/modeling-app/pull/3564 as we don't need it now that config parsing is fixed

* Make new bad prompt each run

* Fix onboarding asset path in web

* Remove double parsing of settings config

* Remove unused imports

* More unused imports

* Fix broken rename test

* Update src/lib/desktop.ts

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>

* Add test for renaming file we do not have open

* fmt

---------

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
2024-08-20 22:16:44 -04:00
d14b8f5443 Add electron test for persisting open panes (#3535)
* Add electron test for persisting open panes

* Debugging persistence across test runs

* Trigger addInitScript for electron

* Remove init of PERSIST_MODELING_CONTEXT key

* Remove unused code

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

---------

Co-authored-by: 49lf <ircsurfer33@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-20 19:11:21 -07:00
4a14ca38ab Fix to convert electron platform name darwin to macos (#3573)
* Fix to convert electron platform name darwin to macos

* Remove unneeded async

* Fix to handle other possible platform strings

* Add electron test for user sidebar menu text

* Fix formatting
2024-08-20 19:08:02 -07:00
3543c5f0e7 Update tests after ben merge of fillet working w shell (#3586)
* fixes

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

* bump all the things

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-20 18:57:23 -07:00
a0dc5f4a89 Update machine-api spec (#3585)
* YOYO NEW API SPEC!

* New machine-api types

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-20 17:13:18 -07:00
9d148938a2 Fix app version in prod (#3579)
* fix app version, make more dry

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

* updates

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

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* empty

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* empty

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* empty

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-20 15:15:25 -07:00
9c6cca2944 Revert "reflow machines from k/v" (#3575)
This reverts commit f77b312ecb.
2024-08-20 14:07:32 -07:00
5c472c63d2 fix for when response status is not okay (#3574)
* fix for when response status is not okay

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>
2024-08-20 13:40:21 -07:00
f77b312ecb reflow machines from k/v 2024-08-20 16:28:41 -04:00
8a66d0df76 Fix a couple issues with settings reset on web & electron (#3564)
* Fix a couple issues with settings reset on web & electron

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2024-08-20 11:06:39 -07:00
b3dc3ff78c Bump google-github-actions/upload-cloud-storage from 2.1.0 to 2.1.3 (#3556)
Bumps [google-github-actions/upload-cloud-storage](https://github.com/google-github-actions/upload-cloud-storage) from 2.1.0 to 2.1.3.
- [Release notes](https://github.com/google-github-actions/upload-cloud-storage/releases)
- [Changelog](https://github.com/google-github-actions/upload-cloud-storage/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/upload-cloud-storage/compare/v2.1.0...v2.1.3)

---
updated-dependencies:
- dependency-name: google-github-actions/upload-cloud-storage
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 10:16:18 -07:00
d02df08471 Bump actions/github-script from 4 to 7 (#3555)
Bumps [actions/github-script](https://github.com/actions/github-script) from 4 to 7.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 10:16:02 -07:00
aac758b396 Run yarn format (#3566) 2024-08-20 10:22:37 -05:00
0ef6eac239 Fix existing: when engine fails export we handle the failure and alert the user (#3561)
Fix existing: when engine fails export we handle the failure and alert the user #3560
2024-08-20 20:29:15 +10:00
c674feb782 Update the Web Banner (#3563)
Update the Web Banner #3503
2024-08-20 20:28:39 +10:00
fba3d7c5c1 skip failing windows tests (#3558) 2024-08-20 06:37:16 +00:00
8b8fb696d0 Fix existing: Can edit a sketch that has been extruded in the same pipe (#3552)
Fix existing: Can edit a sketch that has been extruded in the same pipe #3551
2024-08-20 14:13:56 +10:00
d05f3c00b9 test keyboard shortcuts from help menu (#3553)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-19 20:17:23 -07:00
2541e0c0ea Electron test (regression): select all in code editor does not actually select all, just what is visiable (#3540)
* select all in code editor does not actually select all, just what is visible #3175

* whops

* fix test for linux
2024-08-20 11:23:32 +10:00
5e5a204244 move the file (#3544)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2024-08-19 17:55:26 -07:00
032c2fdd24 Add GitHub action to label issues opened by ZooSpiritWolf (#3543)
* Add GitHub action to label issues opened by ZooSpiritWolf

Fixes #3541

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/KittyCAD/modeling-app/issues/3541?shareId=XXXX-XXXX-XXXX-XXXX).

* Update label-issues.yml
2024-08-19 17:54:24 -07:00
27883e7800 Electron machine api tests (#3534)
* start

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>

* Look at this (photo)Graph *in the voice of Nickelback*

* updates

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

* fixes

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

* hide on webapp

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

* fixes

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

* fix machine-api

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-19 15:57:31 -07:00
1ccb810e23 Revert "electron test code with error loading" (#3533)
Revert "electron test code with error loading (#3531)"

This reverts commit c7f533b38e.
2024-08-19 14:23:01 -07:00
1c83f148d9 export on project/file pane load playwright test (#3489)
* export on project/file pane load

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

add desktop exxport

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

* updates

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

* Look at this (photo)Graph *in the voice of Nickelback*

* updates

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

* fix lint

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

* fixeds

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

* fixes

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

* fixups

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-19 14:21:34 -07:00
c7f533b38e electron test code with error loading (#3531)
* electron test code with error loading

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

* Look at this (photo)Graph *in the voice of Nickelback*

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-19 13:54:11 -07:00
2b711d216f Run eslint in CI (#3487)
* Run eslint in CI

* Add linting of e2e

* Fix formatting

* Fix new warnings in e2e

* Fix more new warnings
2024-08-19 12:36:18 -07:00
c67511f67c Electron test: (regression) you can scroll the file pane when ETOOMANYFILES to view in one view (#3520)
* can scroll files pane

* clean up
2024-08-20 05:34:26 +10:00
d9423219d1 Bump @csstools/postcss-oklab-function from 3.0.19 to 4.0.2 (#3517)
Bumps [@csstools/postcss-oklab-function](https://github.com/csstools/postcss-plugins/tree/HEAD/plugins/postcss-oklab-function) from 3.0.19 to 4.0.2.
- [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)

---
updated-dependencies:
- dependency-name: "@csstools/postcss-oklab-function"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 12:29:10 -07:00
3f270d8bcf Bump react-router-dom from 6.26.0 to 6.26.1 (#3516)
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.26.0 to 6.26.1.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.26.1/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 12:28:59 -07:00
4c7b72329d Bump @playwright/test from 1.45.3 to 1.46.1 (#3514)
Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.45.3 to 1.46.1.
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.45.3...v1.46.1)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 12:27:12 -07:00
4c060f3d2f Bump electron from 31.3.1 to 31.4.0 (#3515)
Bumps [electron](https://github.com/electron/electron) from 31.3.1 to 31.4.0.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v31.3.1...v31.4.0)

---
updated-dependencies:
- dependency-name: electron
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 12:26:53 -07:00
f3afbe8a7b Bump @types/node from 18.19.42 to 22.4.1 (#3513)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 18.19.42 to 22.4.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 12:26:36 -07:00
dad7a84798 Bump tokio from 1.39.2 to 1.39.3 in /src/wasm-lib (#3511)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.39.2 to 1.39.3.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.39.2...tokio-1.39.3)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 12:26:03 -07:00
1a560fdc6a Bump syn from 2.0.74 to 2.0.75 in /src/wasm-lib (#3510)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.74 to 2.0.75.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.74...2.0.75)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 12:25:53 -07:00
358 changed files with 23909 additions and 7515 deletions

View File

@ -1,3 +1,3 @@
[codespell]
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey,atleast,ue,afterall
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,./src-tauri/gen/schemas,.yarn.lock,**/yarn.lock
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock

View File

@ -25,7 +25,9 @@
"files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
"rules": {
"@typescript-eslint/no-floating-promises": "warn",
"testing-library/prefer-screen-queries": "off"
"suggest-no-throw/suggest-no-throw": "off",
"testing-library/prefer-screen-queries": "off",
"jest/valid-expect": "off"
}
},
{

View File

@ -1,4 +1,4 @@
name: build-test-publish-apps
name: build-publish-apps
on:
pull_request:
@ -21,7 +21,7 @@ concurrency:
cancel-in-progress: true
jobs:
prepare-json-files:
prepare-files:
runs-on: ubuntu-22.04 # seperate job on Ubuntu for easy string manipulations (compared to Windows)
outputs:
version: ${{ steps.export_version.outputs.version }}
@ -33,6 +33,19 @@ jobs:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: './src/wasm-lib'
# TODO: see if we can fetch from main instead if no diff at src/wasm-lib
- name: Run build:wasm
run: "yarn build:wasm${{ env.BUILD_RELEASE == 'true' && '-dev' || ''}}"
- name: Set nightly version
if: github.event_name == 'schedule'
run: |
@ -42,36 +55,50 @@ jobs:
# TODO: see if we ned to add updater test URL here https://dl.zoo.dev/releases/modeling-app/updater-test/last_update.json
- uses: actions/upload-artifact@v3
if: ${{ github.event_name == 'schedule' || env.CUT_RELEASE_PR == 'true' }}
with:
name: prepared-files
path: |
package.json
src/wasm-lib/pkg/wasm_lib*
- id: export_version
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
build-test-app-macos:
needs: [prepare-json-files]
runs-on: macos-14
build-apps:
needs: [prepare-files]
strategy:
fail-fast: false
matrix:
os: [macos-14, windows-2022, ubuntu-22.04]
runs-on: ${{ matrix.os }}
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
CSC_FOR_PULL_REQUEST: true
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
VERSION: ${{ github.event_name == 'schedule' && needs.prepare-files.outputs.version || format('v{0}', needs.prepare-files.outputs.version) }}
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
WINDOWS_CERTIFICATE_THUMBPRINT: F4C9A52FF7BC26EE5E054946F6B11DEEA94C748D
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v3
if: github.event_name == 'schedule'
name: prepared-files
- name: Copy updated .json files
if: github.event_name == 'schedule'
- name: Copy prepared files
run: |
ls -l artifact
cp artifact/package.json package.json
ls -R prepared-files
cp prepared-files/package.json package.json
cp prepared-files/src/wasm-lib/pkg/wasm_lib_bg.wasm public
mkdir src/wasm-lib/pkg
cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg
- name: Sync node version and setup cache
uses: actions/setup-node@v4
@ -81,79 +108,10 @@ jobs:
- run: yarn install
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: './src/wasm-lib'
- name: Run build:wasm
run: "yarn build:wasm${{ env.BUILD_RELEASE == 'true' && '-dev' || ''}}"
# TODO: sign the app (and updater bundle potentially)
- name: Add signing certificate
if: ${{ env.BUILD_RELEASE == 'true' }}
run: chmod +x add-osx-cert.sh && ./add-osx-cert.sh
- name: Build the app for arm64
run: "yarn electron-forge make"
- name: Build the app for x64
run: "yarn electron-forge make --arch x64"
- name: List artifacts
run: "ls -R out/make"
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
- uses: actions/upload-artifact@v3
with:
path: "out/make/*/*/*/*"
build-test-app-windows:
needs: [prepare-json-files]
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v3
- name: Copy updated .json files
if: github.event_name == 'schedule'
run: |
ls -l artifact
cp artifact/package.json package.json
- name: Sync node version and setup cache
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn' # Set this to npm, yarn or pnpm.
- run: yarn install
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: './src/wasm-lib'
- name: Run build:wasm manually
shell: bash
env:
MODE: ${{ env.BUILD_RELEASE == 'true' && '--release' || '--debug' }}
run: |
mkdir src/wasm-lib/pkg; cd src/wasm-lib
echo "building with ${{ env.MODE }}"
npx wasm-pack build --target web --out-dir pkg ${{ env.MODE }}
cd ../../
cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
- run: yarn tronb:vite
- name: Prepare certificate and variables (Windows only)
if: ${{ env.BUILD_RELEASE == 'true' }}
if: ${{ env.BUILD_RELEASE == 'true' && matrix.os == 'windows-2022' }}
run: |
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
cat /d/Certificate_pkcs12.p12
@ -168,7 +126,7 @@ jobs:
shell: bash
- name: Setup certicate with SSM KSP (Windows only)
if: ${{ env.BUILD_RELEASE == 'true' }}
if: ${{ env.BUILD_RELEASE == 'true' && matrix.os == 'windows-2022' }}
run: |
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
msiexec /i smtools-windows-x64.msi /quiet /qn
@ -178,83 +136,47 @@ jobs:
smksp_cert_sync.exe
shell: cmd
- name: Build the app for x64
run: "yarn electron-forge make --arch x64"
- name: Build the app
run: yarn electron-builder --config ${{ env.BUILD_RELEASE && '--publish always' || '' }}
- name: Build the app for arm64
run: "yarn electron-forge make --arch arm64"
- name: List artifacts in out/
run: ls -R out
- name: List artifacts
run: "ls -R out/make"
- name: Sign using Signtool
if: ${{ env.BUILD_RELEASE == 'true' }}
env:
THUMBPRINT: "F4C9A52FF7BC26EE5E054946F6B11DEEA94C748D"
X64_FILE: "D:\\a\\modeling-app\\modeling-app\\out\\make\\squirrel.windows\\x64\\Zoo Modeling App-*Setup.exe"
ARM64_FILE: "D:\\a\\modeling-app\\modeling-app\\out\\make\\squirrel.windows\\arm64\\Zoo Modeling App-*Setup.exe"
- name: Prepare the tauri update bundles (macOS)
if: ${{ env.BUILD_RELEASE && matrix.os == 'macos-14' }}
run: |
signtool.exe sign /sha1 ${{ env.THUMBPRINT }} /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 "${{ env.X64_FILE }}"
signtool.exe verify /v /pa "${{ env.X64_FILE }}"
signtool.exe sign /sha1 ${{ env.THUMBPRINT }} /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 "${{ env.ARM64_FILE }}"
signtool.exe verify /v /pa "${{ env.ARM64_FILE }}"
for ARCH in arm64 x64; do
TAURI_DIR=out/tauri/$VERSION/macos
TEMP_DIR=temp/$ARCH
mkdir -p $TAURI_DIR
mkdir -p $TEMP_DIR
unzip out/*-$ARCH-mac.zip -d $TEMP_DIR
tar -czvf "$TAURI_DIR/Zoo Modeling App-$ARCH.app.tar.gz" -C $TEMP_DIR "Zoo Modeling App.app"
yarn tauri signer sign "$TAURI_DIR/Zoo Modeling App-$ARCH.app.tar.gz"
done
ls -R out
- name: Prepare the tauri update bundles (Windows)
if: ${{ env.BUILD_RELEASE && matrix.os == 'windows-2022' }}
run: |
$env:TAURI_DIR="out/tauri/${env:VERSION}/nsis"
mkdir -p ${env:TAURI_DIR}
$env:OUT_FILE="${env:TAURI_DIR}/Zoo Modeling App_${env:VERSION_NO_V}_x64-setup.nsis.zip"
7z a -mm=Copy "${env:OUT_FILE}" ./out/*-x64-win.exe
yarn tauri signer sign "${env:OUT_FILE}"
ls -R out
- uses: actions/upload-artifact@v3
with:
path: "out/make/*/*/*"
# TODO: Run e2e tests
build-test-app-ubuntu:
needs: [prepare-json-files]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v3
if: github.event_name == 'schedule'
- name: Copy updated .json files
if: github.event_name == 'schedule'
run: |
ls -l artifact
cp artifact/package.json package.json
- name: Sync node version and setup cache
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn' # Set this to npm, yarn or pnpm.
- run: yarn install
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: './src/wasm-lib'
- name: Run build:wasm
run: "yarn build:wasm${{ env.BUILD_RELEASE == 'true' && '-dev' || ''}}"
- name: Build the app for arm64
run: "yarn electron-forge make --arch arm64"
- name: Build the app for x64
run: "yarn electron-forge make --arch x64"
- name: List artifacts
run: "ls -R out/make"
name: out-${{ matrix.os }}
path: |
out/Zoo*.*
out/latest*.yml
out/tauri
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
# TODO: sign the app (and updater bundle potentially)
- uses: actions/upload-artifact@v3
with:
path: "out/make/*/*/*"
# TODO: add the updater tests back
publish-apps-release:
@ -262,123 +184,161 @@ jobs:
permissions:
contents: write
if: ${{ github.event_name == 'release' || github.event_name == 'schedule' }}
needs: [prepare-json-files, build-test-app-macos, build-test-app-windows, build-test-app-ubuntu]
needs: [prepare-files, build-apps]
env:
VERSION_NO_V: ${{ needs.prepare-json-files.outputs.version }}
VERSION: ${{ github.event_name == 'release' && format('v{0}', needs.prepare-json-files.outputs.version) || needs.prepare-json-files.outputs.version }}
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
VERSION: ${{ github.event_name == 'schedule' && needs.prepare-files.outputs.version || format('v{0}', needs.prepare-files.outputs.version) }}
PUB_DATE: ${{ github.event_name == 'release' && github.event.release.created_at || github.event.repository.updated_at }}
NOTES: ${{ github.event_name == 'release' && github.event.release.body || format('Nightly build, commit {0}', github.sha) }}
BUCKET_DIR: ${{ github.event_name == 'release' && 'dl.kittycad.io/releases/modeling-app' || 'dl.kittycad.io/releases/modeling-app/nightly' }}
WEBSITE_DIR: ${{ github.event_name == 'release' && 'dl.zoo.dev/releases/modeling-app' || 'dl.zoo.dev/releases/modeling-app/nightly' }}
NOTES: ${{ github.event_name == 'release' && github.event.release.body || format('Non-release build, commit {0}', github.sha) }}
BUCKET_DIR: ${{ github.event_name == 'schedule' && 'dl.kittycad.io/releases/modeling-app/nightly' || 'dl.kittycad.io/releases/modeling-app' }}
WEBSITE_DIR: ${{ github.event_name == 'schedule' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
BUCKET_DIR_TAURI: 'dl.kittycad.io/releases/modeling-app/tauri-compat'
WEBSITE_DIR_TAURI: 'dl.zoo.dev/releases/modeling-app/tauri-compat'
URL_CODED_NAME: ${{ github.event_name == 'schedule' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
steps:
- uses: actions/download-artifact@v3
- uses: actions/checkout@v4
- name: Generate the update static endpoint
- uses: actions/download-artifact@v3
with:
name: out-windows-2022
path: out
- uses: actions/download-artifact@v3
with:
name: out-macos-14
path: out
- uses: actions/download-artifact@v3
with:
name: out-ubuntu-22.04
path: out
- name: Generate the download static endpoint
run: |
ls -l artifact/*/*oo*
DARWIN_SIG=`cat artifact/macos/*.app.tar.gz.sig`
WINDOWS_X86_64_SIG=`cat artifact/msi/*x64*.msi.zip.sig`
WINDOWS_AARCH64_SIG=`cat artifact/msi/*arm64*.msi.zip.sig`
RELEASE_DIR=https://${WEBSITE_DIR}/${VERSION}
RELEASE_DIR=https://${WEBSITE_DIR}
jq --null-input \
--arg version "${VERSION}" \
--arg pub_date "${PUB_DATE}" \
--arg notes "${NOTES}" \
--arg darwin_sig "$DARWIN_SIG" \
--arg darwin_url "$RELEASE_DIR/macos/${{ env.URL_CODED_NAME }}.app.tar.gz" \
--arg windows_x86_64_sig "$WINDOWS_X86_64_SIG" \
--arg windows_x86_64_url "$RELEASE_DIR/msi/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_x64_en-US.msi.zip" \
--arg windows_aarch64_sig "$WINDOWS_AARCH64_SIG" \
--arg windows_aarch64_url "$RELEASE_DIR/msi/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_arm64_en-US.msi.zip" \
--arg mac_arm64_url "$RELEASE_DIR/${{ env.URL_CODED_NAME }}-${VERSION_NO_V}-arm64-mac.dmg" \
--arg mac_x64_url "$RELEASE_DIR/${{ env.URL_CODED_NAME }}-${VERSION_NO_V}-x64-mac.dmg" \
--arg windows_arm64_url "$RELEASE_DIR/${{ env.URL_CODED_NAME }}-${VERSION_NO_V}-arm64-win.msi" \
--arg windows_x64_url "$RELEASE_DIR/${{ env.URL_CODED_NAME }}-${VERSION_NO_V}-x64-win.msi" \
'{
"version": $version,
"pub_date": $pub_date,
"notes": $notes,
"platforms": {
"dmg-arm64": {
"url": $mac_arm64_url
},
"dmg-x64": {
"url": $mac_x64_url
},
"msi-arm64": {
"url": $windows_arm64_url
},
"msi-x64": {
"url": $windows_x64_url
}
}
}' > last_download.json
cat last_download.json
- name: Generate the update static endpoint for tauri
run: |
TAURI_DIR=out/tauri/$VERSION
MAC_ARM64_SIG=`cat $TAURI_DIR/macos/*-arm64.app.tar.gz.sig`
MAC_X64_SIG=`cat $TAURI_DIR/macos/*-x64.app.tar.gz.sig`
WINDOWS_SIG=`cat $TAURI_DIR/nsis/*.nsis.zip.sig`
RELEASE_DIR=https://${WEBSITE_DIR_TAURI}/${VERSION}
jq --null-input \
--arg version "${VERSION}" \
--arg pub_date "${PUB_DATE}" \
--arg notes "${NOTES}" \
--arg mac_arm64_sig "$MAC_ARM64_SIG" \
--arg mac_arm64_url "$RELEASE_DIR/macos/${{ env.URL_CODED_NAME }}-arm64.app.tar.gz" \
--arg mac_x64_sig "$MAC_X64_SIG" \
--arg mac_x64_url "$RELEASE_DIR/macos/${{ env.URL_CODED_NAME }}-x64.app.tar.gz" \
--arg windows_sig "$WINDOWS_SIG" \
--arg windows_url "$RELEASE_DIR/nsis/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_x64-setup.nsis.zip" \
'{
"version": $version,
"pub_date": $pub_date,
"notes": $notes,
"platforms": {
"darwin-x86_64": {
"signature": $darwin_sig,
"url": $darwin_url
"signature": $mac_x64_sig,
"url": $mac_x64_url
},
"darwin-aarch64": {
"signature": $darwin_sig,
"url": $darwin_url
"signature": $mac_arm64_sig,
"url": $mac_arm64_url
},
"windows-x86_64": {
"signature": $windows_x86_64_sig,
"url": $windows_x86_64_url
},
"windows-aarch64": {
"signature": $windows_aarch64_sig,
"url": $windows_aarch64_url
"signature": $windows_sig,
"url": $windows_url
}
}
}' > last_update.json
cat last_update.json
- name: Generate the download static endpoint
run: |
RELEASE_DIR=https://${WEBSITE_DIR}/${VERSION}
jq --null-input \
--arg version "${VERSION}" \
--arg pub_date "${PUB_DATE}" \
--arg notes "${NOTES}" \
--arg darwin_url "$RELEASE_DIR/dmg/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_universal.dmg" \
--arg windows_x86_64_url "$RELEASE_DIR/msi/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_x64_en-US.msi" \
--arg windows_aarch64_url "$RELEASE_DIR/msi/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_arm64_en-US.msi" \
'{
"version": $version,
"pub_date": $pub_date,
"notes": $notes,
"platforms": {
"dmg-universal": {
"url": $darwin_url
},
"msi-x86_64": {
"url": $windows_x86_64_url
},
"msi-aarch64": {
"url": $windows_aarch64_url
}
}
}' > last_download.json
cat last_download.json
- name: List artifacts
run: "ls -R out"
- name: Authenticate to Google Cloud
uses: 'google-github-actions/auth@v2.1.3'
uses: 'google-github-actions/auth@v2.1.5'
with:
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
- name: Set up Google Cloud SDK
uses: google-github-actions/setup-gcloud@v2.1.0
with:
project_id: kittycadapi
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
- name: Upload release files to public bucket
uses: google-github-actions/upload-cloud-storage@v2.1.0
uses: google-github-actions/upload-cloud-storage@v2.1.3
with:
path: artifact
glob: '*/Zoo*'
path: out
glob: 'Zoo*'
parent: false
destination: ${{ env.BUCKET_DIR }}/${{ env.VERSION }}
- name: Upload update endpoint to public bucket
uses: google-github-actions/upload-cloud-storage@v2.1.0
with:
path: last_update.json
destination: ${{ env.BUCKET_DIR }}
- name: Upload update endpoint to public bucket
uses: google-github-actions/upload-cloud-storage@v2.1.3
with:
path: out
glob: 'latest*'
parent: false
destination: ${{ env.BUCKET_DIR }}
- name: Upload download endpoint to public bucket
uses: google-github-actions/upload-cloud-storage@v2.1.0
uses: google-github-actions/upload-cloud-storage@v2.1.3
with:
path: last_download.json
destination: ${{ env.BUCKET_DIR }}
- name: Upload release files to public bucket for tauri
uses: google-github-actions/upload-cloud-storage@v2.1.1
with:
path: "out/tauri/${{ env.VERSION }}"
glob: '*/Zoo*'
parent: false
destination: ${{ env.BUCKET_DIR_TAURI }}/${{ env.VERSION }}
- name: Upload update endpoint to public bucket for tauri
uses: google-github-actions/upload-cloud-storage@v2.1.1
with:
path: last_update.json
destination: ${{ env.BUCKET_DIR }}
- name: Upload release files to Github
if: ${{ github.event_name == 'release' }}
uses: softprops/action-gh-release@v2
with:
files: 'artifact/*/Zoo*'
files: 'out/Zoo*'
# TODO: Add GitHub publisher
announce_release:
needs: [publish-apps-release]

View File

@ -44,6 +44,8 @@ jobs:
- run: yarn build:wasm
- run: yarn xstate:typegen
- run: yarn tsc
- name: Lint
run: yarn eslint --max-warnings 0 src e2e
check-typos:

View File

@ -37,4 +37,4 @@ jobs:
# We specifically want to test the disable-println feature
# Since it is not enabled by default, we need to specify it
# This is used in kcl-lsp
cargo check --all --features disable-println --features pyo3
cargo check --all --features disable-println --features pyo3 --features cli

View File

@ -7,6 +7,7 @@ on:
- '**/Cargo.toml'
- '**/Cargo.lock'
- '**/rust-toolchain.toml'
- 'src/wasm-lib/**.kcl'
- .github/workflows/cargo-test.yml
pull_request:
@ -15,6 +16,7 @@ on:
- '**/Cargo.toml'
- '**/Cargo.lock'
- '**/rust-toolchain.toml'
- 'src/wasm-lib/**.kcl'
- .github/workflows/cargo-test.yml
workflow_dispatch:
permissions: read-all
@ -36,11 +38,6 @@ jobs:
with:
toolchain: stable
override: true
- name: install dependencies
if: matrix.dir == 'src-tauri'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
- name: Install vector
run: |
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh

31
.github/workflows/label-issues.yml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Label Issues
on:
issues:
types: [opened]
permissions:
issues: write
jobs:
label:
runs-on: ubuntu-latest
steps:
- name: Check if issue opener is ZooSpiritWolf
id: check_opener
uses: actions/github-script@v7
with:
script: |
const issueOpener = context.payload.issue.user.login;
return issueOpener === 'ZooSpiritWolf';
- name: Add labels
if: steps.check_opener.outputs.result == 'true'
uses: actions/github-script@v7
with:
script: |
github.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
labels: ['bug', 'regression', 'high-priority']
});

View File

@ -139,7 +139,7 @@ jobs:
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
with:
name: playwright-report-ubuntu-snapshot-${{ matrix.shardIndex }}-${{ github.sha }}
name: playwright-report-${{ matrix.os }}-snapshot-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/
retention-days: 30
overwrite: true
@ -174,14 +174,14 @@ jobs:
- uses: actions/upload-artifact@v4
if: steps.git-check.outputs.modified == 'true'
with:
name: playwright-report-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
name: playwright-report-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/
retention-days: 30
- uses: actions/download-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
continue-on-error: true
with:
name: test-results-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
name: test-results-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/
- name: Run playwright/chrome flow (with retries)
id: retry
@ -244,14 +244,14 @@ jobs:
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-results-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
name: test-results-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: test-results/
retention-days: 30
overwrite: true
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
name: playwright-report-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
path: playwright-report/
retention-days: 30
overwrite: true
@ -346,12 +346,12 @@ jobs:
run: yarn build:wasm
- name: build electron
shell: bash
run: yarn electron:package
run: yarn tron:package
- uses: actions/download-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
continue-on-error: true
with:
name: test-results-ubuntu-${{ github.sha }}
name: test-results-${{ matrix.os }}-${{ github.sha }}
path: test-results/
- name: Run electron tests (with retries)
id: retry
@ -423,14 +423,14 @@ jobs:
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
with:
name: test-results-electron-${{ github.sha }}
name: test-results-electron-${{ matrix.os }}-${{ github.sha }}
path: test-results/
retention-days: 30
overwrite: true
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() && (success() || failure()) }}
with:
name: playwright-report-electron-${{ github.sha }}
name: playwright-report-electron-${{ matrix.os }}-${{ github.sha }}
path: playwright-report/
retention-days: 30
overwrite: true

6
.gitignore vendored
View File

@ -54,19 +54,15 @@ e2e/playwright/export-snapshots/*
## generated files
src/**/*.typegen.ts
src-tauri/gen
src/wasm-lib/grackle/stdlib_cube_partial.json
Mac_App_Distribution.provisionprofile
*.tsbuildinfo
src/wasm-lib/pkg
venv
.vite/
# electron
out/
src-tauri/target
electron-test-projects-dir
electron-test-projects-dir-2

344
Info.plist Normal file
View File

@ -0,0 +1,344 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>dev.zoo.kcl</string>
</array>
<key>CFBundleTypeName</key>
<string>KCL</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Owner</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>dev.zoo.toml</string>
</array>
<key>CFBundleTypeName</key>
<string>TOML</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>dev.zoo.gltf</string>
</array>
<key>CFBundleTypeName</key>
<string>glTF</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>dev.zoo.glb</string>
</array>
<key>CFBundleTypeName</key>
<string>glb</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>dev.zoo.step</string>
</array>
<key>CFBundleTypeName</key>
<string>STEP</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>dev.zoo.fbx</string>
</array>
<key>CFBundleTypeName</key>
<string>FBX</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>dev.zoo.sldprt</string>
</array>
<key>CFBundleTypeName</key>
<string>Solidworks Part</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>public.geometry-definition-format</string>
</array>
<key>CFBundleTypeName</key>
<string>OBJ</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>public.polygon-file-format</string>
</array>
<key>CFBundleTypeName</key>
<string>PLY</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>public.standard-tesselated-geometry-format</string>
</array>
<key>CFBundleTypeName</key>
<string>STL</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>public.folder</string>
</array>
<key>CFBundleTypeName</key>
<string>Folders</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>dev.zoo.kcl</string>
<key>UTTypeReferenceURL</key>
<string>https://zoo.dev/docs/kcl</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.source-code</string>
<string>public.data</string>
<string>public.text</string>
<string>public.plain-text</string>
<string>public.3d-content</string>
<string>public.script</string>
</array>
<key>UTTypeDescription</key>
<string>KCL (KittyCAD Language) document</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>kcl</string>
</array>
<key>public.mime-type</key>
<array>
<string>text/vnd.zoo.kcl</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>dev.zoo.gltf</string>
<key>UTTypeReferenceURL</key>
<string>https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.text</string>
<string>public.plain-text</string>
<string>public.3d-content</string>
<string>public.json</string>
</array>
<key>UTTypeDescription</key>
<string>Graphics Library Transmission Format (glTF)</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>gltf</string>
</array>
<key>public.mime-type</key>
<array>
<string>model/gltf+json</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>dev.zoo.glb</string>
<key>UTTypeReferenceURL</key>
<string>https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.3d-content</string>
</array>
<key>UTTypeDescription</key>
<string>Graphics Library Transmission Format (glTF) binary</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>glb</string>
</array>
<key>public.mime-type</key>
<array>
<string>model/gltf-binary</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>dev.zoo.step</string>
<key>UTTypeReferenceURL</key>
<string>https://www.loc.gov/preservation/digital/formats/fdd/fdd000448.shtml</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.3d-content</string>
<string>public.text</string>
<string>public.plain-text</string>
</array>
<key>UTTypeDescription</key>
<string>STEP-file, ISO 10303-21</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>step</string>
<string>stp</string>
</array>
<key>public.mime-type</key>
<array>
<string>model/step</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>dev.zoo.sldprt</string>
<key>UTTypeReferenceURL</key>
<string>https://docs.fileformat.com/cad/sldprt/</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.3d-content</string>
</array>
<key>UTTypeDescription</key>
<string>Solidworks Part</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>sldprt</string>
</array>
<key>public.mime-type</key>
<array>
<string>model/vnd.solidworks.sldprt</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>dev.zoo.fbx</string>
<key>UTTypeReferenceURL</key>
<string>https://en.wikipedia.org/wiki/FBX</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.3d-content</string>
</array>
<key>UTTypeDescription</key>
<string>Autodesk Filmbox (FBX) format</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>fbx</string>
<string>fbxb</string>
</array>
<key>public.mime-type</key>
<array>
<string>model/vnd.autodesk.fbx</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>dev.zoo.toml</string>
<key>UTTypeReferenceURL</key>
<string>https://toml.io/en/</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.text</string>
<string>public.plain-text</string>
</array>
<key>UTTypeDescription</key>
<string>Tom's Obvious Minimal Language</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>kcl</string>
</array>
<key>public.mime-type</key>
<array>
<string>text/toml</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>

View File

@ -101,7 +101,7 @@ This will start the application and hot-reload on changed.
Devtools can be opened with the usual Cmd/Ctrl-Shift-I.
To build, run `yarn electron:package`.
To build, run `yarn tron:package`.
## Checking out commits / Bisecting
@ -110,7 +110,6 @@ Which commands from setup are one off vs need to be run every time?
The following will need to be run when checking out a new commit and guarantees the build is not stale:
```bash
yarn install
yarn wasm-prep
yarn build:wasm-dev # or yarn build:wasm for slower but more production-like build
yarn start # or yarn build:local && yarn serve for slower but more production-like build
```
@ -189,12 +188,22 @@ For more information on fuzzing you can check out
### Playwright tests
You will need a `./e2e/playwright/playwright-secrets.env` file:
```bash
$ touch ./e2e/playwright/playwright-secrets.env
$ cat ./e2e/playwright/playwright-secrets.env
token=<dev.zoo.dev/account/api-tokens>
snapshottoken=<your-snapshot-token>
```
For a portable way to run Playwright you'll need Docker.
#### Generic example
After that, open a terminal and run:
```bash
docker run --network host --rm --init -it playwright/chrome:playwright-1.43.1
docker run --network host --rm --init -it playwright/chrome:playwright-x.xx.x
```
and in another terminal, run:
@ -203,21 +212,27 @@ and in another terminal, run:
PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn playwright test --project="Google Chrome" <test suite>
```
An example of a `<test suite>` is: `e2e/playwright/flow-tests.spec.ts`
YOU WILL NEED A PLAYWRIGHT-SECRETS.ENV FILE:
#### Specific example
open a terminal and run:
```bash
# ./e2e/playwright/playwright-secrets.env
token=<your-token>
snapshottoken=<your-snapshot-token>
docker run --network host --rm --init -it playwright/chrome:playwright-1.46.0
```
and in another terminal, run:
```bash
PW_TEST_CONNECT_WS_ENDPOINT=ws://127.0.0.1:4444/ yarn playwright test --project="Google Chrome" e2e/playwright/command-bar-tests.spec.ts
```
then replace "your-token" with a dev token from dev.zoo.dev/account/api-tokens
run a specific test change the test from `test('...` to `test.only('...`
(note if you commit this, the tests will instantly fail without running any of the tests)
**Gotcha**: running the docker container with a mismatched image against your `./node_modules/playwright` will cause a failure. Make sure the versions are matched and up to date.
run headed
```

View File

@ -1,24 +0,0 @@
#!/usr/bin/env sh
# From https://dev.to/rwwagner90/signing-electron-apps-with-github-actions-4cof
KEY_CHAIN=build.keychain
CERTIFICATE_P12=certificate.p12
# Recreate the certificate from the secure environment variable
echo $APPLE_CERTIFICATE | base64 --decode > $CERTIFICATE_P12
#create a keychain
security create-keychain -p actions $KEY_CHAIN
# Make the keychain the default so identities are found
security default-keychain -s $KEY_CHAIN
# Unlock the keychain
security unlock-keychain -p actions $KEY_CHAIN
security import $CERTIFICATE_P12 -k $KEY_CHAIN -P $APPLE_CERTIFICATE_PASSWORD -T /usr/bin/codesign;
security set-key-partition-list -S apple-tool:,apple: -s -k actions $KEY_CHAIN
# remove certs
rm -fr *.p12

BIN
assets/icon.icns Normal file

Binary file not shown.

BIN
assets/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

View File

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

BIN
assets/icon@2x.icns Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

38
docs/kcl/cm.md Normal file

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

38
docs/kcl/ft.md Normal file

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

835
docs/kcl/hollow.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

38
docs/kcl/inch.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -32,17 +32,21 @@ layout: manual
* [`chamfer`](kcl/chamfer)
* [`circle`](kcl/circle)
* [`close`](kcl/close)
* [`cm`](kcl/cm)
* [`cos`](kcl/cos)
* [`e`](kcl/e)
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
* [`ft`](kcl/ft)
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
* [`getOppositeEdge`](kcl/getOppositeEdge)
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
* [`helix`](kcl/helix)
* [`hole`](kcl/hole)
* [`hollow`](kcl/hollow)
* [`import`](kcl/import)
* [`inch`](kcl/inch)
* [`int`](kcl/int)
* [`lastSegX`](kcl/lastSegX)
* [`lastSegY`](kcl/lastSegY)
@ -55,8 +59,10 @@ layout: manual
* [`log`](kcl/log)
* [`log10`](kcl/log10)
* [`log2`](kcl/log2)
* [`m`](kcl/m)
* [`max`](kcl/max)
* [`min`](kcl/min)
* [`mm`](kcl/mm)
* [`patternCircular2d`](kcl/patternCircular2d)
* [`patternCircular3d`](kcl/patternCircular3d)
* [`patternLinear2d`](kcl/patternLinear2d)
@ -82,6 +88,7 @@ layout: manual
* [`tan`](kcl/tan)
* [`tangentialArc`](kcl/tangentialArc)
* [`tangentialArcTo`](kcl/tangentialArcTo)
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
* [`tau`](kcl/tau)
* [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians)
@ -89,3 +96,4 @@ layout: manual
* [`xLineTo`](kcl/xLineTo)
* [`yLine`](kcl/yLine)
* [`yLineTo`](kcl/yLineTo)
* [`yd`](kcl/yd)

File diff suppressed because one or more lines are too long

38
docs/kcl/m.md Normal file

File diff suppressed because one or more lines are too long

38
docs/kcl/mm.md Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

38
docs/kcl/yd.md Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,66 @@
import { test, expect } from '@playwright/test'
import { setupElectron, tearDown } from './test-utils'
test.afterEach(async ({ page }, testInfo) => {
await tearDown(page, testInfo)
})
test.describe('Electron app header tests', () => {
test(
'Open Command Palette button has correct shortcut',
{ tag: '@electron' },
async ({ browserName }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async () => {},
})
await page.setViewportSize({ width: 1200, height: 500 })
// No space before the shortcut since it checks textContent.
let text
switch (process.platform) {
case 'darwin':
text = 'Commands⌘K'
break
case 'win32':
text = 'CommandsCtrl+K'
break
default: // 'linux' etc.
text = 'CommandsCtrl+K'
break
}
const commandsButton = page.getByRole('button', { name: 'Commands' })
await expect(commandsButton).toBeVisible()
await expect(commandsButton).toHaveText(text)
await electronApp.close()
}
)
test(
'User settings has correct shortcut',
{ tag: '@electron' },
async ({ browserName }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async () => {},
})
await page.setViewportSize({ width: 1200, height: 500 })
// Open the user sidebar menu.
await page.getByTestId('user-sidebar-toggle').click()
// No space after "User settings" since it's textContent.
const text =
process.platform === 'darwin' ? 'User settings⌘,' : 'User settingsCtrl,'
const userSettingsButton = page.getByTestId('user-settings')
await expect(userSettingsButton).toBeVisible()
await expect(userSettingsButton).toHaveText(text)
await electronApp.close()
}
)
})

View File

@ -96,33 +96,49 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
}
// deselect line tool
await page.getByTestId('line').click()
const btnLine = page.getByTestId('line')
const btnLineAriaPressed = await btnLine.getAttribute('aria-pressed')
if (btnLineAriaPressed === 'true') {
await btnLine.click()
}
await page.waitForTimeout(100)
const line1 = await u.getSegmentBodyCoords(`[data-overlay-index="${0}"]`, 0)
if (openPanes.includes('code')) {
await expect
.poll(async () => u.getGreatestPixDiff(line1, TEST_COLORS.WHITE))
.toBeLessThan(3)
await page.waitForTimeout(100)
await expect
.poll(() => u.getGreatestPixDiff(line1, [249, 249, 249]))
.poll(async () => u.getGreatestPixDiff(line1, [249, 249, 249]))
.toBeLessThan(3)
await page.waitForTimeout(100)
}
// click between first two clicks to get center of the line
await page.mouse.click(startXPx + PUR * 15, 500 - PUR * 10)
await page.waitForTimeout(100)
if (openPanes.includes('code')) {
expect(await u.getGreatestPixDiff(line1, TEST_COLORS.BLUE)).toBeLessThan(3)
await expect(
await u.getGreatestPixDiff(line1, TEST_COLORS.BLUE)
).toBeLessThan(3)
await expect(await u.getGreatestPixDiff(line1, [0, 0, 255])).toBeLessThan(3)
}
// hold down shift
await page.keyboard.down('Shift')
await page.waitForTimeout(100)
// click between the latest two clicks to get center of the line
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 20)
await page.waitForTimeout(100)
// selected two lines therefore there should be two cursors
if (openPanes.includes('code')) {
await expect(page.locator('.cm-cursor')).toHaveCount(2)
await page.waitForTimeout(100)
}
await page.getByRole('button', { name: 'Length: open menu' }).click()

View File

@ -1,8 +1,16 @@
import { test, expect } from '@playwright/test'
import { getUtils, setup, tearDown } from './test-utils'
import {
getUtils,
setup,
setupElectron,
tearDown,
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 fsp from 'fs/promises'
test.beforeEach(async ({ context, page }) => {
await setup(context, page)
@ -83,7 +91,7 @@ test.describe('Code pane and errors', () => {
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.getByText('Unexpected token').first()).toBeVisible()
await expect(page.getByText('Unexpected token: |').first()).toBeVisible()
// Close the code pane
await codePaneButton.click()
@ -106,7 +114,7 @@ test.describe('Code pane and errors', () => {
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.getByText('Unexpected token').first()).toBeVisible()
await expect(page.getByText('Unexpected token: |').first()).toBeVisible()
})
test('When error is not in view you can click the badge to scroll to it', async ({
@ -217,3 +225,91 @@ test.describe('Code pane and errors', () => {
).toBeVisible()
})
})
test(
'Opening multiple panes persists when switching projects',
{ tag: '@electron' },
async ({ browserName }, testInfo) => {
// Setup multiple projects.
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async (dir) => {
const routerTemplateDir = join(dir, 'router-template-slate')
const bracketDir = join(dir, 'bracket')
await Promise.all([
fsp.mkdir(routerTemplateDir, { recursive: true }),
fsp.mkdir(bracketDir, { recursive: true }),
])
await Promise.all([
fsp.copyFile(
executorInputPath('router-template-slate.kcl'),
join(routerTemplateDir, 'main.kcl')
),
fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
join(bracketDir, 'main.kcl')
),
])
},
})
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await test.step('Opening the bracket project should load', async () => {
await expect(page.getByText('bracket')).toBeVisible()
await page.getByText('bracket').click()
await expect(page.getByTestId('loading')).toBeAttached()
await expect(page.getByTestId('loading')).not.toBeAttached({
timeout: 20_000,
})
})
// If they're open by default, we're not actually testing anything.
await test.step('Pre-condition: panes are not already visible', async () => {
await expect(page.locator('#variables-pane')).not.toBeVisible()
await expect(page.locator('#logs-pane')).not.toBeVisible()
})
await test.step('Open multiple panes', async () => {
await u.openKclCodePanel()
await u.openVariablesPane()
await u.openLogsPane()
})
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
await page.getByTestId('app-logo').click()
await expect(page.getByRole('link', { name: 'bracket' })).toBeVisible()
await expect(page.getByText('router-template-slate')).toBeVisible()
await expect(page.getByText('New Project')).toBeVisible()
})
await test.step('Opening the router-template project should load', async () => {
await expect(page.getByText('router-template-slate')).toBeVisible()
await page.getByText('router-template-slate').click()
await expect(page.getByTestId('loading')).toBeAttached()
await expect(page.getByTestId('loading')).not.toBeAttached({
timeout: 20_000,
})
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).toBeEnabled({
timeout: 20_000,
})
})
await test.step('All panes opened before should be visible', async () => {
await expect(page.locator('#code-pane')).toBeVisible()
await expect(page.locator('#variables-pane')).toBeVisible()
await expect(page.locator('#logs-pane')).toBeVisible()
})
await electronApp.close()
}
)

View File

@ -12,50 +12,47 @@ test.afterEach(async ({ page }, testInfo) => {
})
test.describe('Command bar tests', () => {
// TODO fixme: enter is not working in the command bar
test.fixme(
'Extrude from command bar selects extrude line after',
async ({ page }) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch001 = startSketchOn('XY')
test('Extrude from command bar selects extrude line after', async ({
page,
}) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> xLine(-20, %)
|> close(%)
`
)
})
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Click the line of code for xLine.
await page.getByText(`close(%)`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Extrude' }).click()
await page.waitForTimeout(200)
await page.keyboard.press('Enter')
await page.waitForTimeout(200)
await page.keyboard.press('Enter')
await page.waitForTimeout(200)
await expect(page.locator('.cm-activeLine')).toHaveText(
`const extrude001 = extrude(${KCL_DEFAULT_LENGTH}, sketch001)`
)
}
)
})
// TODO fixme: enter is not working in the command bar
test.fixme('Fillet from command bar', async ({ page }) => {
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// Click the line of code for xLine.
await page.getByText(`close(%)`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
await page.waitForTimeout(100)
await page.getByRole('button', { name: 'Extrude' }).click()
await page.waitForTimeout(200)
await page.keyboard.press('Enter')
await page.waitForTimeout(200)
await page.keyboard.press('Enter')
await page.waitForTimeout(200)
await expect(page.locator('.cm-activeLine')).toHaveText(
`const extrude001 = extrude(${KCL_DEFAULT_LENGTH}, sketch001)`
)
})
test('Fillet from command bar', async ({ page }) => {
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
@ -127,7 +124,7 @@ const extrude001 = extrude(-10, sketch001)`
await expect(cmdSearchBar).not.toBeVisible()
// Now try the same, but with the keyboard shortcut, check focus
await page.keyboard.press('Meta+K')
await page.keyboard.press('ControlOrMeta+K')
await expect(cmdSearchBar).toBeVisible()
await expect(cmdSearchBar).toBeFocused()
@ -188,7 +185,7 @@ const extrude001 = extrude(-10, sketch001)`
await page.locator('.cm-content').click()
// Now try the same, but with the keyboard shortcut, check focus
await page.keyboard.press('Meta+K')
await page.keyboard.press('ControlOrMeta+K')
let cmdSearchBar = page.getByPlaceholder('Search commands')
await expect(cmdSearchBar).toBeVisible()
@ -253,7 +250,7 @@ const extrude001 = extrude(-10, sketch001)`
await page.getByRole('button', { name: 'Extrude' }).isEnabled()
let cmdSearchBar = page.getByPlaceholder('Search commands')
await page.keyboard.press('Meta+K')
await page.keyboard.press('ControlOrMeta+K')
await expect(cmdSearchBar).toBeVisible()
// Search for extrude command and choose it

View File

@ -9,6 +9,7 @@ test.afterEach(async ({ page }, testInfo) => {
await tearDown(page, testInfo)
})
test.describe('Copilot ghost text', () => {
// eslint-disable-next-line jest/valid-title
test.skip(true, 'Needs to get covered again')
test('completes code in empty file', async ({ page }) => {
@ -331,7 +332,6 @@ test.describe('Copilot ghost text', () => {
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
const CtrlKey = process.platform === 'darwin' ? 'Meta' : 'Control'
await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``)
@ -348,10 +348,10 @@ test.describe('Copilot ghost text', () => {
)
// Going elsewhere in the code should hide the ghost text.
await page.keyboard.down(CtrlKey)
await page.keyboard.down('ControlOrMeta')
await page.keyboard.down('Shift')
await page.keyboard.press('KeyZ')
await page.keyboard.up(CtrlKey)
await page.keyboard.up('ControlOrMeta')
await page.keyboard.up('Shift')
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
@ -367,8 +367,6 @@ test.describe('Copilot ghost text', () => {
await u.waitForAuthSkipAppStart()
const CtrlKey = process.platform === 'darwin' ? 'Meta' : 'Control'
await page.waitForTimeout(800)
await u.codeLocator.click()
await expect(page.locator('.cm-content')).toHaveText(``)
@ -381,17 +379,17 @@ test.describe('Copilot ghost text', () => {
await page.waitForTimeout(800)
// Ctrl+z
await page.keyboard.down(CtrlKey)
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('KeyZ')
await page.keyboard.up(CtrlKey)
await page.keyboard.up('ControlOrMeta')
await expect(page.locator('.cm-content')).toHaveText(``)
// Ctrl+shift+z
await page.keyboard.down(CtrlKey)
await page.keyboard.down('ControlOrMeta')
await page.keyboard.down('Shift')
await page.keyboard.press('KeyZ')
await page.keyboard.up(CtrlKey)
await page.keyboard.up('ControlOrMeta')
await page.keyboard.up('Shift')
await expect(page.locator('.cm-content')).toHaveText(`{thing: "blah"}`)
@ -410,14 +408,14 @@ test.describe('Copilot ghost text', () => {
)
// Once for the enter.
await page.keyboard.down(CtrlKey)
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('KeyZ')
await page.keyboard.up(CtrlKey)
await page.keyboard.up('ControlOrMeta')
// Once for the text.
await page.keyboard.down(CtrlKey)
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('KeyZ')
await page.keyboard.up(CtrlKey)
await page.keyboard.up('ControlOrMeta')
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()

View File

@ -0,0 +1,191 @@
import { test, expect } from '@playwright/test'
import { join } from 'path'
import {
getUtils,
setupElectron,
tearDown,
executorInputPath,
} from './test-utils'
import fsp from 'fs/promises'
test.afterEach(async ({ page }, testInfo) => {
await tearDown(page, testInfo)
})
test(
'export works on the first try',
{ tag: '@electron' },
async ({ browserName }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async (dir) => {
const bracketDir = join(dir, 'bracket')
await Promise.all([fsp.mkdir(bracketDir, { recursive: true })])
await Promise.all([
fsp.copyFile(
executorInputPath('router-template-slate.kcl'),
join(bracketDir, 'other.kcl')
),
fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
join(bracketDir, 'main.kcl')
),
])
},
})
await page.setViewportSize({ width: 1200, height: 500 })
page.on('console', console.log)
await test.step('on open of project', async () => {
await expect(page.getByText(`bracket`)).toBeVisible()
// open the project
await page.getByText(`bracket`).click()
// wait for the project to load
await expect(page.getByTestId('loading')).toBeAttached()
await expect(page.getByTestId('loading')).not.toBeAttached({
timeout: 20_000,
})
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
const gltfOption = page.getByText('glTF')
const submitButton = page.getByText('Confirm Export')
const exportingToastMessage = page.getByText(`Exporting...`)
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
// Click the export button
await exportButton.click()
await expect(gltfOption).toBeVisible()
await expect(page.getByText('STL')).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
await expect(submitButton).toBeVisible()
await page.waitForTimeout(500)
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
await expect(exportingToastMessage).toBeVisible()
await expect(alreadyExportingToastMessage).not.toBeVisible()
// Expect it to succeed.
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible()
await expect(exportingToastMessage).not.toBeVisible()
await test.step('Check the export size', async () => {
await expect
.poll(
async () => {
try {
const outputGltf = await fsp.readFile('output.gltf')
return outputGltf.byteLength
} catch (e) {
return 0
}
},
{ timeout: 15_000 }
)
.toBe(477327)
// clean up output.gltf
await fsp.rm('output.gltf')
})
})
await test.step('on open of file in file pane', async () => {
const u = await getUtils(page)
await u.openFilePanel()
const otherKclButton = page.getByRole('button', { name: 'other.kcl' })
// Click the file
await otherKclButton.click()
// Close the file pane
await u.closeFilePanel()
// wait for it to finish executing (todo: make this more robust)
await page.waitForTimeout(1000)
// expect zero errors in guter
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
// export the model
const exportButton = page.getByTestId('export-pane-button')
await expect(exportButton).toBeVisible()
const gltfOption = page.getByText('glTF')
const submitButton = page.getByText('Confirm Export')
const exportingToastMessage = page.getByText(`Exporting...`)
const errorToastMessage = page.getByText(`Error while exporting`)
const engineErrorToastMessage = page.getByText(`Nothing to export`)
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
// Click the export button
await exportButton.click()
await expect(gltfOption).toBeVisible()
await expect(page.getByText('STL')).toBeVisible()
await page.keyboard.press('Enter')
// Click the checkbox
await expect(submitButton).toBeVisible()
await page.keyboard.press('Enter')
// Find the toast.
// Look out for the toast message
await expect(exportingToastMessage).toBeVisible()
await expect(alreadyExportingToastMessage).not.toBeVisible()
// Expect it to succeed.
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
const successToastMessage = page.getByText(`Exported successfully`)
await expect(successToastMessage).toBeVisible()
await expect(exportingToastMessage).not.toBeVisible()
await test.step('Check the export size', async () => {
await expect
.poll(
async () => {
try {
const outputGltf = await fsp.readFile('output.gltf')
return outputGltf.byteLength
} catch (e) {
return 0
}
},
{ timeout: 15_000 }
)
.toBe(105022)
// clean up output.gltf
await fsp.rm('output.gltf')
})
await electronApp.close()
})
await electronApp.close()
}
)

View File

@ -16,7 +16,6 @@ test.describe('Editor tests', () => {
await page.setViewportSize({ width: 1000, height: 500 })
await u.waitForAuthSkipAppStart()
const CtrlKey = process.platform === 'darwin' ? 'Meta' : 'Control'
// check no error to begin with
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
@ -29,9 +28,9 @@ test.describe('Editor tests', () => {
|> line([-20, 0], %)
|> close(%)`)
await page.keyboard.down(CtrlKey)
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('/')
await page.keyboard.up(CtrlKey)
await page.keyboard.up('ControlOrMeta')
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XY')
@ -42,9 +41,9 @@ test.describe('Editor tests', () => {
// |> close(%)`)
// uncomment the code
await page.keyboard.down(CtrlKey)
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('/')
await page.keyboard.up(CtrlKey)
await page.keyboard.up('ControlOrMeta')
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XY')
@ -85,6 +84,63 @@ test.describe('Editor tests', () => {
|> close(%)`)
})
test('if you click the format button it formats your code and executes so lints are still there', async ({
page,
}) => {
const u = await getUtils(page)
await page.setViewportSize({ width: 1000, height: 500 })
await u.waitForAuthSkipAppStart()
// check no error to begin with
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
await u.codeLocator.click()
await page.keyboard.type(`const sketch_001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
|> close(%)`)
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// error in guter
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-info')
await expect(
page.getByText('Identifiers must be lowerCamelCase').first()
).toBeVisible()
await page.locator('#code-pane button:first-child').click()
await page.locator('button:has-text("Format code")').click()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch_001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
|> close(%)`)
// error in guter
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-info')
await expect(
page.getByText('Identifiers must be lowerCamelCase').first()
).toBeVisible()
})
test('fold gutters work', async ({ page }) => {
const u = await getUtils(page)
@ -148,9 +204,7 @@ test.describe('Editor tests', () => {
// Delete all the code.
await page.locator('.cm-content').click()
// Select all
await page.keyboard.press('Control+A')
await page.keyboard.press('Backspace')
await page.keyboard.press('Meta+A')
await page.keyboard.press('ControlOrMeta+A')
await page.keyboard.press('Backspace')
await expect(page.locator('.cm-content')).toHaveText(``)
@ -244,6 +298,67 @@ test.describe('Editor tests', () => {
|> close(%)`)
})
test('if you use the format keyboard binding it formats your code and executes so lints are shown', async ({
page,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch_001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
|> close(%)`
)
localStorage.setItem('disableAxis', 'true')
})
await page.setViewportSize({ width: 1000, height: 500 })
await u.waitForAuthSkipAppStart()
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
// error in guter
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-info')
await expect(
page.getByText('Identifiers must be lowerCamelCase').first()
).toBeVisible()
// focus the editor
await u.codeLocator.click()
// Hit alt+shift+f to format the code
await page.keyboard.press('Alt+Shift+KeyF')
await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel()
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch_001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
|> close(%)`)
// error in guter
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
// error text on hover
await page.hover('.cm-lint-marker-info')
await expect(
page.getByText('Identifiers must be lowerCamelCase').first()
).toBeVisible()
})
test('if you write kcl with lint errors you get lints', async ({ page }) => {
const u = await getUtils(page)
await page.setViewportSize({ width: 1000, height: 500 })
@ -354,7 +469,7 @@ test.describe('Editor tests', () => {
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.getByText('Unexpected token').first()).toBeVisible()
await expect(page.getByText('Unexpected token: $').first()).toBeVisible()
// select the line that's causing the error and delete it
await page.getByText('$ error').click()
@ -402,7 +517,7 @@ test.describe('Editor tests', () => {
const width = 0.500
const height = 0.500
const dia = 4
fn squareHole = (l, w) => {
const squareHoleSketch = startSketchOn('XY')
|> startProfileAt([-width / 2, -length / 2], %)
@ -714,17 +829,15 @@ test.describe('Editor tests', () => {
|> close(%)`)
})
// failing for the same reason as "Can edit a sketch that has been extruded in the same pipe"
// please fix together
test.fixme('Can undo a sketch modification with ctrl+z', async ({ page }) => {
test('Can undo a sketch modification with ctrl+z', async ({ page }) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch001 = startSketchOn('XZ')
|> startProfileAt([4.61, -14.01], %)
|> startProfileAt([4.61, -10.01], %)
|> line([12.73, -0.09], %)
|> tangentialArcTo([24.95, -5.38], %)
|> tangentialArcTo([24.95, -0.38], %)
|> close(%)
|> extrude(5, %)`
)
@ -759,11 +872,11 @@ test.describe('Editor tests', () => {
})
await page.waitForTimeout(100)
const startPX = [665, 458]
const startPX = [665, 397]
const dragPX = 40
await page.getByText('startProfileAt([4.61, -14.01], %)').click()
await page.getByText('startProfileAt([4.61, -10.01], %)').click()
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeVisible()
@ -801,7 +914,7 @@ test.describe('Editor tests', () => {
// drag tangentialArcTo handle
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: tangentEnd.x, y: tangentEnd.y - 5 },
sourcePosition: { x: tangentEnd.x + 10, y: tangentEnd.y - 5 },
targetPosition: {
x: tangentEnd.x + dragPX,
y: tangentEnd.y + dragPX,
@ -813,12 +926,12 @@ test.describe('Editor tests', () => {
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([7.12, -16.82], %)
|> line([15.4, -2.74], %)
|> tangentialArcTo([24.95, -5.38], %)
|> line([2.65, -2.69], %)
|> close(%)
|> extrude(5, %)`)
|> startProfileAt([7.12, -12.68], %)
|> line([15.39, -2.78], %)
|> tangentialArcTo([27.6, -3.05], %)
|> close(%)
|> extrude(5, %)
`)
// Hit undo
await page.keyboard.down('Control')
@ -827,11 +940,11 @@ test.describe('Editor tests', () => {
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([7.12, -16.82], %)
|> line([15.4, -2.74], %)
|> tangentialArcTo([24.95, -5.38], %)
|> close(%)
|> extrude(5, %)`)
|> startProfileAt([7.12, -12.68], %)
|> line([15.39, -2.78], %)
|> tangentialArcTo([24.95, -0.38], %)
|> close(%)
|> extrude(5, %)`)
// Hit undo again.
await page.keyboard.down('Control')
@ -840,11 +953,12 @@ test.describe('Editor tests', () => {
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([7.12, -16.82], %)
|> line([12.73, -0.09], %)
|> tangentialArcTo([24.95, -5.38], %)
|> close(%)
|> extrude(5, %)`)
|> startProfileAt([7.12, -12.68], %)
|> line([12.73, -0.09], %)
|> tangentialArcTo([24.95, -0.38], %)
|> close(%)
|> extrude(5, %)
`)
// Hit undo again.
await page.keyboard.down('Control')
@ -854,9 +968,9 @@ test.describe('Editor tests', () => {
await page.waitForTimeout(100)
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([4.61, -14.01], %)
|> startProfileAt([4.61, -10.01], %)
|> line([12.73, -0.09], %)
|> tangentialArcTo([24.95, -5.38], %)
|> tangentialArcTo([24.95, -0.38], %)
|> close(%)
|> extrude(5, %)`)
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -0,0 +1,204 @@
import { test, expect } from '@playwright/test'
import * as fsp from 'fs/promises'
import { getUtils, setup, setupElectron, tearDown } from './test-utils'
test.beforeEach(async ({ context, page }) => {
await setup(context, page)
})
test.afterEach(async ({ page }, testInfo) => {
await tearDown(page, testInfo)
})
test.describe('when using the file tree to', () => {
const fromFile = 'main.kcl'
const toFile = 'hello.kcl'
test(
`rename ${fromFile} to ${toFile}, and doesn't crash on reload and settings load`,
{ tag: '@electron' },
async ({ browser: _ }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async () => {},
})
const {
panesOpen,
createAndSelectProject,
pasteCodeInEditor,
renameFile,
editorTextMatches,
} = await getUtils(page, test)
await page.setViewportSize({ width: 1200, height: 500 })
page.on('console', console.log)
await panesOpen(['files', 'code'])
await createAndSelectProject('project-000')
// File the main.kcl with contents
const kclCube = await fsp.readFile(
'src/wasm-lib/tests/executor/inputs/cube.kcl',
'utf-8'
)
await pasteCodeInEditor(kclCube)
await renameFile(fromFile, toFile)
await page.reload()
await test.step('Postcondition: editor has same content as before the rename', async () => {
await editorTextMatches(kclCube)
})
await test.step('Postcondition: opening and closing settings works', async () => {
const settingsOpenButton = page.getByRole('link', {
name: 'settings Settings',
})
const settingsCloseButton = page.getByTestId('settings-close-button')
await settingsOpenButton.click()
await settingsCloseButton.click()
})
await electronApp.close()
}
)
test(
`create many new untitled files they increment their names`,
{ tag: '@electron' },
async ({ browser: _ }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async () => {},
})
const { panesOpen, createAndSelectProject, createNewFile } =
await getUtils(page, test)
await page.setViewportSize({ width: 1200, height: 500 })
page.on('console', console.log)
await panesOpen(['files'])
await createAndSelectProject('project-000')
await createNewFile('')
await createNewFile('')
await createNewFile('')
await createNewFile('')
await createNewFile('')
await test.step('Postcondition: there are 5 new Untitled-*.kcl files', async () => {
await expect(
page
.locator('[data-testid="file-pane-scroll-container"] button')
.filter({ hasText: /Untitled[-]?[0-5]?/ })
).toHaveCount(5)
})
await electronApp.close()
}
)
test(
'create a new file with the same name as an existing file cancels the operation',
{ tag: '@electron' },
async ({ browser: _ }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async () => {},
})
const {
panesOpen,
createAndSelectProject,
pasteCodeInEditor,
createNewFileAndSelect,
renameFile,
selectFile,
editorTextMatches,
} = await getUtils(page, test)
await page.setViewportSize({ width: 1200, height: 500 })
page.on('console', console.log)
await panesOpen(['files', 'code'])
await createAndSelectProject('project-000')
// File the main.kcl with contents
const kclCube = await fsp.readFile(
'src/wasm-lib/tests/executor/inputs/cube.kcl',
'utf-8'
)
await pasteCodeInEditor(kclCube)
const kcl1 = 'main.kcl'
const kcl2 = '2.kcl'
await createNewFileAndSelect(kcl2)
const kclCylinder = await fsp.readFile(
'src/wasm-lib/tests/executor/inputs/cylinder.kcl',
'utf-8'
)
await pasteCodeInEditor(kclCylinder)
await renameFile(kcl2, kcl1)
await test.step(`Postcondition: ${kcl1} still has the original content`, async () => {
await selectFile(kcl1)
await editorTextMatches(kclCube)
})
await test.step(`Postcondition: ${kcl2} still exists with the original content`, async () => {
await selectFile(kcl2)
await editorTextMatches(kclCylinder)
})
await electronApp.close()
}
)
test(
'deleting all files recreates a default main.kcl with no code',
{ tag: '@electron' },
async ({ browser: _ }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async () => {},
})
const {
panesOpen,
createAndSelectProject,
pasteCodeInEditor,
deleteFile,
editorTextMatches,
} = await getUtils(page, test)
await page.setViewportSize({ width: 1200, height: 500 })
page.on('console', console.log)
await panesOpen(['files', 'code'])
await createAndSelectProject('project-000')
// File the main.kcl with contents
const kclCube = await fsp.readFile(
'src/wasm-lib/tests/executor/inputs/cube.kcl',
'utf-8'
)
await pasteCodeInEditor(kclCube)
const kcl1 = 'main.kcl'
await deleteFile(kcl1)
await test.step(`Postcondition: ${kcl1} is recreated but has no content`, async () => {
await editorTextMatches('')
})
await electronApp.close()
}
)
})

View File

@ -0,0 +1,97 @@
import { test, expect } from '@playwright/test'
import { setupElectron, tearDown, executorInputPath } from './test-utils'
import { join } from 'path'
import fsp from 'fs/promises'
test.afterEach(async ({ page }, testInfo) => {
await tearDown(page, testInfo)
})
test(
'When machine-api server not found butt is disabled and shows the reason',
{ tag: '@electron' },
async ({ browserName }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async (dir) => {
const bracketDir = join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
join(bracketDir, 'main.kcl')
)
},
})
await page.setViewportSize({ width: 1200, height: 500 })
await expect(page.getByText('bracket')).toBeVisible()
await page.getByText('bracket').click()
await expect(page.getByTestId('loading')).toBeAttached()
await expect(page.getByTestId('loading')).not.toBeAttached({
timeout: 20_000,
})
const notFoundText = 'Machine API server was not discovered'
await expect(page.getByText(notFoundText).first()).not.toBeVisible()
// Find the make button
const makeButton = page.getByRole('button', { name: 'Make' })
// Make sure the button is visible but disabled
await expect(makeButton).toBeVisible()
await expect(makeButton).toBeDisabled()
// When you hover over the button, the tooltip should show
// that the machine-api server is not found
await makeButton.hover()
await expect(page.getByText(notFoundText).first()).toBeVisible()
await electronApp.close()
}
)
test(
'When machine-api server not found home screen & project status shows the reason',
{ tag: '@electron' },
async ({ browserName }, testInfo) => {
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async (dir) => {
const bracketDir = join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
join(bracketDir, 'main.kcl')
)
},
})
await page.setViewportSize({ width: 1200, height: 500 })
const notFoundText = 'Machine API server was not discovered'
await expect(page.getByText(notFoundText)).not.toBeVisible()
const networkMachineToggle = page.getByTestId('network-machine-toggle')
await networkMachineToggle.hover()
await expect(page.getByText(notFoundText)).toBeVisible()
await expect(page.getByText('bracket')).toBeVisible()
await page.getByText('bracket').click()
await expect(page.getByTestId('loading')).toBeAttached()
await expect(page.getByTestId('loading')).not.toBeAttached({
timeout: 20_000,
})
await expect(page.getByText(notFoundText).nth(1)).not.toBeVisible()
await networkMachineToggle.hover()
await expect(page.getByText(notFoundText).nth(1)).toBeVisible()
await electronApp.close()
}
)

View File

@ -1,6 +1,13 @@
import { test, expect } from '@playwright/test'
import { join } from 'path'
import fsp from 'fs/promises'
import { getUtils, setup, setupElectron, tearDown } from './test-utils'
import {
getUtils,
setup,
setupElectron,
tearDown,
executorInputPath,
} from './test-utils'
import { bracket } from 'lib/exampleKcl'
import { onboardingPaths } from 'routes/Onboarding/paths'
import {
@ -350,10 +357,11 @@ test(
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async (dir) => {
await fsp.mkdir(`${dir}/router-template-slate`, { recursive: true })
const routerTemplateDir = join(dir, 'router-template-slate')
await fsp.mkdir(routerTemplateDir, { recursive: true })
await fsp.copyFile(
'src/wasm-lib/tests/executor/inputs/router-template-slate.kcl',
`${dir}/router-template-slate/main.kcl`
executorInputPath('router-template-slate.kcl'),
join(routerTemplateDir, 'main.kcl')
)
},
})

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,13 @@
import { test, expect, Page } from '@playwright/test'
import { join } from 'path'
import * as fsp from 'fs/promises'
import { getUtils, setup, setupElectron, tearDown } from './test-utils'
import {
getUtils,
setup,
setupElectron,
tearDown,
executorInputPath,
} from './test-utils'
import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from './storageStates'
import { bracket } from 'lib/exampleKcl'
@ -194,7 +201,7 @@ const sketch001 = startSketchAt([-0, -0])
// error text on hover
await page.hover('.cm-lint-marker-error')
await expect(page.getByText('Unexpected token').first()).toBeVisible()
await expect(page.getByText('Unexpected token: |').first()).toBeVisible()
// Okay execution finished, let's start editing text below the error.
await u.codeLocator.click()
@ -236,9 +243,13 @@ const sketch001 = startSketchAt([-0, -0])
page,
}) => {
const u = await getUtils(page)
await page.addInitScript(async (code) => {
localStorage.setItem('persistCode', code)
}, TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR)
await page.addInitScript(
async ({ code }) => {
localStorage.setItem('persistCode', code)
;(window as any).playwrightSkipFilePicker = true
},
{ code: TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR }
)
await page.setViewportSize({ width: 1000, height: 500 })
@ -325,7 +336,7 @@ const sketch001 = startSketchAt([-0, -0])
await expect(exportingToastMessage).toBeVisible()
// Expect it to succeed.
await expect(exportingToastMessage).not.toBeVisible()
await expect(exportingToastMessage).not.toBeVisible({ timeout: 15_000 })
await expect(errorToastMessage).not.toBeVisible()
await expect(engineErrorToastMessage).not.toBeVisible()
@ -337,6 +348,7 @@ const sketch001 = startSketchAt([-0, -0])
}) => {
// This is being weird on ubuntu and windows.
test.skip(
// eslint-disable-next-line jest/valid-title
process.platform === 'linux' || process.platform === 'win32',
'This test is being weird on ubuntu'
)
@ -423,10 +435,11 @@ const sketch001 = startSketchAt([-0, -0])
const { electronApp, page } = await setupElectron({
testInfo,
folderSetupFn: async (dir) => {
await fsp.mkdir(`${dir}/bracket`, { recursive: true })
const bracketDir = join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile(
'src/wasm-lib/tests/executor/inputs/focusrite_scarlett_mounting_braket.kcl',
`${dir}/bracket/main.kcl`
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
join(bracketDir, 'main.kcl')
)
},
})
@ -472,7 +485,7 @@ async function clickExportButton(page: Page) {
// Click the export button
await exportButton.click()
// Click the stl.
// Click the gltf.
const gltfOption = page.getByRole('option', { name: 'glTF' })
await expect(gltfOption).toBeVisible()

View File

@ -344,111 +344,108 @@ test.describe('Sketch tests', () => {
})
})
// failing for the same reason as "Can undo a sketch modification with ctrl+z"
// please fix together
test.fixme(
'Can edit a sketch that has been extruded in the same pipe',
async ({ page }) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch001 = startSketchOn('XZ')
|> startProfileAt([4.61, -14.01], %)
test('Can edit a sketch that has been extruded in the same pipe', async ({
page,
}) => {
const u = await getUtils(page)
await page.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const sketch001 = startSketchOn('XZ')
|> startProfileAt([4.61, -10.01], %)
|> line([12.73, -0.09], %)
|> tangentialArcTo([24.95, -5.38], %)
|> tangentialArcTo([24.95, -0.38], %)
|> close(%)
|> extrude(5, %)`
)
})
)
})
await page.setViewportSize({ width: 1200, height: 500 })
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await u.waitForAuthSkipAppStart()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await page.waitForTimeout(100)
await u.openAndClearDebugPanel()
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_look_at',
vantage: { x: 0, y: -1250, z: 580 },
center: { x: 0, y: 0, z: 0 },
up: { x: 0, y: 0, z: 1 },
},
})
await page.waitForTimeout(100)
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_get_settings',
},
})
await page.waitForTimeout(100)
await page.waitForTimeout(100)
await u.openAndClearDebugPanel()
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_look_at',
vantage: { x: 0, y: -1250, z: 580 },
center: { x: 0, y: 0, z: 0 },
up: { x: 0, y: 0, z: 1 },
},
})
await page.waitForTimeout(100)
await u.sendCustomCmd({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
cmd: {
type: 'default_camera_get_settings',
},
})
await page.waitForTimeout(100)
const startPX = [665, 458]
const startPX = [665, 397]
const dragPX = 40
const dragPX = 40
await page.getByText('startProfileAt([4.61, -14.01], %)').click()
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400)
let prevContent = await page.locator('.cm-content').innerText()
await page.getByText('startProfileAt([4.61, -10.01], %)').click()
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400)
let prevContent = await page.locator('.cm-content').innerText()
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
// drag startProfieAt handle
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: startPX[0], y: startPX[1] },
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] + dragPX },
})
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText()
// drag startProfieAt handle
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: startPX[0], y: startPX[1] },
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] + dragPX },
})
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText()
// drag line handle
await page.waitForTimeout(100)
// drag line handle
await page.waitForTimeout(100)
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
await page.waitForTimeout(100)
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX },
})
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText()
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
await page.waitForTimeout(100)
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX },
})
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
prevContent = await page.locator('.cm-content').innerText()
// drag tangentialArcTo handle
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: tangentEnd.x, y: tangentEnd.y - 5 },
targetPosition: {
x: tangentEnd.x + dragPX,
y: tangentEnd.y + dragPX,
},
})
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
// drag tangentialArcTo handle
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: tangentEnd.x + 10, y: tangentEnd.y - 5 },
targetPosition: {
x: tangentEnd.x + dragPX,
y: tangentEnd.y + dragPX,
},
})
await page.waitForTimeout(100)
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([7.12, -16.82], %)
|> line([15.4, -2.74], %)
|> tangentialArcTo([24.95, -5.38], %)
|> line([2.65, -2.69], %)
|> close(%)
|> extrude(5, %)`)
}
)
// expect the code to have changed
await expect(page.locator('.cm-content'))
.toHaveText(`const sketch001 = startSketchOn('XZ')
|> startProfileAt([7.12, -12.68], %)
|> line([15.39, -2.78], %)
|> tangentialArcTo([27.6, -3.05], %)
|> close(%)
|> extrude(5, %)
`)
})
test('Can edit a sketch that has been revolved in the same pipe', async ({
page,
@ -602,7 +599,7 @@ test.describe('Sketch tests', () => {
await expect(u.codeLocator).toHaveText(codeStr)
// exit the sketch, reset relative clicker
click00r(undefined, undefined)
await click00r(undefined, undefined)
await u.openAndClearDebugPanel()
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await u.expectCmdLog('[data-message-type="execution-done"]')

View File

@ -53,6 +53,7 @@ test(
async ({ page, context }) => {
// skip on macos and windows.
test.skip(
// eslint-disable-next-line jest/valid-title
process.platform === 'darwin' || process.platform === 'win32',
'Skip on macos and windows'
)
@ -963,3 +964,69 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
})
})
})
test('theme persists', async ({ page, context }) => {
const u = await getUtils(page)
await context.addInitScript(async () => {
localStorage.setItem(
'persistCode',
`const part001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
|> line([-20, 0], %)
|> close(%)
|> extrude(10, %)
`
)
}, KCL_DEFAULT_LENGTH)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await page.waitForTimeout(500)
// await page.getByRole('link', { name: 'Settings Settings (tooltip)' }).click()
await expect(page.getByTestId('settings-link')).toBeVisible()
await page.getByTestId('settings-link').click()
// open user settingns
await page.getByRole('radio', { name: 'person User' }).click()
await page.getByTestId('app-theme').selectOption('light')
await page.getByTestId('settings-close-button').click()
const networkToggle = page.getByTestId('network-toggle')
// simulate network down
await u.emulateNetworkConditions({
offline: true,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
// Disconnect and reconnect to check the theme persists through a reload
// Expect the network to be down
await expect(networkToggle).toContainText('Offline')
// simulate network up
await u.emulateNetworkConditions({
offline: false,
// values of 0 remove any active throttling. crbug.com/456324#c9
latency: 0,
downloadThroughput: -1,
uploadThroughput: -1,
})
await expect(networkToggle).toContainText('Connected')
await expect(page.getByText('building scene')).not.toBeVisible()
await expect(page, 'expect screenshot to have light theme').toHaveScreenshot({
maxDiffPixels: 100,
})
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 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: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 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: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -2,12 +2,13 @@ import {
expect,
Page,
Download,
TestInfo,
BrowserContext,
TestInfo,
_electron as electron,
Locator,
test,
} from '@playwright/test'
import { EngineCommand } from 'lang/std/artifactGraph'
import os from 'os'
import fsp from 'fs/promises'
import fsSync from 'fs'
import { join } from 'path'
@ -25,6 +26,7 @@ import {
import * as TOML from '@iarna/toml'
import { SaveSettingsPayload } from 'lib/settings/settingsTypes'
import { SETTINGS_FILE_NAME } from 'lib/constants'
import { isArray } from 'lib/utils'
type TestColor = [number, number, number]
export const TEST_COLORS = {
@ -43,6 +45,9 @@ export const commonPoints = {
num2: 14.44,
}
export const editorSelector = '[role="textbox"][data-language="kcl"]'
type PaneId = 'variables' | 'code' | 'files' | 'logs'
async function waitForPageLoadWithRetry(page: Page) {
await expect(async () => {
await page.goto('/')
@ -72,11 +77,10 @@ async function waitForPageLoad(page: Page) {
}
async function removeCurrentCode(page: Page) {
const hotkey = process.platform === 'darwin' ? 'Meta' : 'Control'
await page.locator('.cm-content').click()
await page.keyboard.down(hotkey)
await page.keyboard.down('ControlOrMeta')
await page.keyboard.press('a')
await page.keyboard.up(hotkey)
await page.keyboard.up('ControlOrMeta')
await page.keyboard.press('Backspace')
await expect(page.locator('.cm-content')).toHaveText('')
}
@ -94,6 +98,8 @@ async function expectCmdLog(page: Page, locatorStr: string, timeout = 5000) {
await expect(page.locator(locatorStr).last()).toBeVisible({ timeout })
}
// Ignoring the lint since I assume someone will want to use this for a test.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async function waitForDefaultPlanesToBeVisible(page: Page) {
await page.waitForFunction(
() =>
@ -102,17 +108,21 @@ async function waitForDefaultPlanesToBeVisible(page: Page) {
)
}
async function openKclCodePanel(page: Page) {
const paneLocator = page.getByTestId('code-pane-button')
const ariaSelected = await paneLocator?.getAttribute('aria-pressed')
const isOpen = ariaSelected === 'true'
async function openPane(page: Page, testId: string) {
const locator = page.getByTestId(testId)
await expect(locator).toBeVisible()
const isOpen = (await locator?.getAttribute('aria-pressed')) === 'true'
if (!isOpen) {
await paneLocator.click()
await expect(paneLocator).toHaveAttribute('aria-pressed', 'true')
await locator.click()
await expect(locator).toHaveAttribute('aria-pressed', 'true')
}
}
async function openKclCodePanel(page: Page) {
await openPane(page, 'code-pane-button')
}
async function closeKclCodePanel(page: Page) {
const paneLocator = page.getByTestId('code-pane-button')
const ariaSelected = await paneLocator?.getAttribute('aria-pressed')
@ -125,14 +135,7 @@ async function closeKclCodePanel(page: Page) {
}
async function openDebugPanel(page: Page) {
const debugLocator = page.getByTestId('debug-pane-button')
await expect(debugLocator).toBeVisible()
const isOpen = (await debugLocator?.getAttribute('aria-pressed')) === 'true'
if (!isOpen) {
await debugLocator.click()
await expect(debugLocator).toHaveAttribute('aria-pressed', 'true')
}
await openPane(page, 'debug-pane-button')
}
async function closeDebugPanel(page: Page) {
@ -145,6 +148,28 @@ async function closeDebugPanel(page: Page) {
}
}
async function openFilePanel(page: Page) {
await openPane(page, 'files-pane-button')
}
async function closeFilePanel(page: Page) {
const fileLocator = page.getByTestId('files-pane-button')
await expect(fileLocator).toBeVisible()
const isOpen = (await fileLocator?.getAttribute('aria-pressed')) === 'true'
if (isOpen) {
await fileLocator.click()
await expect(fileLocator).not.toHaveAttribute('aria-pressed', 'true')
}
}
async function openVariablesPane(page: Page) {
await openPane(page, 'variables-pane-button')
}
async function openLogsPane(page: Page) {
await openPane(page, 'logs-pane-button')
}
async function waitForCmdReceive(page: Page, commandType: string) {
return page
.locator(`[data-receive-command-type="${commandType}"]`)
@ -171,7 +196,8 @@ export const wiggleMove = async (
const isElVis = await page.locator(locator).isVisible()
if (isElVis) return
}
const [x1, y1] = [0, Math.sin((tau / steps) * j * freq) * amplitude]
// x1 is 0.
const y1 = Math.sin((tau / steps) * j * freq) * amplitude
const [x2, y2] = [
Math.cos(-ang * deg) * i - Math.sin(-ang * deg) * y1,
Math.sin(-ang * deg) * i + Math.cos(-ang * deg) * y1,
@ -182,7 +208,7 @@ export const wiggleMove = async (
}
export const circleMove = async (
page: any,
page: Page,
x: number,
y: number,
steps: number,
@ -288,13 +314,19 @@ export function normaliseKclNumbers(code: string, ignoreZero = true): string {
return replaceNumbers(code)
}
export async function getUtils(page: Page) {
export async function getUtils(page: Page, test_?: typeof test) {
if (!test) {
console.warn(
'Some methods in getUtils requires test object as second argument'
)
}
// Chrome devtools protocol session only works in Chromium
const browserType = page.context().browser()?.browserType().name()
const cdpSession =
browserType !== 'chromium' ? null : await page.context().newCDPSession(page)
return {
const util = {
waitForAuthSkipAppStart: () => waitForAuthAndLsp(page),
waitForPageLoad: () => waitForPageLoad(page),
waitForPageLoadWithRetry: () => waitForPageLoadWithRetry(page),
@ -317,6 +349,10 @@ export async function getUtils(page: Page) {
closeKclCodePanel: () => closeKclCodePanel(page),
openDebugPanel: () => openDebugPanel(page),
closeDebugPanel: () => closeDebugPanel(page),
openFilePanel: () => openFilePanel(page),
closeFilePanel: () => closeFilePanel(page),
openVariablesPane: () => openVariablesPane(page),
openLogsPane: () => openLogsPane(page),
openAndClearDebugPanel: async () => {
await openDebugPanel(page)
return clearCommandLogs(page)
@ -452,9 +488,120 @@ export async function getUtils(page: Page) {
return page.evaluate('window.tearDown()')
}
cdpSession?.send('Network.emulateNetworkConditions', networkOptions)
return cdpSession?.send(
'Network.emulateNetworkConditions',
networkOptions
)
},
toNormalizedCode: (text: string) => {
return text.replace(/\s+/g, '')
},
createAndSelectProject: async (hasText: string) => {
return test_?.step(
`Create and select project with text "${hasText}"`,
async () => {
await page.getByTestId('home-new-file').click()
const projectLinksPost = page.getByTestId('project-link')
await projectLinksPost.filter({ hasText }).click()
}
)
},
editorTextMatches: async (code: string) => {
const editor = page.locator(editorSelector)
return expect(editor).toHaveText(code, { useInnerText: true })
},
pasteCodeInEditor: async (code: string) => {
return test?.step('Paste in KCL code', async () => {
const editor = page.locator(editorSelector)
await editor.fill(code)
await util.editorTextMatches(code)
})
},
clickPane: async (paneId: PaneId) => {
return test?.step(`Open ${paneId} pane`, async () => {
await page.getByTestId(paneId + '-pane-button').click()
await expect(page.locator('#' + paneId + '-pane')).toBeVisible()
})
},
createNewFile: async (name: string) => {
return test?.step(`Create a file named ${name}`, async () => {
await page.getByTestId('create-file-button').click()
await page.getByTestId('file-rename-field').fill(name)
await page.keyboard.press('Enter')
})
},
selectFile: async (name: string) => {
return test?.step(`Select ${name}`, async () => {
await page
.locator('[data-testid="file-pane-scroll-container"] button')
.filter({ hasText: name })
.click()
})
},
createNewFileAndSelect: async (name: string) => {
return test?.step(`Create a file named ${name}, select it`, async () => {
await page.getByTestId('create-file-button').click()
await page.getByTestId('file-rename-field').fill(name)
await page.keyboard.press('Enter')
await page
.locator('[data-testid="file-pane-scroll-container"] button')
.filter({ hasText: name })
.click()
})
},
renameFile: async (fromName: string, toName: string) => {
return test?.step(`Rename ${fromName} to ${toName}`, async () => {
await page
.locator('[data-testid="file-pane-scroll-container"] button')
.filter({ hasText: fromName })
.click({ button: 'right' })
await page.getByTestId('context-menu-rename').click()
await page.getByTestId('file-rename-field').fill(toName)
await page.keyboard.press('Enter')
await page
.locator('[data-testid="file-pane-scroll-container"] button')
.filter({ hasText: toName })
.click()
})
},
deleteFile: async (name: string) => {
return test?.step(`Delete ${name}`, async () => {
await page
.locator('[data-testid="file-pane-scroll-container"] button')
.filter({ hasText: name })
.click({ button: 'right' })
await page.getByTestId('context-menu-delete').click()
await page.getByTestId('delete-confirmation').click()
})
},
panesOpen: async (paneIds: PaneId[]) => {
return test?.step(`Setting ${paneIds} panes to be open`, async () => {
await page.addInitScript(
({ PERSIST_MODELING_CONTEXT, paneIds }) => {
localStorage.setItem(
PERSIST_MODELING_CONTEXT,
JSON.stringify({ openPanes: paneIds })
)
},
{ PERSIST_MODELING_CONTEXT, paneIds }
)
await page.reload()
})
},
}
return util
}
type TemplateOptions = Array<number | Array<number>>
@ -475,7 +622,7 @@ const _makeTemplate = (
templateParts: TemplateStringsArray,
...options: TemplateOptions
) => {
const length = Math.max(...options.map((a) => (Array.isArray(a) ? a[0] : 0)))
const length = Math.max(...options.map((a) => (isArray(a) ? a[0] : 0)))
let reExpTemplate = ''
for (let i = 0; i < length; i++) {
const currentStr = templateParts.map((str, index) => {
@ -483,7 +630,7 @@ const _makeTemplate = (
return (
escapeRegExp(str) +
String(
Array.isArray(currentOptions)
isArray(currentOptions)
? currentOptions[i]
: typeof currentOptions === 'number'
? currentOptions
@ -539,17 +686,34 @@ export interface Paths {
export const doExport = async (
output: Models['OutputFormat_type'],
page: Page,
isElectron = false
exportFrom: 'dropdown' | 'sidebarButton' | 'commandBar' = 'dropdown'
): Promise<Paths> => {
if (!isElectron) {
if (exportFrom === 'dropdown') {
await page.getByRole('button', { name: APP_NAME }).click()
const exportMenuButton = page.getByRole('button', {
name: 'Export current part',
})
await expect(exportMenuButton).toBeVisible()
await exportMenuButton.click()
} else {
} else if (exportFrom === 'sidebarButton') {
await expect(page.getByTestId('export-pane-button')).toBeVisible()
await page.getByTestId('export-pane-button').click()
} else if (exportFrom === 'commandBar') {
const commandBarButton = page.getByRole('button', { name: 'Commands' })
await expect(commandBarButton).toBeVisible()
// Click the command bar button
await commandBarButton.click()
// Wait for the command bar to appear
const cmdSearchBar = page.getByPlaceholder('Search commands')
await expect(cmdSearchBar).toBeVisible()
const textToCadCommand = page.getByRole('option', {
name: 'floppy disk arrow Export',
})
await expect(textToCadCommand.first()).toBeVisible()
// Click the Text-to-CAD command
await textToCadCommand.first().click()
}
await expect(page.getByTestId('command-bar')).toBeVisible()
@ -577,7 +741,7 @@ export const doExport = async (
const [downloadPromise1, downloadResolve1] = getPromiseAndResolve()
let downloadCnt = 0
if (!isElectron)
if (exportFrom === 'dropdown')
page.on('download', async (download) => {
if (downloadCnt === 0) {
downloadResolve1(download)
@ -585,7 +749,7 @@ export const doExport = async (
downloadCnt++
})
await page.getByRole('button', { name: 'Submit command' }).click()
if (isElectron) {
if (exportFrom === 'sidebarButton' || exportFrom === 'commandBar') {
return {
modelPath: '',
imagePath: '',
@ -620,11 +784,6 @@ export const doExport = async (
}
}
/**
* Gets the appropriate modifier key for the platform.
*/
export const metaModifier = os.platform() === 'darwin' ? 'Meta' : 'Control'
export async function tearDown(page: Page, testInfo: TestInfo) {
if (testInfo.status === 'skipped') return
if (testInfo.status === 'failed') return
@ -649,11 +808,11 @@ export async function tearDown(page: Page, testInfo: TestInfo) {
export async function setup(context: BrowserContext, page: Page) {
await context.addInitScript(
async ({ token, settingsKey, settings, IS_PLAYWRIGHT_KEY }) => {
localStorage.clear()
localStorage.setItem('TOKEN_PERSIST_KEY', token)
localStorage.setItem('persistCode', ``)
localStorage.setItem(settingsKey, settings)
localStorage.setItem(IS_PLAYWRIGHT_KEY, 'true')
console.log('TEST_SETTINGS.projects', settings)
},
{
token: secrets.token,
@ -684,6 +843,9 @@ export async function setup(context: BrowserContext, page: Page) {
])
// kill animations, speeds up tests and reduced flakiness
await page.emulateMedia({ reducedMotion: 'reduce' })
// Trigger a navigation, since loading file:// doesn't.
await page.reload()
}
export async function setupElectron({
@ -743,5 +905,54 @@ export async function setupElectron({
await setup(context, page)
return { electronApp, page }
return { electronApp, page, dir: projectDirName }
}
export async function isOutOfViewInScrollContainer(
element: Locator,
container: Locator
): Promise<boolean> {
const elementBox = await element.boundingBox({ timeout: 5_000 })
const containerBox = await container.boundingBox({ timeout: 5_000 })
let isOutOfView = false
if (elementBox && containerBox)
return (
elementBox.y + elementBox.height > containerBox.y + containerBox.height ||
elementBox.y < containerBox.y ||
elementBox.x + elementBox.width > containerBox.x + containerBox.width ||
elementBox.x < containerBox.x
)
return isOutOfView
}
export async function createProjectAndRenameIt({
name,
page,
}: {
name: string
page: Page
}) {
await page.getByRole('button', { name: 'New project' }).click()
await expect(page.getByText('Successfully created')).toBeVisible()
await expect(page.getByText('Successfully created')).not.toBeVisible()
await expect(page.getByText(`project-000`)).toBeVisible()
await page.getByText(`project-000`).hover()
await page.getByText(`project-000`).focus()
await page.getByLabel('sketch').first().click()
await page.waitForTimeout(100)
// type the name passed in
await page.keyboard.press('Backspace')
await page.keyboard.type(name)
await page.getByLabel('checkmark').last().click()
}
export function executorInputPath(fileName: string): string {
return join('src', 'wasm-lib', 'tests', 'executor', 'inputs', fileName)
}

View File

@ -174,168 +174,166 @@ test.describe('Testing Camera Movement', () => {
}, [0, -85, -85])
})
// TODO fixme something is wrong with sketch here
test.fixme(
'Zoom should be consistent when exiting or entering sketches',
async ({ page }) => {
// start new sketch pan and zoom before exiting, when exiting the sketch should stay in the same place
// than zoom and pan outside of sketch mode and enter again and it should not change from where it is
// than again for sketching
test('Zoom should be consistent when exiting or entering sketches', async ({
page,
}) => {
// start new sketch pan and zoom before exiting, when exiting the sketch should stay in the same place
// than zoom and pan outside of sketch mode and enter again and it should not change from where it is
// than again for sketching
test.skip(process.platform !== 'darwin', 'Zoom should be consistent')
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
test.skip(process.platform !== 'darwin', 'Zoom should be consistent')
const u = await getUtils(page)
await page.setViewportSize({ width: 1200, height: 500 })
await u.waitForAuthSkipAppStart()
await u.openDebugPanel()
await u.waitForAuthSkipAppStart()
await u.openDebugPanel()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).toBeVisible()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled()
await expect(
page.getByRole('button', { name: 'Start Sketch' })
).toBeVisible()
// click on "Start Sketch" button
await u.clearCommandLogs()
await page.getByRole('button', { name: 'Start Sketch' }).click()
// click on "Start Sketch" button
await u.clearCommandLogs()
await page.getByRole('button', { name: 'Start Sketch' }).click()
await page.waitForTimeout(100)
// select a plane
await page.mouse.click(700, 325)
let code = `const sketch001 = startSketchOn('XY')`
await expect(u.codeLocator).toHaveText(code)
await u.closeDebugPanel()
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
// move the camera slightly
await page.keyboard.down('Shift')
await page.mouse.move(700, 300)
await page.mouse.down({ button: 'right' })
await page.mouse.move(800, 200)
await page.mouse.up({ button: 'right' })
await page.keyboard.up('Shift')
let y = 350,
x = 948
await u.canvasLocator.click({ position: { x: 783, y } })
code += `\n |> startProfileAt([8.12, -12.98], %)`
// await expect(u.codeLocator).toHaveText(code)
await u.canvasLocator.click({ position: { x, y } })
code += `\n |> line([11.18, 0], %)`
// await expect(u.codeLocator).toHaveText(code)
await u.canvasLocator.click({ position: { x, y: 275 } })
code += `\n |> line([0, 6.99], %)`
// await expect(u.codeLocator).toHaveText(code)
// click the line button
await page.getByRole('button', { name: 'line Line', exact: true }).click()
const hoverOverNothing = async () => {
// await u.canvasLocator.hover({position: {x: 700, y: 325}})
await page.mouse.move(700, 325)
await page.waitForTimeout(100)
// select a plane
await page.mouse.click(700, 325)
let code = `const sketch001 = startSketchOn('XY')`
await expect(u.codeLocator).toHaveText(code)
await u.closeDebugPanel()
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
// move the camera slightly
await page.keyboard.down('Shift')
await page.mouse.move(700, 300)
await page.mouse.down({ button: 'right' })
await page.mouse.move(800, 200)
await page.mouse.up({ button: 'right' })
await page.keyboard.up('Shift')
let y = 350,
x = 948
await u.canvasLocator.click({ position: { x: 783, y } })
code += `\n |> startProfileAt([8.12, -12.98], %)`
// await expect(u.codeLocator).toHaveText(code)
await u.canvasLocator.click({ position: { x, y } })
code += `\n |> line([11.18, 0], %)`
// await expect(u.codeLocator).toHaveText(code)
await u.canvasLocator.click({ position: { x, y: 275 } })
code += `\n |> line([0, 6.99], %)`
// await expect(u.codeLocator).toHaveText(code)
// click the line button
await page.getByRole('button', { name: 'line Line', exact: true }).click()
const hoverOverNothing = async () => {
// await u.canvasLocator.hover({position: {x: 700, y: 325}})
await page.mouse.move(700, 325)
await page.waitForTimeout(100)
await expect(page.getByTestId('hover-highlight')).not.toBeVisible({
timeout: 10_000,
})
}
await expect(page.getByTestId('hover-highlight')).not.toBeVisible()
await page.waitForTimeout(200)
// hover over horizontal line
await u.canvasLocator.hover({ position: { x: 800, y } })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await page.waitForTimeout(200)
await hoverOverNothing()
await page.waitForTimeout(200)
// hover over vertical line
await u.canvasLocator.hover({ position: { x, y: 325 } })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
// click exit sketch
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await page.waitForTimeout(400)
await hoverOverNothing()
await page.waitForTimeout(200)
// hover over horizontal line
await page.mouse.move(858, y, { steps: 5 })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
// hover over vertical line
await page.mouse.move(x, 325)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
// hover over vertical line
await page.mouse.move(857, y)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
// now click it
await page.mouse.click(857, y)
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400)
await hoverOverNothing()
x = 975
y = 468
await page.waitForTimeout(100)
await page.mouse.move(x, 419, { steps: 5 })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
await page.mouse.move(855, y)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await page.waitForTimeout(200)
await hoverOverNothing()
await page.waitForTimeout(200)
await page.mouse.move(x, 419)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
await page.mouse.move(855, y)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
await expect(page.getByTestId('hover-highlight')).not.toBeVisible({
timeout: 10_000,
})
}
)
await expect(page.getByTestId('hover-highlight')).not.toBeVisible()
await page.waitForTimeout(200)
// hover over horizontal line
await u.canvasLocator.hover({ position: { x: 800, y } })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await page.waitForTimeout(200)
await hoverOverNothing()
await page.waitForTimeout(200)
// hover over vertical line
await u.canvasLocator.hover({ position: { x, y: 325 } })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
// click exit sketch
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await page.waitForTimeout(400)
await hoverOverNothing()
await page.waitForTimeout(200)
// hover over horizontal line
await page.mouse.move(858, y, { steps: 5 })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
// hover over vertical line
await page.mouse.move(x, 325)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
// hover over vertical line
await page.mouse.move(857, y)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
// now click it
await page.mouse.click(857, y)
await expect(
page.getByRole('button', { name: 'Edit Sketch' })
).toBeVisible()
await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(400)
await hoverOverNothing()
x = 975
y = 468
await page.waitForTimeout(100)
await page.mouse.move(x, 419, { steps: 5 })
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
await page.mouse.move(855, y)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
await page.getByRole('button', { name: 'Exit Sketch' }).click()
await page.waitForTimeout(200)
await hoverOverNothing()
await page.waitForTimeout(200)
await page.mouse.move(x, 419)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
await hoverOverNothing()
await page.mouse.move(855, y)
await expect(page.getByTestId('hover-highlight').first()).toBeVisible({
timeout: 10_000,
})
})
})

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