Compare commits
2 Commits
parser-in-
...
kcl_prelud
Author | SHA1 | Date | |
---|---|---|---|
ddce447c0b | |||
e8769eb543 |
@ -1,3 +1,3 @@
|
|||||||
[codespell]
|
[codespell]
|
||||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey,atleast
|
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey
|
||||||
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,./src-tauri/gen/schemas
|
skip: **/target,node_modules,build,**/Cargo.lock
|
||||||
|
12
.github/dependabot.yml
vendored
@ -9,27 +9,15 @@ updates:
|
|||||||
directory: '/' # Location of package manifests
|
directory: '/' # Location of package manifests
|
||||||
schedule:
|
schedule:
|
||||||
interval: 'daily'
|
interval: 'daily'
|
||||||
reviewers:
|
|
||||||
- franknoirot
|
|
||||||
- irev-dev
|
|
||||||
- package-ecosystem: 'github-actions' # See documentation for possible values
|
- package-ecosystem: 'github-actions' # See documentation for possible values
|
||||||
directory: '/' # Location of package manifests
|
directory: '/' # Location of package manifests
|
||||||
schedule:
|
schedule:
|
||||||
interval: 'daily'
|
interval: 'daily'
|
||||||
reviewers:
|
|
||||||
- adamchalmers
|
|
||||||
- jessfraz
|
|
||||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||||
directory: '/src/wasm-lib/' # Location of package manifests
|
directory: '/src/wasm-lib/' # Location of package manifests
|
||||||
schedule:
|
schedule:
|
||||||
interval: 'daily'
|
interval: 'daily'
|
||||||
reviewers:
|
|
||||||
- adamchalmers
|
|
||||||
- jessfraz
|
|
||||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||||
directory: '/src-tauri/' # Location of package manifests
|
directory: '/src-tauri/' # Location of package manifests
|
||||||
schedule:
|
schedule:
|
||||||
interval: 'daily'
|
interval: 'daily'
|
||||||
reviewers:
|
|
||||||
- adamchalmers
|
|
||||||
- jessfraz
|
|
||||||
|
@ -7,23 +7,23 @@ on:
|
|||||||
- '**/Cargo.toml'
|
- '**/Cargo.toml'
|
||||||
- '**/Cargo.lock'
|
- '**/Cargo.lock'
|
||||||
- '**/rust-toolchain.toml'
|
- '**/rust-toolchain.toml'
|
||||||
- .github/workflows/cargo-bench.yml
|
- .github/workflows/cargo-criterion.yml
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '**.rs'
|
- '**.rs'
|
||||||
- '**/Cargo.toml'
|
- '**/Cargo.toml'
|
||||||
- '**/Cargo.lock'
|
- '**/Cargo.lock'
|
||||||
- '**/rust-toolchain.toml'
|
- '**/rust-toolchain.toml'
|
||||||
- .github/workflows/cargo-bench.yml
|
- .github/workflows/cargo-criterion.yml
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
permissions: read-all
|
permissions: read-all
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
name: cargo bench
|
name: cargo criterion
|
||||||
jobs:
|
jobs:
|
||||||
cargo-bench:
|
cargocriterion:
|
||||||
name: Benchmark with iai
|
name: cargo criterion
|
||||||
runs-on: ubuntu-latest-8-cores
|
runs-on: ubuntu-latest-8-cores
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -31,12 +31,10 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
cargo install cargo-criterion
|
cargo install cargo-criterion
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y valgrind
|
|
||||||
- name: Rust Cache
|
- name: Rust Cache
|
||||||
uses: Swatinem/rust-cache@v2.6.1
|
uses: Swatinem/rust-cache@v2.6.1
|
||||||
- name: Benchmark kcl library
|
- name: Benchmark kcl library
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |-
|
run: |-
|
||||||
cd src/wasm-lib/kcl; cargo bench -- iai
|
cd src/wasm-lib/kcl; cargo criterion
|
||||||
|
|
4
.github/workflows/check-exampleKcl.yml
vendored
@ -16,10 +16,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Comment on PR
|
- name: Comment on PR
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v6
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const message = '`src/lib/exampleKcl.ts` has been updated in this PR, please review and update the `src/routes/onboarding`, if needed.';
|
const message = '`src/lib/exampleKcl.ts` has been updated in this PR, please review and update the `src/routes/onboarding`, if needed.';
|
||||||
|
41
.github/workflows/ci.yml
vendored
@ -104,11 +104,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
|
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
|
||||||
echo "$(jq --arg url 'https://dl.zoo.dev/releases/modeling-app/nightly/last_update.json' \
|
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
|
'.tauri.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
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
if: github.event_name == 'schedule'
|
if: github.event_name == 'schedule'
|
||||||
@ -129,9 +125,6 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-14, ubuntu-latest, windows-latest]
|
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:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@ -151,12 +144,10 @@ jobs:
|
|||||||
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
|
libgtksourceview-3.0-dev
|
||||||
|
webkit2gtk-4.0
|
||||||
|
libappindicator3-dev
|
||||||
webkit2gtk-driver
|
webkit2gtk-driver
|
||||||
libsoup-3.0-dev
|
|
||||||
libjavascriptcoregtk-4.1-dev
|
|
||||||
libwebkit2gtk-4.1-dev
|
|
||||||
at-spi2-core
|
|
||||||
xvfb
|
xvfb
|
||||||
|
|
||||||
- name: Sync node version and setup cache
|
- name: Sync node version and setup cache
|
||||||
@ -170,9 +161,7 @@ jobs:
|
|||||||
- name: Setup Rust
|
- name: Setup Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
# TODO: re-enable for Windows builds, see https://github.com/tauri-apps/tauri/issues/9045
|
|
||||||
- name: Setup Rust cache
|
- name: Setup Rust cache
|
||||||
if: matrix.os != 'windows-latest'
|
|
||||||
uses: swatinem/rust-cache@v2
|
uses: swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
workspaces: './src-tauri -> target'
|
workspaces: './src-tauri -> target'
|
||||||
@ -235,14 +224,14 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
includeRelease: false
|
includeRelease: false
|
||||||
includeDebug: true
|
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
|
- 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' }}
|
||||||
env:
|
env:
|
||||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||||
@ -251,7 +240,7 @@ jobs:
|
|||||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
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' }}"
|
TAURI_CONF_ARGS: "--config ${{ matrix.os == 'windows-latest' && 'src-tauri\\tauri.release.conf.json' || 'src-tauri/tauri.release.conf.json' }}"
|
||||||
with:
|
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
|
- uses: actions/upload-artifact@v3
|
||||||
if: matrix.os != 'ubuntu-latest'
|
if: matrix.os != 'ubuntu-latest'
|
||||||
@ -261,11 +250,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'
|
||||||
run: |
|
run: |
|
||||||
cargo install tauri-driver
|
cargo install tauri-driver@0.1.3
|
||||||
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
|
||||||
@ -285,7 +273,6 @@ jobs:
|
|||||||
NOTES: ${{ github.event_name == 'release' && github.event.release.body || format('Nightly build, commit {0}', github.sha) }}
|
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' }}
|
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' }}
|
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:
|
steps:
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
|
|
||||||
@ -300,9 +287,9 @@ jobs:
|
|||||||
--arg pub_date "${PUB_DATE}" \
|
--arg pub_date "${PUB_DATE}" \
|
||||||
--arg notes "${NOTES}" \
|
--arg notes "${NOTES}" \
|
||||||
--arg darwin_sig "$DARWIN_SIG" \
|
--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_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,
|
"version": $version,
|
||||||
"pub_date": $pub_date,
|
"pub_date": $pub_date,
|
||||||
@ -331,8 +318,8 @@ jobs:
|
|||||||
--arg version "${VERSION}" \
|
--arg version "${VERSION}" \
|
||||||
--arg pub_date "${PUB_DATE}" \
|
--arg pub_date "${PUB_DATE}" \
|
||||||
--arg notes "${NOTES}" \
|
--arg notes "${NOTES}" \
|
||||||
--arg darwin_url "$RELEASE_DIR/dmg/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_universal.dmg" \
|
--arg darwin_url "$RELEASE_DIR/dmg/Zoo%20Modeling%20App_${VERSION_NO_V}_universal.dmg" \
|
||||||
--arg windows_url "$RELEASE_DIR/msi/${{ env.URL_CODED_NAME }}_${VERSION_NO_V}_x64_en-US.msi" \
|
--arg windows_url "$RELEASE_DIR/msi/Zoo%20Modeling%20App_${VERSION_NO_V}_x64_en-US.msi" \
|
||||||
'{
|
'{
|
||||||
"version": $version,
|
"version": $version,
|
||||||
"pub_date": $pub_date,
|
"pub_date": $pub_date,
|
||||||
|
3
.github/workflows/generate-website-docs.yml
vendored
@ -56,9 +56,6 @@ jobs:
|
|||||||
gh pr create --title "Update KCL docs" \
|
gh pr create --title "Update KCL docs" \
|
||||||
--body "Updating the generated kcl docs cc @jessfraz @franknoirot merge this" \
|
--body "Updating the generated kcl docs cc @jessfraz @franknoirot merge this" \
|
||||||
--head "$NEW_BRANCH" \
|
--head "$NEW_BRANCH" \
|
||||||
--reviewer jessfraz \
|
|
||||||
--reviewer irev-dev \
|
|
||||||
--reviewer franknoirot \
|
|
||||||
--base main || true
|
--base main || true
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||||
|
4
.github/workflows/playwright.yml
vendored
@ -9,10 +9,6 @@ concurrency:
|
|||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
playwright-ubuntu:
|
playwright-ubuntu:
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
1
.gitignore
vendored
@ -51,6 +51,5 @@ e2e/playwright/export-snapshots/*
|
|||||||
|
|
||||||
## generated files
|
## generated files
|
||||||
src/**/*.typegen.ts
|
src/**/*.typegen.ts
|
||||||
src-tauri/gen
|
|
||||||
|
|
||||||
src/wasm-lib/grackle/stdlib_cube_partial.json
|
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>
|
<details>
|
||||||
|
|
||||||
<summary>
|
<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>
|
</summary>
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
|
BIN
app-icon.png
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 120 KiB |
@ -12,10 +12,6 @@ Computes the absolute value of a number.
|
|||||||
abs(num: number) -> number
|
abs(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the arccosine of a number (in radians).
|
|||||||
acos(num: number) -> number
|
acos(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the arcsine of a number (in radians).
|
|||||||
asin(num: number) -> number
|
asin(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the arctangent of a number (in radians).
|
|||||||
atan(num: number) -> number
|
atan(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the smallest integer greater than or equal to a number.
|
|||||||
ceil(num: number) -> number
|
ceil(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: "cos"
|
title: "cos"
|
||||||
excerpt: "Computes the cosine of a number (in radians)."
|
excerpt: "Computes the sine of a number (in radians)."
|
||||||
layout: manual
|
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
|
cos(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Return the value of Euler’s number `e`.
|
|||||||
e() -> number
|
e() -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the largest integer less than or equal to a number.
|
|||||||
floor(num: number) -> number
|
floor(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -30,12 +30,10 @@ layout: manual
|
|||||||
* [`extrude`](kcl/extrude)
|
* [`extrude`](kcl/extrude)
|
||||||
* [`fillet`](kcl/fillet)
|
* [`fillet`](kcl/fillet)
|
||||||
* [`floor`](kcl/floor)
|
* [`floor`](kcl/floor)
|
||||||
* [`getEdge`](kcl/getEdge)
|
|
||||||
* [`getExtrudeWallTransform`](kcl/getExtrudeWallTransform)
|
* [`getExtrudeWallTransform`](kcl/getExtrudeWallTransform)
|
||||||
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
||||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||||
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
||||||
* [`helix`](kcl/helix)
|
|
||||||
* [`hole`](kcl/hole)
|
* [`hole`](kcl/hole)
|
||||||
* [`import`](kcl/import)
|
* [`import`](kcl/import)
|
||||||
* [`lastSegX`](kcl/lastSegX)
|
* [`lastSegX`](kcl/lastSegX)
|
||||||
@ -57,7 +55,6 @@ layout: manual
|
|||||||
* [`patternLinear3d`](kcl/patternLinear3d)
|
* [`patternLinear3d`](kcl/patternLinear3d)
|
||||||
* [`pi`](kcl/pi)
|
* [`pi`](kcl/pi)
|
||||||
* [`pow`](kcl/pow)
|
* [`pow`](kcl/pow)
|
||||||
* [`revolve`](kcl/revolve)
|
|
||||||
* [`segAng`](kcl/segAng)
|
* [`segAng`](kcl/segAng)
|
||||||
* [`segEndX`](kcl/segEndX)
|
* [`segEndX`](kcl/segEndX)
|
||||||
* [`segEndY`](kcl/segEndY)
|
* [`segEndY`](kcl/segEndY)
|
||||||
|
@ -12,10 +12,6 @@ Returns the angle of the given leg for x.
|
|||||||
legAngX(hypotenuse: number, leg: number) -> number
|
legAngX(hypotenuse: number, leg: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `utilities`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Returns the angle of the given leg for y.
|
|||||||
legAngY(hypotenuse: number, leg: number) -> number
|
legAngY(hypotenuse: number, leg: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `utilities`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Returns the length of the given leg.
|
|||||||
legLen(hypotenuse: number, leg: number) -> number
|
legLen(hypotenuse: number, leg: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `utilities`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the natural logarithm of the number.
|
|||||||
ln(num: number) -> number
|
ln(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ The result might not be correctly rounded owing to implementation details; `log2
|
|||||||
log(num: number, base: number) -> number
|
log(num: number, base: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the base 10 logarithm of the number.
|
|||||||
log10(num: number) -> number
|
log10(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the base 2 logarithm of the number.
|
|||||||
log2(num: number) -> number
|
log2(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the maximum of the given arguments.
|
|||||||
max(args: [number]) -> number
|
max(args: [number]) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the minimum of the given arguments.
|
|||||||
min(args: [number]) -> number
|
min(args: [number]) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Return the value of `pi`. Archimedes’ constant (π).
|
|||||||
pi() -> number
|
pi() -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the number to a power.
|
|||||||
pow(num: number, pow: number) -> number
|
pow(num: number, pow: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the sine of a number (in radians).
|
|||||||
sin(num: number) -> number
|
sin(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Computes the square root of a number.
|
|||||||
sqrt(num: number) -> number
|
sqrt(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
4683
docs/kcl/std.json
@ -12,10 +12,6 @@ Computes the tangent of a number (in radians).
|
|||||||
tan(num: number) -> number
|
tan(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Return the value of `tau`. The full circle constant (τ). Equal to 2π.
|
|||||||
tau() -> number
|
tau() -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Converts a number from radians to degrees.
|
|||||||
toDegrees(num: number) -> number
|
toDegrees(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -12,10 +12,6 @@ Converts a number from degrees to radians.
|
|||||||
toRadians(num: number) -> number
|
toRadians(num: number) -> number
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tags
|
|
||||||
|
|
||||||
* `math`
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```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 { APP_NAME } 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 * 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
|
// reducedMotion kills animations, which speeds up tests and reduces flakiness
|
||||||
await page.emulateMedia({ reducedMotion: 'reduce' })
|
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)
|
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 () => {
|
await context.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'SETTINGS_PERSIST_KEY',
|
'SETTINGS_PERSIST_KEY',
|
||||||
@ -348,80 +397,11 @@ const extrudeDefaultPlane = async (context: any, page: any, plane: string) => {
|
|||||||
onboardingStatus: 'dismissed',
|
onboardingStatus: 'dismissed',
|
||||||
showDebugPanel: true,
|
showDebugPanel: true,
|
||||||
textWrapping: 'On',
|
textWrapping: 'On',
|
||||||
theme: 'dark',
|
theme: 'system',
|
||||||
unitSystem: 'imperial',
|
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)
|
const u = getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
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)
|
const u = getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
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 page.waitForTimeout(300) // TODO detect animation ending, or disable animation
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
const startXPx = 600
|
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 u.closeDebugPanel()
|
||||||
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 * 10)
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 30)
|
await page.waitForTimeout(100)
|
||||||
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.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({
|
await expect(page).toHaveScreenshot({
|
||||||
maxDiffPixels: 100,
|
maxDiffPixels: 100,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test.describe('Client side scene scale should match engine scale', () => {
|
test('Client side scene scale should match engine scale mm', async ({
|
||||||
test('Inch scale', async ({ page }) => {
|
page,
|
||||||
const u = getUtils(page)
|
context,
|
||||||
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)
|
|
||||||
await context.addInitScript(async () => {
|
await context.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'persistCode',
|
'SETTINGS_PERSIST_KEY',
|
||||||
`const part001 = startSketchOn('-XZ')
|
JSON.stringify({
|
||||||
|> startProfileAt([1.4, 2.47], %)
|
baseUnit: 'mm',
|
||||||
|> line([9.31, 10.55], %, 'seg01')
|
cameraControls: 'KittyCAD',
|
||||||
|> line([11.91, -10.42], %)
|
defaultDirectory: '',
|
||||||
|> close(%)
|
defaultProjectName: 'project-$nnn',
|
||||||
|> extrude(5 + 7, %)
|
onboardingStatus: 'dismissed',
|
||||||
const part002 = startSketchOn(part001, 'seg01')
|
showDebugPanel: true,
|
||||||
|> startProfileAt([8, 8], %)
|
textWrapping: 'On',
|
||||||
|> line([4.68, 3.05], %)
|
theme: 'system',
|
||||||
|> line([0, -7.79], %, 'seg02')
|
unitSystem: 'metric',
|
||||||
|> close(%)
|
})
|
||||||
|> extrude(5 + 7, %)
|
|
||||||
`
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
const u = getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.goto('/')
|
await page.goto('/')
|
||||||
await u.waitForAuthSkipAppStart()
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
await u.openDebugPanel()
|
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(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled()
|
).not.toBeDisabled()
|
||||||
|
await expect(page.getByRole('button', { name: 'Start Sketch' })).toBeVisible()
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
// click on "Start Sketch" button
|
||||||
let previousCodeContent = await page.locator('.cm-content').innerText()
|
await u.clearCommandLogs()
|
||||||
|
await u.doAndWaitForImageDiff(
|
||||||
|
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||||
|
200
|
||||||
|
)
|
||||||
|
|
||||||
// click at 641, 135
|
// select a plane
|
||||||
await page.mouse.click(641, 135)
|
await page.mouse.click(700, 200)
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
|
||||||
previousCodeContent = await page.locator('.cm-content').innerText()
|
|
||||||
|
|
||||||
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({
|
await expect(page).toHaveScreenshot({
|
||||||
maxDiffPixels: 100,
|
maxDiffPixels: 100,
|
||||||
})
|
})
|
||||||
|
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 45 KiB |