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
|
||||
|
||||
project="https://github.com/KittyCAD/modeling-app"
|
||||
suite="${CI_SUITE:-unit}"
|
||||
branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}"
|
||||
commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}"
|
||||
|
||||
@ -14,7 +13,6 @@ echo "Uploading batch results"
|
||||
curl --silent --request POST \
|
||||
--header "X-API-Key: ${TAB_API_KEY}" \
|
||||
--form "project=${project}" \
|
||||
--form "suite=${suite}" \
|
||||
--form "branch=${branch}" \
|
||||
--form "commit=${commit}" \
|
||||
--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}}
|
||||
ZOO_HOST: https://api.dev.zoo.dev
|
||||
RUST_BACKTRACE: full
|
||||
RUST_MIN_STACK: 10485760000
|
||||
- name: Commit differences
|
||||
if: steps.path-changes.outputs.outside-kcl-samples == 'false' && steps.cargo-test-kcl-samples.outcome == 'failure'
|
||||
shell: bash
|
||||
@ -120,7 +119,6 @@ jobs:
|
||||
# Configure nextest when it's run by insta (via just).
|
||||
NEXTEST_PROFILE: ci
|
||||
RUST_BACKTRACE: full
|
||||
RUST_MIN_STACK: 10485760000
|
||||
- name: Build and archive tests
|
||||
run: |
|
||||
cd rust
|
||||
@ -157,7 +155,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
|
||||
- name: Install Rust
|
||||
- name: Install rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
cache: false # Configured below.
|
||||
@ -184,7 +182,6 @@ jobs:
|
||||
env:
|
||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN_DEV}}
|
||||
ZOO_HOST: https://api.dev.zoo.dev
|
||||
RUST_MIN_STACK: 10485760000
|
||||
- name: Upload results
|
||||
if: always()
|
||||
run: .github/ci-cd-scripts/upload-results.sh
|
||||
@ -193,56 +190,6 @@ jobs:
|
||||
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: 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:
|
||||
name: Run wasm tests
|
||||
strategy:
|
||||
|
17
.github/workflows/e2e-tests.yml
vendored
@ -143,7 +143,7 @@ jobs:
|
||||
- name: Install browsers
|
||||
run: npm run playwright install --with-deps
|
||||
|
||||
- name: Test snapshots
|
||||
- name: Capture snapshots
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
@ -156,19 +156,6 @@ jobs:
|
||||
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
|
||||
|
||||
- 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
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
@ -186,7 +173,7 @@ jobs:
|
||||
id: git-check
|
||||
run: |
|
||||
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
|
||||
else echo "modified=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
99
.github/workflows/kcl-language-server.yml
vendored
@ -21,11 +21,14 @@ on:
|
||||
- '**.rs'
|
||||
- .github/workflows/kcl-language-server.yml
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
CARGO_NET_RETRY: 10
|
||||
@ -35,9 +38,10 @@ env:
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.15
|
||||
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: kcl-language-server (vscode tests)
|
||||
name: vscode tests
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@ -73,20 +77,22 @@ jobs:
|
||||
include:
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
code-target: win32-x64
|
||||
#- os: windows-latest
|
||||
#target: i686-pc-windows-msvc
|
||||
#code-target:
|
||||
#win32-ia32
|
||||
#- os: windows-latest
|
||||
#target: aarch64-pc-windows-msvc
|
||||
#code-target: win32-arm64
|
||||
code-target:
|
||||
win32-x64
|
||||
#- os: windows-latest
|
||||
#target: i686-pc-windows-msvc
|
||||
#code-target:
|
||||
#win32-ia32
|
||||
#- os: windows-latest
|
||||
#target: aarch64-pc-windows-msvc
|
||||
#code-target: win32-arm64
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
code-target: linux-x64
|
||||
#- os: ubuntu-latest
|
||||
#target: aarch64-unknown-linux-musl
|
||||
#code-target: linux-arm64
|
||||
code-target:
|
||||
linux-x64
|
||||
#- os: ubuntu-latest
|
||||
#target: aarch64-unknown-linux-musl
|
||||
#code-target: linux-arm64
|
||||
- os: ubuntu-latest
|
||||
target: aarch64-unknown-linux-gnu
|
||||
code-target: linux-arm64
|
||||
@ -99,33 +105,41 @@ jobs:
|
||||
- os: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
code-target: darwin-arm64
|
||||
name: kcl-language-server build-release (${{ matrix.target }})
|
||||
|
||||
name: build-release (${{ matrix.target }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
container: ${{ matrix.container }}
|
||||
|
||||
env:
|
||||
RA_TARGET: ${{ matrix.target }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||
|
||||
- name: Use correct Rust toolchain
|
||||
shell: bash
|
||||
run: |
|
||||
rm rust/rust-toolchain.toml
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
cache: rust
|
||||
components: rust-src
|
||||
target: ${{ matrix.target }}
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Update apt repositories
|
||||
if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' || matrix.os == 'ubuntu-latest'
|
||||
run: sudo apt-get update
|
||||
|
||||
- if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
name: Install deps
|
||||
shell: bash
|
||||
@ -150,53 +164,64 @@ jobs:
|
||||
zlib1g-dev
|
||||
|
||||
cargo install cross
|
||||
|
||||
- name: Install AArch64 target toolchain
|
||||
if: matrix.target == 'aarch64-unknown-linux-gnu'
|
||||
run: sudo apt-get install gcc-aarch64-linux-gnu
|
||||
|
||||
- name: Install ARM target toolchain
|
||||
if: matrix.target == 'arm-unknown-linux-gnueabihf'
|
||||
run: sudo apt-get install gcc-arm-linux-gnueabihf
|
||||
|
||||
- name: build
|
||||
run: |
|
||||
cd rust
|
||||
cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
# npm will symlink which will cause issues w tarballing later
|
||||
yarn install
|
||||
|
||||
- name: Package Extension (release)
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }}
|
||||
|
||||
- name: Package Extension (nightly)
|
||||
if: startsWith(github.event.ref, 'refs/tags/') == false
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package --yarn -o "../build/kcl-language-server-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release
|
||||
|
||||
- name: remove server
|
||||
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
rm -rf server
|
||||
|
||||
- name: Package Extension (no server, release)
|
||||
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/')
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix
|
||||
|
||||
- name: Package Extension (no server, nightly)
|
||||
if: matrix.target == 'x86_64-unknown-linux-gnu' && startsWith(github.event.ref, 'refs/tags/') == false
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package --yarn -o ../build/kcl-language-server-no-server.vsix --pre-release
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: release-${{ matrix.target }}
|
||||
path: ./rust/build
|
||||
|
||||
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
|
||||
env:
|
||||
RA_TARGET: x86_64-unknown-linux-musl
|
||||
@ -206,6 +231,7 @@ jobs:
|
||||
image: alpine:latest
|
||||
volumes:
|
||||
- /usr/local/cargo/registry:/usr/local/cargo/registry
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
@ -219,46 +245,55 @@ jobs:
|
||||
nodejs \
|
||||
npm \
|
||||
yarn
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||
|
||||
- name: Use correct Rust toolchain
|
||||
shell: bash
|
||||
run: |
|
||||
rm rust/rust-toolchain.toml
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
cache: rust
|
||||
components: rust-src
|
||||
target: ${{ matrix.target }}
|
||||
|
||||
- name: build
|
||||
run: |
|
||||
cd rust
|
||||
cargo kcl-language-server-release build --client-patch-version ${{ github.run_number }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
# npm will symlink which will cause issues w tarballing later
|
||||
yarn install
|
||||
|
||||
- name: Package Extension (release)
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64
|
||||
|
||||
- name: Package Extension (release)
|
||||
if: startsWith(github.event.ref, 'refs/tags/') == false
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce package --yarn -o "../build/kcl-language-server-alpine-x64.vsix" --target alpine-x64 --pre-release
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: release-x86_64-unknown-linux-musl
|
||||
path: ./rust/build
|
||||
|
||||
publish:
|
||||
name: kcl-language-server (publish)
|
||||
name: publish
|
||||
runs-on: ubuntu-latest
|
||||
needs: ["build-release", "build-release-x86_64-unknown-linux-musl"]
|
||||
if: startsWith(github.event.ref, 'refs/tags')
|
||||
@ -266,17 +301,22 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- run: echo "TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- run: 'echo "TAG: $TAG"'
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||
|
||||
- name: Install Nodejs
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
||||
- run: 'echo "HEAD_SHA: $HEAD_SHA"'
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: release-aarch64-apple-darwin
|
||||
@ -304,29 +344,33 @@ jobs:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: release-x86_64-pc-windows-msvc
|
||||
path: rust/build
|
||||
#- uses: actions/download-artifact@v4
|
||||
#with:
|
||||
#name: release-i686-pc-windows-msvc
|
||||
#path:
|
||||
#build
|
||||
#- uses: actions/download-artifact@v4
|
||||
#with:
|
||||
#name: release-aarch64-pc-windows-msvc
|
||||
#path: rust/build
|
||||
path:
|
||||
rust/build
|
||||
#- uses: actions/download-artifact@v4
|
||||
#with:
|
||||
#name: release-i686-pc-windows-msvc
|
||||
#path:
|
||||
#build
|
||||
#- uses: actions/download-artifact@v4
|
||||
#with:
|
||||
#name: release-aarch64-pc-windows-msvc
|
||||
#path: rust/build
|
||||
- run: ls -al ./rust/build
|
||||
|
||||
- name: Publish Release
|
||||
uses: ./.github/actions/github-release
|
||||
with:
|
||||
files: "rust/build/*"
|
||||
name: ${{ env.TAG }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: move files to dir for upload
|
||||
shell: bash
|
||||
run: |
|
||||
cd rust
|
||||
mkdir -p releases/language-server/${{ env.TAG }}
|
||||
cp -r build/* releases/language-server/${{ env.TAG }}
|
||||
|
||||
- name: "Authenticate to Google Cloud"
|
||||
uses: "google-github-actions/auth@v2.1.8"
|
||||
with:
|
||||
@ -341,12 +385,15 @@ jobs:
|
||||
with:
|
||||
path: rust/releases
|
||||
destination: dl.kittycad.io
|
||||
|
||||
- run: rm rust/build/kcl-language-server-no-server.vsix
|
||||
|
||||
- name: Publish Extension (Code Marketplace, release)
|
||||
# token from https://dev.azure.com/kcl-language-server/
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
npx vsce publish --pat ${{ secrets.VSCE_PAT }} --packagePath ../build/kcl-language-server-*.vsix
|
||||
|
||||
- name: Publish Extension (OpenVSX, release)
|
||||
run: |
|
||||
cd rust/kcl-language-server
|
||||
|
32
.github/workflows/kcl-python-bindings.yml
vendored
@ -4,6 +4,7 @@
|
||||
# maturin generate-ci github
|
||||
#
|
||||
name: kcl-python-bindings
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@ -26,14 +27,16 @@ on:
|
||||
- '**.rs'
|
||||
- .github/workflows/kcl-python-bindings.yml
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
linux-x86_64:
|
||||
name: kcl-python-bindings (linux-x86_64)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -55,8 +58,8 @@ jobs:
|
||||
with:
|
||||
name: wheels-linux-x86_64
|
||||
path: rust/kcl-python-bindings/dist
|
||||
|
||||
windows:
|
||||
name: kcl-python-bindings (windows)
|
||||
runs-on: windows-16-cores
|
||||
strategy:
|
||||
matrix:
|
||||
@ -81,8 +84,8 @@ jobs:
|
||||
with:
|
||||
name: wheels-windows-${{ matrix.target }}
|
||||
path: rust/kcl-python-bindings/dist
|
||||
|
||||
macos:
|
||||
name: kcl-python-bindings (macos)
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
@ -107,8 +110,8 @@ jobs:
|
||||
with:
|
||||
name: wheels-macos-${{ matrix.target }}
|
||||
path: rust/kcl-python-bindings/dist
|
||||
|
||||
test:
|
||||
name: kcl-python-bindings (test)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -124,8 +127,8 @@ jobs:
|
||||
env:
|
||||
KITTYCAD_API_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
ZOO_HOST: https://api.dev.zoo.dev
|
||||
|
||||
sdist:
|
||||
name: kcl-python-bindings (sdist)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -133,10 +136,10 @@ jobs:
|
||||
uses: astral-sh/setup-uv@v5
|
||||
- name: Install codespell
|
||||
run: |
|
||||
uv venv .venv
|
||||
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
||||
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
||||
uv pip install pip --upgrade
|
||||
uv venv .venv
|
||||
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
||||
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
||||
uv pip install pip --upgrade
|
||||
- name: Build sdist
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
@ -148,6 +151,7 @@ jobs:
|
||||
with:
|
||||
name: wheels-sdist
|
||||
path: rust/kcl-python-bindings/dist
|
||||
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
@ -164,11 +168,11 @@ jobs:
|
||||
uses: astral-sh/setup-uv@v5
|
||||
- name: do uv things
|
||||
run: |
|
||||
cd rust/kcl-python-bindings
|
||||
uv venv .venv
|
||||
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
||||
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
||||
uv pip install pip --upgrade
|
||||
cd rust/kcl-python-bindings
|
||||
uv venv .venv
|
||||
echo "VIRTUAL_ENV=.venv" >> $GITHUB_ENV
|
||||
echo "$PWD/.venv/bin" >> $GITHUB_PATH
|
||||
uv pip install pip --upgrade
|
||||
- name: Publish to PyPI
|
||||
uses: PyO3/maturin-action@v1
|
||||
env:
|
||||
|
167
.github/workflows/static-analysis.yml
vendored
@ -28,7 +28,53 @@ jobs:
|
||||
- run: npm run fmt:check
|
||||
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
@ -127,3 +173,122 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
- name: Run codespell
|
||||
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/screenshots/main.kcl
|
||||
/public/kcl-samples/step/main.kcl
|
||||
/public/kcl-samples/internal
|
||||
/rust/kcl-lib/tests/kcl_samples/internal
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
|
1
Makefile
@ -114,6 +114,7 @@ test-unit: install ## Run the unit tests
|
||||
npm run test:unit:components
|
||||
@ 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:kcl-samples
|
||||
|
||||
.PHONY: test-e2e
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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]
|
||||
metalness = "metalness" # appearance API
|
||||
metalness = "metalness" # appearance API
|
||||
Hom = "Hom" # short for homogenous
|
||||
typ = "typ" # used to declare a variable named 'type' which is a reserved keyword in Rust
|
||||
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
|
||||
"ot" = "ot" # some abbreviation, idk what
|
||||
"oe" = "oe" # some abbreviation, idk what
|
||||
"colinear" = "colinear" # some engine shit, kidding
|
||||
|
||||
[default]
|
||||
extend-ignore-identifiers-re = [
|
||||
|
@ -4,7 +4,7 @@ excerpt: "Documentation of the KCL language for the Zoo Design Studio."
|
||||
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).
|
||||
|
||||
## Topics
|
||||
|
@ -27,6 +27,9 @@ import increment from "util.kcl"
|
||||
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
|
||||
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"
|
||||
```
|
||||
|
||||
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`
|
||||
@ -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.
|
||||
|
||||
```norun
|
||||
import "cube.kcl"
|
||||
import "tests/inputs/cube.kcl" as cube
|
||||
cube
|
||||
|> 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
|
||||
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
|
||||
@ -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.
|
||||
|
||||
```norun
|
||||
import cube from "cube.kcl"
|
||||
import cube from "tests/inputs/cube.kcl"
|
||||
|
||||
cube
|
||||
|> 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:
|
||||
|
||||
```kcl
|
||||
import "tests/inputs/cube.step"
|
||||
import "tests/inputs/cube.step" as cube
|
||||
|
||||
cube
|
||||
|> translate(x=10)
|
||||
|
@ -46,7 +46,7 @@ angledLine(
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> yLine(endAbsolute = 15)
|
||||
|> angledLine(angle = 30, length = 15)
|
||||
|> angledLine(angle = 30deg, length = 15)
|
||||
|> line(end = [8, -10])
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|
@ -42,7 +42,7 @@ exampleSketch = startSketchOn(XZ)
|
||||
|> line(endAbsolute = [5, 10])
|
||||
|> line(endAbsolute = [-10, 10], tag = $lineToIntersect)
|
||||
|> line(endAbsolute = [0, 20])
|
||||
|> angledLineThatIntersects(angle = 80, intersectTag = lineToIntersect, offset = 10)
|
||||
|> angledLineThatIntersects(angle = 80deg, intersectTag = lineToIntersect, offset = 10)
|
||||
|> close()
|
||||
|
||||
example = extrude(exampleSketch, length = 10)
|
||||
|
@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 5)
|
||||
// Add color to a revolved solid.
|
||||
sketch001 = startSketchOn(XY)
|
||||
|> circle(center = [15, 0], radius = 5)
|
||||
|> revolve(angle = 360, axis = Y)
|
||||
|> revolve(angle = 360deg, axis = Y)
|
||||
|> appearance(color = '#ff0000', metalness = 90, roughness = 90)
|
||||
```
|
||||
|
||||
@ -171,7 +171,7 @@ exampleSketch = startSketchOn(XZ)
|
||||
|> patternCircular2d(
|
||||
center = [0, 0],
|
||||
instances = 13,
|
||||
arcDegrees = 360,
|
||||
arcDegrees = 360deg,
|
||||
rotateDuplicates = true,
|
||||
)
|
||||
|
||||
@ -188,9 +188,9 @@ example = extrude(exampleSketch, length = 1)
|
||||
sweepPath = startSketchOn(XZ)
|
||||
|> startProfile(at = [0.05, 0.05])
|
||||
|> line(end = [0, 7])
|
||||
|> tangentialArc(angle = 90, radius = 5)
|
||||
|> tangentialArc(angle = 90deg, radius = 5)
|
||||
|> line(end = [-3, 0])
|
||||
|> tangentialArc(angle = -90, radius = 5)
|
||||
|> tangentialArc(angle = -90deg, radius = 5)
|
||||
|> line(end = [0, 7])
|
||||
|
||||
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)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> arc(angleStart = 0, angleEnd = 280, radius = 16)
|
||||
|> arc(angleStart = 0deg, angleEnd = 280deg, radius = 16)
|
||||
|> close()
|
||||
example = extrude(exampleSketch, length = 10)
|
||||
```
|
||||
|
@ -19,7 +19,7 @@ E: number = 2.71828182845904523536028747135266250_
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 30,
|
||||
angle = 30deg,
|
||||
length = 2 * E ^ 2,
|
||||
)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
@ -19,7 +19,7 @@ TAU: number = 6.28318530717958647692528676655900577_
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 50,
|
||||
angle = 50deg,
|
||||
length = 10 * TAU,
|
||||
)
|
||||
|> 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)
|
||||
|> startProfile(at = [0, 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 = [0, 10])
|
||||
|> bezierCurve(control1 = [-10, 0], control2 = [2, 10], end = [-5, 10])
|
||||
@ -56,7 +56,7 @@ example = startSketchOn(XZ)
|
||||
```kcl
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [-10, 0])
|
||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
||||
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [5, 0])
|
||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||
@ -72,7 +72,7 @@ example = extrude(exampleSketch, length = 10)
|
||||
```kcl
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [-10, 0])
|
||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
||||
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [5, 0])
|
||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||
@ -88,7 +88,7 @@ example = extrude(exampleSketch, length = 20, symmetric = true)
|
||||
```kcl
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [-10, 0])
|
||||
|> arc(angleStart = 120, angleEnd = -60, radius = 5)
|
||||
|> arc(angleStart = 120deg, angleEnd = -60deg, radius = 5)
|
||||
|> line(end = [10, 0])
|
||||
|> line(end = [5, 0])
|
||||
|> bezierCurve(control1 = [-3, 0], control2 = [2, 10], end = [-5, 10])
|
||||
|
@ -12,7 +12,7 @@ reduce(
|
||||
@array: [any],
|
||||
initial: any,
|
||||
f: fn(any, accum: any): any,
|
||||
): any
|
||||
): [any]
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
[`any`](/docs/kcl-std/types/std-types-any)
|
||||
[`[any]`](/docs/kcl-std/types/std-types-any)
|
||||
|
||||
|
||||
### Examples
|
||||
@ -80,7 +80,7 @@ fn decagon(@radius) {
|
||||
|
||||
// Start the decagon sketch at this point.
|
||||
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.
|
||||
// For each number in the array 1..10, run the given function,
|
||||
|
@ -27,7 +27,7 @@ abs(@input: number): number
|
||||
### Examples
|
||||
|
||||
```kcl
|
||||
myAngle = -120
|
||||
myAngle = -120deg
|
||||
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|
@ -30,7 +30,7 @@ cos(@num: number(Angle)): number(_)
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 30,
|
||||
angle = 30deg,
|
||||
length = 3 / cos(30deg),
|
||||
)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
@ -11,7 +11,7 @@ Compute the length of the given leg.
|
||||
legLen(
|
||||
hypotenuse: number(Length),
|
||||
leg: number(Length),
|
||||
): number(Length)
|
||||
): number(deg)
|
||||
```
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ legLen(
|
||||
|
||||
### Returns
|
||||
|
||||
[`number(Length)`](/docs/kcl-std/types/std-types-number) - A number.
|
||||
[`number(deg)`](/docs/kcl-std/types/std-types-number) - A number.
|
||||
|
||||
|
||||
### Examples
|
||||
|
@ -30,7 +30,7 @@ max(@input: [number; 1+]): number
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 70,
|
||||
angle = 70deg,
|
||||
length = max([15, 31, 4, 13, 22])
|
||||
)
|
||||
|> line(end = [20, 0])
|
||||
|
@ -30,7 +30,7 @@ min(@input: [number; 1+]): number
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 70,
|
||||
angle = 70deg,
|
||||
length = min([15, 31, 4, 13, 22])
|
||||
)
|
||||
|> line(end = [20, 0])
|
||||
|
@ -34,7 +34,7 @@ cartesian (x/y/z grid) coordinates.
|
||||
```kcl
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> 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 = [segEndX(thing), 0])
|
||||
|> line(end = [-20, 10])
|
||||
|
@ -34,7 +34,7 @@ pow(
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 50,
|
||||
angle = 50deg,
|
||||
length = pow(5, exp = 2),
|
||||
)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
@ -30,7 +30,7 @@ sin(@num: number(Angle)): number(_)
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 50,
|
||||
angle = 50deg,
|
||||
length = 15 / sin(135deg),
|
||||
)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
@ -30,7 +30,7 @@ sqrt(@input: number): number
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 50,
|
||||
angle = 50deg,
|
||||
length = sqrt(2500),
|
||||
)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
@ -30,7 +30,7 @@ tan(@num: number(Angle)): number(_)
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 50,
|
||||
angle = 50deg,
|
||||
length = 50 * tan((1/2): number(rad)),
|
||||
)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
@ -14,6 +14,8 @@ mirror2d(
|
||||
): Sketch
|
||||
```
|
||||
|
||||
Only works on unclosed sketches for now.
|
||||
|
||||
Mirror occurs around a local sketch axis rather than a global axis.
|
||||
|
||||
### Arguments
|
||||
|
@ -30,7 +30,7 @@ units::toDegrees(@num: number(Angle)): number(deg)
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 50,
|
||||
angle = 50deg,
|
||||
length = 70 * cos(units::toDegrees((PI/4): number(rad))),
|
||||
)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|
@ -30,8 +30,8 @@ units::toRadians(@num: number(Angle)): number(rad)
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(
|
||||
angle = 50,
|
||||
length = 70 * cos(units::toRadians(45)),
|
||||
angle = 50deg,
|
||||
length = 70 * cos(units::toRadians(45deg)),
|
||||
)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|
@ -30,10 +30,10 @@ getNextAdjacentEdge(@edge: TagIdentifier): Uuid
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> angledLine(angle = 60, length = 10)
|
||||
|> angledLine(angle = 120, length = 10)
|
||||
|> angledLine(angle = 60deg, length = 10)
|
||||
|> angledLine(angle = 120deg, length = 10)
|
||||
|> line(end = [-10, 0])
|
||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
||||
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||
|> close()
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
|
@ -30,10 +30,10 @@ getOppositeEdge(@edge: TagIdentifier): Uuid
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> angledLine(angle = 60, length = 10)
|
||||
|> angledLine(angle = 120, length = 10)
|
||||
|> angledLine(angle = 60deg, length = 10)
|
||||
|> angledLine(angle = 120deg, length = 10)
|
||||
|> line(end = [-10, 0])
|
||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
||||
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||
|> close()
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
|
@ -30,10 +30,10 @@ getPreviousAdjacentEdge(@edge: TagIdentifier): Uuid
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> line(end = [10, 0])
|
||||
|> angledLine(angle = 60, length = 10)
|
||||
|> angledLine(angle = 120, length = 10)
|
||||
|> angledLine(angle = 60deg, length = 10)
|
||||
|> angledLine(angle = 120deg, length = 10)
|
||||
|> line(end = [-10, 0])
|
||||
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
||||
|> angledLine(angle = 240deg, length = 10, tag = $referenceEdge)
|
||||
|> close()
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
|
@ -65,7 +65,7 @@ layout: manual
|
||||
* [`line`](/docs/kcl-std/line)
|
||||
* [`loft`](/docs/kcl-std/loft)
|
||||
* [`patternCircular2d`](/docs/kcl-std/patternCircular2d)
|
||||
* [`patternTransform2d`](/docs/kcl-std/functions/std-sketch-patternTransform2d)
|
||||
* [`patternTransform2d`](/docs/kcl-std/patternTransform2d)
|
||||
* [`polygon`](/docs/kcl-std/polygon)
|
||||
* [`profileStart`](/docs/kcl-std/profileStart)
|
||||
* [`profileStartX`](/docs/kcl-std/profileStartX)
|
||||
@ -94,7 +94,7 @@ layout: manual
|
||||
* [`intersect`](/docs/kcl-std/intersect)
|
||||
* [`patternCircular3d`](/docs/kcl-std/patternCircular3d)
|
||||
* [`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)
|
||||
* [`subtract`](/docs/kcl-std/subtract)
|
||||
* [`union`](/docs/kcl-std/union)
|
||||
|
@ -43,11 +43,11 @@ a = 10
|
||||
b = 14
|
||||
startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> involuteCircular(startRadius = a, endRadius = b, angle = 60)
|
||||
|> involuteCircular(startRadius = a, endRadius = b, angle = 60deg)
|
||||
|> involuteCircular(
|
||||
startRadius = a,
|
||||
endRadius = b,
|
||||
angle = 60,
|
||||
angle = 60deg,
|
||||
reverse = true,
|
||||
)
|
||||
```
|
||||
|
@ -30,7 +30,7 @@ This module contains functions for creating and manipulating sketches, and makin
|
||||
* [`line`](/docs/kcl-std/line)
|
||||
* [`loft`](/docs/kcl-std/loft)
|
||||
* [`patternCircular2d`](/docs/kcl-std/patternCircular2d)
|
||||
* [`patternTransform2d`](/docs/kcl-std/functions/std-sketch-patternTransform2d)
|
||||
* [`patternTransform2d`](/docs/kcl-std/patternTransform2d)
|
||||
* [`polygon`](/docs/kcl-std/polygon)
|
||||
* [`profileStart`](/docs/kcl-std/profileStart)
|
||||
* [`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)
|
||||
* [`patternCircular3d`](/docs/kcl-std/patternCircular3d)
|
||||
* [`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)
|
||||
* [`subtract`](/docs/kcl-std/subtract)
|
||||
* [`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.
|
||||
|
||||
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
|
||||
|
||||
|
@ -12,8 +12,8 @@ patternCircular2d(
|
||||
@sketchSet: [Sketch],
|
||||
instances: number,
|
||||
center: Point2d,
|
||||
arcDegrees?: number,
|
||||
rotateDuplicates?: bool,
|
||||
arcDegrees: number,
|
||||
rotateDuplicates: bool,
|
||||
useOriginal?: bool,
|
||||
): [Sketch]
|
||||
```
|
||||
@ -27,8 +27,8 @@ patternCircular2d(
|
||||
| `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 |
|
||||
| `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 |
|
||||
| `rotateDuplicates` | [`bool`](/docs/kcl-std/types/std-types-bool) | Whether or not to rotate the duplicates as they are copied. Defaults to true. | 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. | 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 |
|
||||
|
||||
### Returns
|
||||
@ -48,7 +48,7 @@ exampleSketch = startSketchOn(XZ)
|
||||
|> patternCircular2d(
|
||||
center = [0, 0],
|
||||
instances = 13,
|
||||
arcDegrees = 360,
|
||||
arcDegrees = 360deg,
|
||||
rotateDuplicates = true,
|
||||
)
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
---
|
||||
title: "patternTransform2d"
|
||||
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
|
||||
---
|
||||
|
||||
Just like `patternTransform`, but works on 2D sketches not 3D solids.
|
||||
Just like patternTransform, but works on 2D sketches not 3D solids.
|
||||
|
||||
```kcl
|
||||
patternTransform2d(
|
||||
@sketches: [Sketch; 1+],
|
||||
instances: number(_),
|
||||
transform: fn(number(_)): { },
|
||||
useOriginal?: boolean,
|
||||
): [Sketch; 1+]
|
||||
@sketches: [Sketch],
|
||||
instances: number,
|
||||
transform: FunctionSource,
|
||||
useOriginal?: bool,
|
||||
): [Sketch]
|
||||
```
|
||||
|
||||
|
||||
@ -22,14 +22,14 @@ patternTransform2d(
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `sketches` | [`[Sketch; 1+]`](/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 |
|
||||
| `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 |
|
||||
| `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 |
|
||||
| `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 |
|
||||
| `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` | [`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
|
||||
|
||||
[`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch)
|
||||
[`[Sketch]`](/docs/kcl-std/types/std-types-Sketch)
|
||||
|
||||
|
||||
### Examples
|
@ -29,8 +29,8 @@ profileStart(@profile: Sketch): [number]
|
||||
```kcl
|
||||
sketch001 = startSketchOn(XY)
|
||||
|> startProfile(at = [5, 2])
|
||||
|> angledLine(angle = 120, length = 50, tag = $seg01)
|
||||
|> angledLine(angle = segAng(seg01) + 120, length = 50)
|
||||
|> angledLine(angle = 120deg, length = 50, tag = $seg01)
|
||||
|> angledLine(angle = segAng(seg01) + 120deg, length = 50)
|
||||
|> line(end = profileStart(%))
|
||||
|> close()
|
||||
|> 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)
|
||||
|> startProfile(at = [0.05, 0.05])
|
||||
|> line(end = [0, 7])
|
||||
|> tangentialArc(angle = 90, radius = 5)
|
||||
|> tangentialArc(angle = 90deg, radius = 5)
|
||||
|> line(end = [-3, 0])
|
||||
|> tangentialArc(angle = -90, radius = 5)
|
||||
|> tangentialArc(angle = -90deg, radius = 5)
|
||||
|> line(end = [0, 7])
|
||||
|
||||
// Create a hole for the pipe.
|
||||
@ -85,8 +85,8 @@ cube
|
||||
|
||||
sketch001 = startSketchOn(XY)
|
||||
rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|
||||
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|
||||
|> angledLine(angle = 0deg, length = 73.47, tag = $rectangleSegmentA001)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 50.61)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
|> close()
|
||||
@ -96,7 +96,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
|
||||
sketch002 = startSketchOn(YZ)
|
||||
sweepPath = startProfile(sketch002, at = [0, 0])
|
||||
|> yLine(length = 231.81)
|
||||
|> tangentialArc(radius = 80, angle = -90)
|
||||
|> tangentialArc(radius = 80, angle = -90deg)
|
||||
|> xLine(length = 384.93)
|
||||
|
||||
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
|
||||
|
@ -29,9 +29,9 @@ segLen(@tag: TagIdentifier): number
|
||||
```kcl
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 60, length = 10, tag = $thing)
|
||||
|> tangentialArc(angle = -120, radius = 5)
|
||||
|> angledLine(angle = -60, length = segLen(thing))
|
||||
|> angledLine(angle = 60deg, length = 10, tag = $thing)
|
||||
|> tangentialArc(angle = -120deg, radius = 5)
|
||||
|> angledLine(angle = -60deg, length = segLen(thing))
|
||||
|> close()
|
||||
|
||||
example = extrude(exampleSketch, length = 5)
|
||||
|
@ -146,7 +146,7 @@ exampleSketch = startSketchOn(XY)
|
||||
|> line(end = [-2, 0])
|
||||
|> close()
|
||||
|
||||
example = revolve(exampleSketch, axis = Y, angle = 180)
|
||||
example = revolve(exampleSketch, axis = Y, angle = 180deg)
|
||||
|
||||
exampleSketch002 = startSketchOn(example, face = END)
|
||||
|> startProfile(at = [4.5, -5])
|
||||
@ -178,7 +178,7 @@ exampleSketch = startSketchOn(XY)
|
||||
example = revolve(
|
||||
exampleSketch,
|
||||
axis = Y,
|
||||
angle = 180,
|
||||
angle = 180deg,
|
||||
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
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 45, length = 10)
|
||||
|> angledLine(angle = 45deg, length = 10)
|
||||
|> tangentialArc(end = [0, -10])
|
||||
|> line(end = [-10, 0])
|
||||
|> close()
|
||||
@ -54,7 +54,7 @@ example = extrude(exampleSketch, length = 10)
|
||||
```kcl
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 60, length = 10)
|
||||
|> angledLine(angle = 60deg, length = 10)
|
||||
|> tangentialArc(endAbsolute = [15, 15])
|
||||
|> line(end = [10, -15])
|
||||
|> close()
|
||||
@ -67,9 +67,9 @@ example = extrude(exampleSketch, length = 10)
|
||||
```kcl
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 60, length = 10)
|
||||
|> tangentialArc(radius = 10, angle = -120)
|
||||
|> angledLine(angle = -60, length = 10)
|
||||
|> angledLine(angle = 60deg, length = 10)
|
||||
|> tangentialArc(radius = 10, angle = -120deg)
|
||||
|> angledLine(angle = -60deg, length = 10)
|
||||
|> close()
|
||||
|
||||
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)
|
||||
|> startProfile(at = [0.05, 0.05])
|
||||
|> line(end = [0, 7])
|
||||
|> tangentialArc(angle = 90, radius = 5)
|
||||
|> tangentialArc(angle = 90deg, radius = 5)
|
||||
|> line(end = [-3, 0])
|
||||
|> tangentialArc(angle = -90, radius = 5)
|
||||
|> tangentialArc(angle = -90deg, radius = 5)
|
||||
|> line(end = [0, 7])
|
||||
|
||||
// Create a hole for the pipe.
|
||||
@ -86,8 +86,8 @@ cube
|
||||
|
||||
sketch001 = startSketchOn(XY)
|
||||
rectangleSketch = startProfile(sketch001, at = [-200, 23.86])
|
||||
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|
||||
|> angledLine(angle = 0deg, length = 73.47, tag = $rectangleSegmentA001)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90deg, length = 50.61)
|
||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
|> close()
|
||||
@ -97,7 +97,7 @@ circleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)
|
||||
sketch002 = startSketchOn(YZ)
|
||||
sweepPath = startProfile(sketch002, at = [0, 0])
|
||||
|> yLine(length = 231.81)
|
||||
|> tangentialArc(radius = 80, angle = -90)
|
||||
|> tangentialArc(radius = 80, angle = -90deg)
|
||||
|> xLine(length = 384.93)
|
||||
|
||||
parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
|
||||
@ -156,7 +156,7 @@ profile001 = square()
|
||||
|
||||
profile002 = square()
|
||||
|> translate(z = 20)
|
||||
|> rotate(axis = [0, 0, 1.0], angle = 45)
|
||||
|> rotate(axis = [0, 0, 1.0], angle = 45deg)
|
||||
|
||||
loft([profile001, profile002])
|
||||
```
|
||||
|
@ -15,9 +15,9 @@ way:
|
||||
```js
|
||||
startSketchOn(XZ)
|
||||
|> startProfile(at = origin)
|
||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||
|> angledLine(
|
||||
angle = segAng(rectangleSegmentA001) - 90,
|
||||
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||
length = 196.99,
|
||||
tag = $rectangleSegmentB001,
|
||||
)
|
||||
@ -49,9 +49,9 @@ However if the code was written like this:
|
||||
fn rect(origin) {
|
||||
return startSketchOn(XZ)
|
||||
|> startProfile(at = origin)
|
||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||
|> angledLine(
|
||||
angle = segAng(rectangleSegmentA001) - 90,
|
||||
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||
length = 196.99,
|
||||
tag = $rectangleSegmentB001)
|
||||
|> angledLine(
|
||||
@ -78,9 +78,9 @@ For example the following code works.
|
||||
fn rect(origin) {
|
||||
return startSketchOn(XZ)
|
||||
|> startProfile(at = origin)
|
||||
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||
|> angledLine(angle = 0deg, length = 191.26, tag = $rectangleSegmentA001)
|
||||
|> angledLine(
|
||||
angle = segAng(rectangleSegmentA001) - 90,
|
||||
angle = segAng(rectangleSegmentA001) - 90deg,
|
||||
length = 196.99
|
||||
tag = $rectangleSegmentB001,
|
||||
)
|
||||
|
@ -38,10 +38,10 @@ xLine(
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> xLine(length = 15)
|
||||
|> angledLine(angle = 80, length = 15)
|
||||
|> angledLine(angle = 80deg, length = 15)
|
||||
|> line(end = [8, -10])
|
||||
|> xLine(length = 10)
|
||||
|> angledLine(angle = 120, length = 30)
|
||||
|> angledLine(angle = 120deg, length = 30)
|
||||
|> xLine(length = -15)
|
||||
|> close()
|
||||
|
||||
|
@ -38,7 +38,7 @@ yLine(
|
||||
exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> yLine(length = 15)
|
||||
|> angledLine(angle = 30, length = 15)
|
||||
|> angledLine(angle = 30deg, length = 15)
|
||||
|> line(end = [8, -10])
|
||||
|> yLine(length = -5)
|
||||
|> close()
|
||||
|
@ -235,48 +235,6 @@ extrude001 = extrude(sketch001, length = 5)`
|
||||
.first()
|
||||
).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(
|
||||
|
@ -36,29 +36,27 @@ test.describe('Command bar tests', () => {
|
||||
await u.closeDebugPanel()
|
||||
|
||||
// Click the line of code for xLine.
|
||||
await page.getByText(`startProfile(at = [-10, -10])`).click()
|
||||
|
||||
// Wait for the selection to register (TODO: we need a definitive way to wait for this)
|
||||
await page.waitForTimeout(200)
|
||||
await page.getByText(`close()`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
|
||||
|
||||
await toolbar.extrudeButton.click()
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
commandName: 'Extrude',
|
||||
currentArgKey: 'length',
|
||||
currentArgValue: '5',
|
||||
currentArgKey: 'sketches',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Profiles: '1 profile',
|
||||
Sketches: '',
|
||||
Length: '',
|
||||
},
|
||||
highlightedHeaderArg: 'length',
|
||||
highlightedHeaderArg: 'sketches',
|
||||
})
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
commandName: 'Extrude',
|
||||
headerArguments: {
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 segment',
|
||||
Length: '5',
|
||||
},
|
||||
})
|
||||
@ -288,7 +286,7 @@ test.describe('Command bar tests', () => {
|
||||
await cmdBar.cmdOptions.getByText('Extrude').click()
|
||||
|
||||
// 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
|
||||
await page.mouse.move(700, 200)
|
||||
await page.mouse.click(700, 200)
|
||||
@ -401,6 +399,7 @@ test.describe('Command bar tests', () => {
|
||||
sortBy: 'last-modified-desc',
|
||||
})
|
||||
await page.goto(page.url() + targetURL)
|
||||
expect(page.url()).toContain(targetURL)
|
||||
})
|
||||
|
||||
await test.step(`Submit the command`, async () => {
|
||||
@ -411,7 +410,7 @@ test.describe('Command bar tests', () => {
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Method: '',
|
||||
Name: 'main.kcl',
|
||||
Name: 'test',
|
||||
Code: '1 line',
|
||||
},
|
||||
highlightedHeaderArg: 'method',
|
||||
@ -422,7 +421,7 @@ test.describe('Command bar tests', () => {
|
||||
commandName: 'Import file from URL',
|
||||
headerArguments: {
|
||||
Method: 'New project',
|
||||
Name: 'main.kcl',
|
||||
Name: 'test',
|
||||
Code: '1 line',
|
||||
},
|
||||
})
|
||||
@ -464,6 +463,7 @@ test.describe('Command bar tests', () => {
|
||||
sortBy: 'last-modified-desc',
|
||||
})
|
||||
await page.goto(page.url() + targetURL)
|
||||
expect(page.url()).toContain(targetURL)
|
||||
})
|
||||
|
||||
await test.step(`Submit the command`, async () => {
|
||||
@ -474,7 +474,7 @@ test.describe('Command bar tests', () => {
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Method: '',
|
||||
Name: 'main.kcl',
|
||||
Name: 'test',
|
||||
Code: '1 line',
|
||||
},
|
||||
highlightedHeaderArg: 'method',
|
||||
@ -487,7 +487,7 @@ test.describe('Command bar tests', () => {
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Method: 'Existing project',
|
||||
Name: 'main.kcl',
|
||||
Name: 'test',
|
||||
ProjectName: '',
|
||||
Code: '1 line',
|
||||
},
|
||||
@ -500,7 +500,7 @@ test.describe('Command bar tests', () => {
|
||||
headerArguments: {
|
||||
Method: 'Existing project',
|
||||
ProjectName: 'testProjectDir',
|
||||
Name: 'main.kcl',
|
||||
Name: 'test',
|
||||
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 editor.expectEditor.toContain('extrusionDistance = 12')
|
||||
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`
|
||||
)
|
||||
})
|
||||
|
||||
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()
|
||||
|
||||
const successToastMessage = page.getByText(`Exported successfully`)
|
||||
await page.waitForTimeout(1_000)
|
||||
const count = await successToastMessage.count()
|
||||
await expect(count).toBeGreaterThanOrEqual(1)
|
||||
await expect(successToastMessage).toBeVisible()
|
||||
|
||||
// Check for the exported file
|
||||
const firstFileFullPath = path.resolve(
|
||||
@ -136,9 +134,7 @@ test(
|
||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
||||
|
||||
const successToastMessage = page.getByText(`Exported successfully`)
|
||||
await page.waitForTimeout(1_000)
|
||||
const count = await successToastMessage.count()
|
||||
await expect(count).toBeGreaterThanOrEqual(1)
|
||||
await expect(successToastMessage).toBeVisible()
|
||||
await expect(exportingToastMessage).not.toBeVisible()
|
||||
|
||||
// Check for the exported file=
|
||||
|
@ -912,7 +912,7 @@ a1 = startSketchOn(offsetPlane(XY, offset = 10))
|
||||
|> close()
|
||||
|> revolve(
|
||||
axis = revolveAxis,
|
||||
angle = 90
|
||||
angle = 90deg
|
||||
)
|
||||
`
|
||||
)
|
||||
@ -1131,15 +1131,14 @@ sketch001 = startSketchOn(XZ)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
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 cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'length',
|
||||
currentArgValue: '5',
|
||||
headerArguments: {
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 face',
|
||||
Length: '',
|
||||
},
|
||||
highlightedHeaderArg: 'length',
|
||||
@ -1149,7 +1148,7 @@ sketch001 = startSketchOn(XZ)
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
headerArguments: {
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 face',
|
||||
Length: '5',
|
||||
},
|
||||
commandName: 'Extrude',
|
||||
@ -1355,9 +1354,7 @@ sketch001 = startSketchOn(XZ)
|
||||
const u = await getUtils(page)
|
||||
const projectLink = page.getByRole('link', { name: 'cube' })
|
||||
const gizmo = page.locator('[aria-label*=gizmo]')
|
||||
const resetCameraButton = page.getByRole('button', {
|
||||
name: 'Reset view',
|
||||
})
|
||||
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
||||
const locationToHaveColor = async (
|
||||
position: { x: number; y: number },
|
||||
color: [number, number, number]
|
||||
|
@ -38,7 +38,7 @@ extrude001 = extrude(sketch002, length = 10)
|
||||
|
||||
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn(XZ)
|
||||
|> 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), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||
|> 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(
|
||||
'deleting all files recreates a default main.kcl with no code',
|
||||
{ tag: '@electron' },
|
||||
|
@ -105,19 +105,14 @@ export class CmdBarFixture {
|
||||
expectState = async (expected: CmdBarSerialised) => {
|
||||
return expect.poll(() => this._serialiseCmdBar()).toEqual(expected)
|
||||
}
|
||||
/**
|
||||
* This method is used to progress the command bar to the next step, defaulting to clicking the next button.
|
||||
* 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,
|
||||
/** The method will use buttons OR press enter randomly to progress the cmdbar,
|
||||
* this could have unexpected results depending on what's focused
|
||||
*
|
||||
* TODO: This method assumes the user has a valid input to the current stage,
|
||||
* and assumes we are past the `pickCommand` step.
|
||||
*/
|
||||
progressCmdBar = async (shouldUseKeyboard = false) => {
|
||||
progressCmdBar = async (shouldFuzzProgressMethod = true) => {
|
||||
await this.page.waitForTimeout(2000)
|
||||
if (shouldUseKeyboard) {
|
||||
await this.page.keyboard.press('Enter')
|
||||
return
|
||||
}
|
||||
|
||||
const arrowButton = this.page.getByRole('button', {
|
||||
name: 'arrow right Continue',
|
||||
})
|
||||
@ -151,7 +146,9 @@ export class CmdBarFixture {
|
||||
await this.cmdBarOpenBtn.click()
|
||||
await expect(this.page.getByPlaceholder('Search commands')).toBeVisible()
|
||||
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 promptEditCommand.first().scrollIntoViewIfNeeded()
|
||||
await promptEditCommand.first().click()
|
||||
@ -313,11 +310,6 @@ export class CmdBarFixture {
|
||||
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) {
|
||||
// Check the placeholder project name exists
|
||||
const actualArgument = await this.cmdBarElement
|
||||
|
@ -26,7 +26,6 @@ export class HomePageFixture {
|
||||
sortByNameBtn!: Locator
|
||||
appHeader!: Locator
|
||||
tutorialBtn!: Locator
|
||||
textToCadBtn!: Locator
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page
|
||||
@ -48,7 +47,6 @@ export class HomePageFixture {
|
||||
this.sortByNameBtn = this.page.getByTestId('home-sort-by-name')
|
||||
this.appHeader = this.page.getByTestId('app-header')
|
||||
this.tutorialBtn = this.page.getByTestId('home-tutorial-button')
|
||||
this.textToCadBtn = this.page.getByTestId('home-text-to-cad')
|
||||
}
|
||||
|
||||
private _serialiseSortBy = async (): Promise<
|
||||
@ -123,13 +121,11 @@ export class HomePageFixture {
|
||||
await projectCard.click()
|
||||
}
|
||||
|
||||
/** Returns the project name in case caller has used the default and needs it */
|
||||
goToModelingScene = async (name = 'testDefault') => {
|
||||
goToModelingScene = async (name: string = 'testDefault') => {
|
||||
// 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)
|
||||
return name
|
||||
}
|
||||
|
||||
isNativeFileMenuCreated = async () => {
|
||||
|
@ -16,7 +16,7 @@ test.describe('Import UI tests', () => {
|
||||
path.join(projectDir, 'toBeImported.kcl'),
|
||||
`sketch001 = startSketchOn(XZ)
|
||||
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), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -33,7 +33,7 @@ importedCube
|
||||
|
||||
sketch001 = startSketchOn(XZ)
|
||||
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), length = -segLen(rectangleSegmentA001), tag = $seg01)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||
|
@ -61,7 +61,6 @@ class MyAPIReporter implements Reporter {
|
||||
const payload = {
|
||||
// Required information
|
||||
project: 'https://github.com/KittyCAD/modeling-app',
|
||||
suite: process.env.CI_SUITE || 'e2e',
|
||||
branch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME || '',
|
||||
commit: process.env.CI_COMMIT_SHA || process.env.GITHUB_SHA || '',
|
||||
test: test.titlePath().slice(2).join(' › '),
|
||||
|
@ -197,6 +197,18 @@ test.describe(
|
||||
await clickElectronNativeMenuById(tronApp, 'File.Export current part')
|
||||
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 page.waitForTimeout(250)
|
||||
await clickElectronNativeMenuById(
|
||||
@ -252,7 +264,7 @@ test.describe(
|
||||
tronApp,
|
||||
'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 page.waitForTimeout(250)
|
||||
@ -518,7 +530,7 @@ test.describe(
|
||||
'Design.Create with Zoo Text-To-CAD'
|
||||
)
|
||||
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 () => {
|
||||
@ -528,7 +540,7 @@ test.describe(
|
||||
'Design.Modify with Zoo Text-To-CAD'
|
||||
)
|
||||
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 () => {
|
||||
|
@ -6,6 +6,7 @@ test.describe('Onboarding tests', () => {
|
||||
homePage,
|
||||
toolbar,
|
||||
editor,
|
||||
scene,
|
||||
tronApp,
|
||||
}) => {
|
||||
if (!tronApp) {
|
||||
@ -61,6 +62,7 @@ test.describe('Onboarding tests', () => {
|
||||
await editor.expectEditor.toContain('@settings(defaultLengthUnit = in)', {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
await scene.connectionEstablished()
|
||||
})
|
||||
|
||||
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 postDismissToast.waitFor({ state: 'hidden' })
|
||||
await page.keyboard.press('Escape')
|
||||
await expect(postDismissToast).toBeVisible()
|
||||
await expect(page.getByTestId('onboarding-content')).not.toBeVisible()
|
||||
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 expect(toolbar.projectName).toContainText('tutorial-project')
|
||||
await expect(tutorialWelcomeHeading).toBeVisible()
|
||||
await scene.connectionEstablished()
|
||||
})
|
||||
|
||||
await test.step('Dismiss the onboarding', async () => {
|
||||
await postDismissToast.waitFor({ state: 'hidden' })
|
||||
await page.keyboard.press('Escape')
|
||||
await expect(postDismissToast).toBeVisible()
|
||||
await expect(page.getByTestId('onboarding-content')).not.toBeVisible()
|
||||
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 toolbar.extrudeButton.click()
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'sketches',
|
||||
currentArgValue: '',
|
||||
headerArguments: { Sketches: '', Length: '' },
|
||||
highlightedHeaderArg: 'sketches',
|
||||
commandName: 'Extrude',
|
||||
})
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'length',
|
||||
currentArgValue: '5',
|
||||
headerArguments: { Profiles: '1 profile', Length: '' },
|
||||
headerArguments: { Sketches: '1 face', Length: '' },
|
||||
highlightedHeaderArg: 'length',
|
||||
commandName: 'Extrude',
|
||||
})
|
||||
@ -89,7 +98,7 @@ test.describe('Point-and-click tests', () => {
|
||||
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
headerArguments: { Profiles: '1 profile', Length: '5' },
|
||||
headerArguments: { Sketches: '1 face', Length: '5' },
|
||||
commandName: 'Extrude',
|
||||
})
|
||||
await cmdBar.progressCmdBar()
|
||||
@ -356,7 +365,7 @@ test.describe('Point-and-click tests', () => {
|
||||
clickCoords: { x: 677, y: 87 },
|
||||
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
||||
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,
|
||||
tags = [
|
||||
getNextAdjacentEdge(yo),
|
||||
@ -398,7 +407,7 @@ test.describe('Point-and-click tests', () => {
|
||||
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> 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), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||
@ -410,28 +419,28 @@ extrude001 = extrude(sketch001, length = 100)
|
||||
|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06)
|
||||
sketch002 = startSketchOn(extrude001, face = seg03)
|
||||
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), length = -segLen(rectangleSegmentA002))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
|> close()
|
||||
sketch003 = startSketchOn(extrude001, face = seg04)
|
||||
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), length = -segLen(rectangleSegmentA003))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
|> close()
|
||||
sketch004 = startSketchOn(extrude001, face = seg05)
|
||||
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), length = -segLen(rectangleSegmentA004))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
|> close()
|
||||
sketch005 = startSketchOn(extrude001, face = seg06)
|
||||
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), length = -segLen(rectangleSegmentA005))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -495,7 +504,7 @@ profile004 = startProfile(sketch005, at = [-23.43, 19.69])
|
||||
`@settings(defaultLengthUnit = in)
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> 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), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||
@ -517,7 +526,7 @@ chamf = chamfer(
|
||||
)
|
||||
sketch002 = startSketchOn(extrude001, face = seg03)
|
||||
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), length = -segLen(rectangleSegmentA002))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -1625,15 +1634,15 @@ sketch002 = startSketchOn(plane001)
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'sketches',
|
||||
currentArgValue: '',
|
||||
headerArguments: { Profiles: '' },
|
||||
highlightedHeaderArg: 'Profiles',
|
||||
headerArguments: { Sketches: '' },
|
||||
highlightedHeaderArg: 'sketches',
|
||||
commandName: 'Loft',
|
||||
})
|
||||
await selectSketches()
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
headerArguments: { Profiles: '2 profiles' },
|
||||
headerArguments: { Sketches: '2 faces' },
|
||||
commandName: 'Loft',
|
||||
})
|
||||
await cmdBar.submit()
|
||||
@ -1645,9 +1654,18 @@ sketch002 = startSketchOn(plane001)
|
||||
|
||||
await test.step(`Go through the command bar flow with preselected sketches`, async () => {
|
||||
await toolbar.loftButton.click()
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'sketches',
|
||||
currentArgValue: '',
|
||||
headerArguments: { Sketches: '' },
|
||||
highlightedHeaderArg: 'sketches',
|
||||
commandName: 'Loft',
|
||||
})
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
headerArguments: { Profiles: '2 profiles' },
|
||||
headerArguments: { Sketches: '2 faces' },
|
||||
commandName: 'Loft',
|
||||
})
|
||||
await cmdBar.submit()
|
||||
@ -1758,7 +1776,7 @@ sketch002 = startSketchOn(XZ)
|
||||
initialCode: `@settings(defaultLengthUnit = in)
|
||||
sketch001 = startSketchOn(YZ)
|
||||
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), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -1812,10 +1830,10 @@ sketch002 = startSketchOn(XZ)
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '',
|
||||
Sketches: '',
|
||||
Path: '',
|
||||
},
|
||||
highlightedHeaderArg: 'Profiles',
|
||||
highlightedHeaderArg: 'sketches',
|
||||
stage: 'arguments',
|
||||
})
|
||||
await clickOnSketch1()
|
||||
@ -1826,7 +1844,7 @@ sketch002 = startSketchOn(XZ)
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 face',
|
||||
Path: '',
|
||||
},
|
||||
highlightedHeaderArg: 'path',
|
||||
@ -1839,7 +1857,7 @@ sketch002 = startSketchOn(XZ)
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 face',
|
||||
Path: '',
|
||||
},
|
||||
highlightedHeaderArg: 'path',
|
||||
@ -1849,17 +1867,13 @@ sketch002 = startSketchOn(XZ)
|
||||
await cmdBar.expectState({
|
||||
commandName: 'Sweep',
|
||||
headerArguments: {
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 face',
|
||||
Path: '1 segment',
|
||||
Sectional: '',
|
||||
},
|
||||
stage: 'review',
|
||||
})
|
||||
// Confirm we can submit from the review step with just `Enter`
|
||||
await cmdBar.progressCmdBar(true)
|
||||
await cmdBar.expectState({
|
||||
stage: 'commandBarClosed',
|
||||
})
|
||||
await cmdBar.progressCmdBar()
|
||||
})
|
||||
|
||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||
@ -1954,10 +1968,10 @@ profile001 = ${circleCode}`
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '',
|
||||
Sketches: '',
|
||||
Path: '',
|
||||
},
|
||||
highlightedHeaderArg: 'Profiles',
|
||||
highlightedHeaderArg: 'sketches',
|
||||
stage: 'arguments',
|
||||
})
|
||||
await editor.scrollToText(circleCode)
|
||||
@ -1969,7 +1983,7 @@ profile001 = ${circleCode}`
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 face',
|
||||
Path: '',
|
||||
},
|
||||
highlightedHeaderArg: 'path',
|
||||
@ -1983,7 +1997,7 @@ profile001 = ${circleCode}`
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sectional: '',
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 face',
|
||||
Path: '',
|
||||
},
|
||||
highlightedHeaderArg: 'path',
|
||||
@ -1993,13 +2007,13 @@ profile001 = ${circleCode}`
|
||||
await cmdBar.expectState({
|
||||
commandName: 'Sweep',
|
||||
headerArguments: {
|
||||
Profiles: '1 profile',
|
||||
Sketches: '1 face',
|
||||
Path: '1 helix',
|
||||
Sectional: '',
|
||||
},
|
||||
stage: 'review',
|
||||
})
|
||||
await cmdBar.progressCmdBar(true)
|
||||
await cmdBar.progressCmdBar()
|
||||
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 page.waitForTimeout(100)
|
||||
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({
|
||||
commandName: 'Fillet',
|
||||
highlightedHeaderArg: 'radius',
|
||||
@ -2621,6 +2647,18 @@ extrude001 = extrude(profile001, length = 5)
|
||||
await test.step(`Apply fillet`, async () => {
|
||||
await page.waitForTimeout(100)
|
||||
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({
|
||||
commandName: 'Fillet',
|
||||
highlightedHeaderArg: 'radius',
|
||||
@ -2726,6 +2764,19 @@ extrude001 = extrude(sketch001, length = -12)
|
||||
await test.step(`Apply chamfer to the preselected edge`, async () => {
|
||||
await page.waitForTimeout(100)
|
||||
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({
|
||||
commandName: 'Chamfer',
|
||||
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 toolbar.shellButton.click()
|
||||
await cmdBar.progressCmdBar()
|
||||
await page.waitForTimeout(500)
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
headerArguments: {
|
||||
@ -3603,7 +3656,7 @@ profile001 = startProfile(sketch001, at = [-20, 20])
|
||||
const initialCode = `
|
||||
sketch001 = startSketchOn(XZ)
|
||||
|> 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),
|
||||
@ -3615,7 +3668,7 @@ tag=$rectangleSegmentC001,
|
||||
extrude001 = extrude(sketch001, length = 200)
|
||||
sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
||||
|> startProfile(at = [-66.77, 84.81])
|
||||
|> angledLine(angle = 180, length = 27.08, tag = $rectangleSegmentA002)
|
||||
|> angledLine(angle = 180deg, length = 27.08, tag = $rectangleSegmentA002)
|
||||
|> angledLine(
|
||||
angle=segAng(rectangleSegmentA002) - 90,
|
||||
length=27.8,
|
||||
@ -3638,19 +3691,18 @@ tag=$rectangleSegmentC002,
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// select line of code
|
||||
const codeToSelection = `startProfile(at = [-66.77, 84.81])`
|
||||
const codeToSelection = `segAng(rectangleSegmentA002) - 90,`
|
||||
// revolve
|
||||
await editor.scrollToText(codeToSelection)
|
||||
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 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()
|
||||
|
||||
// Edit flow
|
||||
@ -3683,7 +3735,7 @@ tag=$rectangleSegmentC002,
|
||||
await cmdBar.progressCmdBar()
|
||||
await toolbar.closePane('feature-tree')
|
||||
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 ({
|
||||
@ -3697,7 +3749,7 @@ tag=$rectangleSegmentC002,
|
||||
}) => {
|
||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||
|> 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), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -3723,13 +3775,13 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
||||
await toolbar.revolveButton.click()
|
||||
await cmdBar.progressCmdBar()
|
||||
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 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)
|
||||
|
||||
// Edit flow
|
||||
@ -3767,7 +3819,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
||||
await toolbar.closePane('feature-tree')
|
||||
await editor.expectEditor.toContain('angle001 = ' + newAngle)
|
||||
await editor.expectEditor.toContain(
|
||||
newCodeToFind.replace('angle = 360', 'angle = angle001')
|
||||
newCodeToFind.replace('angle = 360deg', 'angle = angle001')
|
||||
)
|
||||
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||
})
|
||||
@ -3786,7 +3838,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
||||
|> xLine(length = 2.6)
|
||||
sketch001 = startSketchOn(-XY)
|
||||
|> 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), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -3824,7 +3876,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
||||
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()
|
||||
|
||||
// Edit flow
|
||||
@ -3857,7 +3909,7 @@ sketch002 = startSketchOn(extrude001, face = rectangleSegmentA001)
|
||||
await cmdBar.progressCmdBar()
|
||||
await toolbar.closePane('feature-tree')
|
||||
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 toolbar.extrudeButton.click()
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'sketches',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Sketches: '',
|
||||
Length: '',
|
||||
},
|
||||
highlightedHeaderArg: 'sketches',
|
||||
commandName: 'Extrude',
|
||||
})
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'length',
|
||||
currentArgValue: '5',
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Sketches: '2 faces',
|
||||
Length: '',
|
||||
},
|
||||
highlightedHeaderArg: 'length',
|
||||
@ -4593,7 +4657,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Sketches: '2 faces',
|
||||
Length: '1',
|
||||
},
|
||||
commandName: 'Extrude',
|
||||
@ -4659,12 +4723,25 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
|
||||
await test.step('Go through command bar flow', async () => {
|
||||
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({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'path',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Sketches: '2 faces',
|
||||
Path: '',
|
||||
Sectional: '',
|
||||
},
|
||||
@ -4677,7 +4754,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Sketches: '2 faces',
|
||||
Path: '1 segment',
|
||||
Sectional: '',
|
||||
},
|
||||
@ -4743,12 +4820,25 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
await test.step('Go through command bar flow', async () => {
|
||||
await toolbar.closePane('code')
|
||||
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({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'axisOrEdge',
|
||||
currentArgValue: '',
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Sketches: '2 faces',
|
||||
AxisOrEdge: '',
|
||||
Angle: '',
|
||||
},
|
||||
@ -4764,7 +4854,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
currentArgKey: 'angle',
|
||||
currentArgValue: '360',
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Sketches: '2 faces',
|
||||
AxisOrEdge: 'Edge',
|
||||
Edge: '1 segment',
|
||||
Angle: '',
|
||||
@ -4777,7 +4867,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
await cmdBar.expectState({
|
||||
stage: 'review',
|
||||
headerArguments: {
|
||||
Profiles: '2 profiles',
|
||||
Sketches: '2 faces',
|
||||
AxisOrEdge: 'Edge',
|
||||
Edge: '1 segment',
|
||||
Angle: '180',
|
||||
@ -4803,7 +4893,7 @@ path001 = startProfile(sketch001, at = [0, 0])
|
||||
await page.getByTestId('context-menu-delete').click()
|
||||
await scene.settled(cmdBar)
|
||||
await editor.expectEditor.not.toContain(
|
||||
`revolve001 = revolve([profile001, profile002], axis = XY, angle = 180)`,
|
||||
`revolve001 = revolve([profile001, profile002], axis = XY, angle = 180deg)`,
|
||||
{ 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)
|
||||
|> 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,
|
||||
@ -99,8 +99,6 @@ test.describe('edit with AI example snapshots', () => {
|
||||
await test.step('fire off edit prompt', async () => {
|
||||
await cmdBar.captureTextToCadRequestSnapshot(test.info())
|
||||
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
|
||||
await page
|
||||
.getByTestId('cmd-bar-arg-value')
|
||||
|
@ -23,7 +23,7 @@ sketch002 = startSketchOn(XZ)
|
||||
extrude002 = extrude(sketch002, length = 50)
|
||||
sketch003 = startSketchOn(XY)
|
||||
|> 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), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -88,8 +88,6 @@ test.describe('Prompt-to-edit tests', () => {
|
||||
|
||||
await test.step('fire off edit prompt', async () => {
|
||||
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
|
||||
await page
|
||||
.getByTestId('cmd-bar-arg-value')
|
||||
@ -167,8 +165,6 @@ test.describe('Prompt-to-edit tests', () => {
|
||||
|
||||
await test.step('fire of bad prompt', async () => {
|
||||
await cmdBar.openCmdBar('promptToEdit')
|
||||
await page.waitForTimeout(100)
|
||||
await cmdBar.progressCmdBar()
|
||||
await page
|
||||
.getByTestId('cmd-bar-arg-value')
|
||||
.fill('ansheusha asnthuatshoeuhtaoetuhthaeu laughs in dvorak')
|
||||
|
@ -72,7 +72,7 @@ Internal engine error on request`
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn(XY)
|
||||
|> 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), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -245,7 +245,7 @@ extrude001 = extrude(sketch001, length = 50)
|
||||
'persistCode',
|
||||
`exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 50, length = 45 )
|
||||
|> angledLine(angle = 50deg, length = 45 )
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|>
|
||||
@ -301,7 +301,7 @@ extrude001 = extrude(sketch001, length = 50)
|
||||
page.locator('.cm-content')
|
||||
).toContainText(`exampleSketch = startSketchOn(XZ)
|
||||
|> startProfile(at = [0, 0])
|
||||
|> angledLine(angle = 50, length = 45 )
|
||||
|> angledLine(angle = 50deg, length = 45 )
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
|
||||
@ -321,7 +321,7 @@ extrude001 = extrude(sketch001, length = 50)
|
||||
`@settings(defaultLengthUnit = mm)
|
||||
sketch002 = startSketchOn(XY)
|
||||
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), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -458,10 +458,12 @@ extrude002 = extrude(profile002, length = 150)
|
||||
|
||||
// Click the stl.
|
||||
await expect(stlOption).toBeVisible()
|
||||
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Click the checkbox
|
||||
await expect(submitButton).toBeVisible()
|
||||
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Find the toast.
|
||||
@ -469,13 +471,11 @@ extrude002 = extrude(profile002, length = 150)
|
||||
await expect(exportingToastMessage).toBeVisible()
|
||||
|
||||
// Expect it to succeed.
|
||||
await expect(exportingToastMessage).not.toBeVisible()
|
||||
await expect(exportingToastMessage).not.toBeVisible({ timeout: 15_000 })
|
||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
||||
|
||||
const successToastMessage = page.getByText(`Exported successfully`)
|
||||
await page.waitForTimeout(1_000)
|
||||
const count = await successToastMessage.count()
|
||||
await expect(count).toBeGreaterThanOrEqual(1)
|
||||
await expect(successToastMessage).toBeVisible()
|
||||
}
|
||||
)
|
||||
// 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.closeDebugPanel()
|
||||
|
||||
// click profile in code
|
||||
await page.getByText(`startProfile(at = [-0.45, 0.87])`).click()
|
||||
// click "line(end = [1.32, 0.38])"
|
||||
await page.getByText(`line(end = [1.32, 0.38])`).click()
|
||||
await page.waitForTimeout(100)
|
||||
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeEnabled(
|
||||
{ timeout: 10_000 }
|
||||
@ -1014,13 +1014,14 @@ profile001 = startProfile(sketch001, at = [${roundOff(scale * 69.6)}, ${roundOff
|
||||
// click extrude
|
||||
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.
|
||||
await cmdBar.progressCmdBar()
|
||||
await cmdBar.expectState({
|
||||
stage: 'arguments',
|
||||
currentArgKey: 'length',
|
||||
currentArgValue: '5',
|
||||
headerArguments: { Profiles: '1 profile', Length: '' },
|
||||
headerArguments: { Sketches: '1 segment', Length: '' },
|
||||
highlightedHeaderArg: 'length',
|
||||
commandName: 'Extrude',
|
||||
})
|
||||
@ -1221,7 +1222,7 @@ profile001 = startProfile(sketch001, at = [299.72, 230.82])
|
||||
fn lug(origin, length, diameter, plane) {
|
||||
lugSketch = startSketchOn(plane)
|
||||
|> startProfile(at = [origin[0] + lugDiameter / 2, origin[1]])
|
||||
|> angledLine(angle = 60, lengthY = lugHeadLength)
|
||||
|> angledLine(angle = 60deg, lengthY = lugHeadLength)
|
||||
|> xLine(endAbsolute = 0 + .001)
|
||||
|> yLine(endAbsolute = 0)
|
||||
|> close()
|
||||
@ -1286,7 +1287,7 @@ extrude001 = extrude(profile001, length = 200)
|
||||
|> translate(x = 3.14, y = 3.14, z = -50.154)
|
||||
sketch002 = startSketchOn(XY)
|
||||
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), length = -segLen(rectangleSegmentA001), tag = $mySeg)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|
||||
@ -2057,7 +2058,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
||||
)
|
||||
await crnRect1point2()
|
||||
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), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -2072,7 +2073,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
||||
await crnRect2point2()
|
||||
await page.waitForTimeout(300)
|
||||
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), length = -segLen(rectangleSegmentA002))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -2091,7 +2092,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
||||
await cntrRect1point2()
|
||||
await page.waitForTimeout(300)
|
||||
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), length = -segLen(rectangleSegmentA003))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -2107,7 +2108,7 @@ profile003 = startProfile(sketch001, at = [206.63, -56.73])
|
||||
await cntrRect2point2()
|
||||
await page.waitForTimeout(300)
|
||||
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), length = -segLen(rectangleSegmentA004))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -2257,7 +2258,7 @@ profile001 = startProfile(sketch001, at = [6.24, 4.54])
|
||||
|> line(end = [8.61, 0.74])
|
||||
|> line(end = [10.99, -5.22])
|
||||
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), length = -segLen(rectangleSegmentA001))
|
||||
|> 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 rectEnd()
|
||||
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), length = -segLen(rectangleSegmentA002))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -2395,7 +2396,7 @@ profile001 = startProfile(sketch001, at = [6.24, 4.54])
|
||||
|> line(end = [8.61, 0.74])
|
||||
|> line(end = [10.99, -5.22])
|
||||
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), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -2500,7 +2501,7 @@ profile001 = startProfile(sketch001, at = [-63.43, 193.08])
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
|> close()
|
||||
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), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -2725,7 +2726,7 @@ profile002 = startProfile(sketch002, at = [0.75, 13.46])
|
||||
|> line(end = [4.52, 3.79])
|
||||
|> line(end = [5.98, -2.81])
|
||||
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), length = -segLen(rectangleSegmentA001))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -2743,7 +2744,7 @@ profile006 = startProfile(sketch002, at = [9.65, 3.82])
|
||||
|> close()
|
||||
revolve001 = revolve(
|
||||
profile004,
|
||||
angle = 45,
|
||||
angle = 45deg,
|
||||
axis = getNextAdjacentEdge(seg01)
|
||||
)
|
||||
extrude002 = extrude(profile006, length = 4)
|
||||
@ -2767,14 +2768,14 @@ profile010 = circle(
|
||||
radius = 2.67
|
||||
)
|
||||
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), length = -segLen(rectangleSegmentA002))
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
|> close()
|
||||
extrude003 = extrude(profile011, length = 2.5)
|
||||
// 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 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 ({
|
||||
@ -2989,7 +2990,7 @@ loft([profile001, profile002])
|
||||
)
|
||||
await rect1Crn2()
|
||||
await editor.expectEditor.toContain(
|
||||
`angledLine(angle = 0, length = 106.42], tag = $rectangleSegmentA001)`
|
||||
`angledLine(angle = 0deg, length = 106.42], tag = $rectangleSegmentA001)`
|
||||
)
|
||||
await page.waitForTimeout(100)
|
||||
})
|
||||
@ -3211,7 +3212,7 @@ test.describe('manual edits during sketch mode', () => {
|
||||
extrude001 = extrude(profile001, length = 500)
|
||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||
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(
|
||||
angle = -151,
|
||||
@ -3347,7 +3348,7 @@ profile001 = startProfile(sketch001, at = [106.68, 89.77])
|
||||
extrude001 = extrude(profile001, length = 500)
|
||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||
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(angle = -151, length = 116.27)
|
||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||
@ -3386,7 +3387,7 @@ profile003 = startProfile(sketch002, at = [-201.08, 254.17])
|
||||
extrude001 = extrude(profile001, length = 500)
|
||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
||||
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(
|
||||
angle = -151,
|
||||
|
@ -845,7 +845,7 @@ test.describe('code color goober', { tag: '@snapshot' }, () => {
|
||||
sweepPath = startSketchOn(XZ)
|
||||
|> startProfile(at = [0.05, 0.05])
|
||||
|> line(end = [0, 7])
|
||||
|> tangentialArc(angle = 90, radius = 5)
|
||||
|> tangentialArc(angle = 90deg, radius = 5)
|
||||
|> line(end = [-3, 0])
|
||||
|> tangentialArc(angle = -90, radius = 5)
|
||||
|> line(end = [0, 7])
|
||||
@ -889,7 +889,7 @@ sweepSketch = startSketchOn(XY)
|
||||
sweepPath = startSketchOn(XZ)
|
||||
|> startProfile(at = [0.05, 0.05])
|
||||
|> line(end = [0, 7])
|
||||
|> tangentialArc(angle = 90, radius = 5)
|
||||
|> tangentialArc(angle = 90deg, radius = 5)
|
||||
|> line(end = [-3, 0])
|
||||
|> tangentialArc(angle = -90, radius = 5)
|
||||
|> line(end = [0, 7])
|
||||
@ -934,7 +934,7 @@ sweepSketch = startSketchOn(XY)
|
||||
sweepPath = startSketchOn(XZ)
|
||||
|> startProfile(at = [0.05, 0.05])
|
||||
|> line(end = [0, 7])
|
||||
|> tangentialArc(angle = 90, radius = 5)
|
||||
|> tangentialArc(angle = 90deg, radius = 5)
|
||||
|> line(end = [-3, 0])
|
||||
|> tangentialArc(angle = -90, radius = 5)
|
||||
|> 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 |