Compare commits
2 Commits
url-scheme
...
kcl_prelud
Author | SHA1 | Date | |
---|---|---|---|
ddce447c0b | |||
e8769eb543 |
@ -1,3 +1,3 @@
|
||||
[codespell]
|
||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey,atleast
|
||||
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,./src-tauri/gen/schemas
|
||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey
|
||||
skip: **/target,node_modules,build,**/Cargo.lock
|
||||
|
12
.github/dependabot.yml
vendored
@ -9,27 +9,15 @@ updates:
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
reviewers:
|
||||
- franknoirot
|
||||
- irev-dev
|
||||
- package-ecosystem: 'github-actions' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||
directory: '/src/wasm-lib/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||
directory: '/src-tauri/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
|
33
.github/workflows/build-and-store-wasm.yml
vendored
@ -1,33 +0,0 @@
|
||||
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@v2
|
||||
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
|
||||
strategy:
|
||||
matrix:
|
||||
dir: ['src/wasm-lib', 'src-tauri']
|
||||
dir: ['src/wasm-lib']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install latest rust
|
||||
@ -31,22 +31,9 @@ jobs:
|
||||
|
||||
- name: install dependencies
|
||||
if: matrix.dir == 'src-tauri'
|
||||
shell: bash
|
||||
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
|
||||
yarn install
|
||||
yarn build:wasm
|
||||
yarn build:local
|
||||
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2.6.1
|
||||
|
||||
|
@ -7,23 +7,23 @@ on:
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- .github/workflows/cargo-bench.yml
|
||||
- .github/workflows/cargo-criterion.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.rs'
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- .github/workflows/cargo-bench.yml
|
||||
- .github/workflows/cargo-criterion.yml
|
||||
workflow_dispatch:
|
||||
permissions: read-all
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
name: cargo bench
|
||||
name: cargo criterion
|
||||
jobs:
|
||||
cargo-bench:
|
||||
name: Benchmark with iai
|
||||
cargocriterion:
|
||||
name: cargo criterion
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -31,12 +31,10 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cargo install cargo-criterion
|
||||
sudo apt update
|
||||
sudo apt install -y valgrind
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2.6.1
|
||||
- name: Benchmark kcl library
|
||||
shell: bash
|
||||
run: |-
|
||||
cd src/wasm-lib/kcl; cargo bench -- iai
|
||||
cd src/wasm-lib/kcl; cargo criterion
|
||||
|
57
.github/workflows/cargo-test-tauri.yml
vendored
@ -1,57 +0,0 @@
|
||||
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
|
4
.github/workflows/check-exampleKcl.yml
vendored
@ -16,10 +16,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Comment on PR
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const message = '`src/lib/exampleKcl.ts` has been updated in this PR, please review and update the `src/routes/onboarding`, if needed.';
|
||||
|
67
.github/workflows/ci.yml
vendored
@ -50,7 +50,7 @@ jobs:
|
||||
- run: yarn tsc
|
||||
|
||||
|
||||
check-typos:
|
||||
check-typos:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@ -98,17 +98,13 @@ jobs:
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
|
||||
- name: Set nightly version
|
||||
if: github.event_name == 'schedule'
|
||||
run: |
|
||||
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
|
||||
echo "$(jq --arg url 'https://dl.zoo.dev/releases/modeling-app/nightly/last_update.json' \
|
||||
'.plugins.updater.endpoints[]=$url' src-tauri/tauri.release.conf.json --indent 2)" > src-tauri/tauri.release.conf.json
|
||||
echo "$(jq --arg id 'dev.zoo.modeling-app-nightly' \
|
||||
'.identifier=$id' src-tauri/tauri.release.conf.json --indent 2)" > src-tauri/tauri.release.conf.json
|
||||
echo "$(jq --arg name 'Zoo Modeling App (Nightly)' \
|
||||
'.productName=$name' src-tauri/tauri.release.conf.json --indent 2)" > src-tauri/tauri.release.conf.json
|
||||
'.tauri.updater.endpoints[]=$url' src-tauri/tauri.release.conf.json --indent 2)" > src-tauri/tauri.release.conf.json
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: github.event_name == 'schedule'
|
||||
@ -129,9 +125,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-14, ubuntu-latest, windows-latest]
|
||||
env:
|
||||
TAURI_ARGS_MACOS: ${{ matrix.os == 'macos-14' && '--target universal-apple-darwin' || '' }}
|
||||
TAURI_ARGS_UBUNTU: ${{ matrix.os == 'ubuntu-latest' && '--bundles' || '' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@ -143,21 +136,19 @@ jobs:
|
||||
ls -l artifact
|
||||
cp artifact/package.json package.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
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
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
|
||||
run: >
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install -y
|
||||
libgtk-3-dev
|
||||
libgtksourceview-3.0-dev
|
||||
webkit2gtk-4.0
|
||||
libappindicator3-dev
|
||||
webkit2gtk-driver
|
||||
xvfb
|
||||
|
||||
- name: Sync node version and setup cache
|
||||
uses: actions/setup-node@v4
|
||||
@ -170,9 +161,7 @@ jobs:
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
# TODO: re-enable for Windows builds, see https://github.com/tauri-apps/tauri/issues/9045
|
||||
- name: Setup Rust cache
|
||||
if: matrix.os != 'windows-latest'
|
||||
uses: swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src-tauri -> target'
|
||||
@ -235,14 +224,14 @@ jobs:
|
||||
with:
|
||||
includeRelease: false
|
||||
includeDebug: true
|
||||
args: "${{ env.TAURI_ARGS_MACOS }} ${{ env.TAURI_ARGS_UBUNTU }}"
|
||||
args: ${{ matrix.os == 'macos-14' && '--target universal-apple-darwin' || '' }}
|
||||
|
||||
- name: Build the app (release) and sign
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
if: ${{ env.BUILD_RELEASE == 'true' }}
|
||||
env:
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
@ -251,7 +240,7 @@ jobs:
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
TAURI_CONF_ARGS: "--config ${{ matrix.os == 'windows-latest' && 'src-tauri\\tauri.release.conf.json' || 'src-tauri/tauri.release.conf.json' }}"
|
||||
with:
|
||||
args: "${{ env.TAURI_CONF_ARGS }} ${{ env.TAURI_ARGS_MACOS }} ${{ env.TAURI_ARGS_UBUNTU }}"
|
||||
args: "${{ matrix.os == 'macos-14' && '--target universal-apple-darwin' || '' }} ${{ env.TAURI_CONF_ARGS }}"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: matrix.os != 'ubuntu-latest'
|
||||
@ -261,11 +250,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'
|
||||
run: |
|
||||
cargo install tauri-driver
|
||||
cargo install tauri-driver@0.1.3
|
||||
source .env.${{ env.BUILD_RELEASE == 'true' && 'production' || 'development' }}
|
||||
export VITE_KC_API_BASE_URL
|
||||
xvfb-run yarn test:e2e:tauri
|
||||
@ -285,7 +273,6 @@ jobs:
|
||||
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' }}
|
||||
URL_CODED_NAME: ${{ github.event_name == 'schedule' && 'Zoo%20Modeling%20App%20%28Nightly%29' || 'Zoo%20Modeling%20App' }}
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
|
||||
@ -300,9 +287,9 @@ jobs:
|
||||
--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 darwin_url "$RELEASE_DIR/macos/Zoo%20Modeling%20App.app.tar.gz" \
|
||||
--arg windows_sig "$WINDOWS_SIG" \
|
||||
--arg windows_url "$RELEASE_DIR/msi/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_x64_en-US.msi.zip" \
|
||||
--arg windows_url "$RELEASE_DIR/msi/Zoo%20Modeling%20App_${VERSION_NO_V}_x64_en-US.msi.zip" \
|
||||
'{
|
||||
"version": $version,
|
||||
"pub_date": $pub_date,
|
||||
@ -331,8 +318,8 @@ jobs:
|
||||
--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_url "$RELEASE_DIR/msi/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_x64_en-US.msi" \
|
||||
--arg darwin_url "$RELEASE_DIR/dmg/Zoo%20Modeling%20App_${VERSION_NO_V}_universal.dmg" \
|
||||
--arg windows_url "$RELEASE_DIR/msi/Zoo%20Modeling%20App_${VERSION_NO_V}_x64_en-US.msi" \
|
||||
'{
|
||||
"version": $version,
|
||||
"pub_date": $pub_date,
|
||||
@ -383,7 +370,7 @@ jobs:
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: 'artifact/*/Zoo*'
|
||||
|
||||
|
||||
announce_release:
|
||||
needs: [publish-apps-release]
|
||||
runs-on: ubuntu-latest
|
||||
@ -391,17 +378,17 @@ jobs:
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install requests
|
||||
|
||||
|
||||
- name: Announce Release
|
||||
env:
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
5
.github/workflows/generate-website-docs.yml
vendored
@ -15,7 +15,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
generate-website-docs:
|
||||
name: generate-website-docs
|
||||
name: generate-website-docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -56,9 +56,6 @@ jobs:
|
||||
gh pr create --title "Update KCL docs" \
|
||||
--body "Updating the generated kcl docs cc @jessfraz @franknoirot merge this" \
|
||||
--head "$NEW_BRANCH" \
|
||||
--reviewer jessfraz \
|
||||
--reviewer irev-dev \
|
||||
--reviewer franknoirot \
|
||||
--base main || true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
|
87
.github/workflows/playwright.yml
vendored
@ -9,34 +9,10 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
actions: read
|
||||
|
||||
|
||||
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@v2
|
||||
with:
|
||||
filters: |
|
||||
rust:
|
||||
- 'src/wasm-lib/**'
|
||||
|
||||
playwright-ubuntu:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
needs: check-rust-changes
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
@ -48,39 +24,13 @@ jobs:
|
||||
run: yarn
|
||||
- name: Install Playwright Browsers
|
||||
run: yarn playwright install --with-deps
|
||||
- name: download wasm
|
||||
id: download-wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||
uses: actions/download-artifact@v2
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: wasm-bundle
|
||||
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
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Setup Rust
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Cache wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
- name: Cache wasm
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
- name: build wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
run: yarn build:wasm
|
||||
- name: build wasm
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
run: yarn build:wasm
|
||||
- name: build web
|
||||
run: yarn build:local
|
||||
@ -131,16 +81,10 @@ jobs:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: github.ref == 'refs/heads/main'
|
||||
with:
|
||||
name: wasm-bundle
|
||||
path: src/wasm-lib/pkg
|
||||
|
||||
playwright-macos:
|
||||
timeout-minutes: 60
|
||||
runs-on: macos-14
|
||||
needs: check-rust-changes
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
@ -151,39 +95,13 @@ jobs:
|
||||
run: yarn
|
||||
- name: Install Playwright Browsers
|
||||
run: yarn playwright install --with-deps
|
||||
- name: download wasm
|
||||
id: download-wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: wasm-bundle
|
||||
path: src/wasm-lib/pkg
|
||||
continue-on-error: true
|
||||
- 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
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Setup Rust
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Cache wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
- name: Cache wasm
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
- name: build wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
run: yarn build:wasm
|
||||
- name: build wasm
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
run: yarn build:wasm
|
||||
- name: build web
|
||||
run: yarn build:local
|
||||
@ -200,8 +118,3 @@ jobs:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: github.ref == 'refs/heads/main'
|
||||
with:
|
||||
name: wasm-bundle
|
||||
path: src/wasm-lib/pkg
|
||||
|
1
.gitignore
vendored
@ -51,6 +51,5 @@ e2e/playwright/export-snapshots/*
|
||||
|
||||
## generated files
|
||||
src/**/*.typegen.ts
|
||||
src-tauri/gen
|
||||
|
||||
src/wasm-lib/grackle/stdlib_cube_partial.json
|
||||
|
@ -281,7 +281,7 @@ https://github.com/KittyCAD/modeling-app/assets/29681384/6f5e8e85-1003-4fd9-be7f
|
||||
<details>
|
||||
|
||||
<summary>
|
||||
PS: for the debug panel, the following JSON is useful for snapping the camera
|
||||
Ps for the debug panel, the following JSON is useful for snapping the camera
|
||||
</summary>
|
||||
|
||||
```JSON
|
||||
|
BIN
app-icon.png
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 120 KiB |
@ -1,3 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ['@babel/preset-env'],
|
||||
presets: ["@babel/preset-env"],
|
||||
}
|
||||
|
@ -12,10 +12,6 @@ Computes the absolute value of a number.
|
||||
abs(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the arccosine of a number (in radians).
|
||||
acos(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the arcsine of a number (in radians).
|
||||
asin(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the arctangent of a number (in radians).
|
||||
atan(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the smallest integer greater than or equal to a number.
|
||||
ceil(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: "cos"
|
||||
excerpt: "Computes the cosine of a number (in radians)."
|
||||
excerpt: "Computes the sine of a number (in radians)."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Computes the cosine of a number (in radians).
|
||||
Computes the sine of a number (in radians).
|
||||
|
||||
|
||||
|
||||
@ -12,10 +12,6 @@ Computes the cosine of a number (in radians).
|
||||
cos(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Return the value of Euler’s number `e`.
|
||||
e() -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the largest integer less than or equal to a number.
|
||||
floor(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -30,12 +30,10 @@ layout: manual
|
||||
* [`extrude`](kcl/extrude)
|
||||
* [`fillet`](kcl/fillet)
|
||||
* [`floor`](kcl/floor)
|
||||
* [`getEdge`](kcl/getEdge)
|
||||
* [`getExtrudeWallTransform`](kcl/getExtrudeWallTransform)
|
||||
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
||||
* [`helix`](kcl/helix)
|
||||
* [`hole`](kcl/hole)
|
||||
* [`import`](kcl/import)
|
||||
* [`lastSegX`](kcl/lastSegX)
|
||||
@ -57,7 +55,6 @@ layout: manual
|
||||
* [`patternLinear3d`](kcl/patternLinear3d)
|
||||
* [`pi`](kcl/pi)
|
||||
* [`pow`](kcl/pow)
|
||||
* [`revolve`](kcl/revolve)
|
||||
* [`segAng`](kcl/segAng)
|
||||
* [`segEndX`](kcl/segEndX)
|
||||
* [`segEndY`](kcl/segEndY)
|
||||
|
@ -12,10 +12,6 @@ Returns the angle of the given leg for x.
|
||||
legAngX(hypotenuse: number, leg: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `utilities`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Returns the angle of the given leg for y.
|
||||
legAngY(hypotenuse: number, leg: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `utilities`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Returns the length of the given leg.
|
||||
legLen(hypotenuse: number, leg: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `utilities`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the natural logarithm of the number.
|
||||
ln(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ The result might not be correctly rounded owing to implementation details; `log2
|
||||
log(num: number, base: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the base 10 logarithm of the number.
|
||||
log10(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the base 2 logarithm of the number.
|
||||
log2(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the maximum of the given arguments.
|
||||
max(args: [number]) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the minimum of the given arguments.
|
||||
min(args: [number]) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Return the value of `pi`. Archimedes’ constant (π).
|
||||
pi() -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the number to a power.
|
||||
pow(num: number, pow: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the sine of a number (in radians).
|
||||
sin(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Computes the square root of a number.
|
||||
sqrt(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
12229
docs/kcl/std.json
@ -12,10 +12,6 @@ Computes the tangent of a number (in radians).
|
||||
tan(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Return the value of `tau`. The full circle constant (τ). Equal to 2π.
|
||||
tau() -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Converts a number from radians to degrees.
|
||||
toDegrees(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
@ -12,10 +12,6 @@ Converts a number from degrees to radians.
|
||||
toRadians(num: number) -> number
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
* `math`
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
|
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 193 KiB |
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 193 KiB |
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 193 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 259 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 220 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 220 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 220 KiB |
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 193 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 221 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 221 KiB |
@ -7,36 +7,28 @@ import { spawn } from 'child_process'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
import JSZip from 'jszip'
|
||||
import path from 'path'
|
||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from './storageStates'
|
||||
import * as TOML from '@iarna/toml'
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.beforeEach(async ({ context, page }) => {
|
||||
await context.addInitScript(async (token) => {
|
||||
localStorage.setItem('TOKEN_PERSIST_KEY', token)
|
||||
localStorage.setItem('persistCode', ``)
|
||||
localStorage.setItem(
|
||||
'SETTINGS_PERSIST_KEY',
|
||||
JSON.stringify({
|
||||
baseUnit: 'in',
|
||||
cameraControls: 'KittyCAD',
|
||||
defaultDirectory: '',
|
||||
defaultProjectName: 'project-$nnn',
|
||||
onboardingStatus: 'dismissed',
|
||||
showDebugPanel: true,
|
||||
textWrapping: 'On',
|
||||
theme: 'system',
|
||||
unitSystem: 'imperial',
|
||||
})
|
||||
)
|
||||
}, secrets.token)
|
||||
// reducedMotion kills animations, which speeds up tests and reduces flakiness
|
||||
await page.emulateMedia({ reducedMotion: 'reduce' })
|
||||
|
||||
// set the default settings
|
||||
await page.addInitScript(
|
||||
async ({ token, settingsKey, settings }) => {
|
||||
localStorage.setItem('TOKEN_PERSIST_KEY', token)
|
||||
localStorage.setItem('persistCode', ``)
|
||||
localStorage.setItem(settingsKey, settings)
|
||||
},
|
||||
{
|
||||
token: secrets.token,
|
||||
settingsKey: TEST_SETTINGS_KEY,
|
||||
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)
|
||||
@ -336,7 +328,64 @@ const part001 = startSketchOn('-XZ')
|
||||
}
|
||||
})
|
||||
|
||||
const extrudeDefaultPlane = async (context: any, page: any, plane: string) => {
|
||||
test('extrude on each default plane should be stable', async ({
|
||||
page,
|
||||
context,
|
||||
}) => {
|
||||
const u = getUtils(page)
|
||||
const makeCode = (plane = 'XY') => `const part001 = startSketchOn('${plane}')
|
||||
|> startProfileAt([7.00, 4.40], %)
|
||||
|> line([6.60, -0.20], %)
|
||||
|> line([2.80, 5.00], %)
|
||||
|> line([-5.60, 4.40], %)
|
||||
|> line([-5.40, -3.80], %)
|
||||
|> close(%)
|
||||
|> extrude(10.00, %)
|
||||
`
|
||||
await context.addInitScript(async (code) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
}, makeCode('XY'))
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
|
||||
await page.getByText('Code').click()
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
await page.getByText('Code').click()
|
||||
|
||||
const runSnapshotsForOtherPlanes = async (plane = 'XY') => {
|
||||
// clear code
|
||||
await u.removeCurrentCode()
|
||||
// add makeCode('XZ')
|
||||
await page.locator('.cm-content').fill(makeCode(plane))
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
|
||||
await page.getByText('Code').click()
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
await page.getByText('Code').click()
|
||||
}
|
||||
await runSnapshotsForOtherPlanes('-XY')
|
||||
|
||||
await runSnapshotsForOtherPlanes('XZ')
|
||||
await runSnapshotsForOtherPlanes('-XZ')
|
||||
|
||||
await runSnapshotsForOtherPlanes('YZ')
|
||||
await runSnapshotsForOtherPlanes('-YZ')
|
||||
})
|
||||
|
||||
test('Draft segments should look right', async ({ page, context }) => {
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'SETTINGS_PERSIST_KEY',
|
||||
@ -348,80 +397,11 @@ const extrudeDefaultPlane = async (context: any, page: any, plane: string) => {
|
||||
onboardingStatus: 'dismissed',
|
||||
showDebugPanel: true,
|
||||
textWrapping: 'On',
|
||||
theme: 'dark',
|
||||
theme: 'system',
|
||||
unitSystem: 'imperial',
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
const code = `const part001 = startSketchOn('${plane}')
|
||||
|> startProfileAt([7.00, 4.40], %)
|
||||
|> line([6.60, -0.20], %)
|
||||
|> line([2.80, 5.00], %)
|
||||
|> line([-5.60, 4.40], %)
|
||||
|> line([-5.40, -3.80], %)
|
||||
|> close(%)
|
||||
|> extrude(10.00, %)
|
||||
`
|
||||
await page.addInitScript(async (code: string) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
})
|
||||
|
||||
const u = getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
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()
|
||||
|
||||
await u.closeKclCodePanel()
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
await u.openKclCodePanel()
|
||||
}
|
||||
|
||||
test.describe('extrude on default planes should be stable', () => {
|
||||
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('-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 }) => {
|
||||
const u = getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
@ -480,7 +460,26 @@ test('Draft segments should look right', async ({ page, context }) => {
|
||||
})
|
||||
})
|
||||
|
||||
test('Draft rectangles should look right', async ({ page, context }) => {
|
||||
test('Client side scene scale should match engine scale inch', async ({
|
||||
page,
|
||||
context,
|
||||
}) => {
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'SETTINGS_PERSIST_KEY',
|
||||
JSON.stringify({
|
||||
baseUnit: 'in',
|
||||
cameraControls: 'KittyCAD',
|
||||
defaultDirectory: '',
|
||||
defaultProjectName: 'project-$nnn',
|
||||
onboardingStatus: 'dismissed',
|
||||
showDebugPanel: true,
|
||||
textWrapping: 'On',
|
||||
theme: 'system',
|
||||
unitSystem: 'imperial',
|
||||
})
|
||||
)
|
||||
})
|
||||
const u = getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
@ -508,259 +507,153 @@ test('Draft rectangles should look right', async ({ page, context }) => {
|
||||
)
|
||||
|
||||
await page.waitForTimeout(300) // TODO detect animation ending, or disable animation
|
||||
await u.closeDebugPanel()
|
||||
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)`)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// Equip the rectangle tool
|
||||
await page.getByRole('button', { name: 'Line' }).click()
|
||||
await page.getByRole('button', { name: 'Rectangle' }).click()
|
||||
await u.closeDebugPanel()
|
||||
|
||||
// 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 })
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// Ensure the draft rectangle looks the same as it usually does
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)
|
||||
|> line([9.14, 0], %)`)
|
||||
|
||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)
|
||||
|> line([9.14, 0], %)
|
||||
|> tangentialArcTo([27.34, -3.08], %)`)
|
||||
|
||||
// click tangential arc tool again to unequip it
|
||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// screen shot should show the sketch
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
|
||||
// exit sketch
|
||||
await u.openAndClearDebugPanel()
|
||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||
|
||||
// wait for execution done
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await page.waitForTimeout(200)
|
||||
|
||||
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Client side scene scale should match engine scale', () => {
|
||||
test('Inch scale', async ({ page }) => {
|
||||
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(300) // TODO detect animation ending, or disable animation
|
||||
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)`)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await u.closeDebugPanel()
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)
|
||||
|> line([9.14, 0], %)`)
|
||||
|
||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([9.06, -12.22], %)
|
||||
|> line([9.14, 0], %)
|
||||
|> tangentialArcTo([27.34, -3.08], %)`)
|
||||
|
||||
// click tangential arc tool again to unequip it
|
||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// screen shot should show the sketch
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
|
||||
// exit sketch
|
||||
await u.openAndClearDebugPanel()
|
||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||
|
||||
// wait for execution done
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await page.waitForTimeout(200)
|
||||
|
||||
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
})
|
||||
|
||||
test('Millimeter scale', async ({ page }) => {
|
||||
await page.addInitScript(
|
||||
async ({ settingsKey, settings }) => {
|
||||
localStorage.setItem(settingsKey, settings)
|
||||
},
|
||||
{
|
||||
settingsKey: TEST_SETTINGS_KEY,
|
||||
settings: TOML.stringify({
|
||||
settings: {
|
||||
...TEST_SETTINGS,
|
||||
modeling: {
|
||||
...TEST_SETTINGS.modeling,
|
||||
defaultUnit: 'mm',
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
)
|
||||
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(300) // TODO detect animation ending, or disable animation
|
||||
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([230.03, -310.32], %)`)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await u.closeDebugPanel()
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([230.03, -310.32], %)
|
||||
|> line([232.2, 0], %)`)
|
||||
|
||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([230.03, -310.32], %)
|
||||
|> line([232.2, 0], %)
|
||||
|> tangentialArcTo([694.43, -78.12], %)`)
|
||||
|
||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// screen shot should show the sketch
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
|
||||
// exit sketch
|
||||
await u.openAndClearDebugPanel()
|
||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||
|
||||
// wait for execution done
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await page.waitForTimeout(200)
|
||||
|
||||
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Sketch on face with none z-up', async ({ page, context }) => {
|
||||
const u = getUtils(page)
|
||||
test('Client side scene scale should match engine scale mm', async ({
|
||||
page,
|
||||
context,
|
||||
}) => {
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([1.4, 2.47], %)
|
||||
|> line([9.31, 10.55], %, 'seg01')
|
||||
|> line([11.91, -10.42], %)
|
||||
|> close(%)
|
||||
|> extrude(5 + 7, %)
|
||||
const part002 = startSketchOn(part001, 'seg01')
|
||||
|> startProfileAt([8, 8], %)
|
||||
|> line([4.68, 3.05], %)
|
||||
|> line([0, -7.79], %, 'seg02')
|
||||
|> close(%)
|
||||
|> extrude(5 + 7, %)
|
||||
`
|
||||
'SETTINGS_PERSIST_KEY',
|
||||
JSON.stringify({
|
||||
baseUnit: 'mm',
|
||||
cameraControls: 'KittyCAD',
|
||||
defaultDirectory: '',
|
||||
defaultProjectName: 'project-$nnn',
|
||||
onboardingStatus: 'dismissed',
|
||||
showDebugPanel: true,
|
||||
textWrapping: 'On',
|
||||
theme: 'system',
|
||||
unitSystem: 'metric',
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
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()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(2)
|
||||
await u.closeDebugPanel()
|
||||
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
await expect(page.getByRole('button', { name: 'Start Sketch' })).toBeVisible()
|
||||
|
||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||
let previousCodeContent = await page.locator('.cm-content').innerText()
|
||||
// click on "Start Sketch" button
|
||||
await u.clearCommandLogs()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||
200
|
||||
)
|
||||
|
||||
// click at 641, 135
|
||||
await page.mouse.click(641, 135)
|
||||
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
||||
previousCodeContent = await page.locator('.cm-content').innerText()
|
||||
// select a plane
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await page.waitForTimeout(300)
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`const part001 = startSketchOn('-XZ')`
|
||||
)
|
||||
|
||||
await page.waitForTimeout(300) // TODO detect animation ending, or disable animation
|
||||
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([230.03, -310.33], %)`)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await u.closeDebugPanel()
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([230.03, -310.33], %)
|
||||
|> line([232.2, 0], %)`)
|
||||
|
||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([230.03, -310.33], %)
|
||||
|> line([232.2, 0], %)
|
||||
|> tangentialArcTo([694.43, -78.12], %)`)
|
||||
|
||||
await page.getByRole('button', { name: 'Tangential Arc' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
// screen shot should show the sketch
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
|
||||
// exit sketch
|
||||
await u.openAndClearDebugPanel()
|
||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||
|
||||
// wait for execution done
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await page.waitForTimeout(200)
|
||||
|
||||
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
|
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 45 KiB |