Compare commits
	
		
			126 Commits
		
	
	
		
			reuse-exam
			...
			achalmers/
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| aa79f5b45c | |||
| e3b9a6e5d8 | |||
| e94b1bc12a | |||
| c0eff5bc14 | |||
| b0f92c2f6d | |||
| 718873b3bb | |||
| 9f815eecc1 | |||
| 0384e5e6c6 | |||
| 48ef0885b7 | |||
| 3b2731f924 | |||
| bf4e04f9f1 | |||
| 24475bbcdf | |||
| bcca736a8d | |||
| 440eb2636a | |||
| 344e72d7ec | |||
| ec7b733a0d | |||
| 63159c1cb8 | |||
| df62a995b5 | |||
| fa762c1c4d | |||
| 82b03a9d47 | |||
| 793b7407f6 | |||
| 040bcc2c09 | |||
| ae2e219394 | |||
| a83f549257 | |||
| 3871d2858f | |||
| 3effb87f8e | |||
| 3f2f035a9b | |||
| 4735eaef8c | |||
| 69f8da058a | |||
| 93ebf13621 | |||
| 20c4d44b8b | |||
| 8ea8f80e32 | |||
| d73339fd8d | |||
| 031b230690 | |||
| 1125d74f12 | |||
| 5c7a2822d0 | |||
| d44b1f8e54 | |||
| c4ca69496b | |||
| f06de7f586 | |||
| 75c6ae6e66 | |||
| 48639d70db | |||
| c565d9670d | |||
| 7bf5953299 | |||
| a9ab35e55f | |||
| 15418e98b0 | |||
| 20838bf618 | |||
| acd52ab350 | |||
| 75b9d2913f | |||
| d92e6f6453 | |||
| c1a879837e | |||
| daacca500c | |||
| c1e8bb5288 | |||
| 8ca4166b08 | |||
| 4624f1c0ba | |||
| 7ac6a3a4f2 | |||
| 3cbf2b194a | |||
| 44f06aa199 | |||
| 1b878865b8 | |||
| 3b840e9a80 | |||
| 4a0811eec8 | |||
| e63bf5db11 | |||
| 863e4e206f | |||
| f1cd2355c6 | |||
| 164b675a86 | |||
| b1afe1c541 | |||
| 26ef7218b2 | |||
| e5a4fb439c | |||
| 97ad66a358 | |||
| 26438270ff | |||
| a0cfda6d7a | |||
| 58a62b8097 | |||
| e2909c509f | |||
| 07eaf93e78 | |||
| 6a5ca3088a | |||
| 6501072d80 | |||
| 726fd02bad | |||
| d0f9ae475f | |||
| da323e22d4 | |||
| 8dc3628e9b | |||
| 253744867b | |||
| c45eb1e3e3 | |||
| 758aac9328 | |||
| 309943cf2c | |||
| b3d4ab91fc | |||
| 5e73fa45f0 | |||
| 17d23a17db | |||
| 0460f8eaee | |||
| 2077cdb6fc | |||
| cb0b7e8169 | |||
| 3a05211d30 | |||
| d12d103cba | |||
| 04f6d3dcc8 | |||
| 9c9ffa0d03 | |||
| c62b9f1f04 | |||
| fcac3c72e4 | |||
| 1e2f577a9f | |||
| 1814f340fb | |||
| 43928f88aa | |||
| 6959036688 | |||
| 570d0473c6 | |||
| 44f0d7c25c | |||
| 3ccb04c4e7 | |||
| 00058f699a | |||
| 5a478fe0b3 | |||
| 723cf4f746 | |||
| 3950de0a4d | |||
| 901d474986 | |||
| e7ab645267 | |||
| cf830f9895 | |||
| 2c1f53f0f0 | |||
| d39e2502d0 | |||
| 51fed9c541 | |||
| b3a09abe01 | |||
| cd3a2fea07 | |||
| c29c4a8567 | |||
| 39ccd94884 | |||
| d99ab22b56 | |||
| 20a8f2aa6a | |||
| 93266a9819 | |||
| a9c7a7cb13 | |||
| 8dd9b8d192 | |||
| 23181d8144 | |||
| 834967df6a | |||
| deacaac33a | |||
| c55603853b | |||
| 93f652647e | 
| @ -3,3 +3,4 @@ VITE_KC_API_BASE_URL=https://api.dev.zoo.dev | ||||
| VITE_KC_SITE_BASE_URL=https://dev.zoo.dev | ||||
| VITE_KC_SKIP_AUTH=false | ||||
| VITE_KC_CONNECTION_TIMEOUT_MS=5000 | ||||
| VITE_KC_DEV_TOKEN="your token from dev.zoo.dev should go in .env.development.local" | ||||
|  | ||||
							
								
								
									
										82
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -130,7 +130,9 @@ jobs: | ||||
|       matrix: | ||||
|         os: [macos-14, ubuntu-latest, windows-latest] | ||||
|     env: | ||||
|       # Specific Apple Universal target for macos | ||||
|       TAURI_ARGS_MACOS: ${{ matrix.os == 'macos-14' && '--target universal-apple-darwin' || '' }} | ||||
|       # Only build executable on linux (no appimage or deb) | ||||
|       TAURI_ARGS_UBUNTU: ${{ matrix.os == 'ubuntu-latest' && '--bundles' || '' }} | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
| @ -237,9 +239,9 @@ jobs: | ||||
|           includeDebug: true | ||||
|           args: "${{ env.TAURI_ARGS_MACOS }} ${{ env.TAURI_ARGS_UBUNTU }}" | ||||
|  | ||||
|  | ||||
|       - name: Mac App Store | ||||
|         if: ${{ env.BUILD_RELEASE == 'true' && matrix.os == 'macos-14' }} | ||||
|       - name: Build for Mac TestFlight (nightly) | ||||
|         if: ${{ github.event_name == 'schedule' && matrix.os == 'macos-14' }} | ||||
|         shell: bash | ||||
|         run: | | ||||
|           unset APPLE_SIGNING_IDENTITY | ||||
|           unset APPLE_CERTIFICATE | ||||
| @ -248,45 +250,40 @@ jobs: | ||||
|           profile="src-tauri/entitlements/Mac_App_Distribution.provisionprofile" | ||||
|  | ||||
|           mkdir -p src-tauri/entitlements | ||||
|           echo "${APPLE_STORE_PROVISIONING_PROFILE}" | base64 --decode > "${profile}" | ||||
|           echo -n "${APPLE_STORE_PROVISIONING_PROFILE}" | base64 --decode -o "${profile}" | ||||
|  | ||||
|           echo "${APPLE_STORE_DISTRIBUTION_CERT}" | base64 --decode > "dist.cer" | ||||
|           echo "${APPLE_STORE_INSTALLER_CERT}" | base64 --decode > "installer.cer" | ||||
|           echo -n "${APPLE_STORE_DISTRIBUTION_CERT}" | base64 --decode -o "dist.cer" | ||||
|           echo -n "${APPLE_STORE_INSTALLER_CERT}" | base64 --decode -o "installer.cer" | ||||
|  | ||||
|           # load the certificates into the keychain | ||||
|           # Create a custom keychain | ||||
|           security create-keychain -p gh_actions refine-build.keychain | ||||
|           KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db | ||||
|           KEYCHAIN_PASSWORD="password" | ||||
|  | ||||
|           # Make the custom keychain default, so xcodebuild will use it for signing | ||||
|           security default-keychain -s refine-build.keychain | ||||
|           # create temporary keychain | ||||
|           security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | ||||
|           security set-keychain-settings -lut 21600 $KEYCHAIN_PATH | ||||
|           security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | ||||
|  | ||||
|           # Unlock the keychain | ||||
|           security unlock-keychain -p gh_actions refine-build.keychain | ||||
|           # import certificate to keychain | ||||
|           security import "dist.cer" -P "$APPLE_STORE_P12_PASSWORD" -k $KEYCHAIN_PATH -f pkcs12 -t cert -A | ||||
|           security import "installer.cer" -P "$APPLE_STORE_P12_PASSWORD" -k $KEYCHAIN_PATH -f pkcs12 -t cert -A | ||||
|  | ||||
|           # Set keychain timeout to 1 hour for long builds | ||||
|           security set-keychain-settings -t 3600 -l ~/Library/Keychains/refine-build.keychain | ||||
|  | ||||
|           # Add certificates to keychain and allow codesign to access them | ||||
|           security import "dist.cer" -k ~/Library/Keychains/refine-build.keychain -T /usr/bin/codesign | ||||
|           security import "installer.cer" -k ~/Library/Keychains/refine-build.keychain -T /usr/bin/codesign | ||||
|  | ||||
|           security set-key-partition-list -S apple-tool:,apple: -s -k gh_actions refine-build.keychain | ||||
|           security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | ||||
|           security list-keychain -d user -s $KEYCHAIN_PATH | ||||
|  | ||||
|           target="universal-apple-darwin" | ||||
|  | ||||
|           # Turn off the default target | ||||
|           sed -i "s/default =/# default =/" src-tauri/Cargo.toml | ||||
|           yarn tauri build --target "${target}" --verbose | ||||
|           # We don't want to install the updater for the apple store build | ||||
|           sed -i.bu "s/default =/# default =/" src-tauri/Cargo.toml | ||||
|           rm src-tauri/Cargo.toml.bu | ||||
|           git diff src-tauri/Cargo.toml | ||||
|  | ||||
|           ls -l src-tauri/target/${target} | ||||
|           ls -l src-tauri/target | ||||
|           ls -l src-tauri/target/${target}/release/bundle/macos | ||||
|           ls -l src-tauri/entitlements | ||||
|           yarn tauri build --target "${target}" --verbose --config src-tauri/tauri.app-store.conf.json | ||||
|  | ||||
|           app_path="src-tauri/target/${target}/release/bundle/macos/Zoo Modeling App.app" | ||||
|           build_name="src-tauri/target/${target}/release/bundle/macos/Zoo Modeling App.pkg" | ||||
|           cp_dir="src-tauri/target/${target}/release/bundle/macos/Zoo Modeling App.app/Contents/embedded.provisionprofile" | ||||
|           entitlements="src-tauri/entitlements/Zoo Modeling App.entitlements" | ||||
|           entitlements="src-tauri/entitlements/app-store.entitlements" | ||||
|  | ||||
|           cp "${profile}" "${cp_dir}" | ||||
|  | ||||
| @ -296,20 +293,38 @@ jobs: | ||||
|  | ||||
|           # Undo the changes to the Cargo.toml | ||||
|           git checkout src-tauri/Cargo.toml | ||||
|  | ||||
|         env: | ||||
|           APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | ||||
|           APPLE_STORE_PROVISIONING_PROFILE: ${{ secrets.APPLE_STORE_PROVISIONING_PROFILE }} | ||||
|           APPLE_STORE_DISTRIBUTION_CERT: ${{ secrets.APPLE_STORE_DISTRIBUTION_CERT }} | ||||
|           APPLE_STORE_INSTALLER_CERT: ${{ secrets.APPLE_STORE_INSTALLER_CERT }} | ||||
|           APPLE_STORE_P12_PASSWORD: ${{ secrets.APPLE_STORE_P12_PASSWORD }} | ||||
|  | ||||
|       - name: 'Upload app to TestFlight' | ||||
|  | ||||
|       - name: 'Upload to Mac TestFlight (nightly)' | ||||
|         uses: apple-actions/upload-testflight-build@v1 | ||||
|         if: ${{ env.BUILD_RELEASE == 'true' && matrix.os == 'macos-14' }} | ||||
|         if: ${{ github.event_name == 'schedule' && matrix.os == 'macos-14' }} | ||||
|         with: | ||||
|           app-path: 'src-tauri/target/universal-apple-darwin/release/bundle/macos/Zoo Modeling App.pkg' | ||||
|           issuer-id: ${{ secrets.APPLE_STORE_ISSUER_ID }} | ||||
|           api-key-id: ${{ secrets.APPLE_STORE_API_KEY_ID }} | ||||
|           api-private-key: ${{ secrets.APPLE_STORE_API_PRIVATE_KEY }} | ||||
|           app-type: osx | ||||
|  | ||||
|  | ||||
|       - name: Clean up after Mac TestFlight (nightly) | ||||
|         if: ${{ github.event_name == 'schedule' && matrix.os == 'macos-14' }} | ||||
|         shell: bash | ||||
|         run: | | ||||
|           git status | ||||
|           # remove our target builds because we want to make sure the later build | ||||
|           # includes the updater, and that anything we changed with the target | ||||
|           # does not persist | ||||
|           rm -rf src-tauri/target | ||||
|           # Lets get rid of the info.plist for the normal mac builds since its | ||||
|           # being sketchy. | ||||
|           rm src-tauri/Info.plist | ||||
|  | ||||
|       # We do this after the apple store because the apple store build is | ||||
|       # specific and we want to overwrite it with the this new build after and | ||||
| @ -338,11 +353,10 @@ jobs: | ||||
|         with: | ||||
|           path: "${{ env.PREFIX }}/${{ env.MODE }}/bundle/*/*" | ||||
|  | ||||
|       # TODO: re-enable linux e2e tests when possible | ||||
|       - name: Run e2e tests (linux only) | ||||
|         if: false | ||||
|         if: ${{ matrix.os == 'ubuntu-latest' && github.event_name != 'release' && github.event_name != 'schedule' }} | ||||
|         run: | | ||||
|           cargo install tauri-driver | ||||
|           cargo install tauri-driver --force | ||||
|           source .env.${{ env.BUILD_RELEASE == 'true' && 'production' || 'development' }} | ||||
|           export VITE_KC_API_BASE_URL | ||||
|           xvfb-run yarn test:e2e:tauri | ||||
| @ -426,7 +440,7 @@ jobs: | ||||
|             cat last_download.json | ||||
|  | ||||
|       - name: Authenticate to Google Cloud | ||||
|         uses: 'google-github-actions/auth@v2.1.2' | ||||
|         uses: 'google-github-actions/auth@v2.1.3' | ||||
|         with: | ||||
|           credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}' | ||||
|  | ||||
|  | ||||
							
								
								
									
										4
									
								
								.github/workflows/create-release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -17,11 +17,11 @@ jobs: | ||||
