Compare commits
219 Commits
migrate-to
...
v0.21.7
Author | SHA1 | Date | |
---|---|---|---|
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 | |||
67cea620a6 | |||
ed0c7d038d | |||
d3aa789761 | |||
cd68f80b71 | |||
d341681c0d | |||
0578e9d2a1 | |||
b413538e9e | |||
c4e7754fc5 | |||
94515b5490 | |||
aa52407fda | |||
e45be831d0 | |||
005944f3a3 | |||
755ef8ce7f | |||
005d1f0ca7 | |||
e158f6f513 | |||
879d7ec4f4 | |||
f6838b9b14 | |||
cb75c47631 | |||
9b95ec1083 | |||
a3eeff65c8 | |||
fab3d2b130 | |||
0a96dc6fd2 | |||
e123a00d4b | |||
b950cc0583 | |||
c89780a489 | |||
1afed68dd7 | |||
dcbed4f06f | |||
379f154a5c | |||
60c4969322 | |||
cc6dee8ad4 | |||
2fc7c0d5fd | |||
bf2dcd808f | |||
ee21e486d4 | |||
b5a3eb9e9c | |||
c85645c9f2 | |||
cfa4dd2e33 | |||
c620f7269c | |||
2d8d29b345 | |||
00da062586 | |||
aafbaf6c50 | |||
2894c84a4e | |||
c01084feb0 | |||
c461db5f54 | |||
03fcb73aca | |||
8065e7e51a | |||
2d0ac249df | |||
3d73b82c23 | |||
0b235dc1cd | |||
0857415793 | |||
1da4fd03ef | |||
39d84c12ab | |||
537d86c8ff | |||
f08d955d40 | |||
7ea6722d2d | |||
39bd72fc83 | |||
88aec7e2c5 | |||
b936eafc26 | |||
6c11f0e456 | |||
06a7fcf6a7 | |||
6450622146 | |||
9dfe0c3d80 | |||
ba33b0da19 | |||
21756fe513 | |||
69d34c5318 | |||
f909ea7af5 | |||
38d9b5d4b4 | |||
ac140c054f | |||
215db38b44 | |||
0880199844 | |||
18ce254566 | |||
bc90840e7c | |||
3f8c4e7b5a | |||
168fed038d | |||
9544251b1a | |||
a490b4db8c | |||
410089549d | |||
05e27f354a | |||
6793555e86 | |||
6823c5eedd | |||
b13c1339aa | |||
624b1fc07d | |||
ed69213680 | |||
593b4e6f21 | |||
7eeaf96d18 | |||
6fa7698f42 | |||
4abb8fc267 | |||
ff482e5f9b | |||
dd51eecaed | |||
266450afbf | |||
e01b35d1e9 | |||
f0b9de2c1c | |||
35c3103186 | |||
08534a024c | |||
25fa3b48e1 |
@ -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_SITE_BASE_URL=https://dev.zoo.dev
|
||||||
VITE_KC_SKIP_AUTH=false
|
VITE_KC_SKIP_AUTH=false
|
||||||
VITE_KC_CONNECTION_TIMEOUT_MS=5000
|
VITE_KC_CONNECTION_TIMEOUT_MS=5000
|
||||||
|
VITE_KC_DEV_TOKEN="your token from dev.zoo.dev should go in .env.development.local"
|
||||||
|
33
.github/workflows/build-and-store-wasm.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
name: Build and Store WASM
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-upload:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'yarn'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: yarn
|
||||||
|
- name: Setup Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
- name: Cache wasm
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: './src/wasm-lib'
|
||||||
|
- name: build wasm
|
||||||
|
run: yarn build:wasm
|
||||||
|
|
||||||
|
|
||||||
|
# Upload the WASM bundle as an artifact
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: wasm-bundle
|
||||||
|
path: src/wasm-lib/pkg
|
17
.github/workflows/cargo-clippy.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
dir: ['src/wasm-lib']
|
dir: ['src/wasm-lib', 'src-tauri']
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install latest rust
|
- name: Install latest rust
|
||||||
@ -31,9 +31,22 @@ jobs:
|
|||||||
|
|
||||||
- name: install dependencies
|
- name: install dependencies
|
||||||
if: matrix.dir == 'src-tauri'
|
if: matrix.dir == 'src-tauri'
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
sudo apt-get install -y \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libayatana-appindicator3-dev \
|
||||||
|
webkit2gtk-driver \
|
||||||
|
libsoup-3.0-dev \
|
||||||
|
libjavascriptcoregtk-4.1-dev \
|
||||||
|
libwebkit2gtk-4.1-dev \
|
||||||
|
at-spi2-core \
|
||||||
|
xvfb
|
||||||
|
yarn install
|
||||||
|
yarn build:wasm
|
||||||
|
yarn build:local
|
||||||
|
|
||||||
- name: Rust Cache
|
- name: Rust Cache
|
||||||
uses: Swatinem/rust-cache@v2.6.1
|
uses: Swatinem/rust-cache@v2.6.1
|
||||||
|
|
||||||
|
57
.github/workflows/cargo-test-tauri.yml
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- 'src-tauri/**.rs'
|
||||||
|
- '**/Cargo.toml'
|
||||||
|
- '**/Cargo.lock'
|
||||||
|
- '**/rust-toolchain.toml'
|
||||||
|
- .github/workflows/cargo-test-tauri.yml
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'src-tauri/**.rs'
|
||||||
|
- '**/Cargo.toml'
|
||||||
|
- '**/Cargo.lock'
|
||||||
|
- '**/rust-toolchain.toml'
|
||||||
|
- .github/workflows/cargo-test-tauri.yml
|
||||||
|
workflow_dispatch:
|
||||||
|
permissions: read-all
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
name: cargo test of tauri
|
||||||
|
jobs:
|
||||||
|
cargotest:
|
||||||
|
name: cargo test
|
||||||
|
runs-on: ubuntu-latest-8-cores
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
dir: ['src-tauri']
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install latest rust
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
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 \
|
||||||
|
libayatana-appindicator3-dev \
|
||||||
|
webkit2gtk-driver \
|
||||||
|
libsoup-3.0-dev \
|
||||||
|
libjavascriptcoregtk-4.1-dev \
|
||||||
|
libwebkit2gtk-4.1-dev \
|
||||||
|
at-spi2-core \
|
||||||
|
xvfb
|
||||||
|
- name: Rust Cache
|
||||||
|
uses: Swatinem/rust-cache@v2.6.1
|
||||||
|
- name: cargo test
|
||||||
|
shell: bash
|
||||||
|
run: |-
|
||||||
|
cd "${{ matrix.dir }}"
|
||||||
|
cargo test --all
|
137
.github/workflows/ci.yml
vendored
@ -13,7 +13,7 @@ on:
|
|||||||
# Will checkout the last commit from the default branch (main as of 2023-10-04)
|
# Will checkout the last commit from the default branch (main as of 2023-10-04)
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BUILD_RELEASE: ${{ github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'pull_request' && contains(github.event.pull_request.title, 'Cut release v') }}
|
BUILD_RELEASE: ${{ github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'pull_request' && (contains(github.event.pull_request.title, 'Cut release v')) }}
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
@ -50,7 +50,7 @@ jobs:
|
|||||||
- run: yarn tsc
|
- run: yarn tsc
|
||||||
|
|
||||||
|
|
||||||
check-typos:
|
check-typos:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@ -98,7 +98,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
cache: 'yarn'
|
cache: 'yarn'
|
||||||
|
|
||||||
- name: Set nightly version
|
- name: Set nightly version
|
||||||
if: github.event_name == 'schedule'
|
if: github.event_name == 'schedule'
|
||||||
run: |
|
run: |
|
||||||
@ -130,7 +130,9 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
os: [macos-14, ubuntu-latest, windows-latest]
|
os: [macos-14, ubuntu-latest, windows-latest]
|
||||||
env:
|
env:
|
||||||
|
# Specific Apple Universal target for macos
|
||||||
TAURI_ARGS_MACOS: ${{ matrix.os == 'macos-14' && '--target universal-apple-darwin' || '' }}
|
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' || '' }}
|
TAURI_ARGS_UBUNTU: ${{ matrix.os == 'ubuntu-latest' && '--bundles' || '' }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -143,21 +145,21 @@ jobs:
|
|||||||
ls -l artifact
|
ls -l artifact
|
||||||
cp artifact/package.json package.json
|
cp artifact/package.json package.json
|
||||||
cp artifact/src-tauri/tauri.conf.json src-tauri/tauri.conf.json
|
cp artifact/src-tauri/tauri.conf.json src-tauri/tauri.conf.json
|
||||||
cp artifact/src-tauri/tauri.release.conf.json src-tauri/tauri.release.conf.json
|
cp artifact/src-tauri/tauri.release.conf.json src-tauri/tauri.release.conf.json
|
||||||
|
|
||||||
- name: Install ubuntu system dependencies
|
- name: Install ubuntu system dependencies
|
||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
run: >
|
run: |
|
||||||
sudo apt-get update &&
|
sudo apt-get update
|
||||||
sudo apt-get install -y
|
sudo apt-get install -y \
|
||||||
libgtk-3-dev
|
libgtk-3-dev \
|
||||||
libayatana-appindicator3-dev
|
libayatana-appindicator3-dev \
|
||||||
webkit2gtk-driver
|
webkit2gtk-driver \
|
||||||
libsoup-3.0-dev
|
libsoup-3.0-dev \
|
||||||
libjavascriptcoregtk-4.1-dev
|
libjavascriptcoregtk-4.1-dev \
|
||||||
libwebkit2gtk-4.1-dev
|
libwebkit2gtk-4.1-dev \
|
||||||
at-spi2-core
|
at-spi2-core \
|
||||||
xvfb
|
xvfb
|
||||||
|
|
||||||
- name: Sync node version and setup cache
|
- name: Sync node version and setup cache
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
@ -237,6 +239,96 @@ jobs:
|
|||||||
includeDebug: true
|
includeDebug: true
|
||||||
args: "${{ env.TAURI_ARGS_MACOS }} ${{ env.TAURI_ARGS_UBUNTU }}"
|
args: "${{ env.TAURI_ARGS_MACOS }} ${{ env.TAURI_ARGS_UBUNTU }}"
|
||||||
|
|
||||||
|
- 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
|
||||||
|
sign_app="3rd Party Mac Developer Application: KittyCAD Inc (${APPLE_TEAM_ID})"
|
||||||
|
sign_install="3rd Party Mac Developer Installer: KittyCAD Inc (${APPLE_TEAM_ID})"
|
||||||
|
profile="src-tauri/entitlements/Mac_App_Distribution.provisionprofile"
|
||||||
|
|
||||||
|
mkdir -p src-tauri/entitlements
|
||||||
|
echo -n "${APPLE_STORE_PROVISIONING_PROFILE}" | base64 --decode -o "${profile}"
|
||||||
|
|
||||||
|
echo -n "${APPLE_STORE_DISTRIBUTION_CERT}" | base64 --decode -o "dist.cer"
|
||||||
|
echo -n "${APPLE_STORE_INSTALLER_CERT}" | base64 --decode -o "installer.cer"
|
||||||
|
|
||||||
|
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
||||||
|
KEYCHAIN_PASSWORD="password"
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
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
|
||||||
|
# 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
|
||||||
|
|
||||||
|
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/app-store.entitlements"
|
||||||
|
|
||||||
|
cp "${profile}" "${cp_dir}"
|
||||||
|
|
||||||
|
codesign --deep --force -s "${sign_app}" --entitlements "${entitlements}" "${app_path}"
|
||||||
|
|
||||||
|
productbuild --component "${app_path}" /Applications/ --sign "${sign_install}" "${build_name}"
|
||||||
|
|
||||||
|
# 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 to Mac TestFlight (nightly)'
|
||||||
|
uses: apple-actions/upload-testflight-build@v1
|
||||||
|
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
|
||||||
|
# not upload the apple store build to the public bucket
|
||||||
- name: Build the app (release) and sign
|
- name: Build the app (release) and sign
|
||||||
uses: tauri-apps/tauri-action@v0
|
uses: tauri-apps/tauri-action@v0
|
||||||
if: ${{ env.BUILD_RELEASE == 'true' }}
|
if: ${{ env.BUILD_RELEASE == 'true' }}
|
||||||
@ -261,11 +353,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: "${{ env.PREFIX }}/${{ env.MODE }}/bundle/*/*"
|
path: "${{ env.PREFIX }}/${{ env.MODE }}/bundle/*/*"
|
||||||
|
|
||||||
# TODO: re-enable linux e2e tests when possible
|
|
||||||
- name: Run e2e tests (linux only)
|
- name: Run e2e tests (linux only)
|
||||||
if: false
|
if: ${{ matrix.os == 'ubuntu-latest' && github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
run: |
|
run: |
|
||||||
cargo install tauri-driver
|
cargo install tauri-driver --force
|
||||||
source .env.${{ env.BUILD_RELEASE == 'true' && 'production' || 'development' }}
|
source .env.${{ env.BUILD_RELEASE == 'true' && 'production' || 'development' }}
|
||||||
export VITE_KC_API_BASE_URL
|
export VITE_KC_API_BASE_URL
|
||||||
xvfb-run yarn test:e2e:tauri
|
xvfb-run yarn test:e2e:tauri
|
||||||
@ -349,7 +440,7 @@ jobs:
|
|||||||
cat last_download.json
|
cat last_download.json
|
||||||
|
|
||||||
- name: Authenticate to Google Cloud
|
- name: Authenticate to Google Cloud
|
||||||
uses: 'google-github-actions/auth@v2.1.2'
|
uses: 'google-github-actions/auth@v2.1.3'
|
||||||
with:
|
with:
|
||||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
||||||
|
|
||||||
@ -383,7 +474,7 @@ jobs:
|
|||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
files: 'artifact/*/Zoo*'
|
files: 'artifact/*/Zoo*'
|
||||||
|
|
||||||
announce_release:
|
announce_release:
|
||||||
needs: [publish-apps-release]
|
needs: [publish-apps-release]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -391,17 +482,17 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install requests
|
pip install requests
|
||||||
|
|
||||||
- name: Announce Release
|
- name: Announce Release
|
||||||
env:
|
env:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
|
37
.github/workflows/create-release.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
name: Create Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: read
|
||||||
|
if: contains(github.event.head_commit.message, 'Cut release v')
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@v7
|
||||||
|
name: Read Cut release PR info and create release
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { owner, repo } = context.repo
|
||||||
|
const pulls = await github.rest.repos.listPullRequestsAssociatedWithCommit({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
commit_sha: context.sha,
|
||||||
|
})
|
||||||
|
const { title, body } = pulls.data[0]
|
||||||
|
const version = title.split('Cut release ')[1]
|
||||||
|
|
||||||
|
const result = await github.rest.repos.createRelease({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
body,
|
||||||
|
tag_name: version,
|
||||||
|
name: version,
|
||||||
|
draft: true,
|
||||||
|
})
|
||||||
|
console.log(result)
|
83
.github/workflows/playwright.yml
vendored
@ -12,11 +12,31 @@ concurrency:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
actions: read
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
|
check-rust-changes:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
rust-changed: ${{ steps.filter.outputs.rust }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- id: filter
|
||||||
|
name: Check for Rust changes
|
||||||
|
uses: dorny/paths-filter@v3
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
rust:
|
||||||
|
- 'src/wasm-lib/**'
|
||||||
|
|
||||||
playwright-ubuntu:
|
playwright-ubuntu:
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
runs-on: ubuntu-latest-8-cores
|
runs-on: ubuntu-latest-8-cores
|
||||||
|
needs: check-rust-changes
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
@ -28,13 +48,38 @@ jobs:
|
|||||||
run: yarn
|
run: yarn
|
||||||
- name: Install Playwright Browsers
|
- name: Install Playwright Browsers
|
||||||
run: yarn playwright install --with-deps
|
run: yarn playwright install --with-deps
|
||||||
|
- name: Download Wasm Cache
|
||||||
|
id: download-wasm
|
||||||
|
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||||
|
uses: dawidd6/action-download-artifact@v3
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
name: wasm-bundle
|
||||||
|
workflow: build-and-store-wasm.yml
|
||||||
|
branch: main
|
||||||
|
path: src/wasm-lib/pkg
|
||||||
|
- name: copy wasm blob
|
||||||
|
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||||
|
run: cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
||||||
|
continue-on-error: true
|
||||||
- name: Setup Rust
|
- name: Setup Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
- name: Cache wasm
|
- name: Cache Wasm (because rust diff)
|
||||||
|
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
workspaces: './src/wasm-lib'
|
workspaces: './src/wasm-lib'
|
||||||
- name: build wasm
|
- name: OR Cache Wasm (because wasm cache failed)
|
||||||
|
if: steps.download-wasm.outcome == 'failure'
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: './src/wasm-lib'
|
||||||
|
- name: Build Wasm (because rust diff)
|
||||||
|
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||||
|
run: yarn build:wasm
|
||||||
|
- name: OR Build Wasm (because wasm cache failed)
|
||||||
|
if: steps.download-wasm.outcome == 'failure'
|
||||||
run: yarn build:wasm
|
run: yarn build:wasm
|
||||||
- name: build web
|
- name: build web
|
||||||
run: yarn build:local
|
run: yarn build:local
|
||||||
@ -70,7 +115,7 @@ jobs:
|
|||||||
git fetch origin
|
git fetch origin
|
||||||
echo ${{ github.head_ref }}
|
echo ${{ github.head_ref }}
|
||||||
git checkout ${{ 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 commit -am "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)" || true
|
||||||
git push
|
git push
|
||||||
git push origin ${{ github.head_ref }}
|
git push origin ${{ github.head_ref }}
|
||||||
@ -89,6 +134,7 @@ jobs:
|
|||||||
playwright-macos:
|
playwright-macos:
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
runs-on: macos-14
|
runs-on: macos-14
|
||||||
|
needs: check-rust-changes
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
@ -99,18 +145,43 @@ jobs:
|
|||||||
run: yarn
|
run: yarn
|
||||||
- name: Install Playwright Browsers
|
- name: Install Playwright Browsers
|
||||||
run: yarn playwright install --with-deps
|
run: yarn playwright install --with-deps
|
||||||
|
- name: Download Wasm Cache
|
||||||
|
id: download-wasm
|
||||||
|
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||||
|
uses: dawidd6/action-download-artifact@v3
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
name: wasm-bundle
|
||||||
|
workflow: build-and-store-wasm.yml
|
||||||
|
branch: main
|
||||||
|
path: src/wasm-lib/pkg
|
||||||
|
- name: copy wasm blob
|
||||||
|
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||||
|
run: cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
||||||
|
continue-on-error: true
|
||||||
- name: Setup Rust
|
- name: Setup Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
- name: Cache wasm
|
- name: Cache Wasm (because rust diff)
|
||||||
|
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
workspaces: './src/wasm-lib'
|
workspaces: './src/wasm-lib'
|
||||||
- name: build wasm
|
- name: OR Cache Wasm (because wasm cache failed)
|
||||||
|
if: steps.download-wasm.outcome == 'failure'
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: './src/wasm-lib'
|
||||||
|
- name: Build Wasm (because rust diff)
|
||||||
|
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||||
|
run: yarn build:wasm
|
||||||
|
- name: OR Build Wasm (because wasm cache failed)
|
||||||
|
if: steps.download-wasm.outcome == 'failure'
|
||||||
run: yarn build:wasm
|
run: yarn build:wasm
|
||||||
- name: build web
|
- name: build web
|
||||||
run: yarn build:local
|
run: yarn build:local
|
||||||
- name: Run macos/safari flow
|
- 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
|
# 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
|
run: yarn playwright test --project="webkit" e2e/playwright/flow-tests.spec.ts
|
||||||
env:
|
env:
|
||||||
|
1
.gitignore
vendored
@ -54,3 +54,4 @@ src/**/*.typegen.ts
|
|||||||
src-tauri/gen
|
src-tauri/gen
|
||||||
|
|
||||||
src/wasm-lib/grackle/stdlib_cube_partial.json
|
src/wasm-lib/grackle/stdlib_cube_partial.json
|
||||||
|
Mac_App_Distribution.provisionprofile
|
||||||
|
31
README.md
@ -60,6 +60,12 @@ followed by:
|
|||||||
yarn build:wasm-dev
|
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
|
||||||
|
```
|
||||||
|
|
||||||
That will build the WASM binary and put in the `public` dir (though gitignored)
|
That will build the WASM binary and put in the `public` dir (though gitignored)
|
||||||
|
|
||||||
finally, to run the web app only, run:
|
finally, to run the web app only, run:
|
||||||
@ -68,7 +74,13 @@ finally, to run the web app only, run:
|
|||||||
yarn start
|
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
|
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/).
|
[blocks Third-Party Cookies](https://developer.chrome.com/en/docs/privacy-sandbox/third-party-cookie-phase-out/).
|
||||||
@ -90,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.
|
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
|
For running the rust (not tauri rust though) only, you can
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/wasm-lib
|
cd src/wasm-lib
|
||||||
cargo test
|
cargo test
|
||||||
@ -152,6 +165,7 @@ console.log(
|
|||||||
- `)
|
- `)
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
grab the md list and delete any that are older than the last bump
|
grab the md list and delete any that are older than the last bump
|
||||||
|
|
||||||
2. Merge the PR
|
2. Merge the PR
|
||||||
@ -181,23 +195,26 @@ $ cargo +nightly fuzz run parser
|
|||||||
For more information on fuzzing you can check out
|
For more information on fuzzing you can check out
|
||||||
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
|
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
|
||||||
|
|
||||||
|
|
||||||
### Playwright
|
### Playwright
|
||||||
|
|
||||||
First time running plawright locally, you'll need to add the secrets file
|
First time running plawright locally, you'll need to add the secrets file
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
touch ./e2e/playwright/playwright-secrets.env
|
touch ./e2e/playwright/playwright-secrets.env
|
||||||
printf 'token="your-token"\nsnapshottoken="your-snapshot-token"' > ./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 replace "your-token" with a dev token from dev.zoo.dev/account/api-tokens
|
||||||
|
|
||||||
then:
|
then:
|
||||||
run playwright
|
run playwright
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn playwright test
|
yarn playwright test
|
||||||
```
|
```
|
||||||
|
|
||||||
run a specific test suite
|
run a specific test suite
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn playwright test src/e2e-tests/example.spec.ts
|
yarn playwright test src/e2e-tests/example.spec.ts
|
||||||
```
|
```
|
||||||
@ -206,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)
|
(note if you commit this, the tests will instantly fail without running any of the tests)
|
||||||
|
|
||||||
run headed
|
run headed
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn playwright test --headed
|
yarn playwright test --headed
|
||||||
```
|
```
|
||||||
|
|
||||||
run with step through debugger
|
run with step through debugger
|
||||||
|
|
||||||
```
|
```
|
||||||
PWDEBUG=1 yarn playwright test
|
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.
|
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.
|
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.
|
||||||
|
|
||||||
@ -258,12 +278,11 @@ Where `./store` should look like this
|
|||||||
|
|
||||||
</details>
|
</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.
|
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
|
#### Some notes on CI
|
||||||
|
|
||||||
The tests are broken into snapshot tests and non-snapshot tests, and they run in that order, they automatically commit new snap shots, so if you see an image commit check it was an intended change. If we have non-determinism in the snapshots such that they are always committing new images, hopefully this annoyance makes us fix them asap, if you notice this happening let Kurt know. But for the odd occasion `git reset --hard HEAD~ && git push -f` is your friend.
|
The tests are broken into snapshot tests and non-snapshot tests, and they run in that order, they automatically commit new snap shots, so if you see an image commit check it was an intended change. If we have non-determinism in the snapshots such that they are always committing new images, hopefully this annoyance makes us fix them asap, if you notice this happening let Kurt know. But for the odd occasion `git reset --hard HEAD~ && git push -f` is your friend.
|
||||||
|
|
||||||
How to interpret failing playwright tests?
|
How to interpret failing playwright tests?
|
||||||
If your tests fail, click through to the action and see that the tests failed on a line that includes `await page.getByTestId('loading').waitFor({ state: 'detached' })`, this means the test fail because the stream never started. It's you choice if you want to re-run the test, or ignore the failure.
|
If your tests fail, click through to the action and see that the tests failed on a line that includes `await page.getByTestId('loading').waitFor({ state: 'detached' })`, this means the test fail because the stream never started. It's you choice if you want to re-run the test, or ignore the failure.
|
||||||
@ -289,3 +308,7 @@ PS: for the debug panel, the following JSON is useful for snapping the camera
|
|||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## KCL
|
||||||
|
|
||||||
|
For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/src/wasm-lib/kcl).
|
||||||
|
BIN
app-icon.png
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 113 KiB |
@ -1,3 +1,3 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ["@babel/preset-env"],
|
presets: ['@babel/preset-env'],
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ layout: manual
|
|||||||
* [`fillet`](kcl/fillet)
|
* [`fillet`](kcl/fillet)
|
||||||
* [`floor`](kcl/floor)
|
* [`floor`](kcl/floor)
|
||||||
* [`getEdge`](kcl/getEdge)
|
* [`getEdge`](kcl/getEdge)
|
||||||
* [`getExtrudeWallTransform`](kcl/getExtrudeWallTransform)
|
|
||||||
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
||||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||||
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
||||||
@ -57,6 +56,9 @@ layout: manual
|
|||||||
* [`patternLinear3d`](kcl/patternLinear3d)
|
* [`patternLinear3d`](kcl/patternLinear3d)
|
||||||
* [`pi`](kcl/pi)
|
* [`pi`](kcl/pi)
|
||||||
* [`pow`](kcl/pow)
|
* [`pow`](kcl/pow)
|
||||||
|
* [`profileStart`](kcl/profileStart)
|
||||||
|
* [`profileStartX`](kcl/profileStartX)
|
||||||
|
* [`profileStartY`](kcl/profileStartY)
|
||||||
* [`revolve`](kcl/revolve)
|
* [`revolve`](kcl/revolve)
|
||||||
* [`segAng`](kcl/segAng)
|
* [`segAng`](kcl/segAng)
|
||||||
* [`segEndX`](kcl/segEndX)
|
* [`segEndX`](kcl/segEndX)
|
||||||
|
206
docs/kcl/profileStart.md
Normal file
201
docs/kcl/profileStartX.md
Normal file
200
docs/kcl/profileStartY.md
Normal file
11347
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 { Models } from '@kittycad/lib'
|
||||||
import fsp from 'fs/promises'
|
import fsp from 'fs/promises'
|
||||||
import { spawn } from 'child_process'
|
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 JSZip from 'jszip'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from './storageStates'
|
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from './storageStates'
|
||||||
@ -27,6 +27,16 @@ test.beforeEach(async ({ page }) => {
|
|||||||
settings: TOML.stringify({ settings: TEST_SETTINGS }),
|
settings: TOML.stringify({ settings: TEST_SETTINGS }),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Make the user avatar image always 404
|
||||||
|
// so we see the fallback menu icon for all snapshot tests
|
||||||
|
await page.route('https://lh3.googleusercontent.com/**', async (route) => {
|
||||||
|
await route.fulfill({
|
||||||
|
status: 404,
|
||||||
|
contentType: 'text/plain',
|
||||||
|
body: 'Not Found!',
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.setTimeout(60_000)
|
test.setTimeout(60_000)
|
||||||
@ -263,6 +273,8 @@ const part001 = startSketchOn('-XZ')
|
|||||||
for (let { modelPath, imagePath, outputType } of exportLocations) {
|
for (let { modelPath, imagePath, outputType } of exportLocations) {
|
||||||
// May change depending on the file being dealt with
|
// 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}`
|
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)
|
const parentPath = path.dirname(modelPath)
|
||||||
|
|
||||||
@ -326,10 +338,7 @@ const part001 = startSketchOn('-XZ')
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
test('extrude on each default plane should be stable', async ({
|
const extrudeDefaultPlane = async (context: any, page: any, plane: string) => {
|
||||||
page,
|
|
||||||
context,
|
|
||||||
}) => {
|
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'SETTINGS_PERSIST_KEY',
|
'SETTINGS_PERSIST_KEY',
|
||||||
@ -346,8 +355,8 @@ test('extrude on each default plane should be stable', async ({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
const u = getUtils(page)
|
|
||||||
const makeCode = (plane = 'XY') => `const part001 = startSketchOn('${plane}')
|
const code = `const part001 = startSketchOn('${plane}')
|
||||||
|> startProfileAt([7.00, 4.40], %)
|
|> startProfileAt([7.00, 4.40], %)
|
||||||
|> line([6.60, -0.20], %)
|
|> line([6.60, -0.20], %)
|
||||||
|> line([2.80, 5.00], %)
|
|> line([2.80, 5.00], %)
|
||||||
@ -356,9 +365,11 @@ test('extrude on each default plane should be stable', async ({
|
|||||||
|> close(%)
|
|> close(%)
|
||||||
|> extrude(10.00, %)
|
|> extrude(10.00, %)
|
||||||
`
|
`
|
||||||
await context.addInitScript(async (code) => {
|
await page.addInitScript(async (code: string) => {
|
||||||
localStorage.setItem('persistCode', code)
|
localStorage.setItem('persistCode', code)
|
||||||
}, makeCode('XY'))
|
})
|
||||||
|
|
||||||
|
const u = getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
await page.goto('/')
|
await page.goto('/')
|
||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
@ -368,34 +379,48 @@ test('extrude on each default plane should be stable', async ({
|
|||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.clearAndCloseDebugPanel()
|
await u.clearAndCloseDebugPanel()
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
|
// clear code
|
||||||
|
await u.removeCurrentCode()
|
||||||
|
await u.openAndClearDebugPanel()
|
||||||
|
await u.doAndWaitForImageDiff(
|
||||||
|
() => page.locator('.cm-content').fill(code),
|
||||||
|
200
|
||||||
|
)
|
||||||
|
// wait for execution done
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.clearAndCloseDebugPanel()
|
||||||
|
|
||||||
const runSnapshotsForOtherPlanes = async (plane = 'XY') => {
|
await u.closeKclCodePanel()
|
||||||
// clear code
|
await expect(page).toHaveScreenshot({
|
||||||
await u.removeCurrentCode()
|
maxDiffPixels: 100,
|
||||||
// add makeCode('XZ')
|
})
|
||||||
await u.openAndClearDebugPanel()
|
await u.openKclCodePanel()
|
||||||
await u.doAndWaitForImageDiff(
|
}
|
||||||
() => page.locator('.cm-content').fill(makeCode(plane)),
|
|
||||||
200
|
|
||||||
)
|
|
||||||
// wait for execution done
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
await u.clearAndCloseDebugPanel()
|
|
||||||
|
|
||||||
await u.closeKclCodePanel()
|
test.describe('extrude on default planes should be stable', () => {
|
||||||
await expect(page).toHaveScreenshot({
|
test('XY', async ({ page, context }) => {
|
||||||
maxDiffPixels: 100,
|
await extrudeDefaultPlane(context, page, 'XY')
|
||||||
})
|
})
|
||||||
await u.openKclCodePanel()
|
|
||||||
}
|
|
||||||
await runSnapshotsForOtherPlanes('XY')
|
|
||||||
await runSnapshotsForOtherPlanes('-XY')
|
|
||||||
|
|
||||||
await runSnapshotsForOtherPlanes('XZ')
|
test('XZ', async ({ page, context }) => {
|
||||||
await runSnapshotsForOtherPlanes('-XZ')
|
await extrudeDefaultPlane(context, page, 'XZ')
|
||||||
|
})
|
||||||
|
|
||||||
await runSnapshotsForOtherPlanes('YZ')
|
test('YZ', async ({ page, context }) => {
|
||||||
await runSnapshotsForOtherPlanes('-YZ')
|
await extrudeDefaultPlane(context, page, 'YZ')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('-XY', async ({ page, context }) => {
|
||||||
|
await extrudeDefaultPlane(context, page, '-XY')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('-XZ', async ({ page, context }) => {
|
||||||
|
await extrudeDefaultPlane(context, page, '-XZ')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('-YZ', async ({ page, context }) => {
|
||||||
|
await extrudeDefaultPlane(context, page, '-YZ')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Draft segments should look right', async ({ page, context }) => {
|
test('Draft segments should look right', async ({ page, context }) => {
|
||||||
@ -422,7 +447,7 @@ test('Draft segments should look right', async ({ page, context }) => {
|
|||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
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(300) // TODO detect animation ending, or disable animation
|
||||||
@ -430,7 +455,7 @@ test('Draft segments should look right', async ({ page, context }) => {
|
|||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([9.06, -12.22], %)`)
|
|> startProfileAt([9.06, -12.22], %)`)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
@ -444,7 +469,7 @@ test('Draft segments should look right', async ({ page, context }) => {
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([9.06, -12.22], %)
|
|> startProfileAt([9.06, -12.22], %)
|
||||||
|> line([9.14, 0], %)`)
|
|> line([9.14, 0], %)`)
|
||||||
|
|
||||||
@ -457,6 +482,52 @@ test('Draft segments should look right', async ({ page, context }) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Draft rectangles should look right', async ({ page, context }) => {
|
||||||
|
const u = getUtils(page)
|
||||||
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
|
await page.goto('/')
|
||||||
|
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()
|
||||||
|
|
||||||
|
// click on "Start Sketch" button
|
||||||
|
await u.clearCommandLogs()
|
||||||
|
await u.doAndWaitForImageDiff(
|
||||||
|
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||||
|
200
|
||||||
|
)
|
||||||
|
|
||||||
|
// select a plane
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
|
`const part001 = startSketchOn('XZ')`
|
||||||
|
)
|
||||||
|
|
||||||
|
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
const startXPx = 600
|
||||||
|
|
||||||
|
// Equip the rectangle tool
|
||||||
|
await page.getByRole('button', { name: 'Line' }).click()
|
||||||
|
await page.getByRole('button', { name: 'Rectangle' }).click()
|
||||||
|
|
||||||
|
// Draw the rectangle
|
||||||
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 30)
|
||||||
|
await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 10, { steps: 5 })
|
||||||
|
|
||||||
|
// Ensure the draft rectangle looks the same as it usually does
|
||||||
|
await expect(page).toHaveScreenshot({
|
||||||
|
maxDiffPixels: 100,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test.describe('Client side scene scale should match engine scale', () => {
|
test.describe('Client side scene scale should match engine scale', () => {
|
||||||
test('Inch scale', async ({ page }) => {
|
test('Inch scale', async ({ page }) => {
|
||||||
const u = getUtils(page)
|
const u = getUtils(page)
|
||||||
@ -484,7 +555,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
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(300) // TODO detect animation ending, or disable animation
|
||||||
@ -492,7 +563,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([9.06, -12.22], %)`)
|
|> startProfileAt([9.06, -12.22], %)`)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
@ -502,7 +573,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([9.06, -12.22], %)
|
|> startProfileAt([9.06, -12.22], %)
|
||||||
|> line([9.14, 0], %)`)
|
|> line([9.14, 0], %)`)
|
||||||
|
|
||||||
@ -512,7 +583,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([9.06, -12.22], %)
|
|> startProfileAt([9.06, -12.22], %)
|
||||||
|> line([9.14, 0], %)
|
|> line([9.14, 0], %)
|
||||||
|> tangentialArcTo([27.34, -3.08], %)`)
|
|> tangentialArcTo([27.34, -3.08], %)`)
|
||||||
@ -528,12 +599,15 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
|
|
||||||
// exit sketch
|
// exit sketch
|
||||||
await u.openAndClearDebugPanel()
|
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
|
// wait for execution done
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.clearAndCloseDebugPanel()
|
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.
|
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||||
await expect(page).toHaveScreenshot({
|
await expect(page).toHaveScreenshot({
|
||||||
@ -584,7 +658,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
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(300) // TODO detect animation ending, or disable animation
|
||||||
@ -592,7 +666,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([230.03, -310.32], %)`)
|
|> startProfileAt([230.03, -310.32], %)`)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
@ -602,7 +676,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([230.03, -310.32], %)
|
|> startProfileAt([230.03, -310.32], %)
|
||||||
|> line([232.2, 0], %)`)
|
|> line([232.2, 0], %)`)
|
||||||
|
|
||||||
@ -612,7 +686,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content'))
|
await expect(page.locator('.cm-content'))
|
||||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
.toHaveText(`const part001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([230.03, -310.32], %)
|
|> startProfileAt([230.03, -310.32], %)
|
||||||
|> line([232.2, 0], %)
|
|> line([232.2, 0], %)
|
||||||
|> tangentialArcTo([694.43, -78.12], %)`)
|
|> tangentialArcTo([694.43, -78.12], %)`)
|
||||||
@ -627,12 +701,15 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
|
|
||||||
// exit sketch
|
// exit sketch
|
||||||
await u.openAndClearDebugPanel()
|
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
|
// wait for execution done
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.clearAndCloseDebugPanel()
|
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.
|
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||||
await expect(page).toHaveScreenshot({
|
await expect(page).toHaveScreenshot({
|
||||||
@ -643,7 +720,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
|||||||
|
|
||||||
test('Sketch on face with none z-up', async ({ page, context }) => {
|
test('Sketch on face with none z-up', async ({ page, context }) => {
|
||||||
const u = getUtils(page)
|
const u = getUtils(page)
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async (KCL_DEFAULT_LENGTH) => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'persistCode',
|
||||||
`const part001 = startSketchOn('-XZ')
|
`const part001 = startSketchOn('-XZ')
|
||||||
@ -651,16 +728,16 @@ test('Sketch on face with none z-up', async ({ page, context }) => {
|
|||||||
|> line([9.31, 10.55], %, 'seg01')
|
|> line([9.31, 10.55], %, 'seg01')
|
||||||
|> line([11.91, -10.42], %)
|
|> line([11.91, -10.42], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> extrude(5 + 7, %)
|
|> extrude(${KCL_DEFAULT_LENGTH}, %)
|
||||||
const part002 = startSketchOn(part001, 'seg01')
|
const part002 = startSketchOn(part001, 'seg01')
|
||||||
|> startProfileAt([8, 8], %)
|
|> startProfileAt([8, 8], %)
|
||||||
|> line([4.68, 3.05], %)
|
|> line([4.68, 3.05], %)
|
||||||
|> line([0, -7.79], %, 'seg02')
|
|> line([0, -7.79], %, 'seg02')
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> extrude(5 + 7, %)
|
|> extrude(${KCL_DEFAULT_LENGTH}, %)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
})
|
}, KCL_DEFAULT_LENGTH)
|
||||||
|
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
await page.goto('/')
|
await page.goto('/')
|
||||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 29 KiB |