Compare commits
273 Commits
pierremtb/
...
pierremtb/
Author | SHA1 | Date | |
---|---|---|---|
fecf5c2ee7 | |||
8ef31a0be1 | |||
3adb42b5f2 | |||
20016b101e | |||
8d9dbf36c3 | |||
440704ed9f | |||
2261217a5d | |||
10da986649 | |||
10789d9c3c | |||
67cc4f5835 | |||
2692f2b73a | |||
965cb18059 | |||
a022b8ef6c | |||
4d24bf7c94 | |||
9a537da183 | |||
df81b76b8b | |||
ac3f7ab712 | |||
d531728675 | |||
1d78fc15ac | |||
c32aebc8ad | |||
997ebce3eb | |||
dac91d3b79 | |||
1eaf371b44 | |||
0698432abf | |||
54da18d8ab | |||
2fe5ef7034 | |||
16b5eeadb1 | |||
7be4001839 | |||
ffb2559787 | |||
0592d3b5da | |||
31e4d60045 | |||
c0817b00e4 | |||
4ea1d16fb6 | |||
d049bf33e8 | |||
7b11047d07 | |||
412e9568f2 | |||
9be208e5e1 | |||
842ef5ede9 | |||
3f855d7bad | |||
0a1a6e50cf | |||
d4e955289c | |||
c147a219f4 | |||
38513a1e25 | |||
c0c5c790ca | |||
8b60f75220 | |||
f91ad4331f | |||
59103a2118 | |||
9737c2550a | |||
bf9d01a8dd | |||
702e322f90 | |||
e82830754d | |||
7806377a5a | |||
859afa2fd8 | |||
0a5f3093fc | |||
b65f7939f6 | |||
c35dea5e07 | |||
fc66d4745f | |||
b313d26c2a | |||
00b94ead62 | |||
0531ea1ce9 | |||
5f9a4887c1 | |||
da7dfa16d8 | |||
363ae10658 | |||
ac4a6c84cf | |||
c6fad2e2dc | |||
013cb10961 | |||
6261083cb1 | |||
2b0ba37ed0 | |||
96174f3cf6 | |||
aed62ff912 | |||
9334d64608 | |||
4fa7d2d8c8 | |||
3e615dfdbc | |||
c9860af29f | |||
23a42f0195 | |||
a77fa639f3 | |||
0a5ad7c95b | |||
4a654523d2 | |||
73a7e2bfd6 | |||
eb0850fea9 | |||
029f76f273 | |||
28b5f7080c | |||
5b1dcfecd6 | |||
f89d191425 | |||
2f4e4b62a8 | |||
5ebd5c8dbb | |||
a9ceaf2678 | |||
c8afd3399b | |||
5dda4828c6 | |||
72acab752c | |||
81df38ad1c | |||
0576a2bef1 | |||
4b2f6b4647 | |||
69edaa4183 | |||
2eb7c382bf | |||
38913ecb98 | |||
debd06129f | |||
d38bd342a0 | |||
f026f10335 | |||
895d7ebc6d | |||
65edf17a44 | |||
0c2a0a8c07 | |||
97cef4d16c | |||
9358278f7b | |||
a174e084d4 | |||
df7246897a | |||
0c9f64dd7c | |||
d2b9d3a058 | |||
7e54f08778 | |||
d9c2dd376e | |||
275a2150e7 | |||
8b8feb8d68 | |||
e21ef3f122 | |||
66834931aa | |||
06c1bcaf2e | |||
fc7df7ecbe | |||
67cb7b33bb | |||
ea74b94fac | |||
529833c63f | |||
92da86391a | |||
e7cb390db4 | |||
8a66bbbdbd | |||
3c53babb50 | |||
474acb1c68 | |||
1c941112d7 | |||
6f1d718097 | |||
36957237c0 | |||
da9cae98aa | |||
9ae025dc56 | |||
579ab23d78 | |||
4bef33e745 | |||
ac7bd28c5a | |||
d478d81156 | |||
3d27f0191b | |||
30c2acd18a | |||
a83b4b2145 | |||
70b8541038 | |||
bb51646738 | |||
c02e31a530 | |||
1d06cc7845 | |||
e0c07eecfe | |||
c5d42500fa | |||
e6e47f77f0 | |||
662c2485ac | |||
9f891deebb | |||
d08a07a1f8 | |||
872b196a86 | |||
d535a2862d | |||
63a3bc7bc6 | |||
02055a8b31 | |||
93891422f7 | |||
7193b4110a | |||
76e7d80a55 | |||
b816df21d2 | |||
3630696848 | |||
f165d19fda | |||
3dd98ae1d5 | |||
a46e0a0fe7 | |||
8f9dc06228 | |||
fa22c14723 | |||
1d39983b08 | |||
da301ba862 | |||
efe8089b08 | |||
49de3b0ac9 | |||
2b2ed470c1 | |||
96652a0c48 | |||
04e586d07b | |||
fe5f574a77 | |||
e787495ad0 | |||
8bb9be7a5e | |||
00892464e8 | |||
05ed2a3367 | |||
10cc5bce59 | |||
a32f150fc1 | |||
ac60082e67 | |||
d44dc1b21a | |||
813962ea4c | |||
738443a6ab | |||
4b6bbbe2c5 | |||
6ff8addc8b | |||
da05c38b9e | |||
191b9b71fd | |||
05163fdded | |||
7ed26e21c6 | |||
c668d40efc | |||
f38c6b90b7 | |||
7bc8bae0ec | |||
3804aca27e | |||
b127680f2f | |||
b7de8e60cf | |||
058fccb5e1 | |||
00e97257ae | |||
aeb656d176 | |||
ac49ebd6e0 | |||
b40f03ad25 | |||
a8ad86e645 | |||
87f50cd5e9 | |||
0400e6228e | |||
26f150fd6c | |||
3049f405f5 | |||
53d40301dc | |||
671c01e36f | |||
e80151979b | |||
668e2afb99 | |||
548c664db0 | |||
d3a3f4410c | |||
22eb343171 | |||
f2cfa4d5cf | |||
3f1f40eeba | |||
ff2d161606 | |||
210c78029d | |||
e27840219b | |||
c943a3f192 | |||
6aa588f09f | |||
59a6333aad | |||
403f1507ae | |||
eac7b83504 | |||
667500d1b9 | |||
b15aac9f48 | |||
54153aa646 | |||
943cf21d34 | |||
5a6728c45a | |||
ff2103d493 | |||
2dfa8f2176 | |||
29ed330326 | |||
ca2cc825a6 | |||
83fe1b7ce0 | |||
157b76cc78 | |||
cf957d880e | |||
dfc3d19677 | |||
dd370a9365 | |||
2274d6459c | |||
32ce857119 | |||
88b51da417 | |||
30d365aeb3 | |||
7af62399ac | |||
441d957228 | |||
9e57034873 | |||
eb96d6539c | |||
513c76ecc8 | |||
51d9449280 | |||
6366bc4766 | |||
7a21918223 | |||
8072f1db63 | |||
18e1855fa9 | |||
7be53c7d4a | |||
2bf20988ef | |||
1495cc6d18 | |||
f876e6ca3c | |||
60a0c811ab | |||
cab0c1e6a1 | |||
417d720b22 | |||
77293952c0 | |||
ea3d604b73 | |||
023a659491 | |||
dd3a2b14f9 | |||
424b409cc1 | |||
82a58e69c2 | |||
776b420031 | |||
1087d4223b | |||
089d6df889 | |||
efb067af58 | |||
2aa27eab01 | |||
9c47ac5b57 | |||
5ae1aecd74 | |||
68ae7e98f9 | |||
56771d561a | |||
f09411817c | |||
bed7ae3b8b | |||
c43510732c | |||
51f0b669a4 | |||
3cbedcd3e7 | |||
5d2fa43150 |
@ -1,3 +1,3 @@
|
||||
[codespell]
|
||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey,atleast,ue,afterall
|
||||
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock,./openapi/*.json,./src/lib/machine-api.d.ts
|
||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser
|
||||
skip: **/target,node_modules,build,dist,./out,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock,./openapi/*.json,./packages/codemirror-lang-kcl/test/all.test.ts,tsconfig.tsbuildinfo
|
||||
|
28
.eslintrc
28
.eslintrc
@ -5,16 +5,32 @@
|
||||
},
|
||||
"plugins": [
|
||||
"css-modules",
|
||||
"jest",
|
||||
"jsx-a11y",
|
||||
"react",
|
||||
"react-hooks",
|
||||
"suggest-no-throw",
|
||||
"testing-library",
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest",
|
||||
"plugin:css-modules/recommended"
|
||||
"plugin:css-modules/recommended",
|
||||
"plugin:jsx-a11y/recommended",
|
||||
"plugin:react-hooks/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-floating-promises": "error",
|
||||
"@typescript-eslint/no-misused-promises": "error",
|
||||
"jsx-a11y/click-events-have-key-events": "off",
|
||||
"jsx-a11y/no-autofocus": "off",
|
||||
"jsx-a11y/no-noninteractive-element-interactions": "off",
|
||||
"no-restricted-globals": [
|
||||
"error",
|
||||
{
|
||||
"name": "isNaN",
|
||||
"message": "Use Number.isNaN() instead."
|
||||
}
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"never"
|
||||
@ -25,6 +41,9 @@
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
|
||||
"extends": [
|
||||
"plugin:testing-library/react"
|
||||
],
|
||||
"rules": {
|
||||
"suggest-no-throw/suggest-no-throw": "off",
|
||||
"testing-library/prefer-screen-queries": "off",
|
||||
@ -33,6 +52,9 @@
|
||||
},
|
||||
{
|
||||
"files": ["src/**/*.test.ts"],
|
||||
"extends": [
|
||||
"plugin:testing-library/react"
|
||||
],
|
||||
"rules": {
|
||||
"suggest-no-throw/suggest-no-throw": "off",
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
# bash strict mode
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ! -f "test-results/.last-run.json" ]]; then
|
||||
# if no last run artifact, than run plawright normally
|
||||
echo "run playwright normally"
|
||||
if [[ "$3" == ubuntu-latest* ]]; then
|
||||
yarn test:playwright:browser:chrome:ubuntu -- --shard=$1/$2 || true
|
||||
elif [[ "$3" == windows-latest* ]]; then
|
||||
yarn test:playwright:browser:chrome:windows -- --shard=$1/$2 || true
|
||||
else
|
||||
echo "Do not run playwright. Unable to detect os runtime."
|
||||
exit 1
|
||||
fi
|
||||
# # send to axiom
|
||||
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
retry=1
|
||||
max_retrys=4
|
||||
|
||||
# retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
|
||||
while [[ $retry -le $max_retrys ]]; do
|
||||
if [[ -f "test-results/.last-run.json" ]]; then
|
||||
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
|
||||
if [[ $failed_tests -gt 0 ]]; then
|
||||
echo "retried=true" >>$GITHUB_OUTPUT
|
||||
echo "run playwright with last failed tests and retry $retry"
|
||||
if [[ "$3" == ubuntu-latest* ]]; then
|
||||
yarn test:playwright:browser:chrome:ubuntu -- --last-failed || true
|
||||
elif [[ "$3" == windows-latest* ]]; then
|
||||
yarn test:playwright:browser:chrome:windows -- --last-failed || true
|
||||
else
|
||||
echo "Do not run playwright. Unable to detect os runtime."
|
||||
exit 1
|
||||
fi
|
||||
# send to axiom
|
||||
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
||||
retry=$((retry + 1))
|
||||
else
|
||||
echo "retried=false" >>$GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
echo "retried=false" >>$GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
echo "retried=false" >>$GITHUB_OUTPUT
|
||||
|
||||
if [[ -f "test-results/.last-run.json" ]]; then
|
||||
failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
|
||||
if [[ $failed_tests -gt 0 ]]; then
|
||||
# if it still fails after 3 retrys, then fail the job
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
exit 0
|
22
.github/ci-cd-scripts/playwright-electron.sh
vendored
22
.github/ci-cd-scripts/playwright-electron.sh
vendored
@ -1,15 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# bash strict mode
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ! -f "test-results/.last-run.json" ]]; then
|
||||
# if no last run artifact, than run plawright normally
|
||||
echo "run playwright normally"
|
||||
if [[ "$1" == ubuntu-latest* ]]; then
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu || true
|
||||
elif [[ "$1" == windows-latest* ]]; then
|
||||
yarn test:playwright:electron:windows || true
|
||||
elif [[ "$1" == macos-14* ]]; then
|
||||
yarn test:playwright:electron:macos || true
|
||||
if [[ "$3" == *ubuntu* ]]; then
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --shard=$1/$2 || true
|
||||
elif [[ "$3" == *windows* ]]; then
|
||||
yarn test:playwright:electron:windows -- --shard=$1/$2 || true
|
||||
elif [[ "$3" == *macos* ]]; then
|
||||
yarn test:playwright:electron:macos -- --shard=$1/$2 || true
|
||||
else
|
||||
echo "Do not run playwright. Unable to detect os runtime."
|
||||
exit 1
|
||||
@ -19,7 +21,7 @@ if [[ ! -f "test-results/.last-run.json" ]]; then
|
||||
fi
|
||||
|
||||
retry=1
|
||||
max_retrys=4
|
||||
max_retrys=5
|
||||
|
||||
# retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
|
||||
while [[ $retry -le $max_retrys ]]; do
|
||||
@ -28,11 +30,11 @@ while [[ $retry -le $max_retrys ]]; do
|
||||
if [[ $failed_tests -gt 0 ]]; then
|
||||
echo "retried=true" >>$GITHUB_OUTPUT
|
||||
echo "run playwright with last failed tests and retry $retry"
|
||||
if [[ "$1" == ubuntu-latest* ]]; then
|
||||
if [[ "$3" == *ubuntu* ]]; then
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test:playwright:electron:ubuntu -- --last-failed || true
|
||||
elif [[ "$1" == windows-latest* ]]; then
|
||||
elif [[ "$3" == *windows* ]]; then
|
||||
yarn test:playwright:electron:windows -- --last-failed || true
|
||||
elif [[ "$1" == macos-14* ]]; then
|
||||
elif [[ "$3" == *macos* ]]; then
|
||||
yarn test:playwright:electron:macos -- --last-failed || true
|
||||
else
|
||||
echo "Do not run playwright. Unable to detect os runtime."
|
||||
|
55
.github/dependabot.yml
vendored
55
.github/dependabot.yml
vendored
@ -5,24 +5,37 @@
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'npm' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- franknoirot
|
||||
- irev-dev
|
||||
- package-ecosystem: 'github-actions' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||
directory: '/src/wasm-lib/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'npm' # See documentation for possible values
|
||||
directories:
|
||||
- '/'
|
||||
- '/packages/codemirror-lang-kcl/'
|
||||
- '/packages/codemirror-lsp-client/'
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
reviewers:
|
||||
- franknoirot
|
||||
- irev-dev
|
||||
- package-ecosystem: 'github-actions' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||
directory: '/src/wasm-lib/' # Location of package manifests
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: monday
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
groups:
|
||||
serde-dependencies:
|
||||
patterns:
|
||||
- "serde*"
|
||||
wasm-bindgen-deps:
|
||||
patterns:
|
||||
- "wasm-bindgen*"
|
||||
|
2
.github/workflows/build-and-store-wasm.yml
vendored
2
.github/workflows/build-and-store-wasm.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
|
||||
|
||||
# Upload the WASM bundle as an artifact
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wasm-bundle
|
||||
path: src/wasm-lib/pkg
|
||||
|
53
.github/workflows/build-apps.yml
vendored
53
.github/workflows/build-apps.yml
vendored
@ -126,7 +126,13 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn' # Set this to npm, yarn or pnpm.
|
||||
|
||||
- run: yarn install
|
||||
- name: yarn install
|
||||
# Windows is picky sometimes and fails on fetch. Step takes about ~30s
|
||||
uses: nick-fields/retry@v3.0.0
|
||||
with:
|
||||
timeout_minutes: 2
|
||||
max_attempts: 3
|
||||
command: yarn install
|
||||
|
||||
- run: yarn tronb:vite
|
||||
|
||||
@ -165,7 +171,6 @@ jobs:
|
||||
- name: Build the app (release)
|
||||
if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
|
||||
env:
|
||||
PUBLISH_FOR_PULL_REQUEST: true
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
@ -173,9 +178,14 @@ jobs:
|
||||
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
CSC_FOR_PULL_REQUEST: true
|
||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||
run: yarn electron-builder --config --publish always
|
||||
DEBUG: "electron-notarize*"
|
||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||
uses: nick-fields/retry@v3.0.0
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: yarn electron-builder --config --publish always
|
||||
|
||||
- name: List artifacts in out/
|
||||
run: ls -R out
|
||||
@ -229,9 +239,14 @@ jobs:
|
||||
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
CSC_FOR_PULL_REQUEST: true
|
||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||
run: yarn electron-builder --config --publish always
|
||||
DEBUG: "electron-notarize*"
|
||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||
uses: nick-fields/retry@v3.0.0
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: yarn electron-builder --config --publish always
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ env.IS_RELEASE == 'true' }}
|
||||
@ -362,6 +377,17 @@ jobs:
|
||||
- name: List artifacts
|
||||
run: "ls -R out"
|
||||
|
||||
- name: Set more complete nightly release notes
|
||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||
run: |
|
||||
# Note: preferred going this way instead of a full clone in the checkout step,
|
||||
# see https://github.com/actions/checkout/issues/1471
|
||||
git fetch --prune --unshallow --tags
|
||||
export TAG="nightly-${VERSION}"
|
||||
export PREVIOUS_TAG=$(git describe --tags --match="nightly-v[0-9]*" --abbrev=0)
|
||||
export NOTES=$(./scripts/get-nightly-changelog.sh)
|
||||
yarn files:set-notes
|
||||
|
||||
- name: Authenticate to Google Cloud
|
||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||
uses: 'google-github-actions/auth@v2.1.7'
|
||||
@ -382,3 +408,18 @@ jobs:
|
||||
glob: '*'
|
||||
parent: false
|
||||
destination: 'dl.kittycad.io/releases/modeling-app/nightly'
|
||||
|
||||
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||
run: yarn files:invalidate-bucket:nightly
|
||||
|
||||
- name: Tag nightly commit
|
||||
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const { VERSION } = process.env
|
||||
const { owner, repo } = context.repo
|
||||
const { sha } = context
|
||||
const ref = `refs/tags/nightly-${VERSION}`
|
||||
github.rest.git.createRef({ owner, repo, sha, ref })
|
||||
|
44
.github/workflows/cargo-bench.yml
vendored
44
.github/workflows/cargo-bench.yml
vendored
@ -1,44 +0,0 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- '**.rs'
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- .github/workflows/cargo-bench.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.rs'
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- .github/workflows/cargo-bench.yml
|
||||
workflow_dispatch:
|
||||
permissions: read-all
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
name: cargo bench
|
||||
jobs:
|
||||
cargo-bench:
|
||||
name: Benchmark with iai
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cargo install cargo-criterion
|
||||
sudo apt update
|
||||
sudo apt install -y valgrind
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2.6.1
|
||||
- name: Benchmark kcl library
|
||||
shell: bash
|
||||
run: |-
|
||||
cd src/wasm-lib/kcl; cargo bench --all-features -- iai
|
||||
env:
|
||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
|
||||
|
22
.github/workflows/cargo-test.yml
vendored
22
.github/workflows/cargo-test.yml
vendored
@ -2,28 +2,8 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/wasm-lib/**.rs'
|
||||
- 'src/wasm-lib/**.hbs'
|
||||
- 'src/wasm-lib/**.gen'
|
||||
- 'src/wasm-lib/**.snap'
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- 'src/wasm-lib/**.kcl'
|
||||
- .github/workflows/cargo-test.yml
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/wasm-lib/**.rs'
|
||||
- 'src/wasm-lib/**.hbs'
|
||||
- 'src/wasm-lib/**.gen'
|
||||
- 'src/wasm-lib/**.snap'
|
||||
- '**/Cargo.toml'
|
||||
- '**/Cargo.lock'
|
||||
- '**/rust-toolchain.toml'
|
||||
- 'src/wasm-lib/**.kcl'
|
||||
- .github/workflows/cargo-test.yml
|
||||
workflow_dispatch:
|
||||
permissions: read-all
|
||||
concurrency:
|
||||
@ -71,7 +51,7 @@ jobs:
|
||||
KITTYCAD_API_TOKEN: ${{secrets.KITTYCAD_API_TOKEN}}
|
||||
RUST_MIN_STACK: 10485760000
|
||||
- name: Upload to codecov.io
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{secrets.CODECOV_TOKEN}}
|
||||
fail_ci_if_error: true
|
||||
|
32
.github/workflows/codemirror-lang-kcl.yml
vendored
Normal file
32
.github/workflows/codemirror-lang-kcl.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: CodeMirror Lang KCL
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
yarn-unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
|
||||
- run: yarn install
|
||||
working-directory: packages/codemirror-lang-kcl
|
||||
|
||||
- run: yarn tsc
|
||||
working-directory: packages/codemirror-lang-kcl
|
||||
|
||||
- name: run unit tests
|
||||
run: yarn test
|
||||
working-directory: packages/codemirror-lang-kcl
|
168
.github/workflows/e2e-tests.yml
vendored
168
.github/workflows/e2e-tests.yml
vendored
@ -33,20 +33,19 @@ jobs:
|
||||
rust:
|
||||
- 'src/wasm-lib/**'
|
||||
|
||||
browser:
|
||||
timeout-minutes: ${{ matrix.os == 'macos-14' && 60 || 50 }}
|
||||
name: playwright:browser:${{ matrix.os }} ${{ matrix.shardIndex }} ${{ matrix.shardTotal }}
|
||||
electron:
|
||||
timeout-minutes: 60
|
||||
name: playwright:electron:${{ matrix.os }} ${{ matrix.shardIndex }} ${{ matrix.shardTotal }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest-8-cores, windows-latest-8-cores]
|
||||
# TODO: enable self-hosted-windows-8-cores once available
|
||||
os: [namespace-profile-ubuntu-8-cores, namespace-profile-macos-8-cores, windows-16-cores]
|
||||
shardIndex: [1, 2, 3, 4]
|
||||
shardTotal: [4]
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: check-rust-changes
|
||||
steps:
|
||||
- name: Tune GitHub-hosted runner network
|
||||
uses: smorimoto/tune-github-hosted-runner-network@v1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
@ -68,7 +67,7 @@ jobs:
|
||||
- name: Download Wasm Cache
|
||||
id: download-wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
uses: dawidd6/action-download-artifact@v7
|
||||
continue-on-error: true
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
@ -101,7 +100,8 @@ jobs:
|
||||
echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
|
||||
- name: Install vector
|
||||
shell: bash
|
||||
if: ${{ !startsWith(matrix.os, 'windows') }}
|
||||
# TODO: figure out what to do with this, it's failing
|
||||
if: false
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
|
||||
chmod +x /tmp/vector.sh
|
||||
@ -123,13 +123,16 @@ jobs:
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
shell: bash
|
||||
run: yarn build:wasm
|
||||
- name: build web
|
||||
run: yarn build:local
|
||||
- name: build electron
|
||||
shell: bash
|
||||
run: yarn tron:package
|
||||
- name: Run ubuntu/chrome snapshots
|
||||
if: ${{ matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 }}
|
||||
shell: bash
|
||||
# TODO: break this in its own job, for now it's not slowing down the overall execution as ubuntu is the quickest,
|
||||
# but we could do better. This forces a large 1/1 shard of all 20 snapshot tests that runs in about 3 minutes.
|
||||
run: |
|
||||
yarn playwright test --project="Google Chrome" --config=playwright.ci.config.ts --retries="3" --update-snapshots --grep=@snapshot --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||
PLATFORM=web yarn playwright test --config=playwright.config.ts --retries="3" --update-snapshots --grep=@snapshot --shard=1/1
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: development
|
||||
@ -150,6 +153,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
run: rm -r test-results
|
||||
- name: check for changes
|
||||
if: ${{ matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 }}
|
||||
shell: bash
|
||||
id: git-check
|
||||
run: |
|
||||
@ -186,12 +190,12 @@ jobs:
|
||||
with:
|
||||
name: test-results-${{ matrix.os }}-${{ matrix.shardIndex }}-${{ github.sha }}
|
||||
path: test-results/
|
||||
- name: Run playwright/chrome flow (with retries)
|
||||
- name: Run playwright/electron flow (with retries)
|
||||
id: retry
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
shell: bash
|
||||
run: |
|
||||
.github/ci-cd-scripts/playwright-browser-chrome.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{matrix.os}}
|
||||
.github/ci-cd-scripts/playwright-electron.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{matrix.os}}
|
||||
env:
|
||||
CI: true
|
||||
FAIL_ON_CONSOLE_ERRORS: true
|
||||
@ -199,11 +203,6 @@ jobs:
|
||||
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
VITE_KC_SKIP_AUTH: true
|
||||
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
- name: send to axiom
|
||||
if: always()
|
||||
shell: bash
|
||||
run: |
|
||||
node playwrightProcess.mjs | tee /tmp/github-actions.log
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
@ -221,136 +220,3 @@ jobs:
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
|
||||
|
||||
electron:
|
||||
name: playwright:electron:${{matrix.os}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest-8-cores, windows-latest-8-cores, macos-14-large]
|
||||
timeout-minutes: 60
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: check-rust-changes
|
||||
steps:
|
||||
- name: Tune GitHub-hosted runner network
|
||||
uses: smorimoto/tune-github-hosted-runner-network@v1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- uses: KittyCAD/action-install-cli@main
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: yarn
|
||||
- name: Cache Playwright Browsers
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright/
|
||||
key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
|
||||
- name: Install Playwright Browsers
|
||||
shell: bash
|
||||
run: yarn playwright install chromium --with-deps
|
||||
- name: Download Wasm Cache
|
||||
id: download-wasm
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
continue-on-error: true
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
name: wasm-bundle
|
||||
workflow: build-and-store-wasm.yml
|
||||
branch: main
|
||||
path: src/wasm-lib/pkg
|
||||
- name: copy wasm blob
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'false'
|
||||
shell: bash
|
||||
run: cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
|
||||
continue-on-error: true
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Cache Wasm (because rust diff)
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
- name: OR Cache Wasm (because wasm cache failed)
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src/wasm-lib'
|
||||
- name: install good sed
|
||||
if: ${{ startsWith(matrix.os, 'macos') }}
|
||||
shell: bash
|
||||
run: |
|
||||
brew install gnu-sed
|
||||
echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
|
||||
- name: Install vector
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
shell: bash
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
|
||||
chmod +x /tmp/vector.sh
|
||||
/tmp/vector.sh -y -no-modify-path
|
||||
mkdir -p /tmp/vector
|
||||
cp .github/workflows/vector.toml /tmp/vector.toml
|
||||
sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
|
||||
sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
|
||||
sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
|
||||
sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
|
||||
sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
|
||||
cat /tmp/vector.toml
|
||||
${HOME}/.vector/bin/vector --config /tmp/vector.toml &
|
||||
- name: Build Wasm (because rust diff)
|
||||
if: needs.check-rust-changes.outputs.rust-changed == 'true'
|
||||
shell: bash
|
||||
run: yarn build:wasm
|
||||
- name: OR Build Wasm (because wasm cache failed)
|
||||
if: steps.download-wasm.outcome == 'failure'
|
||||
shell: bash
|
||||
run: yarn build:wasm
|
||||
- name: build electron
|
||||
shell: bash
|
||||
run: yarn tron:package
|
||||
- uses: actions/download-artifact@v4
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: test-results-electron-${{ matrix.os }}-${{ github.sha }}
|
||||
path: test-results/
|
||||
- name: Run electron tests (with retries)
|
||||
id: retry
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
shell: bash
|
||||
run: |
|
||||
.github/ci-cd-scripts/playwright-electron.sh ${{ matrix.os }}
|
||||
env:
|
||||
CI: true
|
||||
FAIL_ON_CONSOLE_ERRORS: true
|
||||
NODE_ENV: development
|
||||
VITE_KC_DEV_TOKEN: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||
VITE_KC_SKIP_AUTH: true
|
||||
IS_UBUNTU: ${{ startsWith(matrix.os, 'ubuntu') && 'true' || 'false' }}
|
||||
#DEBUG: 'pw:browser*'
|
||||
- name: send to axiom
|
||||
if: ${{ !cancelled() && (success() || failure()) && !startsWith(matrix.os, 'windows') }}
|
||||
shell: bash
|
||||
run: |
|
||||
node playwrightProcess.mjs | tee /tmp/github-actions.log
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
with:
|
||||
name: test-results-electron-${{ matrix.os }}-${{ github.sha }}
|
||||
path: test-results/
|
||||
include-hidden-files: true
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
with:
|
||||
name: playwright-report-electron-${{ matrix.os }}-${{ github.sha }}
|
||||
path: playwright-report/
|
||||
include-hidden-files: true
|
||||
retention-days: 30
|
||||
overwrite: true
|
||||
|
6
.github/workflows/publish-apps-release.yml
vendored
6
.github/workflows/publish-apps-release.yml
vendored
@ -126,11 +126,7 @@ jobs:
|
||||
destination: 'dl.kittycad.io/releases/modeling-app'
|
||||
|
||||
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
||||
run: |
|
||||
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/last_download.json" --async
|
||||
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-linux-arm64.yml" --async
|
||||
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest-mac.yml" --async
|
||||
gcloud compute url-maps invalidate-cdn-cache dl-url-map --path="/releases/modeling-app/latest.yml" --async
|
||||
run: yarn files:invalidate-bucket
|
||||
|
||||
- name: Upload release files to Github
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -61,6 +61,7 @@ Mac_App_Distribution.provisionprofile
|
||||
*.tsbuildinfo
|
||||
src/wasm-lib/pkg
|
||||
|
||||
.eslintcache
|
||||
venv
|
||||
.vite/
|
||||
|
||||
|
43
INSTALL.md
Normal file
43
INSTALL.md
Normal file
@ -0,0 +1,43 @@
|
||||
# Setting Up Zoo Modeling App
|
||||
|
||||
Compared to other CAD software, getting Zoo Modeling App up and running is quick and straightforward across platforms. It's about 100MB to download and is quick to install.
|
||||
|
||||
## Windows
|
||||
|
||||
1. Download the [Zoo Modeling App installer](https://zoo.dev/modeling-app/download) for Windows and for your processor type.
|
||||
|
||||
2. Once downloaded, run the installer `Zoo Modeling App-{version}-{arch}-win.exe` which should take a few seconds.
|
||||
|
||||
3. The installation happens at `C:\Program Files\Zoo Modeling App`. A shortcut in the start menu is also created so you can run the app easily by clicking on it.
|
||||
|
||||
## macOS
|
||||
|
||||
1. Download the [Zoo Modeling App installer](https://zoo.dev/modeling-app/download) for macOS and for your processor type.
|
||||
|
||||
2. Once downloaded, open the disk image `Zoo Modeling App-{version}-{arch}-mac.dmg` and drag the applications to your `Applications` directory.
|
||||
|
||||
3. You can then open your `Applications` directory and double-click on `Zoo Modeling App` to open.
|
||||
|
||||
|
||||
## Linux
|
||||
|
||||
1. Download the [Zoo Modeling App installer](https://zoo.dev/modeling-app/download) for Linux and for your processor type.
|
||||
|
||||
2. Install the dependencies needed to run the [AppImage format](https://appimage.org/).
|
||||
- On Ubuntu, install the FUSE library with these commands in a terminal.
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install libfuse2
|
||||
```
|
||||
- Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless.
|
||||
- Once installed, copy the downloaded `Zoo Modeling App-{version}-{arch}-linux.AppImage` to the directory of your choice, for instance `~/Applications`.
|
||||
|
||||
- `appimaged` should automatically find it and make it executable. If not, run:
|
||||
```bash
|
||||
chmod a+x ~/Applications/Zoo\ Modeling\ App-{version}-{arch}-linux.AppImage
|
||||
```
|
||||
|
||||
3. You can double-click on the AppImage to run it, or in a terminal with this command:
|
||||
```bash
|
||||
~/Applications/Zoo\ Modeling\ App-{version}-{arch}-linux.AppImage
|
||||
```
|
59
README.md
59
README.md
@ -99,7 +99,7 @@ yarn tron:start
|
||||
|
||||
This will start the application and hot-reload on changes.
|
||||
|
||||
Devtools can be opened with the usual Cmd/Ctrl-Shift-I.
|
||||
Devtools can be opened with the usual Cmd-Opt-I (Mac) or Ctrl-Shift-I (Linux and Windows).
|
||||
|
||||
To build, run `yarn tron:package`.
|
||||
|
||||
@ -337,13 +337,47 @@ For individual testing:
|
||||
yarn test abstractSyntaxTree -t "unexpected closed curly brace" --silent=false
|
||||
```
|
||||
|
||||
Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testing Library E2E](https://testing-library.com/docs/react-testing-library/intro/) tests, in interactive mode by default.
|
||||
Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testing Library E2E](https://testing-library.com/docs/react-testing-library/intro) tests, in interactive mode by default.
|
||||
|
||||
### Rust tests
|
||||
|
||||
```bash
|
||||
**Dependencies**
|
||||
|
||||
- `KITTYCAD_API_TOKEN`
|
||||
- `cargo-nextest`
|
||||
- `just`
|
||||
|
||||
#### Setting KITTYCAD_API_TOKEN
|
||||
Use the production zoo.dev token, set this environment variable before running the tests
|
||||
|
||||
#### Installing cargonextest
|
||||
|
||||
```
|
||||
cd src/wasm-lib
|
||||
KITTYCAD_API_TOKEN=XXX cargo test -- --test-threads=1
|
||||
cargo search cargo-nextest
|
||||
cargo install cargo-nextest
|
||||
```
|
||||
|
||||
#### just
|
||||
install [`just`](https://github.com/casey/just?tab=readme-ov-file#pre-built-binaries)
|
||||
|
||||
#### Running the tests
|
||||
|
||||
```bash
|
||||
# With just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
# Make sure you installed just
|
||||
cd src/wasm-lib
|
||||
just test
|
||||
```
|
||||
|
||||
```bash
|
||||
# Without just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
cd src/wasm-lib
|
||||
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
|
||||
```
|
||||
|
||||
Where `XXX` is an API token from the production engine (NOT the dev environment).
|
||||
@ -388,23 +422,6 @@ yarn test:unit:local
|
||||
|
||||
#### E2E Tests
|
||||
|
||||
**Playwright Browser**
|
||||
|
||||
These E2E tests run in a browser (without electron).
|
||||
There are tests that are skipped if they are ran in a windows OS or Linux OS. We can use playwright tags to implement test skipping.
|
||||
|
||||
Breaking down the command `yarn test:playwright:browser:chrome:windows`
|
||||
- The application is `playwright`
|
||||
- The runtime is a `browser`
|
||||
- The specific `browser` is `chrome`
|
||||
- The test should run in a `windows` environment. It will skip tests that are broken or flaky in the windows OS.
|
||||
|
||||
```
|
||||
yarn test:playwright:browser:chrome
|
||||
yarn test:playwright:browser:chrome:windows
|
||||
yarn test:playwright:browser:chrome:ubuntu
|
||||
```
|
||||
|
||||
**Playwright Electron**
|
||||
|
||||
These E2E tests run in electron. There are tests that are skipped if they are ran in a windows, linux, or macos environment. We can use playwright tags to implement test skipping.
|
||||
|
@ -22,3 +22,5 @@ once fixed in engine will just start working here with no language changes.
|
||||
|
||||
- **Chamfers**: Chamfers cannot intersect, you will get an error. Only simple
|
||||
chamfer cases work currently.
|
||||
|
||||
- **Appearance**: Changing the appearance on a loft does not work.
|
||||
|
239
docs/kcl/appearance.md
Normal file
239
docs/kcl/appearance.md
Normal file
File diff suppressed because one or more lines are too long
49
docs/kcl/atan2.md
Normal file
49
docs/kcl/atan2.md
Normal file
File diff suppressed because one or more lines are too long
42
docs/kcl/circleThreePoint.md
Normal file
42
docs/kcl/circleThreePoint.md
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
43
docs/kcl/helixRevolutions.md
Normal file
43
docs/kcl/helixRevolutions.md
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -19,6 +19,7 @@ layout: manual
|
||||
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
|
||||
* [`angledLineToX`](kcl/angledLineToX)
|
||||
* [`angledLineToY`](kcl/angledLineToY)
|
||||
* [`appearance`](kcl/appearance)
|
||||
* [`arc`](kcl/arc)
|
||||
* [`arcTo`](kcl/arcTo)
|
||||
* [`asin`](kcl/asin)
|
||||
@ -29,10 +30,12 @@ layout: manual
|
||||
* [`assertLessThan`](kcl/assertLessThan)
|
||||
* [`assertLessThanOrEq`](kcl/assertLessThanOrEq)
|
||||
* [`atan`](kcl/atan)
|
||||
* [`atan2`](kcl/atan2)
|
||||
* [`bezierCurve`](kcl/bezierCurve)
|
||||
* [`ceil`](kcl/ceil)
|
||||
* [`chamfer`](kcl/chamfer)
|
||||
* [`circle`](kcl/circle)
|
||||
* [`circleThreePoint`](kcl/circleThreePoint)
|
||||
* [`close`](kcl/close)
|
||||
* [`cm`](kcl/cm)
|
||||
* [`cos`](kcl/cos)
|
||||
@ -45,11 +48,11 @@ layout: manual
|
||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||
* [`getPreviousAdjacentEdge`](kcl/getPreviousAdjacentEdge)
|
||||
* [`helix`](kcl/helix)
|
||||
* [`helixRevolutions`](kcl/helixRevolutions)
|
||||
* [`hole`](kcl/hole)
|
||||
* [`hollow`](kcl/hollow)
|
||||
* [`import`](kcl/import)
|
||||
* [`inch`](kcl/inch)
|
||||
* [`int`](kcl/int)
|
||||
* [`lastSegX`](kcl/lastSegX)
|
||||
* [`lastSegY`](kcl/lastSegY)
|
||||
* [`legAngX`](kcl/legAngX)
|
||||
@ -78,6 +81,7 @@ layout: manual
|
||||
* [`pi`](kcl/pi)
|
||||
* [`polar`](kcl/polar)
|
||||
* [`polygon`](kcl/polygon)
|
||||
* [`pop`](kcl/pop)
|
||||
* [`pow`](kcl/pow)
|
||||
* [`profileStart`](kcl/profileStart)
|
||||
* [`profileStartX`](kcl/profileStartX)
|
||||
@ -99,8 +103,8 @@ layout: manual
|
||||
* [`sin`](kcl/sin)
|
||||
* [`sqrt`](kcl/sqrt)
|
||||
* [`startProfileAt`](kcl/startProfileAt)
|
||||
* [`startSketchAt`](kcl/startSketchAt)
|
||||
* [`startSketchOn`](kcl/startSketchOn)
|
||||
* [`sweep`](kcl/sweep)
|
||||
* [`tan`](kcl/tan)
|
||||
* [`tangentToEnd`](kcl/tangentToEnd)
|
||||
* [`tangentialArc`](kcl/tangentialArc)
|
||||
|
@ -4,6 +4,8 @@ excerpt: "Convert a number to an integer."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
**WARNING:** This function is deprecated.
|
||||
|
||||
Convert a number to an integer.
|
||||
|
||||
DEPRECATED use floor(), ceil(), or round().
|
||||
|
File diff suppressed because one or more lines are too long
@ -45,7 +45,7 @@ circles = map([1..3], drawCircle)
|
||||
```js
|
||||
r = 10 // radius
|
||||
// Call `map`, using an anonymous function instead of a named one.
|
||||
circles = map([1..3], (id) {
|
||||
circles = map([1..3], fn(id) {
|
||||
return startSketchOn("XY")
|
||||
|> circle({ center = [id * 2 * r, 0], radius = r }, %)
|
||||
})
|
||||
|
File diff suppressed because one or more lines are too long
@ -12,7 +12,7 @@ to other modules.
|
||||
|
||||
```
|
||||
// util.kcl
|
||||
export fn increment = (x) => {
|
||||
export fn increment(x) {
|
||||
return x + 1
|
||||
}
|
||||
```
|
||||
@ -37,11 +37,11 @@ Multiple functions can be exported in a file.
|
||||
|
||||
```
|
||||
// util.kcl
|
||||
export fn increment = (x) => {
|
||||
export fn increment(x) {
|
||||
return x + 1
|
||||
}
|
||||
|
||||
export fn decrement = (x) => {
|
||||
export fn decrement(x) {
|
||||
return x - 1
|
||||
}
|
||||
```
|
||||
|
@ -35,7 +35,7 @@ The transform function returns a transform object. All properties of the object
|
||||
- `rotation.origin` (either "local" i.e. rotate around its own center, "global" i.e. rotate around the scene's center, or a 3D point, defaults to "local")
|
||||
|
||||
```js
|
||||
patternTransform(total_instances: u32, transform_function: FunctionParam, solid_set: SolidSet) -> [Solid]
|
||||
patternTransform(total_instances: integer, transform_function: FunctionParam, solid_set: SolidSet) -> [Solid]
|
||||
```
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ patternTransform(total_instances: u32, transform_function: FunctionParam, solid_
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `total_instances` | `u32` | | Yes |
|
||||
| `total_instances` | `integer` | | Yes |
|
||||
| `transform_function` | `FunctionParam` | | Yes |
|
||||
| `solid_set` | [`SolidSet`](/docs/kcl/types/SolidSet) | A solid or a group of solids. | Yes |
|
||||
|
||||
@ -95,7 +95,8 @@ fn cube(length, center) {
|
||||
p2 = [l + x, l + y]
|
||||
p3 = [l + x, -l + y]
|
||||
|
||||
return startSketchAt(p0)
|
||||
return startSketchOn('XY')
|
||||
|> startProfileAt(p0, %)
|
||||
|> lineTo(p1, %)
|
||||
|> lineTo(p2, %)
|
||||
|> lineTo(p3, %)
|
||||
@ -132,7 +133,8 @@ fn cube(length, center) {
|
||||
p2 = [l + x, l + y]
|
||||
p3 = [l + x, -l + y]
|
||||
|
||||
return startSketchAt(p0)
|
||||
return startSketchOn('XY')
|
||||
|> startProfileAt(p0, %)
|
||||
|> lineTo(p1, %)
|
||||
|> lineTo(p2, %)
|
||||
|> lineTo(p3, %)
|
||||
@ -195,7 +197,8 @@ fn transform(i) {
|
||||
{ rotation = { angle = 45 * i } }
|
||||
]
|
||||
}
|
||||
startSketchAt([0, 0])
|
||||
startSketchOn('XY')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> polygon({
|
||||
radius = 10,
|
||||
numSides = 4,
|
||||
|
@ -9,7 +9,7 @@ Just like patternTransform, but works on 2D sketches not 3D solids.
|
||||
|
||||
|
||||
```js
|
||||
patternTransform2d(total_instances: u32, transform_function: FunctionParam, solid_set: SketchSet) -> [Sketch]
|
||||
patternTransform2d(total_instances: integer, transform_function: FunctionParam, solid_set: SketchSet) -> [Sketch]
|
||||
```
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ patternTransform2d(total_instances: u32, transform_function: FunctionParam, soli
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `total_instances` | `u32` | | Yes |
|
||||
| `total_instances` | `integer` | | Yes |
|
||||
| `transform_function` | `FunctionParam` | | Yes |
|
||||
| `solid_set` | [`SketchSet`](/docs/kcl/types/SketchSet) | A sketch or a group of sketches. | Yes |
|
||||
|
||||
|
39
docs/kcl/pop.md
Normal file
39
docs/kcl/pop.md
Normal file
File diff suppressed because one or more lines are too long
@ -43,7 +43,7 @@ fn sum(arr) {
|
||||
|
||||
/* The above is basically like this pseudo-code:
|
||||
fn sum(arr):
|
||||
let sumSoFar = 0
|
||||
sumSoFar = 0
|
||||
for i in arr:
|
||||
sumSoFar = add(sumSoFar, i)
|
||||
return sumSoFar */
|
||||
@ -61,7 +61,7 @@ assertEqual(sum([1, 2, 3]), 6, 0.00001, "1 + 2 + 3 summed is 6")
|
||||
// an anonymous `add` function as its parameter, instead of declaring a
|
||||
// named function outside.
|
||||
arr = [1, 2, 3]
|
||||
sum = reduce(arr, 0, (i, result_so_far) {
|
||||
sum = reduce(arr, 0, fn(i, result_so_far) {
|
||||
return i + result_so_far
|
||||
})
|
||||
|
||||
@ -79,12 +79,13 @@ fn decagon(radius) {
|
||||
stepAngle = 1 / 10 * tau()
|
||||
|
||||
// Start the decagon sketch at this point.
|
||||
startOfDecagonSketch = startSketchAt([cos(0) * radius, sin(0) * radius])
|
||||
startOfDecagonSketch = startSketchOn('XY')
|
||||
|> startProfileAt([cos(0) * radius, sin(0) * radius], %)
|
||||
|
||||
// Use a `reduce` to draw the remaining decagon sides.
|
||||
// For each number in the array 1..10, run the given function,
|
||||
// Use a `reduce` to draw the remaining decagon sides.
|
||||
// For each number in the array 1..10, run the given function,
|
||||
// which takes a partially-sketched decagon and adds one more edge to it.
|
||||
fullDecagon = reduce([1..10], startOfDecagonSketch, (i, partialDecagon) {
|
||||
fullDecagon = reduce([1..10], startOfDecagonSketch, fn(i, partialDecagon) {
|
||||
// Draw one edge of the decagon.
|
||||
x = cos(stepAngle * i) * radius
|
||||
y = sin(stepAngle * i) * radius
|
||||
@ -96,14 +97,15 @@ fn decagon(radius) {
|
||||
|
||||
/* The `decagon` above is basically like this pseudo-code:
|
||||
fn decagon(radius):
|
||||
let stepAngle = (1/10) * tau()
|
||||
let startOfDecagonSketch = startSketchAt([(cos(0)*radius), (sin(0) * radius)])
|
||||
stepAngle = (1/10) * tau()
|
||||
plane = startSketchOn('XY')
|
||||
startOfDecagonSketch = startProfileAt([(cos(0)*radius), (sin(0) * radius)], plane)
|
||||
|
||||
// Here's the reduce part.
|
||||
let partialDecagon = startOfDecagonSketch
|
||||
partialDecagon = startOfDecagonSketch
|
||||
for i in [1..10]:
|
||||
let x = cos(stepAngle * i) * radius
|
||||
let y = sin(stepAngle * i) * radius
|
||||
x = cos(stepAngle * i) * radius
|
||||
y = sin(stepAngle * i) * radius
|
||||
partialDecagon = lineTo([x, y], partialDecagon)
|
||||
fullDecagon = partialDecagon // it's now full
|
||||
return fullDecagon */
|
||||
|
File diff suppressed because one or more lines are too long
@ -28,7 +28,8 @@ segEnd(tag: TagIdentifier) -> [number]
|
||||
|
||||
```js
|
||||
w = 15
|
||||
cube = startSketchAt([0, 0])
|
||||
cube = startSketchOn('XY')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([w, 0], %, $line1)
|
||||
|> line([0, w], %, $line2)
|
||||
|> line([-w, 0], %, $line3)
|
||||
@ -37,7 +38,8 @@ cube = startSketchAt([0, 0])
|
||||
|> extrude(5, %)
|
||||
|
||||
fn cylinder(radius, tag) {
|
||||
return startSketchAt([0, 0])
|
||||
return startSketchOn('XY')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> circle({
|
||||
radius = radius,
|
||||
center = segEnd(tag)
|
||||
|
@ -28,7 +28,8 @@ segStart(tag: TagIdentifier) -> [number]
|
||||
|
||||
```js
|
||||
w = 15
|
||||
cube = startSketchAt([0, 0])
|
||||
cube = startSketchOn('XY')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([w, 0], %, $line1)
|
||||
|> line([0, w], %, $line2)
|
||||
|> line([-w, 0], %, $line3)
|
||||
@ -37,7 +38,8 @@ cube = startSketchAt([0, 0])
|
||||
|> extrude(5, %)
|
||||
|
||||
fn cylinder(radius, tag) {
|
||||
return startSketchAt([0, 0])
|
||||
return startSketchOn('XY')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> circle({
|
||||
radius = radius,
|
||||
center = segStart(tag)
|
||||
|
@ -4,6 +4,8 @@ excerpt: "Start a new 2-dimensional sketch at a given point on the 'XY' plane."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
**WARNING:** This function is deprecated.
|
||||
|
||||
Start a new 2-dimensional sketch at a given point on the 'XY' plane.
|
||||
|
||||
|
||||
|
74553
docs/kcl/std.json
74553
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
77
docs/kcl/sweep.md
Normal file
77
docs/kcl/sweep.md
Normal file
File diff suppressed because one or more lines are too long
@ -54,7 +54,7 @@ We also have support for defining your own functions. Functions can take in any
|
||||
type of argument. Below is an example of the syntax:
|
||||
|
||||
```
|
||||
fn myFn = (x) => {
|
||||
fn myFn(x) {
|
||||
return x
|
||||
}
|
||||
```
|
||||
@ -118,7 +118,7 @@ use the tag `rectangleSegmentA001` in any function or expression in the file.
|
||||
However if the code was written like this:
|
||||
|
||||
```
|
||||
fn rect = (origin) => {
|
||||
fn rect(origin) {
|
||||
return startSketchOn('XZ')
|
||||
|> startProfileAt(origin, %)
|
||||
|> angledLine([0, 191.26], %, $rectangleSegmentA001)
|
||||
@ -146,7 +146,7 @@ Tags are accessible through the sketch group they are declared in.
|
||||
For example the following code works.
|
||||
|
||||
```
|
||||
fn rect = (origin) => {
|
||||
fn rect(origin) {
|
||||
return startSketchOn('XZ')
|
||||
|> startProfileAt(origin, %)
|
||||
|> angledLine([0, 191.26], %, $rectangleSegmentA001)
|
||||
|
@ -13,13 +13,18 @@ Data to draw an angled line.
|
||||
|
||||
An angle and length with explicitly named parameters
|
||||
|
||||
[`PolarCoordsData`](/docs/kcl/types/PolarCoordsData)
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `angle` |`number`| The angle of the line (in degrees). | No |
|
||||
| `length` |`number`| The length of the line. | No |
|
||||
|
||||
|
||||
----
|
||||
|
23
docs/kcl/types/AppearanceData.md
Normal file
23
docs/kcl/types/AppearanceData.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "AppearanceData"
|
||||
excerpt: "Data for appearance."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Data for appearance.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `color` |`string`| Color of the new material, a hex string like "#ff0000". | No |
|
||||
| `metalness` |`number` (**maximum:** 100.0)| Metalness of the new material, a percentage like 95.7. | No |
|
||||
| `roughness` |`number` (**maximum:** 100.0)| Roughness of the new material, a percentage like 95.7. | No |
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
---
|
||||
title: "AxisOrEdgeReference"
|
||||
excerpt: "Axis or tagged edge."
|
||||
title: "Axis2dOrEdgeReference"
|
||||
excerpt: "A 2D axis or tagged edge."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Axis or tagged edge.
|
||||
A 2D axis or tagged edge.
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts any of the following:**
|
||||
|
||||
Axis and origin.
|
||||
2D axis and origin.
|
||||
|
||||
[`AxisAndOrigin`](/docs/kcl/types/AxisAndOrigin)
|
||||
[`AxisAndOrigin2d`](/docs/kcl/types/AxisAndOrigin2d)
|
||||
|
||||
|
||||
|
42
docs/kcl/types/Axis3dOrEdgeReference.md
Normal file
42
docs/kcl/types/Axis3dOrEdgeReference.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "Axis3dOrEdgeReference"
|
||||
excerpt: "A 3D axis or tagged edge."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A 3D axis or tagged edge.
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts any of the following:**
|
||||
|
||||
3D axis and origin.
|
||||
|
||||
[`AxisAndOrigin3d`](/docs/kcl/types/AxisAndOrigin3d)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Tagged edge.
|
||||
|
||||
[`EdgeReference`](/docs/kcl/types/EdgeReference)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: "AxisAndOrigin"
|
||||
excerpt: "Axis and origin."
|
||||
title: "AxisAndOrigin2d"
|
||||
excerpt: "A 2D axis and origin."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Axis and origin.
|
||||
A 2D axis and origin.
|
||||
|
||||
|
||||
|
105
docs/kcl/types/AxisAndOrigin3d.md
Normal file
105
docs/kcl/types/AxisAndOrigin3d.md
Normal file
@ -0,0 +1,105 @@
|
||||
---
|
||||
title: "AxisAndOrigin3d"
|
||||
excerpt: "A 3D axis and origin."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A 3D axis and origin.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
X-axis.
|
||||
|
||||
**enum:** `X`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Y-axis.
|
||||
|
||||
**enum:** `Y`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Z-axis.
|
||||
|
||||
**enum:** `Z`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Flip the X-axis.
|
||||
|
||||
**enum:** `-X`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Flip the Y-axis.
|
||||
|
||||
**enum:** `-Y`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Flip the Z-axis.
|
||||
|
||||
**enum:** `-Z`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `custom` |`object`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,161 +0,0 @@
|
||||
---
|
||||
title: "BinaryOperator"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
Add two numbers.
|
||||
|
||||
**enum:** `+`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Subtract two numbers.
|
||||
|
||||
**enum:** `-`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Multiply two numbers.
|
||||
|
||||
**enum:** `*`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Divide two numbers.
|
||||
|
||||
**enum:** `/`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Modulo two numbers.
|
||||
|
||||
**enum:** `%`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Raise a number to a power.
|
||||
|
||||
**enum:** `^`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Are two numbers equal?
|
||||
|
||||
**enum:** `==`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Are two numbers not equal?
|
||||
|
||||
**enum:** `!=`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Is left greater than right
|
||||
|
||||
**enum:** `>`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Is left greater than or equal to right
|
||||
|
||||
**enum:** `>=`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Is left less than right
|
||||
|
||||
**enum:** `<`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Is left less than or equal to right
|
||||
|
||||
**enum:** `<=`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,160 +0,0 @@
|
||||
---
|
||||
title: "BinaryPart"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `BinaryExpression`| | No |
|
||||
| `operator` |[`BinaryOperator`](/docs/kcl/types/BinaryOperator)| | No |
|
||||
| `left` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `right` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `CallExpression`| | No |
|
||||
| `callee` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `arguments` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `UnaryExpression`| | No |
|
||||
| `operator` |[`UnaryOperator`](/docs/kcl/types/UnaryOperator)| | No |
|
||||
| `argument` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `IfExpression`| | No |
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `else_ifs` |`[` [`ElseIf`](/docs/kcl/types/ElseIf) `]`| | No |
|
||||
| `final_else` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,97 +0,0 @@
|
||||
---
|
||||
title: "BodyItem"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ImportStatement`| | No |
|
||||
| `items` |`[` [`ImportItem`](/docs/kcl/types/ImportItem) `]`| | No |
|
||||
| `path` |`string`| | No |
|
||||
| `raw_path` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ExpressionStatement`| | No |
|
||||
| `expression` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `VariableDeclaration`| | No |
|
||||
| `declarations` |`[` [`VariableDeclarator`](/docs/kcl/types/VariableDeclarator) `]`| | No |
|
||||
| `visibility` |[`ItemVisibility`](/docs/kcl/types/ItemVisibility)| | No |
|
||||
| `kind` |[`VariableKind`](/docs/kcl/types/VariableKind)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ReturnStatement`| | No |
|
||||
| `argument` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
23
docs/kcl/types/CircleThreePointData.md
Normal file
23
docs/kcl/types/CircleThreePointData.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "CircleThreePointData"
|
||||
excerpt: "Data for drawing a 3-point circle"
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Data for drawing a 3-point circle
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `p1` |`[number, number]`| Point one for circle derivation. | No |
|
||||
| `p2` |`[number, number]`| Point two for circle derivation. | No |
|
||||
| `p3` |`[number, number]`| Point three for circle derivation. | No |
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
---
|
||||
title: "CommentStyle"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
Like // foo
|
||||
|
||||
**enum:** `line`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Like /* foo */
|
||||
|
||||
**enum:** `block`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
---
|
||||
title: "ElseIf"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
title: "EnvironmentRef"
|
||||
excerpt: "An index pointing to an environment."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
An index pointing to an environment.
|
||||
|
||||
**Type:** `integer` (`uint`)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,317 +0,0 @@
|
||||
---
|
||||
title: "Expr"
|
||||
excerpt: "An expression can be evaluated to yield a single KCL value."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
| `value` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `BinaryExpression`| | No |
|
||||
| `operator` |[`BinaryOperator`](/docs/kcl/types/BinaryOperator)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `left` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `right` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`FunctionExpression`](/docs/kcl/types/FunctionExpression)| | No |
|
||||
| `params` |`[` [`Parameter`](/docs/kcl/types/Parameter) `]`| | No |
|
||||
| `body` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `CallExpression`| | No |
|
||||
| `callee` |[`Identifier`](/docs/kcl/types/Identifier)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `arguments` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `PipeExpression`| | No |
|
||||
| `body` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `PipeSubstitution`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ArrayExpression`| | No |
|
||||
| `elements` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ArrayRangeExpression`| | No |
|
||||
| `startElement` |[`Expr`](/docs/kcl/types/Expr)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `endElement` |[`Expr`](/docs/kcl/types/Expr)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `endInclusive` |`boolean`| Is the `end_element` included in the range? | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ObjectExpression`| | No |
|
||||
| `properties` |`[` [`ObjectProperty`](/docs/kcl/types/ObjectProperty) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `UnaryExpression`| | No |
|
||||
| `operator` |[`UnaryOperator`](/docs/kcl/types/UnaryOperator)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `argument` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `IfExpression`| | No |
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `else_ifs` |`[` [`ElseIf`](/docs/kcl/types/ElseIf) `]`| | No |
|
||||
| `final_else` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `None`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
28
docs/kcl/types/Face.md
Normal file
28
docs/kcl/types/Face.md
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
title: "Face"
|
||||
excerpt: "A face."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A face.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `id` |`string`| The id of the face. | No |
|
||||
| `value` |`string`| The tag of the face. | No |
|
||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s X axis be? | No |
|
||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s Y axis be? | No |
|
||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A face. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
---
|
||||
title: "FunctionExpression"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `params` |`[` [`Parameter`](/docs/kcl/types/Parameter) `]`| | No |
|
||||
| `body` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
26
docs/kcl/types/Helix.md
Normal file
26
docs/kcl/types/Helix.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
title: "Helix"
|
||||
excerpt: "A helix."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A helix.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `value` |`string`| The id of the helix. | No |
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A helix. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
title: "HelixData"
|
||||
excerpt: "Data for helices."
|
||||
excerpt: "Data for a helix."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Data for helices.
|
||||
Data for a helix.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
@ -19,6 +19,8 @@ Data for helices.
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
|
||||
| `length` |`number`| Length of the helix. If this argument is not provided, the height of the solid is used. | No |
|
||||
| `length` |`number`| Length of the helix. This is not necessary if the helix is created around an edge. If not given the length of the edge is used. | No |
|
||||
| `radius` |`number`| Radius of the helix. | No |
|
||||
| `axis` |[`Axis3dOrEdgeReference`](/docs/kcl/types/Axis3dOrEdgeReference)| Axis to use as mirror. | No |
|
||||
|
||||
|
||||
|
24
docs/kcl/types/HelixRevolutionsData.md
Normal file
24
docs/kcl/types/HelixRevolutionsData.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
title: "HelixRevolutionsData"
|
||||
excerpt: "Data for helix revolutions."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Data for helix revolutions.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? The default is `false`. | No |
|
||||
| `length` |`number`| Length of the helix. If this argument is not provided, the height of the solid is used. | No |
|
||||
|
||||
|
26
docs/kcl/types/HelixValue.md
Normal file
26
docs/kcl/types/HelixValue.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
title: "HelixValue"
|
||||
excerpt: "A helix."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A helix.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `value` |`string`| The id of the helix. | No |
|
||||
| `revolutions` |`number`| Number of revolutions. | No |
|
||||
| `angleStart` |`number`| Start angle (in degrees). | No |
|
||||
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A helix. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
---
|
||||
title: "Identifier"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
---
|
||||
title: "ImportItem"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `name` |[`Identifier`](/docs/kcl/types/Identifier)| Name of the item to import. | No |
|
||||
| `alias` |[`Identifier`](/docs/kcl/types/Identifier)| Rename the item using an identifier after "as". | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
title: "ItemVisibility"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**enum:** `default`, `export`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -12,5 +12,10 @@ KCL value for an optional parameter which was not given an argument. (remember,
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -168,7 +168,6 @@ Any KCL value.
|
||||
|
||||
|
||||
----
|
||||
A plane.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
@ -181,17 +180,10 @@ A plane.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Plane`](/docs/kcl/types/Plane)| | No |
|
||||
| `id` |`string`| The id of the plane. | No |
|
||||
| `value` |[`PlaneType`](/docs/kcl/types/PlaneType)| Any KCL value. | No |
|
||||
| `origin` |[`Point3d`](/docs/kcl/types/Point3d)| Origin of the plane. | No |
|
||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s X axis be? | No |
|
||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s Y axis be? | No |
|
||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
| `value` |[`Plane`](/docs/kcl/types/Plane)| Any KCL value. | No |
|
||||
|
||||
|
||||
----
|
||||
A face.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
@ -203,14 +195,8 @@ A face.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Face`| | No |
|
||||
| `id` |`string`| The id of the face. | No |
|
||||
| `value` |`string`| The tag of the face. | No |
|
||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s X axis be? | No |
|
||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s Y axis be? | No |
|
||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
| `type` |enum: [`Face`](/docs/kcl/types/Face)| | No |
|
||||
| `value` |[`Face`](/docs/kcl/types/Face)| Any KCL value. | No |
|
||||
|
||||
|
||||
----
|
||||
@ -246,7 +232,6 @@ A face.
|
||||
|
||||
|
||||
----
|
||||
An solid is a collection of extrude surfaces.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
@ -259,14 +244,7 @@ An solid is a collection of extrude surfaces.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Solid`](/docs/kcl/types/Solid)| | No |
|
||||
| `id` |`string`| The id of the solid. | No |
|
||||
| `value` |`[` [`ExtrudeSurface`](/docs/kcl/types/ExtrudeSurface) `]`| The extrude surfaces. | No |
|
||||
| `sketch` |[`Sketch`](/docs/kcl/types/Sketch)| The sketch. | No |
|
||||
| `height` |`number`| The height of the solid. | No |
|
||||
| `startCapId` |`string`| The id of the extrusion start cap | No |
|
||||
| `endCapId` |`string`| The id of the extrusion end cap | No |
|
||||
| `edgeCuts` |`[` [`EdgeCut`](/docs/kcl/types/EdgeCut) `]`| Chamfers or fillets on this solid. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |
|
||||
| `value` |[`Solid`](/docs/kcl/types/Solid)| Any KCL value. | No |
|
||||
|
||||
|
||||
----
|
||||
@ -285,6 +263,22 @@ An solid is a collection of extrude surfaces.
|
||||
| `value` |`[` [`Solid`](/docs/kcl/types/Solid) `]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Helix`](/docs/kcl/types/Helix)| | No |
|
||||
| `value` |[`Helix`](/docs/kcl/types/Helix)| Any KCL value. | No |
|
||||
|
||||
|
||||
----
|
||||
Data for an imported geometry.
|
||||
|
||||
@ -317,7 +311,6 @@ Data for an imported geometry.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Function`| | No |
|
||||
| `expression` |[`FunctionExpression`](/docs/kcl/types/FunctionExpression)| Any KCL value. | No |
|
||||
| `memory` |[`ProgramMemory`](/docs/kcl/types/ProgramMemory)| Any KCL value. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
@ -330,6 +323,23 @@ Data for an imported geometry.
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Module`| | No |
|
||||
| `value` |[`ModuleId`](/docs/kcl/types/ModuleId)| Any KCL value. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|
@ -1,56 +0,0 @@
|
||||
---
|
||||
title: "LiteralIdentifier"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
---
|
||||
title: "LiteralValue"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts any of the following:**
|
||||
|
||||
|
||||
**Type:** `number` (`double`)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `string`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `boolean`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
---
|
||||
title: "MemberObject"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -16,6 +16,6 @@ Data for a mirror.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `axis` |[`AxisOrEdgeReference`](/docs/kcl/types/AxisOrEdgeReference)| Axis to use as mirror. | No |
|
||||
| `axis` |[`Axis2dOrEdgeReference`](/docs/kcl/types/Axis2dOrEdgeReference)| Axis to use as mirror. | No |
|
||||
|
||||
|
||||
|
16
docs/kcl/types/ModuleId.md
Normal file
16
docs/kcl/types/ModuleId.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
title: "ModuleId"
|
||||
excerpt: "Identifier of a source file. Uses a u32 to keep the size small."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Identifier of a source file. Uses a u32 to keep the size small.
|
||||
|
||||
**Type:** `integer` (`uint32`)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
---
|
||||
title: "NonCodeMeta"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `nonCodeNodes` |`object`| | No |
|
||||
| `startNodes` |`[` [`NonCodeNode`](/docs/kcl/types/NonCodeNode) `]`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
---
|
||||
title: "NonCodeNode"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `value` |[`NonCodeValue`](/docs/kcl/types/NonCodeValue)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
@ -1,86 +0,0 @@
|
||||
---
|
||||
title: "NonCodeValue"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
An inline comment. Here are examples: `1 + 1 // This is an inline comment`. `1 + 1 /* Here's another */`.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `inlineComment`| | No |
|
||||
| `value` |`string`| | No |
|
||||
| `style` |[`CommentStyle`](/docs/kcl/types/CommentStyle)| | No |
|
||||
|
||||
|
||||
----
|
||||
A block comment. An example of this is the following: ```python,no_run /* This is a block comment */ 1 + 1 ``` Now this is important. The block comment is attached to the next line. This is always the case. Also the block comment doesn't have a new line above it. If it did it would be a `NewLineBlockComment`.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `blockComment`| | No |
|
||||
| `value` |`string`| | No |
|
||||
| `style` |[`CommentStyle`](/docs/kcl/types/CommentStyle)| | No |
|
||||
|
||||
|
||||
----
|
||||
A block comment that has a new line above it. The user explicitly added a new line above the block comment.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `newLineBlockComment`| | No |
|
||||
| `value` |`string`| | No |
|
||||
| `style` |[`CommentStyle`](/docs/kcl/types/CommentStyle)| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `newLine`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
---
|
||||
title: "ObjectProperty"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `key` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `value` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
---
|
||||
title: "Parameter"
|
||||
excerpt: "Parameter of a KCL function."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Parameter of a KCL function.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `identifier` |[`Identifier`](/docs/kcl/types/Identifier)| The parameter's label or name. | No |
|
||||
| `optional` |`boolean`| Is the parameter optional? | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -22,6 +22,7 @@ A plane.
|
||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s X axis be? | No |
|
||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s Y axis be? | No |
|
||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A plane. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
---
|
||||
title: "Program"
|
||||
excerpt: "A KCL program top level, or function body."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A KCL program top level, or function body.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `body` |`[` [`BodyItem`](/docs/kcl/types/BodyItem) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| A KCL program top level, or function body. | No |
|
||||
| `shebang` |[`Shebang`](/docs/kcl/types/Shebang)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
@ -17,7 +17,7 @@ Data for revolution surfaces.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `angle` |`number` (**maximum:** 360.0) (**minimum:** -360.0)| Angle to revolve (in degrees). Default is 360. | No |
|
||||
| `axis` |[`AxisOrEdgeReference`](/docs/kcl/types/AxisOrEdgeReference)| Axis of revolution. | No |
|
||||
| `axis` |[`Axis2dOrEdgeReference`](/docs/kcl/types/Axis2dOrEdgeReference)| Axis of revolution. | No |
|
||||
| `tolerance` |`number`| Tolerance for the revolve operation. | No |
|
||||
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
---
|
||||
title: "Shebang"
|
||||
excerpt: "A shebang. This is a special type of comment that is at the top of the file. It looks like this: ```python,no_run #!/usr/bin/env python ```"
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A shebang. This is a special type of comment that is at the top of the file. It looks like this: ```python,no_run #!/usr/bin/env python ```
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `content` |`string`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
@ -21,6 +21,7 @@ A sketch is a collection of paths.
|
||||
| `on` |[`SketchSurface`](/docs/kcl/types/SketchSurface)| What the sketch is on (can be a plane or a face). | No |
|
||||
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
|
||||
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch is a collection of paths. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@ A sketch is a collection of paths.
|
||||
| `on` |[`SketchSurface`](/docs/kcl/types/SketchSurface)| What the sketch is on (can be a plane or a face). | No |
|
||||
| `start` |[`BasePath`](/docs/kcl/types/BasePath)| The starting path. | No |
|
||||
| `tags` |`object`| Tag identifiers that have been declared in this sketch. | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch or a group of sketches. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@ A plane.
|
||||
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s X axis be? | No |
|
||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the plane’s Y axis be? | No |
|
||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch type. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
||||
@ -54,6 +55,7 @@ A face.
|
||||
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face’s Y axis be? | No |
|
||||
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
|
||||
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A sketch type. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ An solid is a collection of extrude surfaces.
|
||||
| `startCapId` |`string`| The id of the extrusion start cap | No |
|
||||
| `endCapId` |`string`| The id of the extrusion end cap | No |
|
||||
| `edgeCuts` |`[` [`EdgeCut`](/docs/kcl/types/EdgeCut) `]`| Chamfers or fillets on this solid. | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| An solid is a collection of extrude surfaces. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |
|
||||
|
||||
|
||||
|
@ -32,6 +32,7 @@ An solid is a collection of extrude surfaces.
|
||||
| `startCapId` |`string`| The id of the extrusion start cap | No |
|
||||
| `endCapId` |`string`| The id of the extrusion end cap | No |
|
||||
| `edgeCuts` |`[` [`EdgeCut`](/docs/kcl/types/EdgeCut) `]`| Chamfers or fillets on this solid. | No |
|
||||
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A solid or a group of solids. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| Metadata. | No |
|
||||
|
||||
|
||||
|
23
docs/kcl/types/SweepData.md
Normal file
23
docs/kcl/types/SweepData.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "SweepData"
|
||||
excerpt: "Data for a sweep."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
Data for a sweep.
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `path` |[`SweepPath`](/docs/kcl/types/SweepPath)| The path to sweep along. | No |
|
||||
| `sectional` |`boolean`| If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components. | No |
|
||||
| `tolerance` |`number`| Tolerance for the sweep operation. | No |
|
||||
|
||||
|
42
docs/kcl/types/SweepPath.md
Normal file
42
docs/kcl/types/SweepPath.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "SweepPath"
|
||||
excerpt: "A path to sweep along."
|
||||
layout: manual
|
||||
---
|
||||
|
||||
A path to sweep along.
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts any of the following:**
|
||||
|
||||
A path to sweep along.
|
||||
|
||||
[`Sketch`](/docs/kcl/types/Sketch)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
A path to sweep along.
|
||||
|
||||
[`Helix`](/docs/kcl/types/Helix)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
---
|
||||
title: "Uint"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `integer` (`uint32`)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
---
|
||||
title: "UnaryOperator"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
Negate a number.
|
||||
|
||||
**enum:** `-`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Negate a boolean.
|
||||
|
||||
**enum:** `!`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
107
docs/kcl/types/UnitLen.md
Normal file
107
docs/kcl/types/UnitLen.md
Normal file
@ -0,0 +1,107 @@
|
||||
---
|
||||
title: "UnitLen"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Mm`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Cm`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `M`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Inches`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Feet`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Yards`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
---
|
||||
title: "VariableDeclarator"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
**Type:** `object`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `id` |[`Identifier`](/docs/kcl/types/Identifier)| The identifier of the variable. | No |
|
||||
| `init` |[`Expr`](/docs/kcl/types/Expr)| The value of the variable. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
| `start` |`integer`| | No |
|
||||
| `end` |`integer`| | No |
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
---
|
||||
title: "VariableKind"
|
||||
excerpt: ""
|
||||
layout: manual
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**This schema accepts exactly one of the following:**
|
||||
|
||||
Declare a named constant.
|
||||
|
||||
**enum:** `const`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
Declare a function.
|
||||
|
||||
**enum:** `fn`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,22 +1,11 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
import { setupElectron, tearDown } from './test-utils'
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
import { test, expect } from './zoo-test'
|
||||
|
||||
test.describe('Electron app header tests', () => {
|
||||
test(
|
||||
'Open Command Palette button has correct shortcut',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async () => {},
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
async ({ page }, testInfo) => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
// No space before the shortcut since it checks textContent.
|
||||
let text
|
||||
@ -34,21 +23,14 @@ test.describe('Electron app header tests', () => {
|
||||
const commandsButton = page.getByRole('button', { name: 'Commands' })
|
||||
await expect(commandsButton).toBeVisible()
|
||||
await expect(commandsButton).toHaveText(text)
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'User settings has correct shortcut',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async () => {},
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
async ({ page }, testInfo) => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
// Open the user sidebar menu.
|
||||
await page.getByTestId('user-sidebar-toggle').click()
|
||||
@ -59,8 +41,6 @@ test.describe('Electron app header tests', () => {
|
||||
const userSettingsButton = page.getByTestId('user-settings')
|
||||
await expect(userSettingsButton).toBeVisible()
|
||||
await expect(userSettingsButton).toHaveText(text)
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -1,29 +1,26 @@
|
||||
import { test, expect, Page } from '@playwright/test'
|
||||
import { test, expect, Page } from './zoo-test'
|
||||
import {
|
||||
getUtils,
|
||||
TEST_COLORS,
|
||||
setup,
|
||||
tearDown,
|
||||
commonPoints,
|
||||
PERSIST_MODELING_CONTEXT,
|
||||
} from './test-utils'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
import { HomePageFixture } from './fixtures/homePageFixture'
|
||||
|
||||
test.setTimeout(120000)
|
||||
|
||||
async function doBasicSketch(page: Page, openPanes: string[]) {
|
||||
async function doBasicSketch(
|
||||
page: Page,
|
||||
homePage: HomePageFixture,
|
||||
openPanes: string[]
|
||||
) {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
await u.waitForPageLoad()
|
||||
await page.waitForTimeout(1000)
|
||||
await u.openDebugPanel()
|
||||
|
||||
// If we have the code pane open, we should see the code.
|
||||
@ -148,13 +145,11 @@ async function doBasicSketch(page: Page, openPanes: string[]) {
|
||||
}
|
||||
|
||||
test.describe('Basic sketch', () => {
|
||||
test('code pane open at start', { tag: ['@skipWin'] }, async ({ page }) => {
|
||||
// Skip on windows it is being weird.
|
||||
test.skip(process.platform === 'win32', 'Skip on windows')
|
||||
await doBasicSketch(page, ['code'])
|
||||
test.fixme('code pane open at start', async ({ page, homePage }) => {
|
||||
await doBasicSketch(page, homePage, ['code'])
|
||||
})
|
||||
|
||||
test('code pane closed at start', async ({ page }) => {
|
||||
test('code pane closed at start', async ({ page, homePage }) => {
|
||||
// Load the app with the code panes
|
||||
await page.addInitScript(async (persistModelingContext) => {
|
||||
localStorage.setItem(
|
||||
@ -162,6 +157,6 @@ test.describe('Basic sketch', () => {
|
||||
JSON.stringify({ openPanes: [] })
|
||||
)
|
||||
}, PERSIST_MODELING_CONTEXT)
|
||||
await doBasicSketch(page, [])
|
||||
await doBasicSketch(page, homePage, [])
|
||||
})
|
||||
})
|
||||
|
@ -1,27 +1,21 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { getUtils, setup, tearDown } from './test-utils'
|
||||
import { test, expect, Page } from './zoo-test'
|
||||
import { HomePageFixture } from './fixtures/homePageFixture'
|
||||
import { getUtils } from './test-utils'
|
||||
import { EngineCommand } from 'lang/std/artifactGraph'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
|
||||
test.describe('Can create sketches on all planes and their back sides', () => {
|
||||
const sketchOnPlaneAndBackSideTest = async (
|
||||
page: any,
|
||||
page: Page,
|
||||
homePage: HomePageFixture,
|
||||
plane: string,
|
||||
clickCoords: { x: number; y: number }
|
||||
) => {
|
||||
const u = await getUtils(page)
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
await u.openDebugPanel()
|
||||
|
||||
const coord =
|
||||
@ -83,32 +77,39 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
||||
await u.clearCommandLogs()
|
||||
await u.removeCurrentCode()
|
||||
}
|
||||
test('XY', async ({ page }) => {
|
||||
test('XY', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(
|
||||
page,
|
||||
homePage,
|
||||
'XY',
|
||||
{ x: 600, y: 388 } // red plane
|
||||
// { x: 600, y: 400 }, // red plane // clicks grid helper and that causes problems, should fix so that these coords work too.
|
||||
)
|
||||
})
|
||||
|
||||
test('YZ', async ({ page }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, 'YZ', { x: 700, y: 250 }) // green plane
|
||||
test('YZ', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, 'YZ', { x: 700, y: 250 }) // green plane
|
||||
})
|
||||
|
||||
test('XZ', async ({ page }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, '-XZ', { x: 700, y: 80 }) // blue plane
|
||||
test('XZ', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, '-XZ', { x: 700, y: 80 }) // blue plane
|
||||
})
|
||||
|
||||
test('-XY', async ({ page }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, '-XY', { x: 600, y: 118 }) // back of red plane
|
||||
test('-XY', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, '-XY', {
|
||||
x: 600,
|
||||
y: 118,
|
||||
}) // back of red plane
|
||||
})
|
||||
|
||||
test('-YZ', async ({ page }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, '-YZ', { x: 700, y: 219 }) // back of green plane
|
||||
test('-YZ', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, '-YZ', {
|
||||
x: 700,
|
||||
y: 219,
|
||||
}) // back of green plan
|
||||
})
|
||||
|
||||
test('-XZ', async ({ page }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, 'XZ', { x: 700, y: 427 }) // back of blue plane
|
||||
test('-XZ', async ({ page, homePage }) => {
|
||||
await sketchOnPlaneAndBackSideTest(page, homePage, 'XZ', { x: 700, y: 427 }) // back of blue plane
|
||||
})
|
||||
})
|
||||
|
@ -1,28 +1,15 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { test, expect } from './zoo-test'
|
||||
|
||||
import {
|
||||
getUtils,
|
||||
setup,
|
||||
setupElectron,
|
||||
tearDown,
|
||||
executorInputPath,
|
||||
} from './test-utils'
|
||||
import { getUtils, executorInputPath } from './test-utils'
|
||||
import { join } from 'path'
|
||||
import { bracket } from 'lib/exampleKcl'
|
||||
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates'
|
||||
import fsp from 'fs/promises'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
|
||||
test.describe('Code pane and errors', () => {
|
||||
test('Typing KCL errors induces a badge on the code pane button', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
@ -31,18 +18,18 @@ test.describe('Code pane and errors', () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`// Extruded Triangle
|
||||
sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([10, 0], %)
|
||||
|> line([-5, 10], %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
extrude001 = extrude(5, sketch001)`
|
||||
sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([10, 0], %)
|
||||
|> line([-5, 10], %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
extrude001 = extrude(5, sketch001)`
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
@ -62,11 +49,11 @@ extrude001 = extrude(5, sketch001)`
|
||||
await expect(codePaneButtonHolder).toContainText('notification')
|
||||
})
|
||||
|
||||
test('Opening and closing the code pane will consistently show error diagnostics', async ({
|
||||
test.skip('Opening and closing the code pane will consistently show error diagnostics', async ({
|
||||
page,
|
||||
homePage,
|
||||
editor,
|
||||
}) => {
|
||||
await page.goto('http://localhost:3000')
|
||||
|
||||
const u = await getUtils(page)
|
||||
|
||||
// Load the app with the working starter code
|
||||
@ -74,8 +61,8 @@ extrude001 = extrude(5, sketch001)`
|
||||
localStorage.setItem('persistCode', code)
|
||||
}, bracket)
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 900 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page.setBodyDimensions({ width: 1200, height: 900 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
@ -91,8 +78,9 @@ extrude001 = extrude(5, sketch001)`
|
||||
await expect(codePaneButtonHolder).not.toContainText('notification')
|
||||
|
||||
// Delete a character to break the KCL
|
||||
await u.openKclCodePanel()
|
||||
await page.getByText('thickness, bracketLeg1Sketch)').click()
|
||||
await editor.openPane()
|
||||
await editor.scrollToText('thickness, bracketLeg1Sketch)')
|
||||
await page.getByText('extrude(thickness, bracketLeg1Sketch)').click()
|
||||
await page.keyboard.press('Backspace')
|
||||
|
||||
// Ensure that a badge appears on the button
|
||||
@ -116,7 +104,10 @@ extrude001 = extrude(5, sketch001)`
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
|
||||
// Open the code pane
|
||||
await u.openKclCodePanel()
|
||||
await editor.openPane()
|
||||
|
||||
// Go to our problematic code again (missing closing paren!)
|
||||
await editor.scrollToText('extrude(thickness, bracketLeg1Sketch')
|
||||
|
||||
// Ensure that a badge appears on the button
|
||||
await expect(codePaneButtonHolder).toContainText('notification')
|
||||
@ -129,59 +120,58 @@ extrude001 = extrude(5, sketch001)`
|
||||
await expect(page.locator('.cm-tooltip').first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('When error is not in view you can click the badge to scroll to it', async ({
|
||||
page,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
test.fixme(
|
||||
'When error is not in view you can click the badge to scroll to it',
|
||||
async ({ page, homePage, context }) => {
|
||||
// Load the app with the working starter code
|
||||
await context.addInitScript((code) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
|
||||
|
||||
// Load the app with the working starter code
|
||||
await page.addInitScript((code) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await page.waitForTimeout(1000)
|
||||
// Ensure badge is present
|
||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||
await expect(codePaneButtonHolder).toContainText('notification')
|
||||
|
||||
// Ensure badge is present
|
||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||
await expect(codePaneButtonHolder).toContainText('notification')
|
||||
// Ensure we have no errors in the gutter, since error out of view.
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
|
||||
// Ensure we have no errors in the gutter, since error out of view.
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
// Click the badge.
|
||||
const badge = page.locator('#code-badge')
|
||||
await expect(badge).toBeVisible()
|
||||
await badge.click()
|
||||
|
||||
// Click the badge.
|
||||
const badge = page.locator('#code-badge')
|
||||
await expect(badge).toBeVisible()
|
||||
await badge.click()
|
||||
// Ensure we have an error diagnostic.
|
||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||
|
||||
// Ensure we have an error diagnostic.
|
||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||
|
||||
// Hover over the error to see the error message
|
||||
await page.hover('.cm-lint-marker-error')
|
||||
await expect(
|
||||
page
|
||||
.getByText(
|
||||
'sketch profile must lie entirely on one side of the revolution axis'
|
||||
)
|
||||
.first()
|
||||
).toBeVisible()
|
||||
})
|
||||
// Hover over the error to see the error message
|
||||
await page.hover('.cm-lint-marker-error')
|
||||
await expect(
|
||||
page
|
||||
.getByText(
|
||||
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
|
||||
)
|
||||
.first()
|
||||
).toBeVisible()
|
||||
}
|
||||
)
|
||||
|
||||
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
// Load the app with the working starter code
|
||||
await page.addInitScript((code) => {
|
||||
await context.addInitScript((code) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
@ -241,32 +231,29 @@ extrude001 = extrude(5, sketch001)`
|
||||
test(
|
||||
'Opening multiple panes persists when switching projects',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
async ({ context, page }, testInfo) => {
|
||||
// Setup multiple projects.
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
const routerTemplateDir = join(dir, 'router-template-slate')
|
||||
const bracketDir = join(dir, 'bracket')
|
||||
await Promise.all([
|
||||
fsp.mkdir(routerTemplateDir, { recursive: true }),
|
||||
fsp.mkdir(bracketDir, { recursive: true }),
|
||||
])
|
||||
await Promise.all([
|
||||
fsp.copyFile(
|
||||
executorInputPath('router-template-slate.kcl'),
|
||||
join(routerTemplateDir, 'main.kcl')
|
||||
),
|
||||
fsp.copyFile(
|
||||
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
|
||||
join(bracketDir, 'main.kcl')
|
||||
),
|
||||
])
|
||||
},
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
const routerTemplateDir = join(dir, 'router-template-slate')
|
||||
const bracketDir = join(dir, 'bracket')
|
||||
await Promise.all([
|
||||
fsp.mkdir(routerTemplateDir, { recursive: true }),
|
||||
fsp.mkdir(bracketDir, { recursive: true }),
|
||||
])
|
||||
await Promise.all([
|
||||
fsp.copyFile(
|
||||
executorInputPath('router-template-slate.kcl'),
|
||||
join(routerTemplateDir, 'main.kcl')
|
||||
),
|
||||
fsp.copyFile(
|
||||
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
|
||||
join(bracketDir, 'main.kcl')
|
||||
),
|
||||
])
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await test.step('Opening the bracket project should load', async () => {
|
||||
await expect(page.getByText('bracket')).toBeVisible()
|
||||
@ -293,7 +280,7 @@ test(
|
||||
|
||||
await expect(page.getByRole('link', { name: 'bracket' })).toBeVisible()
|
||||
await expect(page.getByText('router-template-slate')).toBeVisible()
|
||||
await expect(page.getByText('New Project')).toBeVisible()
|
||||
await expect(page.getByText('Create project')).toBeVisible()
|
||||
})
|
||||
|
||||
await test.step('Opening the router-template project should load', async () => {
|
||||
@ -309,30 +296,21 @@ test(
|
||||
await expect(page.locator('#variables-pane')).toBeVisible()
|
||||
await expect(page.locator('#logs-pane')).toBeVisible()
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'external change of file contents are reflected in editor',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
async ({ context, page }, testInfo) => {
|
||||
const PROJECT_DIR_NAME = 'lee-was-here'
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectsDir,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
const aProjectDir = join(dir, PROJECT_DIR_NAME)
|
||||
await fsp.mkdir(aProjectDir, { recursive: true })
|
||||
},
|
||||
const { dir: projectsDir } = await context.folderSetupFn(async (dir) => {
|
||||
const aProjectDir = join(dir, PROJECT_DIR_NAME)
|
||||
await fsp.mkdir(aProjectDir, { recursive: true })
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await test.step('Open the project', async () => {
|
||||
await expect(page.getByText(PROJECT_DIR_NAME)).toBeVisible()
|
||||
@ -351,7 +329,5 @@ test(
|
||||
)
|
||||
await u.editorTextMatches(content)
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
@ -1,37 +1,30 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { test, expect } from './zoo-test'
|
||||
|
||||
import { getUtils, setup, tearDown } from './test-utils'
|
||||
import { getUtils } from './test-utils'
|
||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
|
||||
test.describe('Command bar tests', () => {
|
||||
test('Extrude from command bar selects extrude line after', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> xLine(-20, %)
|
||||
|> close(%)
|
||||
`
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> xLine(-20, %)
|
||||
|> close(%)
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
@ -52,51 +45,12 @@ test.describe('Command bar tests', () => {
|
||||
)
|
||||
})
|
||||
|
||||
test('Fillet from command bar', async ({ page }) => {
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-5, -5], %)
|
||||
|> line([0, 10], %)
|
||||
|> line([10, 0], %)
|
||||
|> line([0, -10], %)
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
extrude001 = extrude(-10, sketch001)`
|
||||
)
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.closeDebugPanel()
|
||||
|
||||
const selectSegment = () => page.getByText(`line([0, -10], %)`).click()
|
||||
|
||||
await selectSegment()
|
||||
await page.waitForTimeout(100)
|
||||
await page.getByRole('button', { name: 'Fillet' }).click()
|
||||
await page.waitForTimeout(100)
|
||||
await page.keyboard.press('Enter') // skip selection
|
||||
await page.waitForTimeout(100)
|
||||
await page.keyboard.press('Enter') // accept default radius
|
||||
await page.waitForTimeout(100)
|
||||
await page.keyboard.press('Enter') // submit
|
||||
await page.waitForTimeout(100)
|
||||
await expect(page.locator('.cm-activeLine')).toContainText(
|
||||
`fillet({ radius = ${KCL_DEFAULT_LENGTH}, tags = [seg01] }, %)`
|
||||
)
|
||||
})
|
||||
|
||||
test('Command bar can change a setting, and switch back and forth between arguments', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
||||
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||
@ -153,7 +107,7 @@ extrude001 = extrude(-10, sketch001)`
|
||||
// Check that the visibility changed
|
||||
await expect(paneSelector).not.toBeVisible()
|
||||
|
||||
commandOptionInput = page.getByPlaceholder('off')
|
||||
commandOptionInput = page.locator('[id="option-input"]')
|
||||
|
||||
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
|
||||
await commandBarButton.click()
|
||||
@ -174,10 +128,10 @@ extrude001 = extrude(-10, sketch001)`
|
||||
|
||||
test('Command bar keybinding works from code editor and can change a setting', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
@ -221,25 +175,25 @@ extrude001 = extrude(-10, sketch001)`
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
})
|
||||
|
||||
test('Can extrude from the command bar', async ({ page }) => {
|
||||
test('Can extrude from the command bar', async ({ page, homePage }) => {
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`distance = sqrt(20)
|
||||
sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([-6.95, 10.98], %)
|
||||
|> line([25.1, 0.41], %)
|
||||
|> line([0.73, -20.93], %)
|
||||
|> line([-23.44, 0.52], %)
|
||||
|> close(%)
|
||||
`
|
||||
sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([-6.95, 10.98], %)
|
||||
|> line([25.1, 0.41], %)
|
||||
|> line([0.73, -20.93], %)
|
||||
|> line([-23.44, 0.52], %)
|
||||
|> close(%)
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// Make sure the stream is up
|
||||
await u.openDebugPanel()
|
||||
@ -293,26 +247,19 @@ extrude001 = extrude(-10, sketch001)`
|
||||
await continueButton.click()
|
||||
await submitButton.click()
|
||||
|
||||
// Check that the code was updated
|
||||
await u.waitForCmdReceive('extrude')
|
||||
// Unfortunately this indentation seems to matter for the test
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`distance = sqrt(20)
|
||||
distance001 = ${KCL_DEFAULT_LENGTH}
|
||||
sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([-6.95, 10.98], %)
|
||||
|> line([25.1, 0.41], %)
|
||||
|> line([0.73, -20.93], %)
|
||||
|> line([-23.44, 0.52], %)
|
||||
|> close(%)
|
||||
extrude001 = extrude(distance001, sketch001)`.replace(/(\r\n|\n|\r)/gm, '') // remove newlines
|
||||
|
||||
await expect(page.locator('.cm-content')).toContainText(
|
||||
'extrude001 = extrude(distance001, sketch001)'
|
||||
)
|
||||
})
|
||||
|
||||
test('Can switch between sketch tools via command bar', async ({ page }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await u.waitForAuthSkipAppStart()
|
||||
test('Can switch between sketch tools via command bar', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
||||
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
||||
|
@ -1,23 +1,16 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { getUtils, setup, tearDown } from './test-utils'
|
||||
import { test, expect } from './zoo-test'
|
||||
import { getUtils } from './test-utils'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
test.describe('Copilot ghost text', () => {
|
||||
// eslint-disable-next-line jest/valid-title
|
||||
test.skip(true, 'Needs to get covered again')
|
||||
|
||||
test('completes code in empty file', async ({ page }) => {
|
||||
test('completes code in empty file', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -52,12 +45,13 @@ test.describe('Copilot ghost text', () => {
|
||||
|
||||
test.skip('copilot disabled in sketch mode no select plane', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -101,12 +95,13 @@ test.describe('Copilot ghost text', () => {
|
||||
|
||||
test('copilot disabled in sketch mode after selecting plane', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -184,12 +179,12 @@ test.describe('Copilot ghost text', () => {
|
||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('ArrowUp in code rejects the suggestion', async ({ page }) => {
|
||||
test('ArrowUp in code rejects the suggestion', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -212,12 +207,15 @@ test.describe('Copilot ghost text', () => {
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
|
||||
test('ArrowDown in code rejects the suggestion', async ({ page }) => {
|
||||
test('ArrowDown in code rejects the suggestion', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -240,12 +238,15 @@ test.describe('Copilot ghost text', () => {
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
|
||||
test('ArrowLeft in code rejects the suggestion', async ({ page }) => {
|
||||
test('ArrowLeft in code rejects the suggestion', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -268,12 +269,15 @@ test.describe('Copilot ghost text', () => {
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
|
||||
test('ArrowRight in code rejects the suggestion', async ({ page }) => {
|
||||
test('ArrowRight in code rejects the suggestion', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -296,12 +300,12 @@ test.describe('Copilot ghost text', () => {
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
|
||||
test('Enter in code scoots it down', async ({ page }) => {
|
||||
test('Enter in code scoots it down', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -326,12 +330,15 @@ test.describe('Copilot ghost text', () => {
|
||||
)
|
||||
})
|
||||
|
||||
test('Ctrl+shift+z in code rejects the suggestion', async ({ page }) => {
|
||||
test('Ctrl+shift+z in code rejects the suggestion', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
@ -360,12 +367,13 @@ test.describe('Copilot ghost text', () => {
|
||||
|
||||
test('Ctrl+z in code rejects the suggestion and undos the last code', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await page.waitForTimeout(800)
|
||||
await u.codeLocator.click()
|
||||
@ -420,98 +428,107 @@ test.describe('Copilot ghost text', () => {
|
||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||
|
||||
// TODO when we make codemirror a widget, we can test this.
|
||||
//await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
//await expect(page.locator('.cm-content')).toHaveText(``) })
|
||||
|
||||
test('delete in code rejects the suggestion', async ({ page }) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
test('delete in code rejects the suggestion', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
|
||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||
await page.waitForTimeout(500)
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||
`fn cube = (pos, scale) => {`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||
await page.waitForTimeout(500)
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||
`fn cube = (pos, scale) => {`
|
||||
)
|
||||
|
||||
// Going elsewhere in the code should hide the ghost text.
|
||||
await page.keyboard.press('Delete')
|
||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||
// Going elsewhere in the code should hide the ghost text.
|
||||
await page.keyboard.press('Delete')
|
||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
|
||||
test('backspace in code rejects the suggestion', async ({ page }) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
test('backspace in code rejects the suggestion', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
|
||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||
await page.waitForTimeout(500)
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||
`fn cube = (pos, scale) => {`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||
await page.waitForTimeout(500)
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||
`fn cube = (pos, scale) => {`
|
||||
)
|
||||
|
||||
// Going elsewhere in the code should hide the ghost text.
|
||||
await page.keyboard.press('Backspace')
|
||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||
// Going elsewhere in the code should hide the ghost text.
|
||||
await page.keyboard.press('Backspace')
|
||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
|
||||
test('focus outside code pane rejects the suggestion', async ({ page }) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
test('focus outside code pane rejects the suggestion', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
await u.codeLocator.click()
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
|
||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||
await page.waitForTimeout(500)
|
||||
await page.keyboard.press('Enter')
|
||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||
`fn cube = (pos, scale) => {`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||
await page.waitForTimeout(500)
|
||||
await page.keyboard.press('Enter')
|
||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||
)
|
||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||
`fn cube = (pos, scale) => {`
|
||||
)
|
||||
|
||||
// Going outside the editor should hide the ghost text.
|
||||
await page.mouse.move(0, 0)
|
||||
await page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||
// Going outside the editor should hide the ghost text.
|
||||
await page.mouse.move(0, 0)
|
||||
await page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,14 +1,6 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { test, expect } from './zoo-test'
|
||||
|
||||
import { getUtils, setup, tearDown } from './test-utils'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
import { getUtils } from './test-utils'
|
||||
|
||||
function countNewlines(input: string): number {
|
||||
let count = 0
|
||||
@ -24,13 +16,14 @@ test.describe('Debug pane', () => {
|
||||
test('Artifact IDs in the artifact graph are stable across code edits', async ({
|
||||
page,
|
||||
context,
|
||||
homePage,
|
||||
}) => {
|
||||
const code = `sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([1, 1], %)
|
||||
`
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([1, 1], %)
|
||||
`
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
const tree = page.getByTestId('debug-feature-tree')
|
||||
const segment = tree.locator('li', {
|
||||
@ -39,20 +32,20 @@ test.describe('Debug pane', () => {
|
||||
})
|
||||
|
||||
await test.step('Test setup', async () => {
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
await u.openKclCodePanel()
|
||||
await u.openDebugPanel()
|
||||
// Set the code in the code editor.
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.type(code, { delay: 0 })
|
||||
// Scroll to the feature tree.
|
||||
// Scroll to the artifact graph.
|
||||
await tree.scrollIntoViewIfNeeded()
|
||||
// Expand the feature tree.
|
||||
await tree.getByText('Feature Tree').click()
|
||||
// Expand the artifact graph.
|
||||
await tree.getByText('Artifact Graph').click()
|
||||
// Just expanded the details, making the element taller, so scroll again.
|
||||
await tree.getByText('Plane').first().scrollIntoViewIfNeeded()
|
||||
})
|
||||
// Extract the artifact IDs from the debug feature tree.
|
||||
// Extract the artifact IDs from the debug artifact graph.
|
||||
const initialSegmentIds = await segment.innerText({ timeout: 5_000 })
|
||||
// The artifact ID should include a UUID.
|
||||
expect(initialSegmentIds).toMatch(
|
||||
|
@ -1,39 +1,31 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { join } from 'path'
|
||||
import { test, expect } from './zoo-test'
|
||||
import path from 'path'
|
||||
import {
|
||||
getUtils,
|
||||
setupElectron,
|
||||
tearDown,
|
||||
executorInputPath,
|
||||
getPlaywrightDownloadDir,
|
||||
} from './test-utils'
|
||||
import fsp from 'fs/promises'
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
|
||||
test(
|
||||
'export works on the first try',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
const bracketDir = join(dir, 'bracket')
|
||||
await Promise.all([fsp.mkdir(bracketDir, { recursive: true })])
|
||||
await Promise.all([
|
||||
fsp.copyFile(
|
||||
executorInputPath('router-template-slate.kcl'),
|
||||
join(bracketDir, 'other.kcl')
|
||||
),
|
||||
fsp.copyFile(
|
||||
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
|
||||
join(bracketDir, 'main.kcl')
|
||||
),
|
||||
])
|
||||
},
|
||||
async ({ page, context }, testInfo) => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
const bracketDir = path.join(dir, 'bracket')
|
||||
await Promise.all([fsp.mkdir(bracketDir, { recursive: true })])
|
||||
await Promise.all([
|
||||
fsp.copyFile(
|
||||
executorInputPath('router-template-slate.kcl'),
|
||||
path.join(bracketDir, 'other.kcl')
|
||||
),
|
||||
fsp.copyFile(
|
||||
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
|
||||
path.join(bracketDir, 'main.kcl')
|
||||
),
|
||||
])
|
||||
})
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
page.on('console', console.log)
|
||||
|
||||
@ -93,12 +85,16 @@ test(
|
||||
await expect(successToastMessage).toBeVisible()
|
||||
await expect(exportingToastMessage).not.toBeVisible()
|
||||
|
||||
const firstFileFullPath = path.resolve(
|
||||
getPlaywrightDownloadDir(page),
|
||||
exportFileName
|
||||
)
|
||||
await test.step('Check the export size', async () => {
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
try {
|
||||
const outputGltf = await fsp.readFile(exportFileName)
|
||||
const outputGltf = await fsp.readFile(firstFileFullPath)
|
||||
return outputGltf.byteLength
|
||||
} catch (e) {
|
||||
return 0
|
||||
@ -107,9 +103,6 @@ test(
|
||||
{ timeout: 15_000 }
|
||||
)
|
||||
.toBeGreaterThan(300_000)
|
||||
|
||||
// clean up exported file
|
||||
await fsp.rm(exportFileName)
|
||||
})
|
||||
})
|
||||
|
||||
@ -170,12 +163,16 @@ test(
|
||||
expect(exportingToastMessage).not.toBeVisible(),
|
||||
]))
|
||||
|
||||
const secondFileFullPath = path.resolve(
|
||||
getPlaywrightDownloadDir(page),
|
||||
exportFileName
|
||||
)
|
||||
await test.step('Check the export size', async () => {
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
try {
|
||||
const outputGltf = await fsp.readFile(exportFileName)
|
||||
const outputGltf = await fsp.readFile(secondFileFullPath)
|
||||
return outputGltf.byteLength
|
||||
} catch (e) {
|
||||
return 0
|
||||
@ -184,13 +181,7 @@ test(
|
||||
{ timeout: 15_000 }
|
||||
)
|
||||
.toBeGreaterThan(100_000)
|
||||
|
||||
// clean up exported file
|
||||
await fsp.rm(exportFileName)
|
||||
})
|
||||
await electronApp.close()
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { test, expect } from './zoo-test'
|
||||
import fsp from 'fs/promises'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import {
|
||||
@ -6,37 +6,27 @@ import {
|
||||
darkModePlaneColorXZ,
|
||||
executorInputPath,
|
||||
getUtils,
|
||||
setup,
|
||||
setupElectron,
|
||||
tearDown,
|
||||
} from './test-utils'
|
||||
|
||||
import { join } from 'path'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
|
||||
test.describe('Editor tests', () => {
|
||||
test('can comment out code with ctrl+/', async ({ page }) => {
|
||||
test('can comment out code with ctrl+/', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.type(`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|
||||
await page.keyboard.down('ControlOrMeta')
|
||||
await page.keyboard.press('/')
|
||||
@ -44,11 +34,11 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
// |> close(%)`)
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
// |> close(%)`)
|
||||
|
||||
// uncomment the code
|
||||
await page.keyboard.down('ControlOrMeta')
|
||||
@ -57,23 +47,22 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
})
|
||||
|
||||
test('if you click the format button it formats your code', async ({
|
||||
test('ensure we use the cache, and do not re-execute', async ({
|
||||
homePage,
|
||||
page,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
await homePage.goToModelingScene()
|
||||
await u.waitForPageLoad()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.type(`sketch001 = startSketchOn('XY')
|
||||
@ -82,36 +71,141 @@ test.describe('Editor tests', () => {
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
await page.locator('#code-pane button:first-child').click()
|
||||
await page.locator('button:has-text("Format code")').click()
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XY')
|
||||
// Ensure we execute the first time.
|
||||
await u.openDebugPanel()
|
||||
await expect(
|
||||
page.locator('[data-receive-command-type="scene_clear_all"]')
|
||||
).toHaveCount(1)
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(2)
|
||||
|
||||
// Add whitespace to the end of the code.
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.press('ArrowUp')
|
||||
await page.keyboard.press('ArrowUp')
|
||||
await page.keyboard.press('ArrowUp')
|
||||
await page.keyboard.press('ArrowUp')
|
||||
await page.keyboard.press('Home')
|
||||
await page.keyboard.type(' ')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.type(' ')
|
||||
|
||||
// Ensure we don't execute the second time.
|
||||
await u.openDebugPanel()
|
||||
// Make sure we didn't clear the scene.
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(3)
|
||||
await expect(
|
||||
page.locator('[data-receive-command-type="scene_clear_all"]')
|
||||
).toHaveCount(1)
|
||||
})
|
||||
|
||||
test('ensure we use the cache, and do not clear on append', async ({
|
||||
homePage,
|
||||
page,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await homePage.goToModelingScene()
|
||||
await u.waitForPageLoad()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.type(`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|
||||
// Ensure we execute the first time.
|
||||
await u.openDebugPanel()
|
||||
await expect(
|
||||
page.locator('[data-receive-command-type="scene_clear_all"]')
|
||||
).toHaveCount(1)
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(2)
|
||||
|
||||
// Add whitespace to the end of the code.
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('End')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.type('const x = 1')
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
await u.openDebugPanel()
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(3)
|
||||
await expect(
|
||||
page.locator('[data-receive-command-type="scene_clear_all"]')
|
||||
).toHaveCount(1)
|
||||
})
|
||||
|
||||
test('if you click the format button it formats your code', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.type(`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
await page.locator('#code-pane button:first-child').click()
|
||||
await page.locator('button:has-text("Format code")').click()
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
})
|
||||
|
||||
test('if you click the format button it formats your code and executes so lints are still there', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.type(`sketch_001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
@ -135,11 +229,11 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch_001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|
||||
// error in guter
|
||||
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
|
||||
@ -151,29 +245,27 @@ test.describe('Editor tests', () => {
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('fold gutters work', async ({ page }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
test('fold gutters work', async ({ page, homePage }) => {
|
||||
const fullCode = `sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
)
|
||||
})
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// TODO: Jess needs to fix this but you have to mod the code to get them to show
|
||||
// up, its an annoying codemirror thing.
|
||||
@ -224,22 +316,25 @@ test.describe('Editor tests', () => {
|
||||
await expect(foldGutterFoldLine).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('hover over functions shows function description', async ({ page }) => {
|
||||
test('hover over functions shows function description', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
)
|
||||
})
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
@ -268,23 +363,24 @@ test.describe('Editor tests', () => {
|
||||
|
||||
test('if you use the format keyboard binding it formats your code', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
)
|
||||
localStorage.setItem('disableAxis', 'true')
|
||||
})
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
@ -301,32 +397,33 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
})
|
||||
|
||||
test('if you use the format keyboard binding it formats your code and executes so lints are shown', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch_001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`
|
||||
)
|
||||
localStorage.setItem('disableAxis', 'true')
|
||||
})
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
@ -353,11 +450,11 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch_001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
|> line([0, 20], %)
|
||||
|> line([-20, 0], %)
|
||||
|> close(%)`)
|
||||
|
||||
// error in guter
|
||||
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
|
||||
@ -369,11 +466,14 @@ test.describe('Editor tests', () => {
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('if you write kcl with lint errors you get lints', async ({ page }) => {
|
||||
test('if you write kcl with lint errors you get lints', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-info')).not.toBeVisible()
|
||||
@ -409,23 +509,26 @@ test.describe('Editor tests', () => {
|
||||
await expect(page.locator('.cm-lint-marker-info')).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('if you fixup kcl errors you clear lints', async ({ page }) => {
|
||||
test('if you fixup kcl errors you clear lints', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([3.29, 7.86], %)
|
||||
|> line([2.48, 2.44], %)
|
||||
|> line([2.66, 1.17], %)
|
||||
|> close(%)
|
||||
`
|
||||
|> startProfileAt([3.29, 7.86], %)
|
||||
|> line([2.48, 2.44], %)
|
||||
|> line([2.66, 1.17], %)
|
||||
|> close(%)
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
@ -447,22 +550,27 @@ test.describe('Editor tests', () => {
|
||||
).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('if you write invalid kcl you get inlined errors', async ({ page }) => {
|
||||
test('if you write invalid kcl you get inlined errors', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
|
||||
/* add the following code to the editor ($ error is not a valid line)
|
||||
$ error
|
||||
const topAng = 30
|
||||
const bottomAng = 25
|
||||
*/
|
||||
/* add the following code to the editor (~ error is not a valid line)
|
||||
* the old check here used $ but this is for tags so it changed meaning.
|
||||
* hopefully ~ doesn't change meaning
|
||||
~ error
|
||||
const topAng = 30
|
||||
const bottomAng = 25
|
||||
*/
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.type('$ error')
|
||||
await page.keyboard.type('~ error')
|
||||
|
||||
// press arrows to clear autocomplete
|
||||
await page.keyboard.press('ArrowLeft')
|
||||
@ -479,10 +587,12 @@ test.describe('Editor tests', () => {
|
||||
|
||||
// error text on hover
|
||||
await page.hover('.cm-lint-marker-error')
|
||||
await expect(page.getByText('Unexpected token: $').first()).toBeVisible()
|
||||
await expect(
|
||||
page.getByText("found unknown token '~'").first()
|
||||
).toBeVisible()
|
||||
|
||||
// select the line that's causing the error and delete it
|
||||
await page.getByText('$ error').click()
|
||||
await page.getByText('~ error').click()
|
||||
await page.keyboard.press('End')
|
||||
await page.keyboard.down('Shift')
|
||||
await page.keyboard.press('Home')
|
||||
@ -518,103 +628,108 @@ test.describe('Editor tests', () => {
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('error with 2 source ranges gets 2 diagnostics', async ({ page }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`length = .750
|
||||
width = 0.500
|
||||
height = 0.500
|
||||
dia = 4
|
||||
test.fixme(
|
||||
'error with 2 source ranges gets 2 diagnostics',
|
||||
async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`length = .750
|
||||
width = 0.500
|
||||
height = 0.500
|
||||
dia = 4
|
||||
|
||||
fn squareHole = (l, w) => {
|
||||
squareHoleSketch = startSketchOn('XY')
|
||||
|> startProfileAt([-width / 2, -length / 2], %)
|
||||
|> lineTo([width / 2, -length / 2], %)
|
||||
|> lineTo([width / 2, length / 2], %)
|
||||
|> lineTo([-width / 2, length / 2], %)
|
||||
|> close(%)
|
||||
return squareHoleSketch
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
fn squareHole = (l, w) => {
|
||||
squareHoleSketch = startSketchOn('XY')
|
||||
|> startProfileAt([-width / 2, -length / 2], %)
|
||||
|> lineTo([width / 2, -length / 2], %)
|
||||
|> lineTo([width / 2, length / 2], %)
|
||||
|> lineTo([-width / 2, length / 2], %)
|
||||
|> close(%)
|
||||
return squareHoleSketch
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
await u.waitForPageLoad()
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.closeDebugPanel()
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.closeDebugPanel()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
|
||||
// Click on the bottom of the code editor to add a new line
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.type(`extrusion = startSketchOn('XY')
|
||||
|> circle({ center = [0, 0], radius = dia/2 }, %)
|
||||
|> hole(squareHole(length, width, height), %)
|
||||
|> extrude(height, %)`)
|
||||
// Click on the bottom of the code editor to add a new line
|
||||
await u.codeLocator.click()
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.type(`extrusion = startSketchOn('XY')
|
||||
|> circle({ center: [0, 0], radius: dia/2 }, %)
|
||||
|> hole(squareHole(length, width, height), %)
|
||||
|> extrude(height, %)`)
|
||||
|
||||
// error in gutter
|
||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||
await page.hover('.cm-lint-marker-error:first-child')
|
||||
await expect(
|
||||
page.getByText('Expected 2 arguments, got 3').first()
|
||||
).toBeVisible()
|
||||
// error in gutter
|
||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||
await page.hover('.cm-lint-marker-error:first-child')
|
||||
await expect(
|
||||
page.getByText('Expected 2 arguments, got 3').first()
|
||||
).toBeVisible()
|
||||
|
||||
// Make sure there are two diagnostics
|
||||
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2)
|
||||
})
|
||||
// Make sure there are two diagnostics
|
||||
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2)
|
||||
}
|
||||
)
|
||||
test('if your kcl gets an error from the engine it is inlined', async ({
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`box = startSketchOn('XY')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([0, 10], %)
|
||||
|> line([10, 0], %)
|
||||
|> line([0, -10], %, $revolveAxis)
|
||||
|> close(%)
|
||||
|> extrude(10, %)
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([0, 10], %)
|
||||
|> line([10, 0], %)
|
||||
|> line([0, -10], %, $revolveAxis)
|
||||
|> close(%)
|
||||
|> extrude(10, %)
|
||||
|
||||
sketch001 = startSketchOn(box, revolveAxis)
|
||||
|> startProfileAt([5, 10], %)
|
||||
|> line([0, -10], %)
|
||||
|> line([2, 0], %)
|
||||
|> line([0, -10], %)
|
||||
|> close(%)
|
||||
|> revolve({
|
||||
axis = revolveAxis,
|
||||
angle = 90
|
||||
}, %)
|
||||
`
|
||||
sketch001 = startSketchOn(box, revolveAxis)
|
||||
|> startProfileAt([5, 10], %)
|
||||
|> line([0, -10], %)
|
||||
|> line([2, 0], %)
|
||||
|> line([0, -10], %)
|
||||
|> close(%)
|
||||
|> revolve({
|
||||
axis: revolveAxis,
|
||||
angle: 90
|
||||
}, %)
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
await page.goto('/')
|
||||
await u.waitForPageLoad()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||
|
||||
@ -625,12 +740,15 @@ test.describe('Editor tests', () => {
|
||||
await expect(page.getByText(searchText)).toBeVisible()
|
||||
})
|
||||
test.describe('Autocomplete works', () => {
|
||||
test('with enter/click to accept the completion', async ({ page }) => {
|
||||
test('with enter/click to accept the completion', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// tests clicking on an option, selection the first option
|
||||
// and arrowing down to an option
|
||||
@ -692,19 +810,19 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([3.14, 12], %)
|
||||
|> xLine(5, %) // lin`)
|
||||
|> startProfileAt([3.14, 12], %)
|
||||
|> xLine(5, %) // lin`)
|
||||
|
||||
// expect there to be no KCL errors
|
||||
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(0)
|
||||
})
|
||||
|
||||
test('with tab to accept the completion', async ({ page }) => {
|
||||
test('with tab to accept the completion', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// this test might be brittle as we add and remove functions
|
||||
// but should also be easy to update.
|
||||
@ -766,26 +884,30 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([3.14, 12], %)
|
||||
|> xLine(5, %) // lin`)
|
||||
|> startProfileAt([3.14, 12], %)
|
||||
|> xLine(5, %) // lin`)
|
||||
})
|
||||
})
|
||||
test('Can undo a click and point extrude with ctrl+z', async ({ page }) => {
|
||||
test('Can undo a click and point extrude with ctrl+z', async ({
|
||||
page,
|
||||
context,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> close(%)`
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> close(%)`
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
@ -838,29 +960,32 @@ test.describe('Editor tests', () => {
|
||||
await page.waitForTimeout(100)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> close(%)`)
|
||||
|> startProfileAt([4.61, -14.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -5.38], %)
|
||||
|> close(%)`)
|
||||
})
|
||||
|
||||
test('Can undo a sketch modification with ctrl+z', async ({ page }) => {
|
||||
test('Can undo a sketch modification with ctrl+z', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -10.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`
|
||||
|> startProfileAt([4.61, -10.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
@ -887,7 +1012,7 @@ test.describe('Editor tests', () => {
|
||||
})
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
const startPX = [665, 397]
|
||||
const startPX = [1200 / 2, 500 / 2]
|
||||
|
||||
const dragPX = 40
|
||||
|
||||
@ -901,9 +1026,9 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
||||
|
||||
// drag startProfieAt handle
|
||||
// drag startProfileAt handle
|
||||
await page.dragAndDrop('#stream', '#stream', {
|
||||
sourcePosition: { x: startPX[0], y: startPX[1] },
|
||||
sourcePosition: { x: startPX[0] + 68, y: startPX[1] + 147 },
|
||||
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] + dragPX },
|
||||
})
|
||||
await page.waitForTimeout(100)
|
||||
@ -941,12 +1066,12 @@ test.describe('Editor tests', () => {
|
||||
// expect the code to have changed
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.12, -12.68], %)
|
||||
|> line([15.39, -2.78], %)
|
||||
|> tangentialArcTo([27.6, -3.05], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)
|
||||
`)
|
||||
|> startProfileAt([2.71, -2.71], %)
|
||||
|> line([15.4, -2.78], %)
|
||||
|> tangentialArcTo([27.6, -3.05], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)
|
||||
`)
|
||||
|
||||
// Hit undo
|
||||
await page.keyboard.down('Control')
|
||||
@ -955,11 +1080,11 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.12, -12.68], %)
|
||||
|> line([15.39, -2.78], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`)
|
||||
|> startProfileAt([2.71, -2.71], %)
|
||||
|> line([15.4, -2.78], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`)
|
||||
|
||||
// Hit undo again.
|
||||
await page.keyboard.down('Control')
|
||||
@ -968,12 +1093,12 @@ test.describe('Editor tests', () => {
|
||||
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.12, -12.68], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)
|
||||
`)
|
||||
|> startProfileAt([2.71, -2.71], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)
|
||||
`)
|
||||
|
||||
// Hit undo again.
|
||||
await page.keyboard.down('Control')
|
||||
@ -983,31 +1108,29 @@ test.describe('Editor tests', () => {
|
||||
await page.waitForTimeout(100)
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([4.61, -10.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`)
|
||||
|> startProfileAt([4.61, -10.01], %)
|
||||
|> line([12.73, -0.09], %)
|
||||
|> tangentialArcTo([24.95, -0.38], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)`)
|
||||
})
|
||||
|
||||
test.fixme(
|
||||
`Can use the import stdlib function on a local OBJ file`,
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
const bracketDir = join(dir, 'cube')
|
||||
await fsp.mkdir(bracketDir, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
executorInputPath('cube.obj'),
|
||||
join(bracketDir, 'cube.obj')
|
||||
)
|
||||
await fsp.writeFile(join(bracketDir, 'main.kcl'), '')
|
||||
},
|
||||
async ({ page, context }, testInfo) => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
const bracketDir = join(dir, 'cube')
|
||||
await fsp.mkdir(bracketDir, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
executorInputPath('cube.obj'),
|
||||
join(bracketDir, 'cube.obj')
|
||||
)
|
||||
await fsp.writeFile(join(bracketDir, 'main.kcl'), '')
|
||||
})
|
||||
|
||||
const viewportSize = { width: 1200, height: 500 }
|
||||
await page.setViewportSize(viewportSize)
|
||||
await page.setBodyDimensions(viewportSize)
|
||||
|
||||
// Locators and constants
|
||||
const u = await getUtils(page)
|
||||
@ -1065,8 +1188,6 @@ test.describe('Editor tests', () => {
|
||||
})
|
||||
.toBeGreaterThan(15)
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user