|         name: Read Cut release PR info and create release | ||||
|         with: | ||||
|           script: | | ||||
|             const { owner, repo, sha } = context.repo | ||||
|             const { owner, repo } = context.repo | ||||
|             const pulls = await github.rest.repos.listPullRequestsAssociatedWithCommit({ | ||||
|               owner, | ||||
|               repo, | ||||
|               commit_sha: sha, | ||||
|               commit_sha: context.sha, | ||||
|             }) | ||||
|             const { title, body } = pulls.data[0] | ||||
|             const version = title.split('Cut release ')[1] | ||||
|  | ||||
							
								
								
									
										4
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -115,7 +115,7 @@ jobs: | ||||
|         git fetch origin | ||||
|         echo ${{ github.head_ref }} | ||||
|         git checkout ${{ github.head_ref }} | ||||
|         # TODO when safari works on ubuntu remove the os part of the commit message | ||||
|         # TODO when webkit works on ubuntu remove the os part of the commit message | ||||
|         git commit -am "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)" || true | ||||
|         git push | ||||
|         git push origin ${{ github.head_ref }} | ||||
| @ -181,7 +181,7 @@ jobs: | ||||
|     - name: build web | ||||
|       run: yarn build:local | ||||
|     - name: Run macos/safari flow | ||||
|       # safari doesn't work on Ubuntu because of the same reason tauri doesn't (webRTC issues) | ||||
|       # webkit doesn't work on Ubuntu because of the same reason tauri doesn't (webRTC issues) | ||||
|       # TODO remove this and the matrix and run all tests on ubuntu when this is fixed | ||||
|       run: yarn playwright test --project="webkit" e2e/playwright/flow-tests.spec.ts | ||||
|       env: | ||||
|  | ||||
							
								
								
									
										25
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @ -59,7 +59,9 @@ followed by: | ||||
| ``` | ||||
| yarn build:wasm-dev | ||||
| ``` | ||||
|  | ||||
| or if you have the gh cli installed | ||||
|  | ||||
| ``` | ||||
| ./get-latest-wasm-bundle.sh # this will download the latest main wasm bundle | ||||
| ``` | ||||
| @ -72,7 +74,13 @@ finally, to run the web app only, run: | ||||
| yarn start | ||||
| ``` | ||||
|  | ||||
| ## Developing in Chrome | ||||
| If you're not an KittyCAD employee you won't be able to access the dev environment, you should copy everything from `.env.production` to `.env.development` to make it point to production instead, then when you navigate to `localhost:3000` the easiest way to sign in is to paste `localStorage.setItem('TOKEN_PERSIST_KEY', "your-token-from-https://zoo.dev/account/api-tokens")` replacing the with a real token from https://zoo.dev/account/api-tokens ofcourse, then navigate to localhost:3000 again. Note that navigating to localhost:3000/signin removes your token so you will need to set the token again. | ||||
|  | ||||
| ### Development environment variables | ||||
|  | ||||
| The Copilot LSP plugin in the editor requires a Zoo API token to run. In production, we authenticate this with a token via cookie in the browser and device auth token in the desktop environment, but this token is inaccessible in the dev browser version because the cookie is considered "cross-site" (from `localhost` to `dev.zoo.dev`). There is an optional environment variable called `VITE_KC_DEV_TOKEN` that you can populate with a dev token in a `.env.development.local` file to not check it into Git, which will use that token instead of other methods for the LSP service. | ||||
|  | ||||
| ### Developing in Chrome | ||||
|  | ||||
| Chrome is in the process of rolling out a new default which | ||||
| [blocks Third-Party Cookies](https://developer.chrome.com/en/docs/privacy-sandbox/third-party-cookie-phase-out/). | ||||
| @ -94,6 +102,7 @@ yarn test | ||||
| Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testing Library E2E](https://testing-library.com/docs/react-testing-library/intro/) tests, in interactive mode by default. | ||||
|  | ||||
| For running the rust (not tauri rust though) only, you can | ||||
|  | ||||
| ```bash | ||||
| cd src/wasm-lib | ||||
| cargo test | ||||
| @ -156,6 +165,7 @@ console.log( | ||||
| - `) | ||||
| ) | ||||
| ``` | ||||
|  | ||||
| grab the md list and delete any that are older than the last bump | ||||
|  | ||||
| 2. Merge the PR | ||||
| @ -185,23 +195,26 @@ $ cargo +nightly fuzz run parser | ||||
| For more information on fuzzing you can check out | ||||
| [this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html). | ||||
|  | ||||
|  | ||||
| ### Playwright | ||||
|  | ||||
| First time running plawright locally, you'll need to add the secrets file | ||||
|  | ||||
| ```bash | ||||
| touch ./e2e/playwright/playwright-secrets.env | ||||
| printf 'token="your-token"\nsnapshottoken="your-snapshot-token"' > ./e2e/playwright/playwright-secrets.env | ||||
| ``` | ||||
|  | ||||
| then replace "your-token" with a dev token from dev.zoo.dev/account/api-tokens | ||||
|  | ||||
| then: | ||||
| run playwright | ||||
|  | ||||
| ``` | ||||
| yarn playwright test | ||||
| ``` | ||||
|  | ||||
| run a specific test suite | ||||
|  | ||||
| ``` | ||||
| yarn playwright test src/e2e-tests/example.spec.ts | ||||
| ``` | ||||
| @ -210,14 +223,17 @@ 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) | ||||
|  | ||||
| run headed | ||||
|  | ||||
| ``` | ||||
| yarn playwright test --headed | ||||
| ``` | ||||
|  | ||||
| run with step through debugger | ||||
|  | ||||
| ``` | ||||
| PWDEBUG=1 yarn playwright test | ||||
| ``` | ||||
|  | ||||
| However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying. | ||||
| With the extension you can set a breakpoint after `waitForDefaultPlanesVisibilityChange` in order to skip app loading, then the vscode debugger's "step over" is much better for being able to stay at the right level of abstraction as you debug the code. | ||||
|  | ||||
| @ -262,7 +278,6 @@ Where `./store` should look like this | ||||
|  | ||||
| </details> | ||||
|  | ||||
|  | ||||
| However because much of our tests involve clicking in the stream at specific locations, it's code-gen looks `await page.locator('video').click();` when really we need to use a pixel coord, so I think it's of limited use. | ||||
|  | ||||
| #### Some notes on CI | ||||
| @ -293,3 +308,7 @@ PS: for the debug panel, the following JSON is useful for snapping the camera | ||||
| ``` | ||||
|  | ||||
| </details> | ||||
|  | ||||
| ## KCL | ||||
|  | ||||
| For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/src/wasm-lib/kcl). | ||||
|  | ||||
| @ -31,7 +31,6 @@ layout: manual | ||||
| * [`fillet`](kcl/fillet) | ||||
| * [`floor`](kcl/floor) | ||||
| * [`getEdge`](kcl/getEdge) | ||||
| * [`getExtrudeWallTransform`](kcl/getExtrudeWallTransform) | ||||
| * [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge) | ||||
| * [`getOppositeEdge`](kcl/getOppositeEdge) | ||||
| * [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge) | ||||
| @ -57,6 +56,9 @@ layout: manual | ||||
| * [`patternLinear3d`](kcl/patternLinear3d) | ||||
| * [`pi`](kcl/pi) | ||||
| * [`pow`](kcl/pow) | ||||
| * [`profileStart`](kcl/profileStart) | ||||
| * [`profileStartX`](kcl/profileStartX) | ||||
| * [`profileStartY`](kcl/profileStartY) | ||||
| * [`revolve`](kcl/revolve) | ||||
| * [`segAng`](kcl/segAng) | ||||
| * [`segEndX`](kcl/segEndX) | ||||
|  | ||||
							
								
								
									
										206
									
								
								docs/kcl/profileStart.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										201
									
								
								docs/kcl/profileStartX.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										200
									
								
								docs/kcl/profileStartY.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										3957
									
								
								docs/kcl/std.json
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 249 KiB | 
| Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 249 KiB | 
| Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 249 KiB | 
| Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB | 
| Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB | 
| Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB | 
| Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB | 
| Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 249 KiB | 
| Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB | 
| Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 171 KiB | 
| @ -4,7 +4,7 @@ import { getUtils } from './test-utils' | ||||
| import { Models } from '@kittycad/lib' | ||||
| import fsp from 'fs/promises' | ||||
| import { spawn } from 'child_process' | ||||
| import { APP_NAME } from 'lib/constants' | ||||
| import { APP_NAME, KCL_DEFAULT_LENGTH } from 'lib/constants' | ||||
| import JSZip from 'jszip' | ||||
| import path from 'path' | ||||
| import { TEST_SETTINGS, TEST_SETTINGS_KEY } from './storageStates' | ||||
| @ -273,6 +273,8 @@ const part001 = startSketchOn('-XZ') | ||||
|   for (let { modelPath, imagePath, outputType } of exportLocations) { | ||||
|     // May change depending on the file being dealt with | ||||
|     let cliCommand = `export ZOO_TOKEN=${secrets.snapshottoken} && zoo file snapshot --output-format=png --src-format=${outputType} ${modelPath} ${imagePath}` | ||||
|     const fileSize = (await fsp.stat(modelPath)).size | ||||
|     console.log(`Size of the file at ${modelPath}: ${fileSize} bytes`) | ||||
|  | ||||
|     const parentPath = path.dirname(modelPath) | ||||
|  | ||||
| @ -445,7 +447,7 @@ test('Draft segments should look right', async ({ page, context }) => { | ||||
|   await page.mouse.click(700, 200) | ||||
|  | ||||
|   await expect(page.locator('.cm-content')).toHaveText( | ||||
|     `const part001 = startSketchOn('-XZ')` | ||||
|     `const part001 = startSketchOn('XZ')` | ||||
|   ) | ||||
|  | ||||
|   await page.waitForTimeout(300) // TODO detect animation ending, or disable animation | ||||
| @ -453,7 +455,7 @@ test('Draft segments should look right', async ({ page, context }) => { | ||||
|   const startXPx = 600 | ||||
|   await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) | ||||
|   await expect(page.locator('.cm-content')) | ||||
|     .toHaveText(`const part001 = startSketchOn('-XZ') | ||||
|     .toHaveText(`const part001 = startSketchOn('XZ') | ||||
|   |> startProfileAt([9.06, -12.22], %)`) | ||||
|   await page.waitForTimeout(100) | ||||
|  | ||||
| @ -467,7 +469,7 @@ test('Draft segments should look right', async ({ page, context }) => { | ||||
|   await page.waitForTimeout(100) | ||||
|  | ||||
|   await expect(page.locator('.cm-content')) | ||||
|     .toHaveText(`const part001 = startSketchOn('-XZ') | ||||
|     .toHaveText(`const part001 = startSketchOn('XZ') | ||||
|   |> startProfileAt([9.06, -12.22], %) | ||||
|   |> line([9.14, 0], %)`) | ||||
|  | ||||
| @ -504,10 +506,10 @@ test('Draft rectangles should look right', async ({ page, context }) => { | ||||
|   await page.mouse.click(700, 200) | ||||
|  | ||||
|   await expect(page.locator('.cm-content')).toHaveText( | ||||
|     `const part001 = startSketchOn('-XZ')` | ||||
|     `const part001 = startSketchOn('XZ')` | ||||
|   ) | ||||
|  | ||||
|   await page.waitForTimeout(300) // TODO detect animation ending, or disable animation | ||||
|   await page.waitForTimeout(500) // TODO detect animation ending, or disable animation | ||||
|   await u.closeDebugPanel() | ||||
|  | ||||
|   const startXPx = 600 | ||||
| @ -553,7 +555,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|     await page.mouse.click(700, 200) | ||||
|  | ||||
|     await expect(page.locator('.cm-content')).toHaveText( | ||||
|       `const part001 = startSketchOn('-XZ')` | ||||
|       `const part001 = startSketchOn('XZ')` | ||||
|     ) | ||||
|  | ||||
|     await page.waitForTimeout(300) // TODO detect animation ending, or disable animation | ||||
| @ -561,7 +563,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|     const startXPx = 600 | ||||
|     await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) | ||||
|     await expect(page.locator('.cm-content')) | ||||
|       .toHaveText(`const part001 = startSketchOn('-XZ') | ||||
|       .toHaveText(`const part001 = startSketchOn('XZ') | ||||
|     |> startProfileAt([9.06, -12.22], %)`) | ||||
|     await page.waitForTimeout(100) | ||||
|  | ||||
| @ -571,7 +573,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|     await page.waitForTimeout(100) | ||||
|  | ||||
|     await expect(page.locator('.cm-content')) | ||||
|       .toHaveText(`const part001 = startSketchOn('-XZ') | ||||
|       .toHaveText(`const part001 = startSketchOn('XZ') | ||||
|     |> startProfileAt([9.06, -12.22], %) | ||||
|     |> line([9.14, 0], %)`) | ||||
|  | ||||
| @ -581,7 +583,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|     await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20) | ||||
|  | ||||
|     await expect(page.locator('.cm-content')) | ||||
|       .toHaveText(`const part001 = startSketchOn('-XZ') | ||||
|       .toHaveText(`const part001 = startSketchOn('XZ') | ||||
|     |> startProfileAt([9.06, -12.22], %) | ||||
|     |> line([9.14, 0], %) | ||||
|     |> tangentialArcTo([27.34, -3.08], %)`) | ||||
| @ -597,12 +599,15 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|  | ||||
|     // exit sketch | ||||
|     await u.openAndClearDebugPanel() | ||||
|     await page.getByRole('button', { name: 'Exit Sketch' }).click() | ||||
|     await u.doAndWaitForImageDiff( | ||||
|       () => page.getByRole('button', { name: 'Exit Sketch' }).click(), | ||||
|       200 | ||||
|     ) | ||||
|  | ||||
|     // wait for execution done | ||||
|     await u.expectCmdLog('[data-message-type="execution-done"]') | ||||
|     await u.clearAndCloseDebugPanel() | ||||
|     await page.waitForTimeout(200) | ||||
|     await page.waitForTimeout(300) | ||||
|  | ||||
|     // second screen shot should look almost identical, i.e. scale should be the same. | ||||
|     await expect(page).toHaveScreenshot({ | ||||
| @ -653,7 +658,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|     await page.mouse.click(700, 200) | ||||
|  | ||||
|     await expect(page.locator('.cm-content')).toHaveText( | ||||
|       `const part001 = startSketchOn('-XZ')` | ||||
|       `const part001 = startSketchOn('XZ')` | ||||
|     ) | ||||
|  | ||||
|     await page.waitForTimeout(300) // TODO detect animation ending, or disable animation | ||||
| @ -661,7 +666,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|     const startXPx = 600 | ||||
|     await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) | ||||
|     await expect(page.locator('.cm-content')) | ||||
|       .toHaveText(`const part001 = startSketchOn('-XZ') | ||||
|       .toHaveText(`const part001 = startSketchOn('XZ') | ||||
|       |> startProfileAt([230.03, -310.32], %)`) | ||||
|     await page.waitForTimeout(100) | ||||
|  | ||||
| @ -671,7 +676,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|     await page.waitForTimeout(100) | ||||
|  | ||||
|     await expect(page.locator('.cm-content')) | ||||
|       .toHaveText(`const part001 = startSketchOn('-XZ') | ||||
|       .toHaveText(`const part001 = startSketchOn('XZ') | ||||
|       |> startProfileAt([230.03, -310.32], %) | ||||
|       |> line([232.2, 0], %)`) | ||||
|  | ||||
| @ -681,7 +686,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|     await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20) | ||||
|  | ||||
|     await expect(page.locator('.cm-content')) | ||||
|       .toHaveText(`const part001 = startSketchOn('-XZ') | ||||
|       .toHaveText(`const part001 = startSketchOn('XZ') | ||||
|       |> startProfileAt([230.03, -310.32], %) | ||||
|       |> line([232.2, 0], %) | ||||
|       |> tangentialArcTo([694.43, -78.12], %)`) | ||||
| @ -696,12 +701,15 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|  | ||||
|     // exit sketch | ||||
|     await u.openAndClearDebugPanel() | ||||
|     await page.getByRole('button', { name: 'Exit Sketch' }).click() | ||||
|     await u.doAndWaitForImageDiff( | ||||
|       () => page.getByRole('button', { name: 'Exit Sketch' }).click(), | ||||
|       200 | ||||
|     ) | ||||
|  | ||||
|     // wait for execution done | ||||
|     await u.expectCmdLog('[data-message-type="execution-done"]') | ||||
|     await u.clearAndCloseDebugPanel() | ||||
|     await page.waitForTimeout(200) | ||||
|     await page.waitForTimeout(300) | ||||
|  | ||||
|     // second screen shot should look almost identical, i.e. scale should be the same. | ||||
|     await expect(page).toHaveScreenshot({ | ||||
| @ -712,7 +720,7 @@ test.describe('Client side scene scale should match engine scale', () => { | ||||
|  | ||||
| test('Sketch on face with none z-up', async ({ page, context }) => { | ||||
|   const u = getUtils(page) | ||||
|   await context.addInitScript(async () => { | ||||
|   await context.addInitScript(async (KCL_DEFAULT_LENGTH) => { | ||||
|     localStorage.setItem( | ||||
|       'persistCode', | ||||
|       `const part001 = startSketchOn('-XZ') | ||||
| @ -720,16 +728,16 @@ test('Sketch on face with none z-up', async ({ page, context }) => { | ||||
|   |> line([9.31, 10.55], %, 'seg01') | ||||
|   |> line([11.91, -10.42], %) | ||||
|   |> close(%) | ||||
|   |> extrude(5 + 7, %) | ||||
|   |> extrude(${KCL_DEFAULT_LENGTH}, %) | ||||
| const part002 = startSketchOn(part001, 'seg01') | ||||
|   |> startProfileAt([8, 8], %) | ||||
|   |> line([4.68, 3.05], %) | ||||
|   |> line([0, -7.79], %, 'seg02') | ||||
|   |> close(%) | ||||
|   |> extrude(5 + 7, %) | ||||
|   |> extrude(${KCL_DEFAULT_LENGTH}, %) | ||||
| ` | ||||
|     ) | ||||
|   }) | ||||
|   }, KCL_DEFAULT_LENGTH) | ||||
|  | ||||
|   await page.setViewportSize({ width: 1200, height: 500 }) | ||||
|   await page.goto('/') | ||||
|  | ||||
| Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 38 KiB | 
| Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 39 KiB | 
| Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 44 KiB | 
| Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 40 KiB | 
| Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB | 
| Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 32 KiB | 
| Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB | 
| Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 71 KiB | 
| Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 48 KiB | 
| Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 43 KiB | 
| Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 41 KiB | 
| Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 49 KiB | 
