Compare commits
2 Commits
nested_dir
...
nrc-no-ang
Author | SHA1 | Date | |
---|---|---|---|
7b7d587141 | |||
5db6564804 |
2
.github/ci-cd-scripts/upload-results.sh
vendored
@ -6,7 +6,6 @@ if [ -z "${TAB_API_URL:-}" ] || [ -z "${TAB_API_KEY:-}" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
project="https://github.com/KittyCAD/modeling-app"
|
project="https://github.com/KittyCAD/modeling-app"
|
||||||
suite="${CI_SUITE:-unit}"
|
|
||||||
branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}"
|
branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}"
|
||||||
commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}"
|
commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}"
|
||||||
|
|
||||||
@ -14,7 +13,6 @@ echo "Uploading batch results"
|
|||||||
curl --silent --request POST \
|
curl --silent --request POST \
|
||||||
--header "X-API-Key: ${TAB_API_KEY}" \
|
--header "X-API-Key: ${TAB_API_KEY}" \
|
||||||
--form "project=${project}" \
|
--form "project=${project}" \
|
||||||
--form "suite=${suite}" \
|
|
||||||
--form "branch=${branch}" \
|
--form "branch=${branch}" \
|
||||||
--form "commit=${commit}" \
|
--form "commit=${commit}" \
|
||||||
--form "tests=@test-results/junit.xml" \
|
--form "tests=@test-results/junit.xml" \
|
||||||
|
56
.github/workflows/build-wasm.yml
vendored
@ -1,56 +0,0 @@
|
|||||||
name: Build WASM
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
npm-build-wasm:
|
|
||||||
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Use correct Rust toolchain
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
|
||||||
|
|
||||||
- name: Install rust
|
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
||||||
with:
|
|
||||||
cache: false # configured below
|
|
||||||
|
|
||||||
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
|
||||||
with:
|
|
||||||
tool: wasm-pack
|
|
||||||
|
|
||||||
- name: Use Rust cache
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
workspaces: './rust'
|
|
||||||
|
|
||||||
- name: Build Wasm
|
|
||||||
shell: bash
|
|
||||||
run: npm run build:wasm
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: prepared-wasm
|
|
||||||
path: |
|
|
||||||
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: prepared-ts-rs-bindings
|
|
||||||
path: |
|
|
||||||
rust/kcl-lib/bindings/*
|
|
55
.github/workflows/cargo-test.yml
vendored
@ -88,7 +88,6 @@ jobs:
|
|||||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
|
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
|
||||||
ZOO_HOST: https://api.dev.zoo.dev
|
ZOO_HOST: https://api.dev.zoo.dev
|
||||||
RUST_BACKTRACE: full
|
RUST_BACKTRACE: full
|
||||||
RUST_MIN_STACK: 10485760000
|
|
||||||
- name: Commit differences
|
- name: Commit differences
|
||||||
if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure'
|
if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure'
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -120,7 +119,6 @@ jobs:
|
|||||||
# Configure nextest when it's run by insta (via just).
|
# Configure nextest when it's run by insta (via just).
|
||||||
NEXTEST_PROFILE: ci
|
NEXTEST_PROFILE: ci
|
||||||
RUST_BACKTRACE: full
|
RUST_BACKTRACE: full
|
||||||
RUST_MIN_STACK: 10485760000
|
|
||||||
- name: Build and archive tests
|
- name: Build and archive tests
|
||||||
run: |
|
run: |
|
||||||
cd rust
|
cd rust
|
||||||
@ -157,7 +155,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
||||||
- name: Install Rust
|
- name: Install rust
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
with:
|
with:
|
||||||
cache: false # Configured below.
|
cache: false # Configured below.
|
||||||
@ -184,7 +182,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
|
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
|
||||||
ZOO_HOST: https://api.dev.zoo.dev
|
ZOO_HOST: https://api.dev.zoo.dev
|
||||||
RUST_MIN_STACK: 10485760000
|
|
||||||
- name: Upload results
|
- name: Upload results
|
||||||
if: always()
|
if: always()
|
||||||
run: .github/ci-cd-scripts/upload-results.sh
|
run: .github/ci-cd-scripts/upload-results.sh
|
||||||
@ -193,56 +190,6 @@ jobs:
|
|||||||
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
||||||
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
||||||
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
|
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
CI_SUITE: unit:kcl
|
|
||||||
run-internal-kcl-samples:
|
|
||||||
name: cargo test (internal-kcl-samples)
|
|
||||||
runs-on:
|
|
||||||
- runs-on=${{ github.run_id }}
|
|
||||||
- runner=32cpu-linux-x64
|
|
||||||
- extras=s3-cache
|
|
||||||
steps:
|
|
||||||
- uses: runs-on/action@v1
|
|
||||||
- uses: actions/create-github-app-token@v1
|
|
||||||
id: app-token
|
|
||||||
with:
|
|
||||||
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
|
||||||
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
|
|
||||||
owner: ${{ github.repository_owner }}
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
token: ${{ steps.app-token.outputs.token }}
|
|
||||||
- name: Use correct Rust toolchain
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
|
||||||
- name: Install Rust
|
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
||||||
with:
|
|
||||||
cache: false # Configured below.
|
|
||||||
- name: Start Vector
|
|
||||||
run: .github/ci-cd-scripts/start-vector-ubuntu.sh
|
|
||||||
env:
|
|
||||||
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
|
|
||||||
OS_NAME: ${{ env.OS_NAME }}
|
|
||||||
- uses: taiki-e/install-action@nextest
|
|
||||||
- name: Download internal KCL samples
|
|
||||||
run: git clone --depth=1 https://x-access-token:${{ secrets.GH_PAT_KCL_SAMPLES_INTERNAL }}@github.com/KittyCAD/kcl-samples-internal public/kcl-samples/internal
|
|
||||||
- name: Run tests
|
|
||||||
shell: bash
|
|
||||||
run: |-
|
|
||||||
cd rust/kcl-lib
|
|
||||||
cargo nextest run \
|
|
||||||
--retries=10 --no-fail-fast --features artifact-graph --profile=ci \
|
|
||||||
internal \
|
|
||||||
2>&1 | tee /tmp/github-actions.log
|
|
||||||
env:
|
|
||||||
TWENTY_TWENTY: overwrite
|
|
||||||
INSTA_UPDATE: always
|
|
||||||
EXPECTORATE: overwrite
|
|
||||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
|
|
||||||
ZOO_HOST: https://api.dev.zoo.dev
|
|
||||||
MODELING_APP_INTERNAL_SAMPLES_SECRET: ${{secrets.MODELING_APP_INTERNAL_SAMPLES_SECRET}}
|
|
||||||
RUST_MIN_STACK: 10485760000
|
|
||||||
run-wasm-tests:
|
run-wasm-tests:
|
||||||
name: Run wasm tests
|
name: Run wasm tests
|
||||||
strategy:
|
strategy:
|
||||||
|
17
.github/workflows/e2e-tests.yml
vendored
@ -143,7 +143,7 @@ jobs:
|
|||||||
- name: Install browsers
|
- name: Install browsers
|
||||||
run: npm run playwright install --with-deps
|
run: npm run playwright install --with-deps
|
||||||
|
|
||||||
- name: Test snapshots
|
- name: Capture snapshots
|
||||||
uses: nick-fields/retry@v3.0.2
|
uses: nick-fields/retry@v3.0.2
|
||||||
with:
|
with:
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -156,19 +156,6 @@ jobs:
|
|||||||
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
||||||
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
||||||
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
|
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
CI_SUITE: snapshots
|
|
||||||
TARGET: web
|
|
||||||
|
|
||||||
- name: Update snapshots
|
|
||||||
if: always()
|
|
||||||
run: npm run test:snapshots -- --last-failed --update-snapshots
|
|
||||||
env:
|
|
||||||
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
|
||||||
TAB_API_URL: ${{ secrets.TAB_API_URL }}
|
|
||||||
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
|
||||||
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
|
||||||
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
||||||
CI_SUITE: snapshots
|
|
||||||
TARGET: web
|
TARGET: web
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
@ -186,7 +173,7 @@ jobs:
|
|||||||
id: git-check
|
id: git-check
|
||||||
run: |
|
run: |
|
||||||
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
|
git add e2e/playwright/snapshot-tests.spec.ts-snapshots e2e/playwright/snapshots
|
||||||
if git status | grep --quiet "Changes to be committed"
|
if git status | grep -q "Changes to be committed"
|
||||||
then echo "modified=true" >> $GITHUB_OUTPUT
|
then echo "modified=true" >> $GITHUB_OUTPUT
|
||||||
else echo "modified=false" >> $GITHUB_OUTPUT
|
else echo "modified=false" >> $GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
|
99
.github/workflows/kcl-language-server.yml
vendored
@ -21,11 +21,14 @@ on:
|
|||||||
- '**.rs'
|
- '**.rs'
|
||||||
- .github/workflows/kcl-language-server.yml
|
- .github/workflows/kcl-language-server.yml
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_INCREMENTAL: 0
|
CARGO_INCREMENTAL: 0
|
||||||
CARGO_NET_RETRY: 10
|
CARGO_NET_RETRY: 10
|
||||||
@ -35,9 +38,10 @@ env:
|
|||||||
MACOSX_DEPLOYMENT_TARGET: 10.15
|
MACOSX_DEPLOYMENT_TARGET: 10.15
|
||||||
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
||||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
|
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: kcl-language-server (vscode tests)
|
name: vscode tests
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@ -73,20 +77,22 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
target: x86_64-pc-windows-msvc
|
target: x86_64-pc-windows-msvc
|
||||||
code-target: win32-x64
|
code-target:
|
||||||
#- os: windows-latest
|
win32-x64
|
||||||
#target: i686-pc-windows-msvc
|
#- os: windows-latest
|
||||||
#code-target:
|
#target: i686-pc-windows-msvc
|
||||||
#win32-ia32
|
#code-target:
|
||||||
#- os: windows-latest
|
#win32-ia32
|
||||||
#target: aarch64-pc-windows-msvc
|
#- os: windows-latest
|
||||||
#code-target: win32-arm64
|
#target: aarch64-pc-windows-msvc
|
||||||
|
#code-target: win32-arm64
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
target: x86_64-unknown-linux-gnu
|
target: x86_64-unknown-linux-gnu
|
||||||
code-target: linux-x64
|
code-target:
|
||||||
#- os: ubuntu-latest
|
linux-x64
|
||||||
#target: aarch64-unknown-linux-musl
|
#- os: ubuntu-latest
|
||||||
#code-target: linux-arm64
|
#target: aarch64-unknown-linux-musl
|
||||||
|
#code-target: linux-arm64
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
target: aarch64-unknown-linux-gnu
|
target: aarch64-unknown-linux-gnu
|
||||||
code-target: linux-arm64
|
code-target: linux-arm64
|
||||||
@ -99,33 +105,41 @@ jobs:
|
|||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
target: aarch64-apple-darwin
|
target: aarch64-apple-darwin
|
||||||
code-target: darwin-arm64
|
code-target: darwin-arm64
|
||||||
name: kcl-language-server build-release (${{ matrix.target }})
|
|
||||||
|
name: build-release (${{ matrix.target }})
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
container: ${{ matrix.container }}
|
container: ${{ matrix.container }}
|
||||||
|
|
||||||
env:
|
env:
|
||||||
RA_TARGET: ${{ matrix.target }}
|
RA_TARGET: ${{ matrix.target }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||||
|
|
||||||
- name: Use correct Rust toolchain
|
- name: Use correct Rust toolchain
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
rm rust/rust-toolchain.toml
|
rm rust/rust-toolchain.toml
|
||||||
|
|
||||||
- name: Install rust
|
- name: Install rust
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
with:
|
with:
|
||||||
cache: rust
|
cache: rust
|
||||||
components: rust-src
|
components: rust-src
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
|
|
||||||
- name: Update apt repositories
|
- name: Update apt repositories
|
||||||
if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' || matrix.os == 'ubuntu-latest'
|
if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' || matrix.os == 'ubuntu-latest'
|
||||||
run: sudo apt-get update
|
run: sudo apt-get update
|
||||||
|
|
||||||
- if: ${{ matrix.os == 'ubuntu-latest' }}
|
- if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||||
name: Install deps
|
name: Install deps
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -150,53 +164,64 @@ jobs:
|
|||||||
zlib1g-dev
|
zlib1g-dev
|
||||||
|
|
||||||
cargo install cross
|
cargo install cross
|
||||||
|
|
||||||
- name: Install AArch64 target toolchain
|
- name: Install AArch64 target toolchain
|
||||||
if: matrix.target == 'aarch64-unknown-linux-gnu'
|
if: matrix.target == 'aarch64-unknown-linux-gnu'
|
||||||
run: sudo apt-get install gcc-aarch64-linux-gnu
|
run: sudo apt-get install gcc-aarch64-linux-gnu
|
||||||
|
|
||||||
- name: Install ARM target toolchain
|
- name: Install ARM target toolchain
|
||||||
if: matrix.target == 'arm-unknown-linux-gnueabihf'
|
if: matrix.target == 'arm-unknown-linux-gnueabihf'
|
||||||
run: sudo apt-get install gcc-arm-linux-gnueabihf
|
run: sudo apt-get install gcc-arm-linux-gnueabihf
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
run: |
|
run: |
|
||||||
cd rust
|
cd rust
|
||||||
cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }}
|
cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
# npm will symlink which will cause issues w tarballing later
|
# npm will symlink which will cause issues w tarballing later
|
||||||
yarn install
|
yarn install
|
||||||
|
|
||||||
- name: Package Extension (release)
|
- name: Package Extension (release)
|
||||||
if: startsWith(github.event.ref, 'refs/tags/')
|
if: startsWith(github.event.ref, 'refs/tags/')
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }}
|
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }}
|
||||||
|
|
||||||
- name: Package Extension (nightly)
|
- name: Package Extension (nightly)
|
||||||
if: startsWith(github.event.ref, 'refs/tags/') == false
|
if: startsWith(github.event.ref, 'refs/tags/') == false
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release
|
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release
|
||||||
|
|
||||||
- name: remove server
|
- name: remove server
|
||||||
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
rm -rf server
|
rm -rf server
|
||||||
|
|
||||||
- name: Package Extension (no server, release)
|
- name: Package Extension (no server, release)
|
||||||
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/')
|
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/')
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix
|
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix
|
||||||
|
|
||||||
- name: Package Extension (no server, nightly)
|
- name: Package Extension (no server, nightly)
|
||||||
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/') == false
|
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/') == false
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix --pre-release
|
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix --pre-release
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: release-${{ matrix.target }}
|
name: release-${{ matrix.target }}
|
||||||
path: ./rust/build
|
path: ./rust/build
|
||||||
|
|
||||||
build-release-x86_64-unknown-linux-musl:
|
build-release-x86_64-unknown-linux-musl:
|
||||||
name: kcl-language-server build-release (x86_64-unknown-linux-musl)
|
name: build-release (x86_64-unknown-linux-musl)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
RA_TARGET: x86_64-unknown-linux-musl
|
RA_TARGET: x86_64-unknown-linux-musl
|
||||||
@ -206,6 +231,7 @@ jobs:
|
|||||||
image: alpine:latest
|
image: alpine:latest
|
||||||
volumes:
|
volumes:
|
||||||
- /usr/local/cargo/registry:/usr/local/cargo/registry
|
- /usr/local/cargo/registry:/usr/local/cargo/registry
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
@ -219,46 +245,55 @@ jobs:
|
|||||||
nodejs \
|
nodejs \
|
||||||
npm \
|
npm \
|
||||||
yarn
|
yarn
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||||
|
|
||||||
- name: Use correct Rust toolchain
|
- name: Use correct Rust toolchain
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
rm rust/rust-toolchain.toml
|
rm rust/rust-toolchain.toml
|
||||||
|
|
||||||
- name: Install rust
|
- name: Install rust
|
||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
with:
|
with:
|
||||||
cache: rust
|
cache: rust
|
||||||
components: rust-src
|
components: rust-src
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
run: |
|
run: |
|
||||||
cd rust
|
cd rust
|
||||||
cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }}
|
cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
# npm will symlink which will cause issues w tarballing later
|
# npm will symlink which will cause issues w tarballing later
|
||||||
yarn install
|
yarn install
|
||||||
|
|
||||||
- name: Package Extension (release)
|
- name: Package Extension (release)
|
||||||
if: startsWith(github.event.ref, 'refs/tags/')
|
if: startsWith(github.event.ref, 'refs/tags/')
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64
|
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64
|
||||||
|
|
||||||
- name: Package Extension (release)
|
- name: Package Extension (release)
|
||||||
if: startsWith(github.event.ref, 'refs/tags/') == false
|
if: startsWith(github.event.ref, 'refs/tags/') == false
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64 --pre-release
|
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64 --pre-release
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: release-x86_64-unknown-linux-musl
|
name: release-x86_64-unknown-linux-musl
|
||||||
path: ./rust/build
|
path: ./rust/build
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
name: kcl-language-server (publish)
|
name: publish
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: ["build-release", "build-release-x86_64-unknown-linux-musl"]
|
needs: ["build-release", "build-release-x86_64-unknown-linux-musl"]
|
||||||
if: startsWith(github.event.ref, 'refs/tags')
|
if: startsWith(github.event.ref, 'refs/tags')
|
||||||
@ -266,17 +301,22 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- run: echo "TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
- run: echo "TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- run: 'echo "TAG: $TAG"'
|
- run: 'echo "TAG: $TAG"'
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||||
|
|
||||||
- name: Install Nodejs
|
- name: Install Nodejs
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: ".nvmrc"
|
node-version-file: ".nvmrc"
|
||||||
|
|
||||||
- run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
- run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
||||||
- run: 'echo "HEAD_SHA: $HEAD_SHA"'
|
- run: 'echo "HEAD_SHA: $HEAD_SHA"'
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: release-aarch64-apple-darwin
|
name: release-aarch64-apple-darwin
|
||||||
@ -304,29 +344,33 @@ jobs:
|
|||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: release-x86_64-pc-windows-msvc
|
name: release-x86_64-pc-windows-msvc
|
||||||
path: rust/build
|
path:
|
||||||
#- uses: actions/download-artifact@v4
|
rust/build
|
||||||
#with:
|
#- uses: actions/download-artifact@v4
|
||||||
#name: release-i686-pc-windows-msvc
|
#with:
|
||||||
#path:
|
#name: release-i686-pc-windows-msvc
|
||||||
#build
|
#path:
|
||||||
#- uses: actions/download-artifact@v4
|
#build
|
||||||
#with:
|
#- uses: actions/download-artifact@v4
|
||||||
#name: release-aarch64-pc-windows-msvc
|
#with:
|
||||||
#path: rust/build
|
#name: release-aarch64-pc-windows-msvc
|
||||||
|
#path: rust/build
|
||||||
- run: ls -al ./rust/build
|
- run: ls -al ./rust/build
|
||||||
|
|
||||||
- name: Publish Release
|
- name: Publish Release
|
||||||
uses: ./.github/actions/github-release
|
uses: ./.github/actions/github-release
|
||||||
with:
|
with:
|
||||||
files: "rust/build/*"
|
files: "rust/build/*"
|
||||||
name: ${{ env.TAG }}
|
name: ${{ env.TAG }}
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: move files to dir for upload
|
- name: move files to dir for upload
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cd rust
|
cd rust
|
||||||
mkdir -p releases/language-server/${{ env.TAG }}
|
mkdir -p releases/language-server/${{ env.TAG }}
|
||||||
cp -r build/* releases/language-server/${{ env.TAG }}
|
cp -r build/* releases/language-server/${{ env.TAG }}
|
||||||
|
|
||||||
- name: "Authenticate to Google Cloud"
|
- name: "Authenticate to Google Cloud"
|
||||||
uses: "google-github-actions/auth@v2.1.8"
|
uses: "google-github-actions/auth@v2.1.8"
|
||||||
with:
|
with:
|
||||||
@ -341,12 +385,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: rust/releases
|
path: rust/releases
|
||||||
destination: dl.kittycad.io
|
destination: dl.kittycad.io
|
||||||
|
|
||||||
- run: rm rust/build/kcl-language-server-no-server.vsix
|
- run: rm rust/build/kcl-language-server-no-server.vsix
|
||||||
|
|
||||||
- name: Publish Extension (Code Marketplace, release)
|
- name: Publish Extension (Code Marketplace, release)
|
||||||
# token from https://dev.azure.com/kcl-language-server/
|
# token from https://dev.azure.com/kcl-language-server/
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
npx vsce publish --pat ${{ secrets.VSCE_PAT }} --packagePath ../build/kcl-language-server-*.vsix
|
npx vsce publish --pat ${{ secrets.VSCE_PAT }} --packagePath ../build/kcl-language-server-*.vsix
|
||||||
|
|
||||||
- name: Publish Extension (OpenVSX, release)
|
- name: Publish Extension (OpenVSX, release)
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-language-server
|
cd rust/kcl-language-server
|
||||||
|
32
.github/workflows/kcl-python-bindings.yml
vendored
@ -4,6 +4,7 @@
|
|||||||
# maturin generate-ci github
|
# maturin generate-ci github
|
||||||
#
|
#
|
||||||
name: kcl-python-bindings
|
name: kcl-python-bindings
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@ -26,14 +27,16 @@ on:
|
|||||||
- '**.rs'
|
- '**.rs'
|
||||||
- .github/workflows/kcl-python-bindings.yml
|
- .github/workflows/kcl-python-bindings.yml
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
linux-x86_64:
|
linux-x86_64:
|
||||||
name: kcl-python-bindings (linux-x86_64)
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -55,8 +58,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: wheels-linux-x86_64
|
name: wheels-linux-x86_64
|
||||||
path: rust/kcl-python-bindings/dist
|
path: rust/kcl-python-bindings/dist
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
name: kcl-python-bindings (windows)
|
|
||||||
runs-on: windows-16-cores
|
runs-on: windows-16-cores
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@ -81,8 +84,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: wheels-windows-${{ matrix.target }}
|
name: wheels-windows-${{ matrix.target }}
|
||||||
path: rust/kcl-python-bindings/dist
|
path: rust/kcl-python-bindings/dist
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
name: kcl-python-bindings (macos)
|
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@ -107,8 +110,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: wheels-macos-${{ matrix.target }}
|
name: wheels-macos-${{ matrix.target }}
|
||||||
path: rust/kcl-python-bindings/dist
|
path: rust/kcl-python-bindings/dist
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: kcl-python-bindings (test)
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -124,8 +127,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||||
ZOO_HOST: https://api.dev.zoo.dev
|
ZOO_HOST: https://api.dev.zoo.dev
|
||||||
|
|
||||||
sdist:
|
sdist:
|
||||||
name: kcl-python-bindings (sdist)
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -133,10 +136,10 @@ jobs:
|
|||||||
uses: astral-sh/setup-uv@v5
|
uses: astral-sh/setup-uv@v5
|
||||||
- name: Install codespell
|
- name: Install codespell
|
||||||
run: |
|
run: |
|
||||||
uv venv .venv
|
uv venv .venv
|
||||||
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
||||||
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
||||||
uv pip install pip --upgrade
|
uv pip install pip --upgrade
|
||||||
- name: Build sdist
|
- name: Build sdist
|
||||||
uses: PyO3/maturin-action@v1
|
uses: PyO3/maturin-action@v1
|
||||||
with:
|
with:
|
||||||
@ -148,6 +151,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: wheels-sdist
|
name: wheels-sdist
|
||||||
path: rust/kcl-python-bindings/dist
|
path: rust/kcl-python-bindings/dist
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: Release
|
name: Release
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -164,11 +168,11 @@ jobs:
|
|||||||
uses: astral-sh/setup-uv@v5
|
uses: astral-sh/setup-uv@v5
|
||||||
- name: do uv things
|
- name: do uv things
|
||||||
run: |
|
run: |
|
||||||
cd rust/kcl-python-bindings
|
cd rust/kcl-python-bindings
|
||||||
uv venv .venv
|
uv venv .venv
|
||||||
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
||||||
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
||||||
uv pip install pip --upgrade
|
uv pip install pip --upgrade
|
||||||
- name: Publish to PyPI
|
- name: Publish to PyPI
|
||||||
uses: PyO3/maturin-action@v1
|
uses: PyO3/maturin-action@v1
|
||||||
env:
|
env:
|
||||||
|
167
.github/workflows/static-analysis.yml
vendored
@ -28,7 +28,53 @@ jobs:
|
|||||||
- run: npm run fmt:check
|
- run: npm run fmt:check
|
||||||
|
|
||||||
npm-build-wasm:
|
npm-build-wasm:
|
||||||
uses: ./.github/workflows/build-wasm.yml
|
# Build the wasm blob once on the fastest runner.
|
||||||
|
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Use correct Rust toolchain
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
||||||
|
|
||||||
|
- name: Install rust
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
|
with:
|
||||||
|
cache: false # Configured below.
|
||||||
|
|
||||||
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
|
with:
|
||||||
|
tool: wasm-pack
|
||||||
|
|
||||||
|
- name: Rust Cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: './rust'
|
||||||
|
|
||||||
|
- name: Build Wasm
|
||||||
|
shell: bash
|
||||||
|
run: npm run build:wasm
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: prepared-wasm
|
||||||
|
path: |
|
||||||
|
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: prepared-ts-rs-bindings
|
||||||
|
path: |
|
||||||
|
rust/kcl-lib/bindings/*
|
||||||
|
|
||||||
npm-tsc:
|
npm-tsc:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -127,3 +173,122 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Run codespell
|
- name: Run codespell
|
||||||
uses: crate-ci/typos@v1.32.0
|
uses: crate-ci/typos@v1.32.0
|
||||||
|
|
||||||
|
npm-unit-test-kcl-samples:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: npm-build-wasm
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- run: npm install
|
||||||
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
|
with:
|
||||||
|
tool: wasm-pack
|
||||||
|
|
||||||
|
- name: Download all artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
|
||||||
|
- name: Copy prepared wasm
|
||||||
|
run: |
|
||||||
|
ls -R prepared-wasm
|
||||||
|
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
|
||||||
|
mkdir rust/kcl-wasm-lib/pkg
|
||||||
|
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
|
||||||
|
|
||||||
|
- name: Copy prepared ts-rs bindings
|
||||||
|
run: |
|
||||||
|
ls -R prepared-ts-rs-bindings
|
||||||
|
mkdir rust/kcl-lib/bindings
|
||||||
|
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
||||||
|
|
||||||
|
- run: npm run simpleserver:bg
|
||||||
|
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
|
|
||||||
|
- name: Install Chromium Browser
|
||||||
|
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
|
run: npm run playwright install chromium --with-deps
|
||||||
|
|
||||||
|
- name: Download internal KCL samples
|
||||||
|
run: git clone --depth=1 https://x-access-token:${{ secrets.GH_PAT_KCL_SAMPLES_INTERNAL }}@github.com/KittyCAD/kcl-samples-internal public/kcl-samples/internal
|
||||||
|
|
||||||
|
- name: Regenerate KCL samples manifest
|
||||||
|
run: cd rust/kcl-lib && EXPECTORATE=overwrite cargo test generate_manifest
|
||||||
|
|
||||||
|
- name: Check public and internal KCL samples
|
||||||
|
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
|
run: npm run test:unit:kcl-samples
|
||||||
|
env:
|
||||||
|
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||||
|
|
||||||
|
npm-unit-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: npm-build-wasm
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- run: npm install
|
||||||
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
|
with:
|
||||||
|
tool: wasm-pack
|
||||||
|
|
||||||
|
- name: Download all artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
|
||||||
|
- name: Copy prepared wasm
|
||||||
|
run: |
|
||||||
|
ls -R prepared-wasm
|
||||||
|
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
|
||||||
|
mkdir rust/kcl-wasm-lib/pkg
|
||||||
|
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
|
||||||
|
|
||||||
|
- name: Copy prepared ts-rs bindings
|
||||||
|
run: |
|
||||||
|
ls -R prepared-ts-rs-bindings
|
||||||
|
mkdir rust/kcl-lib/bindings
|
||||||
|
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
||||||
|
|
||||||
|
- run: npm run simpleserver:bg
|
||||||
|
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
|
|
||||||
|
- name: Install Chromium Browser
|
||||||
|
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
|
run: npm run playwright install chromium --with-deps
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
|
run: xvfb-run -a npm run test:unit
|
||||||
|
env:
|
||||||
|
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||||
|
|
||||||
|
- name: Check for changes
|
||||||
|
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
||||||
|
id: git-check
|
||||||
|
run: |
|
||||||
|
git add src/lang/std/artifactMapGraphs
|
||||||
|
if git status src/lang/std/artifactMapGraphs | grep -q "Changes to be committed"
|
||||||
|
then echo "modified=true" >> $GITHUB_OUTPUT
|
||||||
|
else echo "modified=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
- name: Commit changes, if any
|
||||||
|
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' && steps.git-check.outputs.modified == 'true' }}
|
||||||
|
run: |
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
|
||||||
|
git fetch origin
|
||||||
|
echo ${{ github.head_ref }}
|
||||||
|
git checkout ${{ github.head_ref }}
|
||||||
|
# TODO when webkit works on ubuntu remove the os part of the commit message
|
||||||
|
git commit -am "Look at this (photo)Graph *in the voice of Nickelback*" || true
|
||||||
|
git push
|
||||||
|
git push origin ${{ github.head_ref }}
|
||||||
|
124
.github/workflows/unit-tests.yml
vendored
@ -1,124 +0,0 @@
|
|||||||
name: Unit Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
pull-requests: write
|
|
||||||
actions: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
npm-build-wasm:
|
|
||||||
uses: ./.github/workflows/build-wasm.yml
|
|
||||||
|
|
||||||
npm-test-unit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: npm-build-wasm
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- run: npm install
|
|
||||||
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
|
||||||
with:
|
|
||||||
tool: wasm-pack
|
|
||||||
|
|
||||||
- name: Download all artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
|
|
||||||
- name: Copy prepared wasm
|
|
||||||
run: |
|
|
||||||
ls -R prepared-wasm
|
|
||||||
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
|
|
||||||
mkdir rust/kcl-wasm-lib/pkg
|
|
||||||
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
|
|
||||||
|
|
||||||
- name: Copy prepared ts-rs bindings
|
|
||||||
run: |
|
|
||||||
ls -R prepared-ts-rs-bindings
|
|
||||||
mkdir rust/kcl-lib/bindings
|
|
||||||
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
|
||||||
|
|
||||||
- run: npm run simpleserver:bg
|
|
||||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
|
||||||
|
|
||||||
- name: Install Chromium Browser
|
|
||||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
|
||||||
run: npm run playwright install chromium --with-deps
|
|
||||||
|
|
||||||
- name: Run unit tests
|
|
||||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
|
||||||
run: xvfb-run -a npm run test:unit
|
|
||||||
env:
|
|
||||||
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
|
||||||
|
|
||||||
- name: Check for changes
|
|
||||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
|
|
||||||
id: git-check
|
|
||||||
run: |
|
|
||||||
git add src/lang/std/artifactMapGraphs
|
|
||||||
if git status src/lang/std/artifactMapGraphs | grep -q "Changes to be committed"
|
|
||||||
then echo "modified=true" >> $GITHUB_OUTPUT
|
|
||||||
else echo "modified=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Commit changes, if any
|
|
||||||
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' && steps.git-check.outputs.modified == 'true' }}
|
|
||||||
run: |
|
|
||||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
git config --local user.name "github-actions[bot]"
|
|
||||||
git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
|
|
||||||
git fetch origin
|
|
||||||
echo ${{ github.head_ref }}
|
|
||||||
git checkout ${{ github.head_ref }}
|
|
||||||
# TODO when webkit works on ubuntu remove the os part of the commit message
|
|
||||||
git commit -am "Look at this (photo)Graph *in the voice of Nickelback*" || true
|
|
||||||
git push
|
|
||||||
git push origin ${{ github.head_ref }}
|
|
||||||
|
|
||||||
npm-test-unit-components:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: npm-build-wasm
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version-file: '.nvmrc'
|
|
||||||
cache: 'npm'
|
|
||||||
|
|
||||||
- run: npm install
|
|
||||||
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
|
||||||
with:
|
|
||||||
tool: wasm-pack
|
|
||||||
|
|
||||||
- name: Download all artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
|
|
||||||
- name: Copy prepared wasm
|
|
||||||
run: |
|
|
||||||
ls -R prepared-wasm
|
|
||||||
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
|
|
||||||
mkdir rust/kcl-wasm-lib/pkg
|
|
||||||
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
|
|
||||||
|
|
||||||
- name: Copy prepared ts-rs bindings
|
|
||||||
run: |
|
|
||||||
ls -R prepared-ts-rs-bindings
|
|
||||||
mkdir rust/kcl-lib/bindings
|
|
||||||
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
|
|
||||||
|
|
||||||
- name: Run component tests
|
|
||||||
run: npm run test:unit:components
|
|
2
.gitignore
vendored
@ -58,8 +58,6 @@ trace.zip
|
|||||||
/public/kcl-samples/.github
|
/public/kcl-samples/.github
|
||||||
/public/kcl-samples/screenshots/main.kcl
|
/public/kcl-samples/screenshots/main.kcl
|
||||||
/public/kcl-samples/step/main.kcl
|
/public/kcl-samples/step/main.kcl
|
||||||
/public/kcl-samples/internal
|
|
||||||
/rust/kcl-lib/tests/kcl_samples/internal
|
|
||||||
/test-results/
|
/test-results/
|
||||||
/playwright-report/
|
/playwright-report/
|
||||||
/blob-report/
|
/blob-report/
|
||||||
|
1
Makefile
@ -114,6 +114,7 @@ test-unit: install ## Run the unit tests
|
|||||||
npm run test:unit:components
|
npm run test:unit:components
|
||||||
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
|
@ curl -fs localhost:3000 >/dev/null || ( echo "Error: localhost:3000 not available, 'make run-web' first" && exit 1 )
|
||||||
npm run test:unit
|
npm run test:unit
|
||||||
|
npm run test:unit:kcl-samples
|
||||||
|
|
||||||
.PHONY: test-e2e
|
.PHONY: test-e2e
|
||||||
test-e2e: test-e2e-$(TARGET)
|
test-e2e: test-e2e-$(TARGET)
|
||||||
|
@ -42,6 +42,8 @@ The 3D view in Design Studio is just a video stream from our hosted geometry eng
|
|||||||
|
|
||||||
We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
|
We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
|
||||||
|
|
||||||
|
If you'd like to try out upcoming changes sooner, you can also download those from our [nightly releases](https://zoo.dev/modeling-app/download/nightly) page.
|
||||||
|
|
||||||
## Developing
|
## Developing
|
||||||
|
|
||||||
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
|
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
|
||||||
|
@ -21,7 +21,7 @@ extend-exclude = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[default.extend-words]
|
[default.extend-words]
|
||||||
metalness = "metalness" # appearance API
|
metalness = "metalness" # appearance API
|
||||||
Hom = "Hom" # short for homogenous
|
Hom = "Hom" # short for homogenous
|
||||||
typ = "typ" # used to declare a variable named 'type' which is a reserved keyword in Rust
|
typ = "typ" # used to declare a variable named 'type' which is a reserved keyword in Rust
|
||||||
ue = "ue" # short for UnaryExpression
|
ue = "ue" # short for UnaryExpression
|
||||||
@ -29,7 +29,6 @@ THRE = "THRE" # Weird bug that wrongly detects THREEjs as a typo
|
|||||||
nwo = "nwo" # don't know what this is about tbh
|
nwo = "nwo" # don't know what this is about tbh
|
||||||
"ot" = "ot" # some abbreviation, idk what
|
"ot" = "ot" # some abbreviation, idk what
|
||||||
"oe" = "oe" # some abbreviation, idk what
|
"oe" = "oe" # some abbreviation, idk what
|
||||||
"colinear" = "colinear" # some engine shit, kidding
|
|
||||||
|
|
||||||
[default]
|
[default]
|
||||||
extend-ignore-identifiers-re = [
|
extend-ignore-identifiers-re = [
|
||||||
|
@ -4,7 +4,7 @@ excerpt: "Documentation of the KCL language for the Zoo Design Studio."
|
|||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
This is a reference for KCL. If you are learning KCL, you may prefer the [guide](https://zoo.dev/docs/kcl-book/intro.html) which explains
|
This is a reference for KCL. If you are learning KCL, you may prefer the [guide]() which explains
|
||||||
things in a more tutorial fashion. See also our documentation of the [standard library](/docs/kcl-std).
|
things in a more tutorial fashion. See also our documentation of the [standard library](/docs/kcl-std).
|
||||||
|
|
||||||
## Topics
|
## Topics
|
||||||
|
@ -27,6 +27,9 @@ import increment from "util.kcl"
|
|||||||
answer = increment(41)
|
answer = increment(41)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Imported files _must_ be in the same project so that units are uniform across
|
||||||
|
modules. This means that it must be in the same directory.
|
||||||
|
|
||||||
Import statements must be at the top-level of a file. It is not allowed to have
|
Import statements must be at the top-level of a file. It is not allowed to have
|
||||||
an `import` statement inside a function or in the body of an if‑else.
|
an `import` statement inside a function or in the body of an if‑else.
|
||||||
|
|
||||||
@ -55,9 +58,6 @@ Imported symbols can be renamed for convenience or to avoid name collisions.
|
|||||||
import increment as inc, decrement as dec from "util.kcl"
|
import increment as inc, decrement as dec from "util.kcl"
|
||||||
```
|
```
|
||||||
|
|
||||||
You can import files from the current directory or from subdirectories, but if importing from a
|
|
||||||
subdirectory you can only import `main.kcl`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Functions vs `clone`
|
## Functions vs `clone`
|
||||||
@ -177,7 +177,7 @@ You can also import the whole module. This is useful if you want to use the
|
|||||||
result of a module as a variable, like a part.
|
result of a module as a variable, like a part.
|
||||||
|
|
||||||
```norun
|
```norun
|
||||||
import "cube.kcl"
|
import "tests/inputs/cube.kcl" as cube
|
||||||
cube
|
cube
|
||||||
|> translate(x=10)
|
|> translate(x=10)
|
||||||
```
|
```
|
||||||
@ -229,19 +229,6 @@ The final statement is what's important because it's the return value of the
|
|||||||
entire module. The module is expected to return a single object that can be used
|
entire module. The module is expected to return a single object that can be used
|
||||||
as a variable by the file that imports it.
|
as a variable by the file that imports it.
|
||||||
|
|
||||||
The name of the file or subdirectory is used as the name of the variable within the importing program.
|
|
||||||
If you want to use a different name, you can do so by using the `as` keyword:
|
|
||||||
|
|
||||||
```kcl,norun
|
|
||||||
import "cube.kcl" // Introduces a new variable called `cube`.
|
|
||||||
import "cube.kcl" as block // Introduces a new variable called `block`.
|
|
||||||
import "cube/main.kcl" // Introduces a new variable called `cube`.
|
|
||||||
import "cube/main.kcl" as block // Introduces a new variable called `block`.
|
|
||||||
```
|
|
||||||
|
|
||||||
If the filename includes hyphens (`-`) or starts with an underscore (`_`), then you must specify a
|
|
||||||
variable name.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Multiple instances of the same import
|
## Multiple instances of the same import
|
||||||
@ -254,7 +241,7 @@ If you want to have multiple instances of the same object, you can use the
|
|||||||
[`clone`](/docs/kcl/clone) function. This will render a new instance of the object in memory.
|
[`clone`](/docs/kcl/clone) function. This will render a new instance of the object in memory.
|
||||||
|
|
||||||
```norun
|
```norun
|
||||||
import cube from "cube.kcl"
|
import cube from "tests/inputs/cube.kcl"
|
||||||
|
|
||||||
cube
|
cube
|
||||||
|> translate(x=10)
|
|> translate(x=10)
|
||||||
@ -270,7 +257,7 @@ separate objects in memory, and can be manipulated independently.
|
|||||||
Here is an example with a file from another CAD system:
|
Here is an example with a file from another CAD system:
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
import "tests/inputs/cube.step"
|
import "tests/inputs/cube.step" as cube
|
||||||
|
|
||||||
cube
|
cube
|
||||||
|> translate(x=10)
|
|> translate(x=10)
|
||||||
|
@ -46,7 +46,7 @@ angledLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> yLine(endAbsolute = 15)
|
|> yLine(endAbsolute = 15)
|
||||||
|> angledLine(angle = 30, length = 15)
|
|> angledLine(angle = 30deg, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -42,7 +42,7 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> line(endAbsolute = [5, 10])
|
|> line(endAbsolute = [5, 10])
|
||||||
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|
||||||
|> line(endAbsolute = [0, 20])
|
|> line(endAbsolute = [0, 20])
|
||||||
|> angledLineThatIntersects(angle = 80, intersectTag = lineToIntersect, offset = 10)
|
|> angledLineThatIntersects(angle = 80deg, intersectTag = lineToIntersect, offset = 10)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 10)
|
example = extrude(exampleSketch, length = 10)
|
||||||
|
@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 5)
|
|||||||
// Add color to a revolved solid.
|
// Add color to a revolved solid.
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
|> circle(center = [15, 0], radius = 5)
|
|> circle(center = [15, 0], radius = 5)
|
||||||
|> revolve(angle = 360, axis = Y)
|
|> revolve(angle = 360deg, axis = Y)
|
||||||
|> appearance(color = '#ff0000', metalness = 90, roughness = 90)
|
|> appearance(color = '#ff0000', metalness = 90, roughness = 90)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> patternCircular2d(
|
|> patternCircular2d(
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
instances = 13,
|
instances = 13,
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -188,9 +188,9 @@ example = extrude(exampleSketch, length = 1)
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90deg, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|
|
||||||
pipeHole = startSketchOn(XY)
|
pipeHole = startSketchOn(XY)
|
||||||
|
@ -46,7 +46,7 @@ Unless this makes a lot of sense and feels like what you're looking for to const
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> arc(angleStart = 0, angleEnd = 280, radius = 16)
|
|> arc(angleStart = 0deg, angleEnd = 280deg, radius = 16)
|
||||||
|> close()
|
|> close()
|
||||||
example = extrude(exampleSketch, length = 10)
|
example = extrude(exampleSketch, length = 10)
|
||||||
```
|
```
|
||||||
|
@ -19,7 +19,7 @@ E: number = 2.71828182845904523536028747135266250_
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 30,
|
angle = 30deg,
|
||||||
length = 2 * E ^ 2,
|
length = 2 * E ^ 2,
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -19,7 +19,7 @@ TAU: number = 6.28318530717958647692528676655900577_
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 10 * TAU,
|
length = 10 * TAU,
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -42,7 +42,7 @@ You can provide more than one sketch to extrude, and they will all be extruded i
|
|||||||
example = startSketchOn(XZ)
|
example = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> arc(angleStart = 120, angleEnd = 0, radius = 5)
|
|> arc(angleStart = 120deg, angleEnd = 0deg, radius = 5)
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> line(end = [0, 10])
|
|> line(end = [0, 10])
|
||||||
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|
||||||
@ -56,7 +56,7 @@ example = startSketchOn(XZ)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-10, 0])
|
|> startProfile(at = [-10, 0])
|
||||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||||
@ -72,7 +72,7 @@ example = extrude(exampleSketch, length = 10)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-10, 0])
|
|> startProfile(at = [-10, 0])
|
||||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||||
@ -88,7 +88,7 @@ example = extrude(exampleSketch, length = 20, symmetric = true)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-10, 0])
|
|> startProfile(at = [-10, 0])
|
||||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||||
|
@ -12,7 +12,7 @@ reduce(
|
|||||||
@array: [any],
|
@array: [any],
|
||||||
initial: any,
|
initial: any,
|
||||||
f: fn(any, accum: any): any,
|
f: fn(any, accum: any): any,
|
||||||
): any
|
): [any]
|
||||||
```
|
```
|
||||||
|
|
||||||
Take a starting value. Then, for each element of an array, calculate the next value,
|
Take a starting value. Then, for each element of an array, calculate the next value,
|
||||||
@ -28,7 +28,7 @@ using the previous value and the element.
|
|||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`any`](/docs/kcl-std/types/std-types-any)
|
[`[any]`](/docs/kcl-std/types/std-types-any)
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
@ -80,7 +80,7 @@ fn decagon(@radius) {
|
|||||||
|
|
||||||
// Start the decagon sketch at this point.
|
// Start the decagon sketch at this point.
|
||||||
startOfDecagonSketch = startSketchOn(XY)
|
startOfDecagonSketch = startSketchOn(XY)
|
||||||
|> startProfile(at = [(cos(0)*radius), (sin(0) * radius)])
|
|> startProfile(at = [(cos(0deg)*radius), (sin(0deg) * radius)])
|
||||||
|
|
||||||
// Use a `reduce` to draw the remaining decagon sides.
|
// Use a `reduce` to draw the remaining decagon sides.
|
||||||
// For each number in the array 1..10, run the given function,
|
// For each number in the array 1..10, run the given function,
|
||||||
|
@ -27,7 +27,7 @@ abs(@input: number): number
|
|||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
myAngle = -120
|
myAngle = -120deg
|
||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|
@ -30,7 +30,7 @@ cos(@num: number(Angle)): number(_)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 30,
|
angle = 30deg,
|
||||||
length = 3 / cos(30deg),
|
length = 3 / cos(30deg),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -11,7 +11,7 @@ Compute the length of the given leg.
|
|||||||
legLen(
|
legLen(
|
||||||
hypotenuse: number(Length),
|
hypotenuse: number(Length),
|
||||||
leg: number(Length),
|
leg: number(Length),
|
||||||
): number(Length)
|
): number(deg)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ legLen(
|
|||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
|
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
@ -30,7 +30,7 @@ max(@input: [number; 1+]): number
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 70,
|
angle = 70deg,
|
||||||
length = max([15, 31, 4, 13, 22])
|
length = max([15, 31, 4, 13, 22])
|
||||||
)
|
)
|
||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|
@ -30,7 +30,7 @@ min(@input: [number; 1+]): number
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 70,
|
angle = 70deg,
|
||||||
length = min([15, 31, 4, 13, 22])
|
length = min([15, 31, 4, 13, 22])
|
||||||
)
|
)
|
||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|
@ -34,7 +34,7 @@ cartesian (x/y/z grid) coordinates.
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = polar(angle = 30, length = 5), tag = $thing)
|
|> line(end = polar(angle = 30deg, length = 5), tag = $thing)
|
||||||
|> line(end = [0, 5])
|
|> line(end = [0, 5])
|
||||||
|> line(end = [segEndX(thing), 0])
|
|> line(end = [segEndX(thing), 0])
|
||||||
|> line(end = [-20, 10])
|
|> line(end = [-20, 10])
|
||||||
|
@ -34,7 +34,7 @@ pow(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = pow(5, exp = 2),
|
length = pow(5, exp = 2),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,7 +30,7 @@ sin(@num: number(Angle)): number(_)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 15 / sin(135deg),
|
length = 15 / sin(135deg),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,7 +30,7 @@ sqrt(@input: number): number
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = sqrt(2500),
|
length = sqrt(2500),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,7 +30,7 @@ tan(@num: number(Angle)): number(_)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 50 * tan((1/2): number(rad)),
|
length = 50 * tan((1/2): number(rad)),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -14,6 +14,8 @@ mirror2d(
|
|||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Only works on unclosed sketches for now.
|
||||||
|
|
||||||
Mirror occurs around a local sketch axis rather than a global axis.
|
Mirror occurs around a local sketch axis rather than a global axis.
|
||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
@ -30,7 +30,7 @@ units::toDegrees(@num: number(Angle)): number(deg)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 70 * cos(units::toDegrees((PI/4): number(rad))),
|
length = 70 * cos(units::toDegrees((PI/4): number(rad))),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|
@ -30,8 +30,8 @@ units::toRadians(@num: number(Angle)): number(rad)
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50deg,
|
||||||
length = 70 * cos(units::toRadians(45)),
|
length = 70 * cos(units::toRadians(45deg)),
|
||||||
)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -30,10 +30,10 @@ getNextAdjacentEdge(@edge: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> angledLine(angle = 120, length = 10)
|
|> angledLine(angle = 120deg, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -30,10 +30,10 @@ getOppositeEdge(@edge: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> angledLine(angle = 120, length = 10)
|
|> angledLine(angle = 120deg, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -30,10 +30,10 @@ getPreviousAdjacentEdge(@edge: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> angledLine(angle = 120, length = 10)
|
|> angledLine(angle = 120deg, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -65,7 +65,7 @@ layout: manual
|
|||||||
* [`line`](/docs/kcl-std/line)
|
* [`line`](/docs/kcl-std/line)
|
||||||
* [`loft`](/docs/kcl-std/loft)
|
* [`loft`](/docs/kcl-std/loft)
|
||||||
* [`patternCircular2d`](/docs/kcl-std/patternCircular2d)
|
* [`patternCircular2d`](/docs/kcl-std/patternCircular2d)
|
||||||
* [`patternTransform2d`](/docs/kcl-std/functions/std-sketch-patternTransform2d)
|
* [`patternTransform2d`](/docs/kcl-std/patternTransform2d)
|
||||||
* [`polygon`](/docs/kcl-std/polygon)
|
* [`polygon`](/docs/kcl-std/polygon)
|
||||||
* [`profileStart`](/docs/kcl-std/profileStart)
|
* [`profileStart`](/docs/kcl-std/profileStart)
|
||||||
* [`profileStartX`](/docs/kcl-std/profileStartX)
|
* [`profileStartX`](/docs/kcl-std/profileStartX)
|
||||||
@ -94,7 +94,7 @@ layout: manual
|
|||||||
* [`intersect`](/docs/kcl-std/intersect)
|
* [`intersect`](/docs/kcl-std/intersect)
|
||||||
* [`patternCircular3d`](/docs/kcl-std/patternCircular3d)
|
* [`patternCircular3d`](/docs/kcl-std/patternCircular3d)
|
||||||
* [`patternLinear3d`](/docs/kcl-std/patternLinear3d)
|
* [`patternLinear3d`](/docs/kcl-std/patternLinear3d)
|
||||||
* [`patternTransform`](/docs/kcl-std/functions/std-solid-patternTransform)
|
* [`patternTransform`](/docs/kcl-std/patternTransform)
|
||||||
* [`shell`](/docs/kcl-std/functions/std-solid-shell)
|
* [`shell`](/docs/kcl-std/functions/std-solid-shell)
|
||||||
* [`subtract`](/docs/kcl-std/subtract)
|
* [`subtract`](/docs/kcl-std/subtract)
|
||||||
* [`union`](/docs/kcl-std/union)
|
* [`union`](/docs/kcl-std/union)
|
||||||
|
@ -43,11 +43,11 @@ a = 10
|
|||||||
b = 14
|
b = 14
|
||||||
startSketchOn(XZ)
|
startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> involuteCircular(startRadius = a, endRadius = b, angle = 60)
|
|> involuteCircular(startRadius = a, endRadius = b, angle = 60deg)
|
||||||
|> involuteCircular(
|
|> involuteCircular(
|
||||||
startRadius = a,
|
startRadius = a,
|
||||||
endRadius = b,
|
endRadius = b,
|
||||||
angle = 60,
|
angle = 60deg,
|
||||||
reverse = true,
|
reverse = true,
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
@ -30,7 +30,7 @@ This module contains functions for creating and manipulating sketches, and makin
|
|||||||
* [`line`](/docs/kcl-std/line)
|
* [`line`](/docs/kcl-std/line)
|
||||||
* [`loft`](/docs/kcl-std/loft)
|
* [`loft`](/docs/kcl-std/loft)
|
||||||
* [`patternCircular2d`](/docs/kcl-std/patternCircular2d)
|
* [`patternCircular2d`](/docs/kcl-std/patternCircular2d)
|
||||||
* [`patternTransform2d`](/docs/kcl-std/functions/std-sketch-patternTransform2d)
|
* [`patternTransform2d`](/docs/kcl-std/patternTransform2d)
|
||||||
* [`polygon`](/docs/kcl-std/polygon)
|
* [`polygon`](/docs/kcl-std/polygon)
|
||||||
* [`profileStart`](/docs/kcl-std/profileStart)
|
* [`profileStart`](/docs/kcl-std/profileStart)
|
||||||
* [`profileStartX`](/docs/kcl-std/profileStartX)
|
* [`profileStartX`](/docs/kcl-std/profileStartX)
|
||||||
|
@ -18,7 +18,7 @@ This module contains functions for modifying solids, e.g., by adding a fillet or
|
|||||||
* [`intersect`](/docs/kcl-std/intersect)
|
* [`intersect`](/docs/kcl-std/intersect)
|
||||||
* [`patternCircular3d`](/docs/kcl-std/patternCircular3d)
|
* [`patternCircular3d`](/docs/kcl-std/patternCircular3d)
|
||||||
* [`patternLinear3d`](/docs/kcl-std/patternLinear3d)
|
* [`patternLinear3d`](/docs/kcl-std/patternLinear3d)
|
||||||
* [`patternTransform`](/docs/kcl-std/functions/std-solid-patternTransform)
|
* [`patternTransform`](/docs/kcl-std/patternTransform)
|
||||||
* [`shell`](/docs/kcl-std/functions/std-solid-shell)
|
* [`shell`](/docs/kcl-std/functions/std-solid-shell)
|
||||||
* [`subtract`](/docs/kcl-std/subtract)
|
* [`subtract`](/docs/kcl-std/subtract)
|
||||||
* [`union`](/docs/kcl-std/union)
|
* [`union`](/docs/kcl-std/union)
|
||||||
|
@ -11,7 +11,7 @@ Contains frequently used constants, functions for interacting with the KittyCAD
|
|||||||
|
|
||||||
The standard library is organised into modules (listed below), but most things are always available in KCL programs.
|
The standard library is organised into modules (listed below), but most things are always available in KCL programs.
|
||||||
|
|
||||||
You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL guide](https://zoo.dev/docs/kcl-book/intro.html).
|
You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL guide]().
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ patternCircular2d(
|
|||||||
@sketchSet: [Sketch],
|
@sketchSet: [Sketch],
|
||||||
instances: number,
|
instances: number,
|
||||||
center: Point2d,
|
center: Point2d,
|
||||||
arcDegrees?: number,
|
arcDegrees: number,
|
||||||
rotateDuplicates?: bool,
|
rotateDuplicates: bool,
|
||||||
useOriginal?: bool,
|
useOriginal?: bool,
|
||||||
): [Sketch]
|
): [Sketch]
|
||||||
```
|
```
|
||||||
@ -27,8 +27,8 @@ patternCircular2d(
|
|||||||
| `sketchSet` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch(es) to pattern | Yes |
|
| `sketchSet` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch(es) to pattern | Yes |
|
||||||
| `instances` | [`number`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
|
| `instances` | [`number`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
|
||||||
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center about which to make the pattern. This is a 2D vector. | Yes |
|
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center about which to make the pattern. This is a 2D vector. | Yes |
|
||||||
| `arcDegrees` | [`number`](/docs/kcl-std/types/std-types-number) | The arc angle (in degrees) to place the repetitions. Must be greater than 0. Defaults to 360. | No |
|
| `arcDegrees` | [`number`](/docs/kcl-std/types/std-types-number) | The arc angle (in degrees) to place the repetitions. Must be greater than 0. | Yes |
|
||||||
| `rotateDuplicates` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether or not to rotate the duplicates as they are copied. Defaults to true. | No |
|
| `rotateDuplicates` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether or not to rotate the duplicates as they are copied. | Yes |
|
||||||
| `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
|
| `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
@ -48,7 +48,7 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> patternCircular2d(
|
|> patternCircular2d(
|
||||||
center = [0, 0],
|
center = [0, 0],
|
||||||
instances = 13,
|
instances = 13,
|
||||||
arcDegrees = 360,
|
arcDegrees = 360deg,
|
||||||
rotateDuplicates = true,
|
rotateDuplicates = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
---
|
---
|
||||||
title: "patternTransform2d"
|
title: "patternTransform2d"
|
||||||
subtitle: "Function in std::sketch"
|
subtitle: "Function in std::sketch"
|
||||||
excerpt: "Just like `patternTransform`, but works on 2D sketches not 3D solids."
|
excerpt: "Just like patternTransform, but works on 2D sketches not 3D solids."
|
||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
|
|
||||||
Just like `patternTransform`, but works on 2D sketches not 3D solids.
|
Just like patternTransform, but works on 2D sketches not 3D solids.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
patternTransform2d(
|
patternTransform2d(
|
||||||
@sketches: [Sketch; 1+],
|
@sketches: [Sketch],
|
||||||
instances: number(_),
|
instances: number,
|
||||||
transform: fn(number(_)): { },
|
transform: FunctionSource,
|
||||||
useOriginal?: boolean,
|
useOriginal?: bool,
|
||||||
): [Sketch; 1+]
|
): [Sketch]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -22,14 +22,14 @@ patternTransform2d(
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `sketches` | [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch) | The sketch(es) to duplicate. | Yes |
|
| `sketches` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | The sketch(es) to duplicate | Yes |
|
||||||
| `instances` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
|
| `instances` | [`number`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes |
|
||||||
| `transform` | [`fn(number(_)): { }`](/docs/kcl-std/types/std-types-fn) | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes |
|
| `transform` | `FunctionSource` | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes |
|
||||||
| `useOriginal` | `boolean` | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. | No |
|
| `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch)
|
[`[Sketch]`](/docs/kcl-std/types/std-types-Sketch)
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
@ -29,8 +29,8 @@ profileStart(@profile: Sketch): [number]
|
|||||||
```kcl
|
```kcl
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
|> startProfile(at = [5, 2])
|
|> startProfile(at = [5, 2])
|
||||||
|> angledLine(angle = 120, length = 50, tag = $seg01)
|
|> angledLine(angle = 120deg, length = 50, tag = $seg01)
|
||||||
|> angledLine(angle = segAng(seg01) + 120, length = 50)
|
|> angledLine(angle = segAng(seg01) + 120deg, length = 50)
|
||||||
|> line(end = profileStart(%))
|
|> line(end = profileStart(%))
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 20)
|
|> extrude(length = 20)
|
||||||
|
@ -49,9 +49,9 @@ If you want to apply the transform in global space, set `global` to `true`. The
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90deg, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|
|
||||||
// Create a hole for the pipe.
|
// Create a hole for the pipe.
|
||||||
@ -85,8 +85,8 @@ cube
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|
rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|
||||||
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 73.47, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 50.61)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
@ -96,7 +96,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
|
|||||||
sketch002 = startSketchOn(YZ)
|
sketch002 = startSketchOn(YZ)
|
||||||
sweepPath = startProfile(sketch002, at = [0, 0])
|
sweepPath = startProfile(sketch002, at = [0, 0])
|
||||||
|> yLine(length = 231.81)
|
|> yLine(length = 231.81)
|
||||||
|> tangentialArc(radius = 80, angle = -90)
|
|> tangentialArc(radius = 80, angle = -90deg)
|
||||||
|> xLine(length = 384.93)
|
|> xLine(length = 384.93)
|
||||||
|
|
||||||
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
|
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
|
||||||
|
@ -29,9 +29,9 @@ segLen(@tag: TagIdentifier): number
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 60, length = 10, tag = $thing)
|
|> angledLine(angle = 60deg, length = 10, tag = $thing)
|
||||||
|> tangentialArc(angle = -120, radius = 5)
|
|> tangentialArc(angle = -120deg, radius = 5)
|
||||||
|> angledLine(angle = -60, length = segLen(thing))
|
|> angledLine(angle = -60deg, length = segLen(thing))
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -146,7 +146,7 @@ exampleSketch = startSketchOn(XY)
|
|||||||
|> line(end = [-2, 0])
|
|> line(end = [-2, 0])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = revolve(exampleSketch, axis = Y, angle = 180)
|
example = revolve(exampleSketch, axis = Y, angle = 180deg)
|
||||||
|
|
||||||
exampleSketch002 = startSketchOn(example, face = END)
|
exampleSketch002 = startSketchOn(example, face = END)
|
||||||
|> startProfile(at = [4.5, -5])
|
|> startProfile(at = [4.5, -5])
|
||||||
@ -178,7 +178,7 @@ exampleSketch = startSketchOn(XY)
|
|||||||
example = revolve(
|
example = revolve(
|
||||||
exampleSketch,
|
exampleSketch,
|
||||||
axis = Y,
|
axis = Y,
|
||||||
angle = 180,
|
angle = 180deg,
|
||||||
tagEnd = $end01,
|
tagEnd = $end01,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
16248
docs/kcl-std/std.json
@ -41,7 +41,7 @@ When using radius and angle, draw a curved line segment along part of an imagina
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 45, length = 10)
|
|> angledLine(angle = 45deg, length = 10)
|
||||||
|> tangentialArc(end = [0, -10])
|
|> tangentialArc(end = [0, -10])
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> close()
|
|> close()
|
||||||
@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 10)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> tangentialArc(endAbsolute = [15, 15])
|
|> tangentialArc(endAbsolute = [15, 15])
|
||||||
|> line(end = [10, -15])
|
|> line(end = [10, -15])
|
||||||
|> close()
|
|> close()
|
||||||
@ -67,9 +67,9 @@ example = extrude(exampleSketch, length = 10)
|
|||||||
```kcl
|
```kcl
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 60, length = 10)
|
|> angledLine(angle = 60deg, length = 10)
|
||||||
|> tangentialArc(radius = 10, angle = -120)
|
|> tangentialArc(radius = 10, angle = -120deg)
|
||||||
|> angledLine(angle = -60, length = 10)
|
|> angledLine(angle = -60deg, length = 10)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 10)
|
example = extrude(exampleSketch, length = 10)
|
||||||
|
@ -45,9 +45,9 @@ Translate is really useful for sketches if you want to move a sketch and then ro
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90deg, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|
|
||||||
// Create a hole for the pipe.
|
// Create a hole for the pipe.
|
||||||
@ -86,8 +86,8 @@ cube
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|
rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|
||||||
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 73.47, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 50.61)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
@ -97,7 +97,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
|
|||||||
sketch002 = startSketchOn(YZ)
|
sketch002 = startSketchOn(YZ)
|
||||||
sweepPath = startProfile(sketch002, at = [0, 0])
|
sweepPath = startProfile(sketch002, at = [0, 0])
|
||||||
|> yLine(length = 231.81)
|
|> yLine(length = 231.81)
|
||||||
|> tangentialArc(radius = 80, angle = -90)
|
|> tangentialArc(radius = 80, angle = -90deg)
|
||||||
|> xLine(length = 384.93)
|
|> xLine(length = 384.93)
|
||||||
|
|
||||||
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
|
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
|
||||||
@ -156,7 +156,7 @@ profile001 = square()
|
|||||||
|
|
||||||
profile002 = square()
|
profile002 = square()
|
||||||
|> translate(z = 20)
|
|> translate(z = 20)
|
||||||
|> rotate(axis = [0, 0, 1.0], angle = 45)
|
|> rotate(axis = [0, 0, 1.0], angle = 45deg)
|
||||||
|
|
||||||
loft([profile001, profile002])
|
loft([profile001, profile002])
|
||||||
```
|
```
|
||||||
|
@ -15,9 +15,9 @@ way:
|
|||||||
```js
|
```js
|
||||||
startSketchOn(XZ)
|
startSketchOn(XZ)
|
||||||
|> startProfile(at = origin)
|
|> startProfile(at = origin)
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||||
length = 196.99,
|
length = 196.99,
|
||||||
tag = $rectangleSegmentB001,
|
tag = $rectangleSegmentB001,
|
||||||
)
|
)
|
||||||
@ -49,9 +49,9 @@ However if the code was written like this:
|
|||||||
fn rect(origin) {
|
fn rect(origin) {
|
||||||
return startSketchOn(XZ)
|
return startSketchOn(XZ)
|
||||||
|> startProfile(at = origin)
|
|> startProfile(at = origin)
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||||
length = 196.99,
|
length = 196.99,
|
||||||
tag = $rectangleSegmentB001)
|
tag = $rectangleSegmentB001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
@ -78,9 +78,9 @@ For example the following code works.
|
|||||||
fn rect(origin) {
|
fn rect(origin) {
|
||||||
return startSketchOn(XZ)
|
return startSketchOn(XZ)
|
||||||
|> startProfile(at = origin)
|
|> startProfile(at = origin)
|
||||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||||
length = 196.99
|
length = 196.99
|
||||||
tag = $rectangleSegmentB001,
|
tag = $rectangleSegmentB001,
|
||||||
)
|
)
|
||||||
|
@ -38,10 +38,10 @@ xLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> xLine(length = 15)
|
|> xLine(length = 15)
|
||||||
|> angledLine(angle = 80, length = 15)
|
|> angledLine(angle = 80deg, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> xLine(length = 10)
|
|> xLine(length = 10)
|
||||||
|> angledLine(angle = 120, length = 30)
|
|> angledLine(angle = 120deg, length = 30)
|
||||||
|> xLine(length = -15)
|
|> xLine(length = -15)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ yLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> yLine(length = 15)
|
|> yLine(length = 15)
|
||||||
|> angledLine(angle = 30, length = 15)
|
|> angledLine(angle = 30deg, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> yLine(length = -5)
|
|> yLine(length = -5)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -235,48 +235,6 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
.first()
|
.first()
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('KCL errors with functions show hints for the entire backtrace', async ({
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
scene,
|
|
||||||
cmdBar,
|
|
||||||
editor,
|
|
||||||
toolbar,
|
|
||||||
}) => {
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
const code = `fn check(@x) {
|
|
||||||
return assert(x, isGreaterThan = 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn middle(@x) {
|
|
||||||
return check(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
middle(1)
|
|
||||||
middle(0)
|
|
||||||
`
|
|
||||||
await test.step('Set the code with a KCL error', async () => {
|
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.replaceCode('', code)
|
|
||||||
})
|
|
||||||
// This shows all the diagnostics in a way that doesn't require the mouse
|
|
||||||
// pointer hovering over a coordinate, which would be brittle.
|
|
||||||
await test.step('Open CodeMirror diagnostics list', async () => {
|
|
||||||
// Ensure keyboard focus is in the editor.
|
|
||||||
await page.getByText('fn check(').click()
|
|
||||||
await page.keyboard.press('ControlOrMeta+Shift+M')
|
|
||||||
})
|
|
||||||
await expect(
|
|
||||||
page.getByText(`assert failed: Expected 0 to be greater than 0 but it wasn't
|
|
||||||
check()
|
|
||||||
middle()`)
|
|
||||||
).toBeVisible()
|
|
||||||
// There should be one hint inside middle() and one at the top level.
|
|
||||||
await expect(page.getByText('Part of the error backtrace')).toHaveCount(2)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test(
|
test(
|
||||||
|
@ -36,29 +36,27 @@ test.describe('Command bar tests', () => {
|
|||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
// Click the line of code for xLine.
|
// Click the line of code for xLine.
|
||||||
await page.getByText(`startProfile(at = [-10, -10])`).click()
|
await page.getByText(`close()`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
|
||||||
|
|
||||||
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
|
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'sketches',
|
||||||
currentArgValue: '5',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '1 profile',
|
Sketches: '',
|
||||||
Length: '',
|
Length: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'length',
|
highlightedHeaderArg: 'sketches',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '1 profile',
|
Sketches: '1 segment',
|
||||||
Length: '5',
|
Length: '5',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -288,7 +286,7 @@ test.describe('Command bar tests', () => {
|
|||||||
await cmdBar.cmdOptions.getByText('Extrude').click()
|
await cmdBar.cmdOptions.getByText('Extrude').click()
|
||||||
|
|
||||||
// Assert that we're on the selection step
|
// Assert that we're on the selection step
|
||||||
await expect(page.getByRole('button', { name: 'Profiles' })).toBeDisabled()
|
await expect(page.getByRole('button', { name: 'sketches' })).toBeDisabled()
|
||||||
// Select a face
|
// Select a face
|
||||||
await page.mouse.move(700, 200)
|
await page.mouse.move(700, 200)
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
@ -401,6 +399,7 @@ test.describe('Command bar tests', () => {
|
|||||||
sortBy: 'last-modified-desc',
|
sortBy: 'last-modified-desc',
|
||||||
})
|
})
|
||||||
await page.goto(page.url() + targetURL)
|
await page.goto(page.url() + targetURL)
|
||||||
|
expect(page.url()).toContain(targetURL)
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Submit the command`, async () => {
|
await test.step(`Submit the command`, async () => {
|
||||||
@ -411,7 +410,7 @@ test.describe('Command bar tests', () => {
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Method: '',
|
Method: '',
|
||||||
Name: 'main.kcl',
|
Name: 'test',
|
||||||
Code: '1 line',
|
Code: '1 line',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'method',
|
highlightedHeaderArg: 'method',
|
||||||
@ -422,7 +421,7 @@ test.describe('Command bar tests', () => {
|
|||||||
commandName: 'Import file from URL',
|
commandName: 'Import file from URL',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Method: 'New project',
|
Method: 'New project',
|
||||||
Name: 'main.kcl',
|
Name: 'test',
|
||||||
Code: '1 line',
|
Code: '1 line',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -464,6 +463,7 @@ test.describe('Command bar tests', () => {
|
|||||||
sortBy: 'last-modified-desc',
|
sortBy: 'last-modified-desc',
|
||||||
})
|
})
|
||||||
await page.goto(page.url() + targetURL)
|
await page.goto(page.url() + targetURL)
|
||||||
|
expect(page.url()).toContain(targetURL)
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Submit the command`, async () => {
|
await test.step(`Submit the command`, async () => {
|
||||||
@ -474,7 +474,7 @@ test.describe('Command bar tests', () => {
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Method: '',
|
Method: '',
|
||||||
Name: 'main.kcl',
|
Name: 'test',
|
||||||
Code: '1 line',
|
Code: '1 line',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'method',
|
highlightedHeaderArg: 'method',
|
||||||
@ -487,7 +487,7 @@ test.describe('Command bar tests', () => {
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Method: 'Existing project',
|
Method: 'Existing project',
|
||||||
Name: 'main.kcl',
|
Name: 'test',
|
||||||
ProjectName: '',
|
ProjectName: '',
|
||||||
Code: '1 line',
|
Code: '1 line',
|
||||||
},
|
},
|
||||||
@ -500,7 +500,7 @@ test.describe('Command bar tests', () => {
|
|||||||
headerArguments: {
|
headerArguments: {
|
||||||
Method: 'Existing project',
|
Method: 'Existing project',
|
||||||
ProjectName: 'testProjectDir',
|
ProjectName: 'testProjectDir',
|
||||||
Name: 'main.kcl',
|
Name: 'test',
|
||||||
Code: '1 line',
|
Code: '1 line',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -510,7 +510,7 @@ test.describe('Command bar tests', () => {
|
|||||||
await test.step(`Ensure we created the project and are in the modeling scene`, async () => {
|
await test.step(`Ensure we created the project and are in the modeling scene`, async () => {
|
||||||
await editor.expectEditor.toContain('extrusionDistance = 12')
|
await editor.expectEditor.toContain('extrusionDistance = 12')
|
||||||
await toolbar.openPane('files')
|
await toolbar.openPane('files')
|
||||||
await toolbar.expectFileTreeState(['main-1.kcl', 'main.kcl'])
|
await toolbar.expectFileTreeState(['main.kcl', 'test.kcl'])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -661,56 +661,4 @@ c = 3 + a`
|
|||||||
`a = 5b = a * amyParameter001 = ${newValue}c = 3 + a`
|
`a = 5b = a * amyParameter001 = ${newValue}c = 3 + a`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Command palette can be opened via query parameter', async ({
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
await page.goto(`${page.url()}/?cmd=app.theme&groupId=settings`)
|
|
||||||
await homePage.expectState({
|
|
||||||
projectCards: [],
|
|
||||||
sortBy: 'last-modified-desc',
|
|
||||||
})
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
commandName: 'Settings · app · theme',
|
|
||||||
currentArgKey: 'value',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Level: 'user',
|
|
||||||
Value: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'value',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Text-to-CAD command can be closed with escape while in prompt', async ({
|
|
||||||
page,
|
|
||||||
homePage,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
await homePage.expectState({
|
|
||||||
projectCards: [],
|
|
||||||
sortBy: 'last-modified-desc',
|
|
||||||
})
|
|
||||||
await homePage.textToCadBtn.click()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'arguments',
|
|
||||||
commandName: 'Text-to-CAD Create',
|
|
||||||
currentArgKey: 'prompt',
|
|
||||||
currentArgValue: '',
|
|
||||||
headerArguments: {
|
|
||||||
Method: 'New project',
|
|
||||||
NewProjectName: 'untitled',
|
|
||||||
Prompt: '',
|
|
||||||
},
|
|
||||||
highlightedHeaderArg: 'prompt',
|
|
||||||
})
|
|
||||||
await page.keyboard.press('Escape')
|
|
||||||
await cmdBar.toBeClosed()
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'commandBarClosed',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
@ -65,9 +65,7 @@ test(
|
|||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
await expect(engineErrorToastMessage).not.toBeVisible()
|
||||||
|
|
||||||
const successToastMessage = page.getByText(`Exported successfully`)
|
const successToastMessage = page.getByText(`Exported successfully`)
|
||||||
await page.waitForTimeout(1_000)
|
await expect(successToastMessage).toBeVisible()
|
||||||
const count = await successToastMessage.count()
|
|
||||||
await expect(count).toBeGreaterThanOrEqual(1)
|
|
||||||
|
|
||||||
// Check for the exported file
|
// Check for the exported file
|
||||||
const firstFileFullPath = path.resolve(
|
const firstFileFullPath = path.resolve(
|
||||||
@ -136,9 +134,7 @@ test(
|
|||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
await expect(engineErrorToastMessage).not.toBeVisible()
|
||||||
|
|
||||||
const successToastMessage = page.getByText(`Exported successfully`)
|
const successToastMessage = page.getByText(`Exported successfully`)
|
||||||
await page.waitForTimeout(1_000)
|
await expect(successToastMessage).toBeVisible()
|
||||||
const count = await successToastMessage.count()
|
|
||||||
await expect(count).toBeGreaterThanOrEqual(1)
|
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
await expect(exportingToastMessage).not.toBeVisible()
|
||||||
|
|
||||||
// Check for the exported file=
|
// Check for the exported file=
|
||||||
|
@ -912,7 +912,7 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
|
|||||||
|> close()
|
|> close()
|
||||||
|> revolve(
|
|> revolve(
|
||||||
axis = revolveAxis,
|
axis = revolveAxis,
|
||||||
angle = 90
|
angle = 90deg
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
@ -1131,15 +1131,14 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.getByText('startProfile(at = [4.61, -14.01])').click()
|
await page.getByText('startProfile(at = [4.61, -14.01])').click()
|
||||||
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'length',
|
||||||
currentArgValue: '5',
|
currentArgValue: '5',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '1 profile',
|
Sketches: '1 face',
|
||||||
Length: '',
|
Length: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'length',
|
highlightedHeaderArg: 'length',
|
||||||
@ -1149,7 +1148,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '1 profile',
|
Sketches: '1 face',
|
||||||
Length: '5',
|
Length: '5',
|
||||||
},
|
},
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
@ -1355,9 +1354,7 @@ sketch001 = startSketchOn(XZ)
|
|||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
const projectLink = page.getByRole('link', { name: 'cube' })
|
const projectLink = page.getByRole('link', { name: 'cube' })
|
||||||
const gizmo = page.locator('[aria-label*=gizmo]')
|
const gizmo = page.locator('[aria-label*=gizmo]')
|
||||||
const resetCameraButton = page.getByRole('button', {
|
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
||||||
name: 'Reset view',
|
|
||||||
})
|
|
||||||
const locationToHaveColor = async (
|
const locationToHaveColor = async (
|
||||||
position: { x: number; y: number },
|
position: { x: number; y: number },
|
||||||
color: [number, number, number]
|
color: [number, number, number]
|
||||||
|
@ -38,7 +38,7 @@ extrude001 = extrude(sketch002, length = 10)
|
|||||||
|
|
||||||
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn(XZ)
|
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 0, length = 4, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|
@ -238,26 +238,6 @@ test.describe('when using the file tree to', () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
test(
|
|
||||||
`create new folders and that doesn't trigger a navigation`,
|
|
||||||
{ tag: ['@electron', '@macos', '@windows'] },
|
|
||||||
async ({ page, homePage, scene, toolbar, cmdBar }) => {
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
await toolbar.openPane('files')
|
|
||||||
const { createNewFolder } = await getUtils(page, test)
|
|
||||||
|
|
||||||
await createNewFolder('folder')
|
|
||||||
|
|
||||||
await createNewFolder('folder.kcl')
|
|
||||||
|
|
||||||
await test.step(`Postcondition: folders are created and we didn't navigate`, async () => {
|
|
||||||
await toolbar.expectFileTreeState(['folder', 'folder.kcl', 'main.kcl'])
|
|
||||||
await expect(toolbar.fileName).toHaveText('main.kcl')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'deleting all files recreates a default main.kcl with no code',
|
'deleting all files recreates a default main.kcl with no code',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
|
@ -105,19 +105,14 @@ export class CmdBarFixture {
|
|||||||
expectState = async (expected: CmdBarSerialised) => {
|
expectState = async (expected: CmdBarSerialised) => {
|
||||||
return expect.poll(() => this._serialiseCmdBar()).toEqual(expected)
|
return expect.poll(() => this._serialiseCmdBar()).toEqual(expected)
|
||||||
}
|
}
|
||||||
/**
|
/** The method will use buttons OR press enter randomly to progress the cmdbar,
|
||||||
* This method is used to progress the command bar to the next step, defaulting to clicking the next button.
|
* this could have unexpected results depending on what's focused
|
||||||
* Optionally, with the `shouldUseKeyboard` parameter, it will hit `Enter` to progress.
|
*
|
||||||
* * TODO: This method assumes the user has a valid input to the current stage,
|
* TODO: This method assumes the user has a valid input to the current stage,
|
||||||
* and assumes we are past the `pickCommand` step.
|
* and assumes we are past the `pickCommand` step.
|
||||||
*/
|
*/
|
||||||
progressCmdBar = async (shouldUseKeyboard = false) => {
|
progressCmdBar = async (shouldFuzzProgressMethod = true) => {
|
||||||
await this.page.waitForTimeout(2000)
|
await this.page.waitForTimeout(2000)
|
||||||
if (shouldUseKeyboard) {
|
|
||||||
await this.page.keyboard.press('Enter')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const arrowButton = this.page.getByRole('button', {
|
const arrowButton = this.page.getByRole('button', {
|
||||||
name: 'arrow right Continue',
|
name: 'arrow right Continue',
|
||||||
})
|
})
|
||||||
@ -151,7 +146,9 @@ export class CmdBarFixture {
|
|||||||
await this.cmdBarOpenBtn.click()
|
await this.cmdBarOpenBtn.click()
|
||||||
await expect(this.page.getByPlaceholder('Search commands')).toBeVisible()
|
await expect(this.page.getByPlaceholder('Search commands')).toBeVisible()
|
||||||
if (selectCmd === 'promptToEdit') {
|
if (selectCmd === 'promptToEdit') {
|
||||||
const promptEditCommand = this.selectOption({ name: 'Text-to-CAD Edit' })
|
const promptEditCommand = this.page.getByText(
|
||||||
|
'Use Zoo AI to edit your parts and code.'
|
||||||
|
)
|
||||||
await expect(promptEditCommand.first()).toBeVisible()
|
await expect(promptEditCommand.first()).toBeVisible()
|
||||||
await promptEditCommand.first().scrollIntoViewIfNeeded()
|
await promptEditCommand.first().scrollIntoViewIfNeeded()
|
||||||
await promptEditCommand.first().click()
|
await promptEditCommand.first().click()
|
||||||
@ -313,11 +310,6 @@ export class CmdBarFixture {
|
|||||||
await expect(this.cmdBarElement).toBeVisible({ timeout: 10_000 })
|
await expect(this.cmdBarElement).toBeVisible({ timeout: 10_000 })
|
||||||
}
|
}
|
||||||
|
|
||||||
async toBeClosed() {
|
|
||||||
// Check that the command bar is closed
|
|
||||||
await expect(this.cmdBarElement).not.toBeVisible({ timeout: 10_000 })
|
|
||||||
}
|
|
||||||
|
|
||||||
async expectArgValue(value: string) {
|
async expectArgValue(value: string) {
|
||||||
// Check the placeholder project name exists
|
// Check the placeholder project name exists
|
||||||
const actualArgument = await this.cmdBarElement
|
const actualArgument = await this.cmdBarElement
|
||||||
|
@ -26,7 +26,6 @@ export class HomePageFixture {
|
|||||||
sortByNameBtn!: Locator
|
sortByNameBtn!: Locator
|
||||||
appHeader!: Locator
|
appHeader!: Locator
|
||||||
tutorialBtn!: Locator
|
tutorialBtn!: Locator
|
||||||
textToCadBtn!: Locator
|
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page
|
this.page = page
|
||||||
@ -48,7 +47,6 @@ export class HomePageFixture {
|
|||||||
this.sortByNameBtn = this.page.getByTestId('home-sort-by-name')
|
this.sortByNameBtn = this.page.getByTestId('home-sort-by-name')
|
||||||
this.appHeader = this.page.getByTestId('app-header')
|
this.appHeader = this.page.getByTestId('app-header')
|
||||||
this.tutorialBtn = this.page.getByTestId('home-tutorial-button')
|
this.tutorialBtn = this.page.getByTestId('home-tutorial-button')
|
||||||
this.textToCadBtn = this.page.getByTestId('home-text-to-cad')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _serialiseSortBy = async (): Promise<
|
private _serialiseSortBy = async (): Promise<
|
||||||
@ -123,13 +121,11 @@ export class HomePageFixture {
|
|||||||
await projectCard.click()
|
await projectCard.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the project name in case caller has used the default and needs it */
|
goToModelingScene = async (name: string = 'testDefault') => {
|
||||||
goToModelingScene = async (name = 'testDefault') => {
|
|
||||||
// On web this is a no-op. There is no project view.
|
// On web this is a no-op. There is no project view.
|
||||||
if (process.env.PLATFORM === 'web') return ''
|
if (process.env.PLATFORM === 'web') return
|
||||||
|
|
||||||
await this.createAndGoToProject(name)
|
await this.createAndGoToProject(name)
|
||||||
return name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isNativeFileMenuCreated = async () => {
|
isNativeFileMenuCreated = async () => {
|
||||||
|
@ -16,7 +16,7 @@ test.describe('Import UI tests', () => {
|
|||||||
path.join(projectDir, 'toBeImported.kcl'),
|
path.join(projectDir, 'toBeImported.kcl'),
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfile(sketch001, at = [281.54, 305.81])
|
profile001 = startProfile(sketch001, at = [281.54, 305.81])
|
||||||
|> angledLine(angle = 0, length = 123.43, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 123.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 85.99)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 85.99)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -33,7 +33,7 @@ importedCube
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfile(sketch001, at = [-134.53, -56.17])
|
profile001 = startProfile(sketch001, at = [-134.53, -56.17])
|
||||||
|> angledLine(angle = 0, length = 79.05, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 79.05, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 76.28)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 76.28)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg01)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg01)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
|
@ -61,7 +61,6 @@ class MyAPIReporter implements Reporter {
|
|||||||
const payload = {
|
const payload = {
|
||||||
// Required information
|
// Required information
|
||||||
project: 'https://github.com/KittyCAD/modeling-app',
|
project: 'https://github.com/KittyCAD/modeling-app',
|
||||||
suite: process.env.CI_SUITE || 'e2e',
|
|
||||||
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
|
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
|
||||||
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
|
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
|
||||||
test: test.titlePath().slice(2).join(' › '),
|
test: test.titlePath().slice(2).join(' › '),
|
||||||
|
@ -197,6 +197,18 @@ test.describe(
|
|||||||
await clickElectronNativeMenuById(tronApp, 'File.Export current part')
|
await clickElectronNativeMenuById(tronApp, 'File.Export current part')
|
||||||
await cmdBar.expectCommandName('Export')
|
await cmdBar.expectCommandName('Export')
|
||||||
})
|
})
|
||||||
|
await test.step('Modeling.File.Share part via Zoo link', async () => {
|
||||||
|
await page.waitForTimeout(250)
|
||||||
|
await clickElectronNativeMenuById(
|
||||||
|
tronApp,
|
||||||
|
'File.Share part via Zoo link'
|
||||||
|
)
|
||||||
|
const textToCheck =
|
||||||
|
'Link copied to clipboard. Anyone who clicks this link will get a copy of this file. Share carefully!'
|
||||||
|
// Check if text appears anywhere in the page
|
||||||
|
const isTextVisible = page.getByText(textToCheck)
|
||||||
|
await expect(isTextVisible).toBeVisible({ timeout: 10000 })
|
||||||
|
})
|
||||||
await test.step('Modeling.File.Preferences.Project settings', async () => {
|
await test.step('Modeling.File.Preferences.Project settings', async () => {
|
||||||
await page.waitForTimeout(250)
|
await page.waitForTimeout(250)
|
||||||
await clickElectronNativeMenuById(
|
await clickElectronNativeMenuById(
|
||||||
@ -252,7 +264,7 @@ test.describe(
|
|||||||
tronApp,
|
tronApp,
|
||||||
'Edit.Modify with Zoo Text-To-CAD'
|
'Edit.Modify with Zoo Text-To-CAD'
|
||||||
)
|
)
|
||||||
await cmdBar.expectCommandName('Text-to-CAD Edit')
|
await cmdBar.expectCommandName('Prompt-to-edit')
|
||||||
})
|
})
|
||||||
await test.step('Modeling.Edit.Edit parameter', async () => {
|
await test.step('Modeling.Edit.Edit parameter', async () => {
|
||||||
await page.waitForTimeout(250)
|
await page.waitForTimeout(250)
|
||||||
@ -518,7 +530,7 @@ test.describe(
|
|||||||
'Design.Create with Zoo Text-To-CAD'
|
'Design.Create with Zoo Text-To-CAD'
|
||||||
)
|
)
|
||||||
await cmdBar.toBeOpened()
|
await cmdBar.toBeOpened()
|
||||||
await cmdBar.expectCommandName('Text-to-CAD Create')
|
await cmdBar.expectCommandName('Text to CAD')
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Modeling.Design.Modify with Zoo Text-To-CAD', async () => {
|
await test.step('Modeling.Design.Modify with Zoo Text-To-CAD', async () => {
|
||||||
@ -528,7 +540,7 @@ test.describe(
|
|||||||
'Design.Modify with Zoo Text-To-CAD'
|
'Design.Modify with Zoo Text-To-CAD'
|
||||||
)
|
)
|
||||||
await cmdBar.toBeOpened()
|
await cmdBar.toBeOpened()
|
||||||
await cmdBar.expectCommandName('Text-to-CAD Edit')
|
await cmdBar.expectCommandName('Prompt-to-edit')
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Modeling.Help.KCL code samples', async () => {
|
await test.step('Modeling.Help.KCL code samples', async () => {
|
||||||
|
@ -6,6 +6,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
homePage,
|
homePage,
|
||||||
toolbar,
|
toolbar,
|
||||||
editor,
|
editor,
|
||||||
|
scene,
|
||||||
tronApp,
|
tronApp,
|
||||||
}) => {
|
}) => {
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
@ -61,6 +62,7 @@ test.describe('Onboarding tests', () => {
|
|||||||
await editor.expectEditor.toContain('@settings(defaultLengthUnit = in)', {
|
await editor.expectEditor.toContain('@settings(defaultLengthUnit = in)', {
|
||||||
shouldNormalise: true,
|
shouldNormalise: true,
|
||||||
})
|
})
|
||||||
|
await scene.connectionEstablished()
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Go home and verify we still see the tutorial button, then begin it.', async () => {
|
await test.step('Go home and verify we still see the tutorial button, then begin it.', async () => {
|
||||||
@ -130,7 +132,9 @@ test.describe('Onboarding tests', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Dismiss the onboarding', async () => {
|
await test.step('Dismiss the onboarding', async () => {
|
||||||
|
await postDismissToast.waitFor({ state: 'hidden' })
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
|
await expect(postDismissToast).toBeVisible()
|
||||||
await expect(page.getByTestId('onboarding-content')).not.toBeVisible()
|
await expect(page.getByTestId('onboarding-content')).not.toBeVisible()
|
||||||
await expect.poll(() => page.url()).not.toContain('/onboarding')
|
await expect.poll(() => page.url()).not.toContain('/onboarding')
|
||||||
})
|
})
|
||||||
@ -158,10 +162,13 @@ test.describe('Onboarding tests', () => {
|
|||||||
await test.step('Gets to the onboarding start', async () => {
|
await test.step('Gets to the onboarding start', async () => {
|
||||||
await expect(toolbar.projectName).toContainText('tutorial-project')
|
await expect(toolbar.projectName).toContainText('tutorial-project')
|
||||||
await expect(tutorialWelcomeHeading).toBeVisible()
|
await expect(tutorialWelcomeHeading).toBeVisible()
|
||||||
|
await scene.connectionEstablished()
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Dismiss the onboarding', async () => {
|
await test.step('Dismiss the onboarding', async () => {
|
||||||
|
await postDismissToast.waitFor({ state: 'hidden' })
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
|
await expect(postDismissToast).toBeVisible()
|
||||||
await expect(page.getByTestId('onboarding-content')).not.toBeVisible()
|
await expect(page.getByTestId('onboarding-content')).not.toBeVisible()
|
||||||
await expect.poll(() => page.url()).not.toContain('/onboarding')
|
await expect.poll(() => page.url()).not.toContain('/onboarding')
|
||||||
})
|
})
|
||||||
|
@ -74,11 +74,20 @@ test.describe('Point-and-click tests', () => {
|
|||||||
|
|
||||||
await test.step('do extrude flow and check extrude code is added to editor', async () => {
|
await test.step('do extrude flow and check extrude code is added to editor', async () => {
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'sketches',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: { Sketches: '', Length: '' },
|
||||||
|
highlightedHeaderArg: 'sketches',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'length',
|
||||||
currentArgValue: '5',
|
currentArgValue: '5',
|
||||||
headerArguments: { Profiles: '1 profile', Length: '' },
|
headerArguments: { Sketches: '1 face', Length: '' },
|
||||||
highlightedHeaderArg: 'length',
|
highlightedHeaderArg: 'length',
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
})
|
})
|
||||||
@ -89,7 +98,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: { Profiles: '1 profile', Length: '5' },
|
headerArguments: { Sketches: '1 face', Length: '5' },
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -356,7 +365,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
clickCoords: { x: 677, y: 87 },
|
clickCoords: { x: 677, y: 87 },
|
||||||
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
||||||
cameraTarget: { x: 8300, y: 1100, z: 4800 },
|
cameraTarget: { x: 8300, y: 1100, z: 4800 },
|
||||||
beforeChamferSnippet: `angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)chamfer(
|
beforeChamferSnippet: `angledLine(angle = 0deg, length = 268.43, tag = $rectangleSegmentA001)chamfer(
|
||||||
length = 30,
|
length = 30,
|
||||||
tags = [
|
tags = [
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
@ -398,7 +407,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [75.8, 317.2]) // [$startCapTag, $EndCapTag]
|
|> startProfile(at = [75.8, 317.2]) // [$startCapTag, $EndCapTag]
|
||||||
|> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 268.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
@ -410,28 +419,28 @@ extrude001 = extrude(sketch001, length = 100)
|
|||||||
|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06)
|
|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg03)
|
sketch002 = startSketchOn(extrude001, face = seg03)
|
||||||
profile001 = startProfile(sketch002, at = [205.96, 254.59])
|
profile001 = startProfile(sketch002, at = [205.96, 254.59])
|
||||||
|> angledLine(angle = 0, length = 11.39, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 0deg, length = 11.39, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch003 = startSketchOn(extrude001, face = seg04)
|
sketch003 = startSketchOn(extrude001, face = seg04)
|
||||||
profile002 = startProfile(sketch003, at = [-209.64, 255.28])
|
profile002 = startProfile(sketch003, at = [-209.64, 255.28])
|
||||||
|> angledLine(angle = 0, length = 11.56, tag = $rectangleSegmentA003)
|
|> angledLine(angle = 0deg, length = 11.56, tag = $rectangleSegmentA003)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA003) - 90, length = 106.84)
|
|> angledLine(angle = segAng(rectangleSegmentA003) - 90, length = 106.84)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch004 = startSketchOn(extrude001, face = seg05)
|
sketch004 = startSketchOn(extrude001, face = seg05)
|
||||||
profile003 = startProfile(sketch004, at = [82.57, 322.96])
|
profile003 = startProfile(sketch004, at = [82.57, 322.96])
|
||||||
|> angledLine(angle = 0, length = 11.16, tag = $rectangleSegmentA004)
|
|> angledLine(angle = 0deg, length = 11.16, tag = $rectangleSegmentA004)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA004) - 90, length = 103.07)
|
|> angledLine(angle = segAng(rectangleSegmentA004) - 90, length = 103.07)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch005 = startSketchOn(extrude001, face = seg06)
|
sketch005 = startSketchOn(extrude001, face = seg06)
|
||||||
profile004 = startProfile(sketch005, at = [-23.43, 19.69])
|
profile004 = startProfile(sketch005, at = [-23.43, 19.69])
|
||||||
|> angledLine(angle = 0, length = 9.1, tag = $rectangleSegmentA005)
|
|> angledLine(angle = 0deg, length = 9.1, tag = $rectangleSegmentA005)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA005) - 90, length = 84.07)
|
|> angledLine(angle = segAng(rectangleSegmentA005) - 90, length = 84.07)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA005), length = -segLen(rectangleSegmentA005))
|
|> angledLine(angle = segAng(rectangleSegmentA005), length = -segLen(rectangleSegmentA005))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -495,7 +504,7 @@ profile004 = startProfile(sketch005, at = [-23.43, 19.69])
|
|||||||
`@settings(defaultLengthUnit = in)
|
`@settings(defaultLengthUnit = in)
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [75.8, 317.2])
|
|> startProfile(at = [75.8, 317.2])
|
||||||
|> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 268.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
@ -517,7 +526,7 @@ chamf = chamfer(
|
|||||||
)
|
)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg03)
|
sketch002 = startSketchOn(extrude001, face = seg03)
|
||||||
profile001 = startProfile(sketch002, at = [205.96, 254.59])
|
profile001 = startProfile(sketch002, at = [205.96, 254.59])
|
||||||
|> angledLine(angle = 0, length = 11.39, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 0deg, length = 11.39, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -1625,15 +1634,15 @@ sketch002 = startSketchOn(plane001)
|
|||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'sketches',
|
currentArgKey: 'sketches',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: { Profiles: '' },
|
headerArguments: { Sketches: '' },
|
||||||
highlightedHeaderArg: 'Profiles',
|
highlightedHeaderArg: 'sketches',
|
||||||
commandName: 'Loft',
|
commandName: 'Loft',
|
||||||
})
|
})
|
||||||
await selectSketches()
|
await selectSketches()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: { Profiles: '2 profiles' },
|
headerArguments: { Sketches: '2 faces' },
|
||||||
commandName: 'Loft',
|
commandName: 'Loft',
|
||||||
})
|
})
|
||||||
await cmdBar.submit()
|
await cmdBar.submit()
|
||||||
@ -1645,9 +1654,18 @@ sketch002 = startSketchOn(plane001)
|
|||||||
|
|
||||||
await test.step(`Go through the command bar flow with preselected sketches`, async () => {
|
await test.step(`Go through the command bar flow with preselected sketches`, async () => {
|
||||||
await toolbar.loftButton.click()
|
await toolbar.loftButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'sketches',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: { Sketches: '' },
|
||||||
|
highlightedHeaderArg: 'sketches',
|
||||||
|
commandName: 'Loft',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: { Profiles: '2 profiles' },
|
headerArguments: { Sketches: '2 faces' },
|
||||||
commandName: 'Loft',
|
commandName: 'Loft',
|
||||||
})
|
})
|
||||||
await cmdBar.submit()
|
await cmdBar.submit()
|
||||||
@ -1758,7 +1776,7 @@ sketch002 = startSketchOn(XZ)
|
|||||||
initialCode: `@settings(defaultLengthUnit = in)
|
initialCode: `@settings(defaultLengthUnit = in)
|
||||||
sketch001 = startSketchOn(YZ)
|
sketch001 = startSketchOn(YZ)
|
||||||
profile001 = startProfile(sketch001, at = [-400, -400])
|
profile001 = startProfile(sketch001, at = [-400, -400])
|
||||||
|> angledLine(angle = 0, length = 800, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 800, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = 800)
|
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = 800)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -1812,10 +1830,10 @@ sketch002 = startSketchOn(XZ)
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
Profiles: '',
|
Sketches: '',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'Profiles',
|
highlightedHeaderArg: 'sketches',
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
})
|
})
|
||||||
await clickOnSketch1()
|
await clickOnSketch1()
|
||||||
@ -1826,7 +1844,7 @@ sketch002 = startSketchOn(XZ)
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
Profiles: '1 profile',
|
Sketches: '1 face',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'path',
|
highlightedHeaderArg: 'path',
|
||||||
@ -1839,7 +1857,7 @@ sketch002 = startSketchOn(XZ)
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
Profiles: '1 profile',
|
Sketches: '1 face',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'path',
|
highlightedHeaderArg: 'path',
|
||||||
@ -1849,17 +1867,13 @@ sketch002 = startSketchOn(XZ)
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '1 profile',
|
Sketches: '1 face',
|
||||||
Path: '1 segment',
|
Path: '1 segment',
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
},
|
},
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
})
|
})
|
||||||
// Confirm we can submit from the review step with just `Enter`
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar(true)
|
|
||||||
await cmdBar.expectState({
|
|
||||||
stage: 'commandBarClosed',
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
@ -1954,10 +1968,10 @@ profile001 = ${circleCode}`
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
Profiles: '',
|
Sketches: '',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'Profiles',
|
highlightedHeaderArg: 'sketches',
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
})
|
})
|
||||||
await editor.scrollToText(circleCode)
|
await editor.scrollToText(circleCode)
|
||||||
@ -1969,7 +1983,7 @@ profile001 = ${circleCode}`
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
Profiles: '1 profile',
|
Sketches: '1 face',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'path',
|
highlightedHeaderArg: 'path',
|
||||||
@ -1983,7 +1997,7 @@ profile001 = ${circleCode}`
|
|||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
Profiles: '1 profile',
|
Sketches: '1 face',
|
||||||
Path: '',
|
Path: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'path',
|
highlightedHeaderArg: 'path',
|
||||||
@ -1993,13 +2007,13 @@ profile001 = ${circleCode}`
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '1 profile',
|
Sketches: '1 face',
|
||||||
Path: '1 helix',
|
Path: '1 helix',
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
},
|
},
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar(true)
|
await cmdBar.progressCmdBar()
|
||||||
await editor.expectEditor.toContain(sweepDeclaration)
|
await editor.expectEditor.toContain(sweepDeclaration)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -2092,6 +2106,18 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
await test.step(`Apply fillet to the preselected edge`, async () => {
|
await test.step(`Apply fillet to the preselected edge`, async () => {
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await toolbar.filletButton.click()
|
await toolbar.filletButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Fillet',
|
||||||
|
highlightedHeaderArg: 'selection',
|
||||||
|
currentArgKey: 'selection',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Selection: '',
|
||||||
|
Radius: '',
|
||||||
|
},
|
||||||
|
stage: 'arguments',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Fillet',
|
commandName: 'Fillet',
|
||||||
highlightedHeaderArg: 'radius',
|
highlightedHeaderArg: 'radius',
|
||||||
@ -2621,6 +2647,18 @@ extrude001 = extrude(profile001, length = 5)
|
|||||||
await test.step(`Apply fillet`, async () => {
|
await test.step(`Apply fillet`, async () => {
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await toolbar.filletButton.click()
|
await toolbar.filletButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Fillet',
|
||||||
|
highlightedHeaderArg: 'selection',
|
||||||
|
currentArgKey: 'selection',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Selection: '',
|
||||||
|
Radius: '',
|
||||||
|
},
|
||||||
|
stage: 'arguments',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Fillet',
|
commandName: 'Fillet',
|
||||||
highlightedHeaderArg: 'radius',
|
highlightedHeaderArg: 'radius',
|
||||||
@ -2726,6 +2764,19 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
await test.step(`Apply chamfer to the preselected edge`, async () => {
|
await test.step(`Apply chamfer to the preselected edge`, async () => {
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await toolbar.chamferButton.click()
|
await toolbar.chamferButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
commandName: 'Chamfer',
|
||||||
|
highlightedHeaderArg: 'selection',
|
||||||
|
currentArgKey: 'selection',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Selection: '',
|
||||||
|
Length: '',
|
||||||
|
},
|
||||||
|
stage: 'arguments',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Chamfer',
|
commandName: 'Chamfer',
|
||||||
highlightedHeaderArg: 'length',
|
highlightedHeaderArg: 'length',
|
||||||
@ -3209,6 +3260,8 @@ extrude001 = extrude(sketch001, length = 30)
|
|||||||
await test.step(`Go through the command bar flow with a preselected face (cap)`, async () => {
|
await test.step(`Go through the command bar flow with a preselected face (cap)`, async () => {
|
||||||
await toolbar.shellButton.click()
|
await toolbar.shellButton.click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(500)
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
@ -3603,7 +3656,7 @@ profile001 = startProfile(sketch001, at = [-20, 20])
|
|||||||
const initialCode = `
|
const initialCode = `
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-100.0, 100.0])
|
|> startProfile(at = [-100.0, 100.0])
|
||||||
|> angledLine(angle = 0, length = 200.0, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 200.0, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 200, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 200, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle=segAng(rectangleSegmentA001),
|
angle=segAng(rectangleSegmentA001),
|
||||||
@ -3615,7 +3668,7 @@ tag=$rectangleSegmentC001,
|
|||||||
extrude001 = extrude(sketch001, length = 200)
|
extrude001 = extrude(sketch001, length = 200)
|
||||||
sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
||||||
|> startProfile(at = [-66.77, 84.81])
|
|> startProfile(at = [-66.77, 84.81])
|
||||||
|> angledLine(angle = 180, length = 27.08, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 180deg, length = 27.08, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle=segAng(rectangleSegmentA002) - 90,
|
angle=segAng(rectangleSegmentA002) - 90,
|
||||||
length=27.8,
|
length=27.8,
|
||||||
@ -3638,19 +3691,18 @@ tag=$rectangleSegmentC002,
|
|||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// select line of code
|
// select line of code
|
||||||
const codeToSelection = `startProfile(at = [-66.77, 84.81])`
|
const codeToSelection = `segAng(rectangleSegmentA002) - 90,`
|
||||||
// revolve
|
// revolve
|
||||||
await editor.scrollToText(codeToSelection)
|
await editor.scrollToText(codeToSelection)
|
||||||
await page.getByText(codeToSelection).click()
|
await page.getByText(codeToSelection).click()
|
||||||
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = X)`
|
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360deg, axis = X)`
|
||||||
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||||
|
|
||||||
// Edit flow
|
// Edit flow
|
||||||
@ -3683,7 +3735,7 @@ tag=$rectangleSegmentC002,
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
newCodeToFind.replace('angle = 360', 'angle = ' + newAngle)
|
newCodeToFind.replace('angle = 360deg', 'angle = ' + newAngle)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
test('revolve surface around edge from an extruded solid2d', async ({
|
test('revolve surface around edge from an extruded solid2d', async ({
|
||||||
@ -3697,7 +3749,7 @@ tag=$rectangleSegmentC002,
|
|||||||
}) => {
|
}) => {
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||||
|> startProfile(at = [-102.57, 101.72])
|
|> startProfile(at = [-102.57, 101.72])
|
||||||
|> angledLine(angle = 0, length = 202.6, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 202.6, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 202.6, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 202.6, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -3723,13 +3775,13 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.getByText('Edge', { exact: true }).click()
|
await page.getByText('Edge', { exact: true }).click()
|
||||||
const lineCodeToSelection = `angledLine(angle = 0, length = 202.6, tag = $rectangleSegmentA001)`
|
const lineCodeToSelection = `angledLine(angle = 0deg, length = 202.6, tag = $rectangleSegmentA001)`
|
||||||
await page.getByText(lineCodeToSelection).click()
|
await page.getByText(lineCodeToSelection).click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360, axis = rectangleSegmentA001)`
|
const newCodeToFind = `revolve001 = revolve(sketch002, angle = 360deg, axis = rectangleSegmentA001)`
|
||||||
await editor.expectEditor.toContain(newCodeToFind)
|
await editor.expectEditor.toContain(newCodeToFind)
|
||||||
|
|
||||||
// Edit flow
|
// Edit flow
|
||||||
@ -3767,7 +3819,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await editor.expectEditor.toContain('angle001 = ' + newAngle)
|
await editor.expectEditor.toContain('angle001 = ' + newAngle)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
newCodeToFind.replace('angle = 360', 'angle = angle001')
|
newCodeToFind.replace('angle = 360deg', 'angle = angle001')
|
||||||
)
|
)
|
||||||
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||||
})
|
})
|
||||||
@ -3786,7 +3838,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
|> xLine(length = 2.6)
|
|> xLine(length = 2.6)
|
||||||
sketch001 = startSketchOn(-XY)
|
sketch001 = startSketchOn(-XY)
|
||||||
|> startProfile(at = [-0.48, 1.25])
|
|> startProfile(at = [-0.48, 1.25])
|
||||||
|> angledLine(angle = 0, length = 2.38, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 2.38, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2.4, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2.4, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -3824,7 +3876,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
const newCodeToFind = `revolve001 = revolve(sketch003, angle = 360, axis = seg01)`
|
const newCodeToFind = `revolve001 = revolve(sketch003, angle = 360deg, axis = seg01)`
|
||||||
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||||
|
|
||||||
// Edit flow
|
// Edit flow
|
||||||
@ -3857,7 +3909,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
newCodeToFind.replace('angle = 360', 'angle = ' + newAngle)
|
newCodeToFind.replace('angle = 360deg', 'angle = ' + newAngle)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -4577,12 +4629,24 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
|
|
||||||
await test.step('Go through command bar flow', async () => {
|
await test.step('Go through command bar flow', async () => {
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'sketches',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Sketches: '',
|
||||||
|
Length: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'sketches',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'length',
|
||||||
currentArgValue: '5',
|
currentArgValue: '5',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Sketches: '2 faces',
|
||||||
Length: '',
|
Length: '',
|
||||||
},
|
},
|
||||||
highlightedHeaderArg: 'length',
|
highlightedHeaderArg: 'length',
|
||||||
@ -4593,7 +4657,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Sketches: '2 faces',
|
||||||
Length: '1',
|
Length: '1',
|
||||||
},
|
},
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
@ -4659,12 +4723,25 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
|
|
||||||
await test.step('Go through command bar flow', async () => {
|
await test.step('Go through command bar flow', async () => {
|
||||||
await toolbar.sweepButton.click()
|
await toolbar.sweepButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'sketches',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Sketches: '',
|
||||||
|
Path: '',
|
||||||
|
Sectional: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'sketches',
|
||||||
|
commandName: 'Sweep',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'path',
|
currentArgKey: 'path',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Sketches: '2 faces',
|
||||||
Path: '',
|
Path: '',
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
},
|
},
|
||||||
@ -4677,7 +4754,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Sketches: '2 faces',
|
||||||
Path: '1 segment',
|
Path: '1 segment',
|
||||||
Sectional: '',
|
Sectional: '',
|
||||||
},
|
},
|
||||||
@ -4743,12 +4820,25 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
await test.step('Go through command bar flow', async () => {
|
await test.step('Go through command bar flow', async () => {
|
||||||
await toolbar.closePane('code')
|
await toolbar.closePane('code')
|
||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'sketches',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: {
|
||||||
|
Sketches: '',
|
||||||
|
AxisOrEdge: '',
|
||||||
|
Angle: '',
|
||||||
|
},
|
||||||
|
highlightedHeaderArg: 'sketches',
|
||||||
|
commandName: 'Revolve',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'axisOrEdge',
|
currentArgKey: 'axisOrEdge',
|
||||||
currentArgValue: '',
|
currentArgValue: '',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Sketches: '2 faces',
|
||||||
AxisOrEdge: '',
|
AxisOrEdge: '',
|
||||||
Angle: '',
|
Angle: '',
|
||||||
},
|
},
|
||||||
@ -4764,7 +4854,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
currentArgKey: 'angle',
|
currentArgKey: 'angle',
|
||||||
currentArgValue: '360',
|
currentArgValue: '360',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Sketches: '2 faces',
|
||||||
AxisOrEdge: 'Edge',
|
AxisOrEdge: 'Edge',
|
||||||
Edge: '1 segment',
|
Edge: '1 segment',
|
||||||
Angle: '',
|
Angle: '',
|
||||||
@ -4777,7 +4867,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
Profiles: '2 profiles',
|
Sketches: '2 faces',
|
||||||
AxisOrEdge: 'Edge',
|
AxisOrEdge: 'Edge',
|
||||||
Edge: '1 segment',
|
Edge: '1 segment',
|
||||||
Angle: '180',
|
Angle: '180',
|
||||||
@ -4803,7 +4893,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
|||||||
await page.getByTestId('context-menu-delete').click()
|
await page.getByTestId('context-menu-delete').click()
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
await editor.expectEditor.not.toContain(
|
await editor.expectEditor.not.toContain(
|
||||||
`revolve001 = revolve([profile001, profile002], axis = XY, angle = 180)`,
|
`revolve001 = revolve([profile001, profile002], axis = XY, angle = 180deg)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -2064,59 +2064,3 @@ test(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
test(
|
|
||||||
'nested dir import works on windows',
|
|
||||||
{ tag: ['@electron', '@windows'] },
|
|
||||||
async ({ scene, cmdBar, context, page }, testInfo) => {
|
|
||||||
// Skip if on non-windows
|
|
||||||
if (process.platform !== 'win32') {
|
|
||||||
test.skip()
|
|
||||||
}
|
|
||||||
await context.folderSetupFn(async (dir) => {
|
|
||||||
const bracketDir = path.join(dir, 'bracket')
|
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
|
||||||
const nestedDir = path.join(bracketDir, 'nested')
|
|
||||||
await fsp.mkdir(nestedDir, { recursive: true })
|
|
||||||
|
|
||||||
await fsp.copyFile(
|
|
||||||
executorInputPath('cylinder-inches.kcl'),
|
|
||||||
path.join(nestedDir, 'main.kcl')
|
|
||||||
)
|
|
||||||
await fsp.writeFile(
|
|
||||||
path.join(bracketDir, 'main.kcl'),
|
|
||||||
`import 'nested\\main.kcl' as thing
|
|
||||||
|
|
||||||
thing`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
const u = await getUtils(page)
|
|
||||||
|
|
||||||
const pointOnModel = { x: 630, y: 280 }
|
|
||||||
|
|
||||||
await test.step('Opening the bracket project should load the stream', async () => {
|
|
||||||
// expect to see the text bracket
|
|
||||||
await expect(page.getByText('bracket')).toBeVisible()
|
|
||||||
|
|
||||||
await page.getByText('bracket').click()
|
|
||||||
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
).toBeEnabled({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
// gray at this pixel means the stream has loaded in the most
|
|
||||||
// user way we can verify it (pixel color)
|
|
||||||
await expect
|
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), {
|
|
||||||
timeout: 10_000,
|
|
||||||
})
|
|
||||||
.toBeLessThan(15)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
@ -47,7 +47,7 @@ b
|
|||||||
|
|
||||||
const importedFile = `sketch003 = startSketchOn(XY)
|
const importedFile = `sketch003 = startSketchOn(XY)
|
||||||
|> startProfile(at = [52.92, 157.81])
|
|> startProfile(at = [52.92, 157.81])
|
||||||
|> angledLine(angle = 0, length = 176.4, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 176.4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
length = 53.4,
|
length = 53.4,
|
||||||
@ -99,8 +99,6 @@ test.describe('edit with AI example snapshots', () => {
|
|||||||
await test.step('fire off edit prompt', async () => {
|
await test.step('fire off edit prompt', async () => {
|
||||||
await cmdBar.captureTextToCadRequestSnapshot(test.info())
|
await cmdBar.captureTextToCadRequestSnapshot(test.info())
|
||||||
await cmdBar.openCmdBar('promptToEdit')
|
await cmdBar.openCmdBar('promptToEdit')
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
// being specific about the color with a hex means asserting pixel color is more stable
|
// being specific about the color with a hex means asserting pixel color is more stable
|
||||||
await page
|
await page
|
||||||
.getByTestId('cmd-bar-arg-value')
|
.getByTestId('cmd-bar-arg-value')
|
||||||
|
@ -23,7 +23,7 @@ sketch002 = startSketchOn(XZ)
|
|||||||
extrude002 = extrude(sketch002, length = 50)
|
extrude002 = extrude(sketch002, length = 50)
|
||||||
sketch003 = startSketchOn(XY)
|
sketch003 = startSketchOn(XY)
|
||||||
|> startProfile(at = [52.92, 157.81])
|
|> startProfile(at = [52.92, 157.81])
|
||||||
|> angledLine(angle = 0, length = 176.4, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 176.4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 53.4, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 53.4, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -88,8 +88,6 @@ test.describe('Prompt-to-edit tests', () => {
|
|||||||
|
|
||||||
await test.step('fire off edit prompt', async () => {
|
await test.step('fire off edit prompt', async () => {
|
||||||
await cmdBar.openCmdBar('promptToEdit')
|
await cmdBar.openCmdBar('promptToEdit')
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
// being specific about the color with a hex means asserting pixel color is more stable
|
// being specific about the color with a hex means asserting pixel color is more stable
|
||||||
await page
|
await page
|
||||||
.getByTestId('cmd-bar-arg-value')
|
.getByTestId('cmd-bar-arg-value')
|
||||||
@ -167,8 +165,6 @@ test.describe('Prompt-to-edit tests', () => {
|
|||||||
|
|
||||||
await test.step('fire of bad prompt', async () => {
|
await test.step('fire of bad prompt', async () => {
|
||||||
await cmdBar.openCmdBar('promptToEdit')
|
await cmdBar.openCmdBar('promptToEdit')
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await cmdBar.progressCmdBar()
|
|
||||||
await page
|
await page
|
||||||
.getByTestId('cmd-bar-arg-value')
|
.getByTestId('cmd-bar-arg-value')
|
||||||
.fill('ansheusha asnthuatshoeuhtaoetuhthaeu laughs in dvorak')
|
.fill('ansheusha asnthuatshoeuhtaoetuhthaeu laughs in dvorak')
|
||||||
|
@ -72,7 +72,7 @@ Internal engine error on request`
|
|||||||
'persistCode',
|
'persistCode',
|
||||||
`sketch001 = startSketchOn(XY)
|
`sketch001 = startSketchOn(XY)
|
||||||
|> startProfile(at = [82.33, 238.21])
|
|> startProfile(at = [82.33, 238.21])
|
||||||
|> angledLine(angle = 0, length = 288.63, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 288.63, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 197.97, tag = $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 197.97, tag = $rectangleSegmentB001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -245,7 +245,7 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
'persistCode',
|
'persistCode',
|
||||||
`exampleSketch = startSketchOn(XZ)
|
`exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 50, length = 45 )
|
|> angledLine(angle = 50deg, length = 45 )
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|>
|
|>
|
||||||
@ -301,7 +301,7 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
page.locator('.cm-content')
|
page.locator('.cm-content')
|
||||||
).toContainText(`exampleSketch = startSketchOn(XZ)
|
).toContainText(`exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0, 0])
|
|> startProfile(at = [0, 0])
|
||||||
|> angledLine(angle = 50, length = 45 )
|
|> angledLine(angle = 50deg, length = 45 )
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
`@settings(defaultLengthUnit = mm)
|
`@settings(defaultLengthUnit = mm)
|
||||||
sketch002 = startSketchOn(XY)
|
sketch002 = startSketchOn(XY)
|
||||||
profile002 = startProfile(sketch002, at = [72.24, -52.05])
|
profile002 = startProfile(sketch002, at = [72.24, -52.05])
|
||||||
|> angledLine(angle = 0, length = 181.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 181.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -458,10 +458,12 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
|
|
||||||
// Click the stl.
|
// Click the stl.
|
||||||
await expect(stlOption).toBeVisible()
|
await expect(stlOption).toBeVisible()
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
await expect(submitButton).toBeVisible()
|
await expect(submitButton).toBeVisible()
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Find the toast.
|
// Find the toast.
|
||||||
@ -469,13 +471,11 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
await expect(exportingToastMessage).toBeVisible()
|
await expect(exportingToastMessage).toBeVisible()
|
||||||
|
|
||||||
// Expect it to succeed.
|
// Expect it to succeed.
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
await expect(exportingToastMessage).not.toBeVisible({ timeout: 15_000 })
|
||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
await expect(engineErrorToastMessage).not.toBeVisible()
|
||||||
|
|
||||||
const successToastMessage = page.getByText(`Exported successfully`)
|
const successToastMessage = page.getByText(`Exported successfully`)
|
||||||
await page.waitForTimeout(1_000)
|
await expect(successToastMessage).toBeVisible()
|
||||||
const count = await successToastMessage.count()
|
|
||||||
await expect(count).toBeGreaterThanOrEqual(1)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// We updated this test such that you can have multiple exports going at once.
|
// We updated this test such that you can have multiple exports going at once.
|
||||||
|
@ -995,8 +995,8 @@ profile001 = startProfile(sketch001, at = [${roundOff(scale * 69.6)}, ${roundOff
|
|||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
// click profile in code
|
// click "line(end = [1.32, 0.38])"
|
||||||
await page.getByText(`startProfile(at = [-0.45, 0.87])`).click()
|
await page.getByText(`line(end = [1.32, 0.38])`).click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeEnabled(
|
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeEnabled(
|
||||||
{ timeout: 10_000 }
|
{ timeout: 10_000 }
|
||||||
@ -1014,13 +1014,14 @@ profile001 = startProfile(sketch001, at = [${roundOff(scale * 69.6)}, ${roundOff
|
|||||||
// click extrude
|
// click extrude
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
|
|
||||||
// sketch selection should already have been made.
|
// sketch selection should already have been made. "Sketches: 1 face" only show up when the selection has been made already
|
||||||
// otherwise the cmdbar would be waiting for a selection.
|
// otherwise the cmdbar would be waiting for a selection.
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'length',
|
currentArgKey: 'length',
|
||||||
currentArgValue: '5',
|
currentArgValue: '5',
|
||||||
headerArguments: { Profiles: '1 profile', Length: '' },
|
headerArguments: { Sketches: '1 segment', Length: '' },
|
||||||
highlightedHeaderArg: 'length',
|
highlightedHeaderArg: 'length',
|
||||||
commandName: 'Extrude',
|
commandName: 'Extrude',
|
||||||
})
|
})
|
||||||
@ -1221,7 +1222,7 @@ profile001 = startProfile(sketch001, at = [299.72, 230.82])
|
|||||||
fn lug(origin, length, diameter, plane) {
|
fn lug(origin, length, diameter, plane) {
|
||||||
lugSketch = startSketchOn(plane)
|
lugSketch = startSketchOn(plane)
|
||||||
|> startProfile(at = [origin[0] + lugDiameter / 2, origin[1]])
|
|> startProfile(at = [origin[0] + lugDiameter / 2, origin[1]])
|
||||||
|> angledLine(angle = 60, lengthY = lugHeadLength)
|
|> angledLine(angle = 60deg, lengthY = lugHeadLength)
|
||||||
|> xLine(endAbsolute = 0 + .001)
|
|> xLine(endAbsolute = 0 + .001)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
@ -1286,7 +1287,7 @@ extrude001 = extrude(profile001, length = 200)
|
|||||||
|> translate(x = 3.14, y = 3.14, z = -50.154)
|
|> translate(x = 3.14, y = 3.14, z = -50.154)
|
||||||
sketch002 = startSketchOn(XY)
|
sketch002 = startSketchOn(XY)
|
||||||
profile002 = startProfile(sketch002, at = [72.2, -52.05])
|
profile002 = startProfile(sketch002, at = [72.2, -52.05])
|
||||||
|> angledLine(angle = 0, length = 181.26, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 181.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 21.54)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $mySeg)
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $mySeg)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|
||||||
@ -2057,7 +2058,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
|||||||
)
|
)
|
||||||
await crnRect1point2()
|
await crnRect1point2()
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 0, length = 2.37, tag = $rectangleSegmentA001)
|
`|> angledLine(angle = 0deg, length = 2.37, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 7.8)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 7.8)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2072,7 +2073,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
|||||||
await crnRect2point2()
|
await crnRect2point2()
|
||||||
await page.waitForTimeout(300)
|
await page.waitForTimeout(300)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 0, length = 5.49, tag = $rectangleSegmentA002)
|
`|> angledLine(angle = 0deg, length = 5.49, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 4.14)
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 4.14)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2091,7 +2092,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
|||||||
await cntrRect1point2()
|
await cntrRect1point2()
|
||||||
await page.waitForTimeout(300)
|
await page.waitForTimeout(300)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 0, length = 7.06, tag = $rectangleSegmentA003)
|
`|> angledLine(angle = 0deg, length = 7.06, tag = $rectangleSegmentA003)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA003) + 90, length = 4.34)
|
|> angledLine(angle = segAng(rectangleSegmentA003) + 90, length = 4.34)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2107,7 +2108,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
|||||||
await cntrRect2point2()
|
await cntrRect2point2()
|
||||||
await page.waitForTimeout(300)
|
await page.waitForTimeout(300)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 0, length = 3.12, tag = $rectangleSegmentA004)
|
`|> angledLine(angle = 0deg, length = 3.12, tag = $rectangleSegmentA004)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA004) + 90, length = 6.24)
|
|> angledLine(angle = segAng(rectangleSegmentA004) + 90, length = 6.24)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2257,7 +2258,7 @@ profile001 = startProfile(sketch001, at = [6.24, 4.54])
|
|||||||
|> line(end = [8.61, 0.74])
|
|> line(end = [8.61, 0.74])
|
||||||
|> line(end = [10.99, -5.22])
|
|> line(end = [10.99, -5.22])
|
||||||
profile002 = startProfile(sketch001, at = [11.19, 5.02])
|
profile002 = startProfile(sketch001, at = [11.19, 5.02])
|
||||||
|> angledLine(angle = 0, length = 10.78, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 10.78, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 4.14)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 4.14)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2369,7 +2370,7 @@ profile004 = circleThreePoint(sketch001, p1 = [13.44, -6.8], p2 = [13.39, -2.07]
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await rectEnd()
|
await rectEnd()
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`|> angledLine(angle = 180, length = 1.97, tag = $rectangleSegmentA002)
|
`|> angledLine(angle = 180deg, length = 1.97, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) + 90, length = 3.89)
|
|> angledLine(angle = segAng(rectangleSegmentA002) + 90, length = 3.89)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2395,7 +2396,7 @@ profile001 = startProfile(sketch001, at = [6.24, 4.54])
|
|||||||
|> line(end = [8.61, 0.74])
|
|> line(end = [8.61, 0.74])
|
||||||
|> line(end = [10.99, -5.22])
|
|> line(end = [10.99, -5.22])
|
||||||
profile002 = startProfile(sketch001, at = [11.19, 5.02])
|
profile002 = startProfile(sketch001, at = [11.19, 5.02])
|
||||||
|> angledLine(angle = 0, length = 10.78, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 10.78, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 4.14)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 4.14)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2500,7 +2501,7 @@ profile001 = startProfile(sketch001, at = [-63.43, 193.08])
|
|||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
profile003 = startProfile(sketch001, at = [16.79, 38.24])
|
profile003 = startProfile(sketch001, at = [16.79, 38.24])
|
||||||
|> angledLine(angle = 0, length = 182.82, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 182.82, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 105.71)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 105.71)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2725,7 +2726,7 @@ profile002 = startProfile(sketch002, at = [0.75, 13.46])
|
|||||||
|> line(end = [4.52, 3.79])
|
|> line(end = [4.52, 3.79])
|
||||||
|> line(end = [5.98, -2.81])
|
|> line(end = [5.98, -2.81])
|
||||||
profile003 = startProfile(sketch002, at = [3.19, 13.3])
|
profile003 = startProfile(sketch002, at = [3.19, 13.3])
|
||||||
|> angledLine(angle = 0, length = 6.64, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 6.64, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2.81)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2.81)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -2743,7 +2744,7 @@ profile006 = startProfile(sketch002, at = [9.65, 3.82])
|
|||||||
|> close()
|
|> close()
|
||||||
revolve001 = revolve(
|
revolve001 = revolve(
|
||||||
profile004,
|
profile004,
|
||||||
angle = 45,
|
angle = 45deg,
|
||||||
axis = getNextAdjacentEdge(seg01)
|
axis = getNextAdjacentEdge(seg01)
|
||||||
)
|
)
|
||||||
extrude002 = extrude(profile006, length = 4)
|
extrude002 = extrude(profile006, length = 4)
|
||||||
@ -2767,14 +2768,14 @@ profile010 = circle(
|
|||||||
radius = 2.67
|
radius = 2.67
|
||||||
)
|
)
|
||||||
profile011 = startProfile(sketch003, at = [5.07, -6.39])
|
profile011 = startProfile(sketch003, at = [5.07, -6.39])
|
||||||
|> angledLine(angle = 0, length = 4.54, tag = $rectangleSegmentA002)
|
|> angledLine(angle = 0deg, length = 4.54, tag = $rectangleSegmentA002)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 4.17)
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 4.17)
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude003 = extrude(profile011, length = 2.5)
|
extrude003 = extrude(profile011, length = 2.5)
|
||||||
// TODO this breaks the test,
|
// TODO this breaks the test,
|
||||||
// revolve002 = revolve(profile008, angle = 45, axis = seg02)
|
// revolve002 = revolve(profile008, angle = 45deg, axis = seg02)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -2920,7 +2921,7 @@ loft([profile001, profile002])
|
|||||||
)
|
)
|
||||||
await rect1Crn2()
|
await rect1Crn2()
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`angledLine(angle = 0, length = 113.01, tag = $rectangleSegmentA001)`
|
`angledLine(angle = 0deg, length = 113.01, tag = $rectangleSegmentA001)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
test('Can enter sketch loft edges offsetPlane and continue sketch', async ({
|
test('Can enter sketch loft edges offsetPlane and continue sketch', async ({
|
||||||
@ -2989,7 +2990,7 @@ loft([profile001, profile002])
|
|||||||
)
|
)
|
||||||
await rect1Crn2()
|
await rect1Crn2()
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`angledLine(angle = 0, length = 106.42], tag = $rectangleSegmentA001)`
|
`angledLine(angle = 0deg, length = 106.42], tag = $rectangleSegmentA001)`
|
||||||
)
|
)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
})
|
})
|
||||||
@ -3211,7 +3212,7 @@ test.describe('manual edits during sketch mode', () => {
|
|||||||
extrude001 = extrude(profile001, length = 500)
|
extrude001 = extrude(profile001, length = 500)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||||
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
||||||
|> angledLine(angle = 0, length = 119.61, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 119.61, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(length = 156.54, angle = -28)
|
|> angledLine(length = 156.54, angle = -28)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = -151,
|
angle = -151,
|
||||||
@ -3347,7 +3348,7 @@ profile001 = startProfile(sketch001, at = [106.68, 89.77])
|
|||||||
extrude001 = extrude(profile001, length = 500)
|
extrude001 = extrude(profile001, length = 500)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||||
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
||||||
|> angledLine(angle = 0, length = 119.61, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 119.61, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(length = 219.2, angle = -56)
|
|> angledLine(length = 219.2, angle = -56)
|
||||||
|> angledLine(angle = -151, length = 116.27)
|
|> angledLine(angle = -151, length = 116.27)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
@ -3386,7 +3387,7 @@ profile003 = startProfile(sketch002, at = [-201.08, 254.17])
|
|||||||
extrude001 = extrude(profile001, length = 500)
|
extrude001 = extrude(profile001, length = 500)
|
||||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||||
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
profile002 = startProfile(sketch002, at = [83.39, 329.15])
|
||||||
|> angledLine(angle = 0, length = 119.61, tag = $rectangleSegmentA001)
|
|> angledLine(angle = 0deg, length = 119.61, tag = $rectangleSegmentA001)
|
||||||
|> angledLine(length = 156.54, angle = -28)
|
|> angledLine(length = 156.54, angle = -28)
|
||||||
|> angledLine(
|
|> angledLine(
|
||||||
angle = -151,
|
angle = -151,
|
||||||
|
@ -845,7 +845,7 @@ test.describe('code color goober', { tag: '@snapshot' }, () => {
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
@ -889,7 +889,7 @@ sweepSketch = startSketchOn(XY)
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
@ -934,7 +934,7 @@ sweepSketch = startSketchOn(XY)
|
|||||||
sweepPath = startSketchOn(XZ)
|
sweepPath = startSketchOn(XZ)
|
||||||
|> startProfile(at = [0.05, 0.05])
|
|> startProfile(at = [0.05, 0.05])
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|> tangentialArc(angle = 90, radius = 5)
|
|> tangentialArc(angle = 90deg, radius = 5)
|
||||||
|> line(end = [-3, 0])
|
|> line(end = [-3, 0])
|
||||||
|> tangentialArc(angle = -90, radius = 5)
|
|> tangentialArc(angle = -90, radius = 5)
|
||||||
|> line(end = [0, 7])
|
|> line(end = [0, 7])
|
||||||
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 46 KiB |