Compare commits
68 Commits
jess/chang
...
pierremtb/
Author | SHA1 | Date | |
---|---|---|---|
e8a82ea85e | |||
c1894edaed | |||
8c28f34238 | |||
d2340628a8 | |||
a1f5cdd690 | |||
d1d8d0a82c | |||
f76b328136 | |||
a13548da17 | |||
65f4b0f239 | |||
dbcc0bd3b4 | |||
472b3618ac | |||
43e89e8bae | |||
94a9e01301 | |||
3980a1caf8 | |||
d4f23f8469 | |||
9143c6f08a | |||
1d4456c458 | |||
c6fbb4fc63 | |||
b7c8d6c185 | |||
f23aa5e642 | |||
8bb26c9b89 | |||
0d7aebdee9 | |||
ad333c2055 | |||
3559df0c5e | |||
e2dda07829 | |||
ea585cb5d6 | |||
8af9af2aa7 | |||
f0ba35c0b2 | |||
970cf7f017 | |||
d125efcd60 | |||
4664427832 | |||
d84b9cc875 | |||
0c6b6bf5d5 | |||
d275995dfe | |||
b03ca30379 | |||
e5f23a49b4 | |||
e78100eaac | |||
ae9d8be4e4 | |||
e4f73a6d5c | |||
a31fd608cf | |||
a98d5aa2fb | |||
4c6ef841bb | |||
997f539a8c | |||
83f74faaf7 | |||
0bb5797377 | |||
c3097aa334 | |||
2cd0fcc9a7 | |||
5b653fb558 | |||
6a5b23f848 | |||
a480783ee8 | |||
bc0f5b5787 | |||
962eb0e376 | |||
ababe24b97 | |||
1bf7a2abd4 | |||
0ea4f94e8f | |||
6cc6130b6a | |||
8294903cd0 | |||
7b7379c3dd | |||
9acdf1e42f | |||
5dd95d27de | |||
1016b4c879 | |||
df6f571294 | |||
be05dd7ba1 | |||
bc22d888ee | |||
e6ae89ebf9 | |||
e7b23e1638 | |||
ce7a967f5f | |||
38446b5b2a |
@ -1,3 +1,3 @@
|
|||||||
[codespell]
|
[codespell]
|
||||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser
|
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,atleast,ue,afterall,ser,fromM,FromM
|
||||||
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,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo
|
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,./public/kcl-samples,./rust/kcl-lib/tests/kcl_samples,tsconfig.tsbuildinfo
|
||||||
|
24
.github/ci-cd-scripts/start-vector-macos.sh
vendored
Executable file
24
.github/ci-cd-scripts/start-vector-macos.sh
vendored
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Install vector
|
||||||
|
brew tap vectordotdev/brew && brew install vector
|
||||||
|
|
||||||
|
# Configure vector
|
||||||
|
mkdir -p /tmp/vector
|
||||||
|
cp .github/workflows/vector.toml /tmp/vector.toml
|
||||||
|
sed -i '' "s#OS_NAME#${OS_NAME}#g" /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#${GH_ACTIONS_AXIOM_TOKEN}#g" /tmp/vector.toml
|
||||||
|
|
||||||
|
# Display settings
|
||||||
|
echo
|
||||||
|
echo 'Vector config:'
|
||||||
|
cat /tmp/vector.toml
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Start in the background
|
||||||
|
$(brew --prefix)/opt/vector/bin/vector --config /tmp/vector.toml &
|
24
.github/ci-cd-scripts/start-vector-ubuntu.sh
vendored
Executable file
24
.github/ci-cd-scripts/start-vector-ubuntu.sh
vendored
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Install vector
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev | bash -s -- -y
|
||||||
|
|
||||||
|
# Configure vector
|
||||||
|
mkdir -p /tmp/vector
|
||||||
|
cp .github/workflows/vector.toml /tmp/vector.toml
|
||||||
|
sed -i "s#OS_NAME#${OS_NAME}#g" /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#${GH_ACTIONS_AXIOM_TOKEN}#g" /tmp/vector.toml
|
||||||
|
|
||||||
|
# Display settings
|
||||||
|
echo
|
||||||
|
echo 'Vector config:'
|
||||||
|
cat /tmp/vector.toml
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Start in background
|
||||||
|
${HOME}/.vector/bin/vector --config /tmp/vector.toml &
|
2
.github/workflows/build-and-store-wasm.yml
vendored
2
.github/workflows/build-and-store-wasm.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
|||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
with:
|
with:
|
||||||
cache: false # Configured below.
|
cache: false # Configured below.
|
||||||
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
- name: Rust Cache
|
- name: Rust Cache
|
||||||
|
35
.github/workflows/build-apps.yml
vendored
35
.github/workflows/build-apps.yml
vendored
@ -10,7 +10,8 @@ on:
|
|||||||
- 'nightly-v[0-9]+.[0-9]+.[0-9]+'
|
- 'nightly-v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }}
|
# IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }}
|
||||||
|
IS_RELEASE: true
|
||||||
IS_NIGHTLY: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'nightly-v') }}
|
IS_NIGHTLY: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'nightly-v') }}
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
@ -77,7 +78,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
cache: false # Configured below.
|
cache: false # Configured below.
|
||||||
|
|
||||||
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
@ -99,11 +100,11 @@ jobs:
|
|||||||
yarn files:set-version
|
yarn files:set-version
|
||||||
yarn files:flip-to-nightly
|
yarn files:flip-to-nightly
|
||||||
|
|
||||||
- name: Set release version
|
# - name: Set release version
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
# if: ${{ env.IS_RELEASE == 'true' }}
|
||||||
run: |
|
# run: |
|
||||||
export VERSION=${GITHUB_REF_NAME#v}
|
# export VERSION=${GITHUB_REF_NAME#v}
|
||||||
yarn files:set-version
|
# yarn files:set-version
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@ -183,30 +184,32 @@ jobs:
|
|||||||
max_attempts: 3
|
max_attempts: 3
|
||||||
command: yarn install
|
command: yarn install
|
||||||
|
|
||||||
|
# Next steps are from Digicert docs at
|
||||||
|
# https://docs.digicert.com/en/digicert-keylocker/ci-cd-integrations/scripts/github/scripts-for-signing-using-ksp-library-on-github.html#ksp-signing-using-github-action-488726
|
||||||
- name: Prepare certificate and variables (Windows only)
|
- name: Prepare certificate and variables (Windows only)
|
||||||
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
||||||
run: |
|
run: |
|
||||||
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
|
CERTIFICATE_PATH=$RUNNER_TEMP/certificate.p12
|
||||||
cat /d/Certificate_pkcs12.p12
|
echo "$SM_CLIENT_CERT_FILE_B64" | base64 --decode > $CERTIFICATE_PATH
|
||||||
echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
|
echo "SM_CLIENT_CERT_FILE=$CERTIFICATE_PATH" >> "$GITHUB_ENV"
|
||||||
echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
|
echo "SM_HOST=${{ secrets.SM_HOST }}" >> "$GITHUB_ENV"
|
||||||
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
|
echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> "$GITHUB_ENV"
|
||||||
echo "SM_CLIENT_CERT_FILE=D:\\Certificate_pkcs12.p12" >> "$GITHUB_ENV"
|
|
||||||
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
|
echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> "$GITHUB_ENV"
|
||||||
echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH
|
echo "C:\Program Files (x86)\Windows Kits\10\App Certification Kit" >> $GITHUB_PATH
|
||||||
echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH
|
echo "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" >> $GITHUB_PATH
|
||||||
echo "C:\Program Files\DigiCert\DigiCert One Signing Manager Tools" >> $GITHUB_PATH
|
echo "C:\Program Files\DigiCert\DigiCert Keylocker Tools" >> $GITHUB_PATH
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Setup certicate with SSM KSP (Windows only)
|
- name: Setup certicate with SSM KSP (Windows only)
|
||||||
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
||||||
run: |
|
run: |
|
||||||
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
|
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/Keylockertools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o Keylockertools-windows-x64.msi
|
||||||
msiexec /i smtools-windows-x64.msi /quiet /qn
|
msiexec /i Keylockertools-windows-x64.msi /quiet /qn
|
||||||
smksp_registrar.exe list
|
smksp_registrar.exe list
|
||||||
smctl.exe keypair ls
|
smctl.exe keypair ls
|
||||||
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
|
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
|
||||||
smksp_cert_sync.exe
|
smksp_cert_sync.exe
|
||||||
|
smctl windows certsync
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
||||||
- name: Build the app (debug)
|
- name: Build the app (debug)
|
||||||
@ -225,8 +228,8 @@ jobs:
|
|||||||
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
|
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||||
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
# DEBUG: "electron-notarize*"
|
||||||
DEBUG: "electron-notarize*"
|
DEBUG: electron-builder
|
||||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||||
uses: nick-fields/retry@v3.0.2
|
uses: nick-fields/retry@v3.0.2
|
||||||
with:
|
with:
|
||||||
|
19
.github/workflows/cargo-test.yml
vendored
19
.github/workflows/cargo-test.yml
vendored
@ -34,20 +34,11 @@ jobs:
|
|||||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
with:
|
with:
|
||||||
cache: false # Configured below.
|
cache: false # Configured below.
|
||||||
- name: Install vector
|
- name: Start Vector
|
||||||
run: |
|
run: .github/ci-cd-scripts/start-vector-ubuntu.sh
|
||||||
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
|
env:
|
||||||
chmod +x /tmp/vector.sh
|
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
|
||||||
/tmp/vector.sh -y -no-modify-path
|
OS_NAME: ${{ env.OS_NAME }}
|
||||||
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 &
|
|
||||||
- uses: taiki-e/install-action@cargo-llvm-cov
|
- uses: taiki-e/install-action@cargo-llvm-cov
|
||||||
- uses: taiki-e/install-action@nextest
|
- uses: taiki-e/install-action@nextest
|
||||||
- name: Install just
|
- name: Install just
|
||||||
|
24
.github/workflows/e2e-tests.yml
vendored
24
.github/workflows/e2e-tests.yml
vendored
@ -140,7 +140,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
cache: false # Configured below.
|
cache: false # Configured below.
|
||||||
|
|
||||||
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
|
if: ${{ needs.conditions.outputs.should-run == 'true' && steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
@ -339,22 +339,12 @@ jobs:
|
|||||||
if: needs.conditions.outputs.should-run == 'true'
|
if: needs.conditions.outputs.should-run == 'true'
|
||||||
run: yarn tronb:vite:dev
|
run: yarn tronb:vite:dev
|
||||||
|
|
||||||
- name: Install vector
|
- name: Start Vector
|
||||||
if: ${{ needs.conditions.outputs.should-run == 'true' && contains(matrix.os, 'ubuntu') }}
|
if: ${{ needs.conditions.outputs.should-run == 'true' && !contains(matrix.os, 'windows') }}
|
||||||
shell: bash
|
run: .github/ci-cd-scripts/start-vector-${{ env.OS_NAME }}.sh
|
||||||
run: |
|
env:
|
||||||
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
|
GH_ACTIONS_AXIOM_TOKEN: ${{ secrets.GH_ACTIONS_AXIOM_TOKEN }}
|
||||||
chmod +x /tmp/vector.sh
|
OS_NAME: ${{ env.OS_NAME }}
|
||||||
/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 &
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
|
if: ${{ needs.conditions.outputs.should-run == 'true' && !cancelled() && (success() || failure()) }}
|
||||||
|
6
.github/workflows/static-analysis.yml
vendored
6
.github/workflows/static-analysis.yml
vendored
@ -51,7 +51,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
cache: false # Configured below.
|
cache: false # Configured below.
|
||||||
|
|
||||||
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ jobs:
|
|||||||
cache: 'yarn'
|
cache: 'yarn'
|
||||||
|
|
||||||
- run: yarn install
|
- run: yarn install
|
||||||
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ jobs:
|
|||||||
cache: 'yarn'
|
cache: 'yarn'
|
||||||
|
|
||||||
- run: yarn install
|
- run: yarn install
|
||||||
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
|
- uses: taiki-e/install-action@d4635f2de61c8b8104d59cd4aede2060638378cc
|
||||||
with:
|
with:
|
||||||
tool: wasm-pack
|
tool: wasm-pack
|
||||||
|
|
||||||
|
1
.github/workflows/vector.toml
vendored
1
.github/workflows/vector.toml
vendored
@ -8,6 +8,7 @@ include = ["/tmp/github-actions.log"]
|
|||||||
type = "remap"
|
type = "remap"
|
||||||
inputs = [ "github-actions-file" ]
|
inputs = [ "github-actions-file" ]
|
||||||
source = '''
|
source = '''
|
||||||
|
.platform = "OS_NAME"
|
||||||
.action = "GITHUB_WORKFLOW"
|
.action = "GITHUB_WORKFLOW"
|
||||||
.repo = "GITHUB_REPOSITORY"
|
.repo = "GITHUB_REPOSITORY"
|
||||||
.sha = "GITHUB_SHA"
|
.sha = "GITHUB_SHA"
|
||||||
|
25
Makefile
25
Makefile
@ -5,8 +5,15 @@ all: install build check
|
|||||||
# INSTALL
|
# INSTALL
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
CARGO ?= ~/.cargo/bin/cargo.exe
|
export WINDOWS := true
|
||||||
WASM_PACK ?= ~/.cargo/bin/wasm-pack.exe
|
ifndef MSYSTEM
|
||||||
|
export POWERSHELL := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef WINDOWS
|
||||||
|
CARGO ?= $(USERPROFILE)/.cargo/bin/cargo.exe
|
||||||
|
WASM_PACK ?= $(USERPROFILE)/.cargo/bin/wasm-pack.exe
|
||||||
else
|
else
|
||||||
CARGO ?= ~/.cargo/bin/cargo
|
CARGO ?= ~/.cargo/bin/cargo
|
||||||
WASM_PACK ?= ~/.cargo/bin/wasm-pack
|
WASM_PACK ?= ~/.cargo/bin/wasm-pack
|
||||||
@ -17,21 +24,21 @@ install: node_modules/.yarn-integrity $(CARGO) $(WASM_PACK) ## Install dependenc
|
|||||||
|
|
||||||
node_modules/.yarn-integrity: package.json yarn.lock
|
node_modules/.yarn-integrity: package.json yarn.lock
|
||||||
yarn install
|
yarn install
|
||||||
ifeq ($(OS),Windows_NT)
|
ifdef POWERSHELL
|
||||||
@ type nul > $@
|
@ type nul > $@
|
||||||
else
|
else
|
||||||
@ touch $@
|
@ touch $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(CARGO):
|
$(CARGO):
|
||||||
ifeq ($(OS),Windows_NT)
|
ifdef WINDOWS
|
||||||
yarn install:rust:windows
|
yarn install:rust:windows
|
||||||
else
|
else
|
||||||
yarn install:rust
|
yarn install:rust
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(WASM_PACK):
|
$(WASM_PACK):
|
||||||
ifeq ($(OS),Windows_NT)
|
ifdef WINDOWS
|
||||||
yarn install:wasm-pack:cargo
|
yarn install:wasm-pack:cargo
|
||||||
else
|
else
|
||||||
yarn install:wasm-pack:sh
|
yarn install:wasm-pack:sh
|
||||||
@ -57,7 +64,7 @@ build-web: install public/kcl_wasm_lib_bg.wasm build/index.html
|
|||||||
build-desktop: install public/kcl_wasm_lib_bg.wasm .vite/build/main.js
|
build-desktop: install public/kcl_wasm_lib_bg.wasm .vite/build/main.js
|
||||||
|
|
||||||
public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES) $(RUST_SOURCES)
|
public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES) $(RUST_SOURCES)
|
||||||
ifeq ($(OS),Windows_NT)
|
ifdef WINDOWS
|
||||||
yarn build:wasm:dev:windows
|
yarn build:wasm:dev:windows
|
||||||
else
|
else
|
||||||
yarn build:wasm:dev
|
yarn build:wasm:dev
|
||||||
@ -140,8 +147,8 @@ endif
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: ## Delete all artifacts
|
clean: ## Delete all artifacts
|
||||||
ifeq ($(OS),Windows_NT)
|
ifdef POWERSHELL
|
||||||
git clean --force -d -X
|
git clean --force -d -x --exclude=.env* --exclude=**/*.env
|
||||||
else
|
else
|
||||||
rm -rf .vite/ build/
|
rm -rf .vite/ build/
|
||||||
rm -rf trace.zip playwright-report/ test-results/
|
rm -rf trace.zip playwright-report/ test-results/
|
||||||
@ -152,7 +159,7 @@ endif
|
|||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help: install
|
help: install
|
||||||
ifeq ($(OS),Windows_NT)
|
ifdef POWERSHELL
|
||||||
@ powershell -Command "Get-Content $(MAKEFILE_LIST) | Select-String -Pattern '^[^\s]+:.*##\s.*$$' | ForEach-Object { $$line = $$_.Line -split ':.*?##\s+'; Write-Host -NoNewline $$line[0].PadRight(30) -ForegroundColor Cyan; Write-Host $$line[1] }"
|
@ powershell -Command "Get-Content $(MAKEFILE_LIST) | Select-String -Pattern '^[^\s]+:.*##\s.*$$' | ForEach-Object { $$line = $$_.Line -split ':.*?##\s+'; Write-Host -NoNewline $$line[0].PadRight(30) -ForegroundColor Cyan; Write-Host $$line[1] }"
|
||||||
else
|
else
|
||||||
@ grep -E '^[^[:space:]]+:.*## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@ grep -E '^[^[:space:]]+:.*## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
@ -36,9 +36,9 @@ myAngle = -120
|
|||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [8, 0])
|
|> line(end = [8, 0])
|
||||||
|> angledLine({ angle = abs(myAngle), length = 5 }, %)
|
|> angledLine(angle = abs(myAngle), length = 5)
|
||||||
|> line(end = [-5, 0])
|
|> line(end = [-5, 0])
|
||||||
|> angledLine({ angle = myAngle, length = 5 }, %)
|
|> angledLine(angle = myAngle, length = 5)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
baseExtrusion = extrude(sketch001, length = 5)
|
baseExtrusion = extrude(sketch001, length = 5)
|
||||||
|
@ -33,10 +33,7 @@ acos(num: number): number
|
|||||||
```js
|
```js
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(angle = toDegrees(acos(0.5)), length = 10)
|
||||||
angle = toDegrees(acos(0.5)),
|
|
||||||
length = 10
|
|
||||||
}, %)
|
|
||||||
|> line(end = [5, 0])
|
|> line(end = [5, 0])
|
||||||
|> line(endAbsolute = [12, 0])
|
|> line(endAbsolute = [12, 0])
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -36,7 +36,7 @@ angleToMatchLengthX(
|
|||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [2, 5], tag = $seg01)
|
|> line(end = [2, 5], tag = $seg01)
|
||||||
|> angledLineToX([-angleToMatchLengthX(seg01, 7, %), 10], %)
|
|> angledLine(angle = -angleToMatchLengthX(seg01, 7, %), endAbsoluteX = 10)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
extrusion = extrude(sketch001, length = 5)
|
extrusion = extrude(sketch001, length = 5)
|
||||||
|
@ -36,10 +36,7 @@ angleToMatchLengthY(
|
|||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [1, 2], tag = $seg01)
|
|> line(end = [1, 2], tag = $seg01)
|
||||||
|> angledLine({
|
|> angledLine(angle = angleToMatchLengthY(seg01, 15, %), length = 5)
|
||||||
angle = angleToMatchLengthY(seg01, 15, %),
|
|
||||||
length = 5
|
|
||||||
}, %)
|
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -10,8 +10,13 @@ Draw a line segment relative to the current origin using the polar measure of so
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
angledLine(
|
angledLine(
|
||||||
data: AngledLineData,
|
|
||||||
sketch: Sketch,
|
sketch: Sketch,
|
||||||
|
angle: number,
|
||||||
|
length?: number,
|
||||||
|
lengthX?: number,
|
||||||
|
lengthY?: number,
|
||||||
|
endAbsoluteX?: number,
|
||||||
|
endAbsoluteY?: number,
|
||||||
tag?: TagDeclarator,
|
tag?: TagDeclarator,
|
||||||
): Sketch
|
): Sketch
|
||||||
```
|
```
|
||||||
@ -21,9 +26,14 @@ angledLine(
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `data` | [`AngledLineData`](/docs/kcl/types/AngledLineData) | Data to draw an angled line. | Yes |
|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | Which sketch should this path be added to? | Yes |
|
||||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | | Yes |
|
| `angle` | [`number`](/docs/kcl/types/number) | Which angle should the line be drawn at? | Yes |
|
||||||
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
| `length` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||||
|
| `lengthX` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||||
|
| `lengthY` | [`number`](/docs/kcl/types/number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||||
|
| `endAbsoluteX` | [`number`](/docs/kcl/types/number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||||
|
| `endAbsoluteY` | [`number`](/docs/kcl/types/number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `lengthAbsoluteEndX`, `lengthAbsoluteEndY` can be given. | No |
|
||||||
|
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Create a new tag which refers to this line | No |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
@ -36,7 +46,7 @@ angledLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> yLine(endAbsolute = 15)
|
|> yLine(endAbsolute = 15)
|
||||||
|> angledLine({ angle = 30, length = 15 }, %)
|
|> angledLine(angle = 30, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -33,10 +33,7 @@ asin(num: number): number
|
|||||||
```js
|
```js
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(angle = toDegrees(asin(0.5)), length = 20)
|
||||||
angle = toDegrees(asin(0.5)),
|
|
||||||
length = 20
|
|
||||||
}, %)
|
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -33,10 +33,7 @@ atan(num: number): number
|
|||||||
```js
|
```js
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(angle = toDegrees(atan(1.25)), length = 20)
|
||||||
angle = toDegrees(atan(1.25)),
|
|
||||||
length = 20
|
|
||||||
}, %)
|
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -37,10 +37,7 @@ atan2(
|
|||||||
```js
|
```js
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(angle = toDegrees(atan2(1.25, 2)), length = 20)
|
||||||
angle = toDegrees(atan2(1.25, 2)),
|
|
||||||
length = 20
|
|
||||||
}, %)
|
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -17,10 +17,10 @@ std::math::E: number = 2.71828182845904523536028747135266250_
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = 30,
|
angle = 30,
|
||||||
length = 2 * E ^ 2,
|
length = 2 * E ^ 2,
|
||||||
}, %)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -17,10 +17,10 @@ std::math::TAU: number = 6.28318530717958647692528676655900577_
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50,
|
||||||
length = 10 * TAU,
|
length = 10 * TAU,
|
||||||
}, %)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ e(): number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 30, length = 2 * e() ^ 2 }, %)
|
|> angledLine(angle = 30, length = 2 * e() ^ 2)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
45
docs/kcl/fromCm.md
Normal file
45
docs/kcl/fromCm.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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -30,10 +30,10 @@ getNextAdjacentEdge(tag: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine(angle = 60, length = 10)
|
||||||
|> angledLine({ angle = 120, length = 10 }, %)
|
|> angledLine(angle = 120, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -30,10 +30,10 @@ getOppositeEdge(tag: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine(angle = 60, length = 10)
|
||||||
|> angledLine({ angle = 120, length = 10 }, %)
|
|> angledLine(angle = 120, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -30,10 +30,10 @@ getPreviousAdjacentEdge(tag: TagIdentifier): Uuid
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine(angle = 60, length = 10)
|
||||||
|> angledLine({ angle = 120, length = 10 }, %)
|
|> angledLine(angle = 120, length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine({ angle = 240, length = 10 }, %, $referenceEdge)
|
|> angledLine(angle = 240, length = 10, tag = $referenceEdge)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -43,11 +43,7 @@ layout: manual
|
|||||||
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
|
* [`angleToMatchLengthX`](kcl/angleToMatchLengthX)
|
||||||
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
|
* [`angleToMatchLengthY`](kcl/angleToMatchLengthY)
|
||||||
* [`angledLine`](kcl/angledLine)
|
* [`angledLine`](kcl/angledLine)
|
||||||
* [`angledLineOfXLength`](kcl/angledLineOfXLength)
|
|
||||||
* [`angledLineOfYLength`](kcl/angledLineOfYLength)
|
|
||||||
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
|
* [`angledLineThatIntersects`](kcl/angledLineThatIntersects)
|
||||||
* [`angledLineToX`](kcl/angledLineToX)
|
|
||||||
* [`angledLineToY`](kcl/angledLineToY)
|
|
||||||
* [`appearance`](kcl/appearance)
|
* [`appearance`](kcl/appearance)
|
||||||
* [`arc`](kcl/arc)
|
* [`arc`](kcl/arc)
|
||||||
* [`arcTo`](kcl/arcTo)
|
* [`arcTo`](kcl/arcTo)
|
||||||
@ -65,11 +61,15 @@ layout: manual
|
|||||||
* [`chamfer`](kcl/chamfer)
|
* [`chamfer`](kcl/chamfer)
|
||||||
* [`circleThreePoint`](kcl/circleThreePoint)
|
* [`circleThreePoint`](kcl/circleThreePoint)
|
||||||
* [`close`](kcl/close)
|
* [`close`](kcl/close)
|
||||||
* [`cm`](kcl/cm)
|
|
||||||
* [`extrude`](kcl/extrude)
|
* [`extrude`](kcl/extrude)
|
||||||
* [`fillet`](kcl/fillet)
|
* [`fillet`](kcl/fillet)
|
||||||
* [`floor`](kcl/floor)
|
* [`floor`](kcl/floor)
|
||||||
* [`ft`](kcl/ft)
|
* [`fromCm`](kcl/fromCm)
|
||||||
|
* [`fromFt`](kcl/fromFt)
|
||||||
|
* [`fromInches`](kcl/fromInches)
|
||||||
|
* [`fromM`](kcl/fromM)
|
||||||
|
* [`fromMm`](kcl/fromMm)
|
||||||
|
* [`fromYd`](kcl/fromYd)
|
||||||
* [`getCommonEdge`](kcl/getCommonEdge)
|
* [`getCommonEdge`](kcl/getCommonEdge)
|
||||||
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
* [`getNextAdjacentEdge`](kcl/getNextAdjacentEdge)
|
||||||
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
* [`getOppositeEdge`](kcl/getOppositeEdge)
|
||||||
@ -77,7 +77,6 @@ layout: manual
|
|||||||
* [`helix`](kcl/std-helix)
|
* [`helix`](kcl/std-helix)
|
||||||
* [`hole`](kcl/hole)
|
* [`hole`](kcl/hole)
|
||||||
* [`hollow`](kcl/hollow)
|
* [`hollow`](kcl/hollow)
|
||||||
* [`inch`](kcl/inch)
|
|
||||||
* [`lastSegX`](kcl/lastSegX)
|
* [`lastSegX`](kcl/lastSegX)
|
||||||
* [`lastSegY`](kcl/lastSegY)
|
* [`lastSegY`](kcl/lastSegY)
|
||||||
* [`legAngX`](kcl/legAngX)
|
* [`legAngX`](kcl/legAngX)
|
||||||
@ -89,11 +88,9 @@ layout: manual
|
|||||||
* [`log`](kcl/log)
|
* [`log`](kcl/log)
|
||||||
* [`log10`](kcl/log10)
|
* [`log10`](kcl/log10)
|
||||||
* [`log2`](kcl/log2)
|
* [`log2`](kcl/log2)
|
||||||
* [`m`](kcl/m)
|
|
||||||
* [`map`](kcl/map)
|
* [`map`](kcl/map)
|
||||||
* [`max`](kcl/max)
|
* [`max`](kcl/max)
|
||||||
* [`min`](kcl/min)
|
* [`min`](kcl/min)
|
||||||
* [`mm`](kcl/mm)
|
|
||||||
* [`offsetPlane`](kcl/offsetPlane)
|
* [`offsetPlane`](kcl/offsetPlane)
|
||||||
* [`patternCircular2d`](kcl/patternCircular2d)
|
* [`patternCircular2d`](kcl/patternCircular2d)
|
||||||
* [`patternCircular3d`](kcl/patternCircular3d)
|
* [`patternCircular3d`](kcl/patternCircular3d)
|
||||||
@ -101,7 +98,6 @@ layout: manual
|
|||||||
* [`patternLinear3d`](kcl/patternLinear3d)
|
* [`patternLinear3d`](kcl/patternLinear3d)
|
||||||
* [`patternTransform`](kcl/patternTransform)
|
* [`patternTransform`](kcl/patternTransform)
|
||||||
* [`patternTransform2d`](kcl/patternTransform2d)
|
* [`patternTransform2d`](kcl/patternTransform2d)
|
||||||
* [`polar`](kcl/polar)
|
|
||||||
* [`polygon`](kcl/polygon)
|
* [`polygon`](kcl/polygon)
|
||||||
* [`pop`](kcl/pop)
|
* [`pop`](kcl/pop)
|
||||||
* [`pow`](kcl/pow)
|
* [`pow`](kcl/pow)
|
||||||
@ -137,12 +133,12 @@ layout: manual
|
|||||||
* [`translate`](kcl/translate)
|
* [`translate`](kcl/translate)
|
||||||
* [`xLine`](kcl/xLine)
|
* [`xLine`](kcl/xLine)
|
||||||
* [`yLine`](kcl/yLine)
|
* [`yLine`](kcl/yLine)
|
||||||
* [`yd`](kcl/yd)
|
|
||||||
* **std::math**
|
* **std::math**
|
||||||
* [`E`](kcl/consts/std-math-E)
|
* [`E`](kcl/consts/std-math-E)
|
||||||
* [`PI`](kcl/consts/std-math-PI)
|
* [`PI`](kcl/consts/std-math-PI)
|
||||||
* [`TAU`](kcl/consts/std-math-TAU)
|
* [`TAU`](kcl/consts/std-math-TAU)
|
||||||
* [`cos`](kcl/std-math-cos)
|
* [`cos`](kcl/std-math-cos)
|
||||||
|
* [`polar`](kcl/std-math-polar)
|
||||||
* [`sin`](kcl/std-math-sin)
|
* [`sin`](kcl/std-math-sin)
|
||||||
* [`tan`](kcl/std-math-tan)
|
* [`tan`](kcl/std-math-tan)
|
||||||
* **std::sketch**
|
* **std::sketch**
|
||||||
|
@ -33,10 +33,7 @@ max(args: [number]): number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(angle = 70, length = max(15, 31, 4, 13, 22))
|
||||||
angle = 70,
|
|
||||||
length = max(15, 31, 4, 13, 22)
|
|
||||||
}, %)
|
|
||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -33,10 +33,7 @@ min(args: [number]): number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(angle = 70, length = min(15, 31, 4, 13, 22))
|
||||||
angle = 70,
|
|
||||||
length = min(15, 31, 4, 13, 22)
|
|
||||||
}, %)
|
|
||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -37,7 +37,7 @@ pow(
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 50, length = pow(5, 2) }, %)
|
|> angledLine(angle = 50, length = pow(5, 2))
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -29,11 +29,8 @@ profileStart(sketch: Sketch): [number]
|
|||||||
```js
|
```js
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
|> startProfileAt([5, 2], %)
|
|> startProfileAt([5, 2], %)
|
||||||
|> angledLine({ angle = 120, length = 50 }, %, $seg01)
|
|> angledLine(angle = 120, length = 50, tag = $seg01)
|
||||||
|> angledLine({
|
|> angledLine(angle = segAng(seg01) + 120, length = 50)
|
||||||
angle = segAng(seg01) + 120,
|
|
||||||
length = 50
|
|
||||||
}, %)
|
|
||||||
|> line(end = profileStart(%))
|
|> line(end = profileStart(%))
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 20)
|
|> extrude(length = 20)
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -78,7 +78,7 @@ assertEqual(sum, 6, 0.00001, "1 + 2 + 3 summed is 6")
|
|||||||
```js
|
```js
|
||||||
// Declare a function that sketches a decagon.
|
// Declare a function that sketches a decagon.
|
||||||
fn decagon(radius) {
|
fn decagon(radius) {
|
||||||
// Each side of the decagon is turned this many degrees from the previous angle.
|
// Each side of the decagon is turned this many radians from the previous angle.
|
||||||
stepAngle = 1 / 10 * TAU
|
stepAngle = 1 / 10 * TAU
|
||||||
|
|
||||||
// Start the decagon sketch at this point.
|
// Start the decagon sketch at this point.
|
||||||
|
@ -151,15 +151,9 @@ cube
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|
||||||
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
50.61
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -85,15 +85,9 @@ cube
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|
||||||
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
50.61
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ exampleSketch = startSketchOn(XZ)
|
|||||||
|> line(end = [10, 0])
|
|> line(end = [10, 0])
|
||||||
|> line(end = [5, 10], tag = $seg01)
|
|> line(end = [5, 10], tag = $seg01)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine([segAng(seg01), 10], %)
|
|> angledLine(angle = segAng(seg01), length = 10)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> angledLine([segAng(seg01), -15], %)
|
|> angledLine(angle = segAng(seg01), length = -15)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 4)
|
example = extrude(exampleSketch, length = 4)
|
||||||
|
@ -29,9 +29,9 @@ segLen(tag: TagIdentifier): number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %, $thing)
|
|> angledLine(angle = 60, length = 10, tag = $thing)
|
||||||
|> tangentialArc({ offset = -120, radius = 5 }, %)
|
|> tangentialArc({ offset = -120, radius = 5 }, %)
|
||||||
|> angledLine({ angle = -60, length = segLen(thing) }, %)
|
|> angledLine(angle = -60, length = segLen(thing))
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
|
@ -6,7 +6,7 @@ layout: manual
|
|||||||
|
|
||||||
# KCL Settings
|
# KCL Settings
|
||||||
|
|
||||||
There are three levels of settings available in the KittyCAD Design Studiolication:
|
There are three levels of settings available in Zoo Design Studio:
|
||||||
|
|
||||||
1. [User Settings](/docs/kcl/settings/user): Global settings that apply to all projects, stored in `user.toml`
|
1. [User Settings](/docs/kcl/settings/user): Global settings that apply to all projects, stored in `user.toml`
|
||||||
2. [Project Settings](/docs/kcl/settings/project): Settings specific to a project, stored in `project.toml`
|
2. [Project Settings](/docs/kcl/settings/project): Settings specific to a project, stored in `project.toml`
|
||||||
@ -14,7 +14,7 @@ There are three levels of settings available in the KittyCAD Design Studiolicati
|
|||||||
|
|
||||||
## Configuration Files
|
## Configuration Files
|
||||||
|
|
||||||
The KittyCAD Design Studio uses TOML files for configuration:
|
Zoo Design Studio uses TOML files for configuration:
|
||||||
|
|
||||||
* **User Settings**: `user.toml` - See [complete documentation](/docs/kcl/settings/user)
|
* **User Settings**: `user.toml` - See [complete documentation](/docs/kcl/settings/user)
|
||||||
* **Project Settings**: `project.toml` - See [complete documentation](/docs/kcl/settings/project)
|
* **Project Settings**: `project.toml` - See [complete documentation](/docs/kcl/settings/project)
|
||||||
|
@ -96,7 +96,7 @@ Permanently dismiss the banner warning to download the desktop app. This setting
|
|||||||
|
|
||||||
##### stream_idle_mode
|
##### stream_idle_mode
|
||||||
|
|
||||||
When the user is idle, and this is true, the stream will be torn down.
|
When the user is idle, teardown the stream after some time.
|
||||||
|
|
||||||
|
|
||||||
**Default:** None
|
**Default:** None
|
||||||
|
@ -33,7 +33,7 @@ sqrt(num: number): number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 50, length = sqrt(2500) }, %)
|
|> angledLine(angle = 50, length = sqrt(2500))
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -9,7 +9,15 @@ Create a helix.
|
|||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
helix(revolutions: number(_), angleStart: number(deg), ccw?: bool, radius?: number(mm), axis?: Axis3d | Edge, length?: number(mm), cylinder?: Solid): Helix
|
helix(
|
||||||
|
revolutions: number(_),
|
||||||
|
angleStart: number(deg),
|
||||||
|
ccw?: bool,
|
||||||
|
radius?: number(mm),
|
||||||
|
axis?: Axis3d | Edge,
|
||||||
|
length?: number(mm),
|
||||||
|
cylinder?: Solid,
|
||||||
|
): Helix
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ cos(@num: number(rad)): number(_)
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = 30,
|
angle = 30,
|
||||||
length = 3 / cos(toRadians(30)),
|
length = 3 / cos(toRadians(30)),
|
||||||
}, %)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
48
docs/kcl/std-math-polar.md
Normal file
48
docs/kcl/std-math-polar.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
@ -29,10 +29,10 @@ tan(@num: number(rad)): number(_)
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = 50,
|
angle = 50,
|
||||||
length = 50 * tan(1/2),
|
length = 50 * tan(1/2),
|
||||||
}, %)
|
)
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -6,10 +6,16 @@ layout: manual
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Construct a 2-dimensional circle, of the specified radius, centered atthe provided (x, y) origin point.
|
Construct a 2-dimensional circle, of the specified radius, centered at
|
||||||
|
the provided (x, y) origin point.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
circle(@sketch_or_surface: Sketch | Plane | Face, center: Point2d, radius: number, tag?: tag): Sketch
|
circle(
|
||||||
|
@sketch_or_surface: Sketch | Plane | Face,
|
||||||
|
center: Point2d,
|
||||||
|
radius: number,
|
||||||
|
tag?: tag,
|
||||||
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,10 @@ Only works on unclosed sketches for now.
|
|||||||
Mirror occurs around a local sketch axis rather than a global axis.
|
Mirror occurs around a local sketch axis rather than a global axis.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
mirror2d(@sketches: [Sketch; 1+], axis: Axis2d | Edge): Sketch
|
mirror2d(
|
||||||
|
@sketches: [Sketch; 1+],
|
||||||
|
axis: Axis2d | Edge,
|
||||||
|
): Sketch
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
33235
docs/kcl/std.json
33235
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
@ -91,15 +91,9 @@ springSketch = startSketchOn(YZ)
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|
||||||
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
50.61
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -32,10 +32,7 @@ pillSketch = startSketchOn(XZ)
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [20, 0])
|
|> line(end = [20, 0])
|
||||||
|> tangentialArcToRelative([0, 10], %, $arc1)
|
|> tangentialArcToRelative([0, 10], %, $arc1)
|
||||||
|> angledLine({
|
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|
||||||
angle = tangentToEnd(arc1),
|
|
||||||
length = 20
|
|
||||||
}, %)
|
|
||||||
|> tangentialArcToRelative([0, -10], %)
|
|> tangentialArcToRelative([0, -10], %)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
@ -50,10 +47,7 @@ pillSketch = startSketchOn(XZ)
|
|||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [0, 20])
|
|> line(end = [0, 20])
|
||||||
|> tangentialArcTo([10, 20], %, $arc1)
|
|> tangentialArcTo([10, 20], %, $arc1)
|
||||||
|> angledLine({
|
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|
||||||
angle = tangentToEnd(arc1),
|
|
||||||
length = 20
|
|
||||||
}, %)
|
|
||||||
|> tangentialArcToRelative([-10, 0], %)
|
|> tangentialArcToRelative([-10, 0], %)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
@ -66,10 +60,7 @@ pillExtrude = extrude(pillSketch, length = 10)
|
|||||||
rectangleSketch = startSketchOn(XZ)
|
rectangleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line(end = [10, 0], tag = $seg1)
|
|> line(end = [10, 0], tag = $seg1)
|
||||||
|> angledLine({
|
|> angledLine(angle = tangentToEnd(seg1), length = 10)
|
||||||
angle = tangentToEnd(seg1),
|
|
||||||
length = 10
|
|
||||||
}, %)
|
|
||||||
|> line(end = [0, 10])
|
|> line(end = [0, 10])
|
||||||
|> line(end = [-20, 0])
|
|> line(end = [-20, 0])
|
||||||
|> close()
|
|> close()
|
||||||
@ -83,7 +74,7 @@ rectangleExtrude = extrude(rectangleSketch, length = 10)
|
|||||||
bottom = startSketchOn(XY)
|
bottom = startSketchOn(XY)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> arcTo({ end = [10, 10], interior = [5, 1] }, %, $arc1)
|
|> arcTo({ end = [10, 10], interior = [5, 1] }, %, $arc1)
|
||||||
|> angledLine([tangentToEnd(arc1), 20], %)
|
|> angledLine(angle = tangentToEnd(arc1), length = 20)
|
||||||
|> close()
|
|> close()
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -95,7 +86,7 @@ circSketch = startSketchOn(XY)
|
|||||||
|
|
||||||
triangleSketch = startSketchOn(XY)
|
triangleSketch = startSketchOn(XY)
|
||||||
|> startProfileAt([-5, 0], %)
|
|> startProfileAt([-5, 0], %)
|
||||||
|> angledLine([tangentToEnd(circ), 10], %)
|
|> angledLine(angle = tangentToEnd(circ), length = 10)
|
||||||
|> line(end = [-15, 0])
|
|> line(end = [-15, 0])
|
||||||
|> close()
|
|> close()
|
||||||
```
|
```
|
||||||
|
@ -35,9 +35,9 @@ tangentialArc(
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine(angle = 60, length = 10)
|
||||||
|> tangentialArc({ radius = 10, offset = -120 }, %)
|
|> tangentialArc({ radius = 10, offset = -120 }, %)
|
||||||
|> angledLine({ angle = -60, length = 10 }, %)
|
|> angledLine(angle = -60, length = 10)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
example = extrude(exampleSketch, length = 10)
|
example = extrude(exampleSketch, length = 10)
|
||||||
|
@ -35,7 +35,7 @@ tangentialArcTo(
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 60, length = 10 }, %)
|
|> angledLine(angle = 60, length = 10)
|
||||||
|> tangentialArcTo([15, 15], %)
|
|> tangentialArcTo([15, 15], %)
|
||||||
|> line(end = [10, -15])
|
|> line(end = [10, -15])
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -35,7 +35,7 @@ tangentialArcToRelative(
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 45, length = 10 }, %)
|
|> angledLine(angle = 45, length = 10)
|
||||||
|> tangentialArcToRelative([0, -10], %)
|
|> tangentialArcToRelative([0, -10], %)
|
||||||
|> line(end = [-10, 0])
|
|> line(end = [-10, 0])
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -30,7 +30,7 @@ tau(): number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({ angle = 50, length = 10 * tau() }, %)
|
|> angledLine(angle = 50, length = 10 * tau())
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -33,10 +33,7 @@ toDegrees(num: number): number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(angle = 50, length = 70 * cos(toDegrees(pi() / 4)))
|
||||||
angle = 50,
|
|
||||||
length = 70 * cos(toDegrees(pi() / 4))
|
|
||||||
}, %)
|
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -33,10 +33,7 @@ toRadians(num: number): number
|
|||||||
```js
|
```js
|
||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine({
|
|> angledLine(angle = 50, length = 70 * cos(toRadians(45)))
|
||||||
angle = 50,
|
|
||||||
length = 70 * cos(toRadians(45))
|
|
||||||
}, %)
|
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -86,15 +86,9 @@ cube
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XY)
|
sketch001 = startSketchOn(XY)
|
||||||
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|
rectangleSketch = startProfileAt([-200, 23.86], sketch001)
|
||||||
|> angledLine([0, 73.47], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 73.47, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 50.61)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
50.61
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -184,15 +184,17 @@ way:
|
|||||||
```norun
|
```norun
|
||||||
startSketchOn('XZ')
|
startSketchOn('XZ')
|
||||||
|> startProfileAt(origin, %)
|
|> startProfileAt(origin, %)
|
||||||
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
length = 196.99,
|
length = 196.99,
|
||||||
}, %, $rectangleSegmentB001)
|
tag = $rectangleSegmentB001,
|
||||||
|> angledLine({
|
)
|
||||||
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001),
|
angle = segAng(rectangleSegmentA001),
|
||||||
length = -segLen(rectangleSegmentA001),
|
length = -segLen(rectangleSegmentA001),
|
||||||
}, %, $rectangleSegmentC001)
|
tag = $rectangleSegmentC001,
|
||||||
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
```
|
```
|
||||||
@ -217,15 +219,17 @@ However if the code was written like this:
|
|||||||
fn rect(origin) {
|
fn rect(origin) {
|
||||||
return startSketchOn('XZ')
|
return startSketchOn('XZ')
|
||||||
|> startProfileAt(origin, %)
|
|> startProfileAt(origin, %)
|
||||||
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
length = 196.99
|
length = 196.99,
|
||||||
}, %, $rectangleSegmentB001)
|
tag = $rectangleSegmentB001,
|
||||||
|> angledLine({
|
)
|
||||||
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001),
|
angle = segAng(rectangleSegmentA001),
|
||||||
length = -segLen(rectangleSegmentA001)
|
length = -segLen(rectangleSegmentA001)
|
||||||
}, %, $rectangleSegmentC001)
|
tag = $rectangleSegmentC001,
|
||||||
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
}
|
}
|
||||||
@ -245,15 +249,17 @@ For example the following code works.
|
|||||||
fn rect(origin) {
|
fn rect(origin) {
|
||||||
return startSketchOn('XZ')
|
return startSketchOn('XZ')
|
||||||
|> startProfileAt(origin, %)
|
|> startProfileAt(origin, %)
|
||||||
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
length = 196.99
|
length = 196.99,
|
||||||
}, %, $rectangleSegmentB001)
|
tag = $rectangleSegmentB001,
|
||||||
|> angledLine({
|
)
|
||||||
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001),
|
angle = segAng(rectangleSegmentA001),
|
||||||
length = -segLen(rectangleSegmentA001)
|
length = -segLen(rectangleSegmentA001)
|
||||||
}, %, $rectangleSegmentC001)
|
tag = $rectangleSegmentC001,
|
||||||
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
}
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
title: "PolarCoordsData"
|
|
||||||
excerpt: "Data for polar coordinates."
|
|
||||||
layout: manual
|
|
||||||
---
|
|
||||||
|
|
||||||
Data for polar coordinates.
|
|
||||||
|
|
||||||
**Type:** `object`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
| Property | Type | Description | Required |
|
|
||||||
|----------|------|-------------|----------|
|
|
||||||
| `angle` |[`number`](/docs/kcl/types/number)| The angle of the line (in degrees). | No |
|
|
||||||
| `length` |[`number`](/docs/kcl/types/number)| The length of the line. | No |
|
|
||||||
|
|
||||||
|
|
@ -14,15 +14,17 @@ way:
|
|||||||
```js
|
```js
|
||||||
startSketchOn('XZ')
|
startSketchOn('XZ')
|
||||||
|> startProfileAt(origin, %)
|
|> startProfileAt(origin, %)
|
||||||
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
length = 196.99,
|
length = 196.99,
|
||||||
}, %, $rectangleSegmentB001)
|
tag = $rectangleSegmentB001,
|
||||||
|> angledLine({
|
)
|
||||||
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001),
|
angle = segAng(rectangleSegmentA001),
|
||||||
length = -segLen(rectangleSegmentA001),
|
length = -segLen(rectangleSegmentA001),
|
||||||
}, %, $rectangleSegmentC001)
|
tag = $rectangleSegmentC001,
|
||||||
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
```
|
```
|
||||||
@ -46,15 +48,16 @@ However if the code was written like this:
|
|||||||
fn rect(origin) {
|
fn rect(origin) {
|
||||||
return startSketchOn('XZ')
|
return startSketchOn('XZ')
|
||||||
|> startProfileAt(origin, %)
|
|> startProfileAt(origin, %)
|
||||||
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
length = 196.99
|
length = 196.99,
|
||||||
}, %, $rectangleSegmentB001)
|
tag = $rectangleSegmentB001)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001),
|
angle = segAng(rectangleSegmentA001),
|
||||||
length = -segLen(rectangleSegmentA001)
|
length = -segLen(rectangleSegmentA001),
|
||||||
}, %, $rectangleSegmentC001)
|
tag = $rectangleSegmentC001
|
||||||
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
}
|
}
|
||||||
@ -74,15 +77,15 @@ For example the following code works.
|
|||||||
fn rect(origin) {
|
fn rect(origin) {
|
||||||
return startSketchOn('XZ')
|
return startSketchOn('XZ')
|
||||||
|> startProfileAt(origin, %)
|
|> startProfileAt(origin, %)
|
||||||
|> angledLine({angle = 0, length = 191.26}, %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
length = 196.99
|
length = 196.99
|
||||||
}, %, $rectangleSegmentB001)
|
, %, $rectangleSegmentB001)
|
||||||
|> angledLine({
|
|> angledLine(
|
||||||
angle = segAng(rectangleSegmentA001),
|
angle = segAng(rectangleSegmentA001),
|
||||||
length = -segLen(rectangleSegmentA001)
|
length = -segLen(rectangleSegmentA001)
|
||||||
}, %, $rectangleSegmentC001)
|
, %, $rectangleSegmentC001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
}
|
}
|
||||||
|
@ -38,10 +38,10 @@ xLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> xLine(length = 15)
|
|> xLine(length = 15)
|
||||||
|> angledLine({ angle = 80, length = 15 }, %)
|
|> angledLine(angle = 80, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> xLine(length = 10)
|
|> xLine(length = 10)
|
||||||
|> angledLine({ angle = 120, length = 30 }, %)
|
|> angledLine(angle = 120, length = 30)
|
||||||
|> xLine(length = -15)
|
|> xLine(length = -15)
|
||||||
|> close()
|
|> close()
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ yLine(
|
|||||||
exampleSketch = startSketchOn(XZ)
|
exampleSketch = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> yLine(length = 15)
|
|> yLine(length = 15)
|
||||||
|> angledLine({ angle = 30, length = 15 }, %)
|
|> angledLine(angle = 30, length = 15)
|
||||||
|> line(end = [8, -10])
|
|> line(end = [8, -10])
|
||||||
|> yLine(length = -5)
|
|> yLine(length = -5)
|
||||||
|> close()
|
|> close()
|
||||||
|
@ -137,7 +137,7 @@ async function doBasicSketch(
|
|||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Length: open menu' }).click()
|
await page.getByRole('button', { name: 'constraints: open menu' }).click()
|
||||||
await page.getByRole('button', { name: 'Equal Length' }).click()
|
await page.getByRole('button', { name: 'Equal Length' }).click()
|
||||||
|
|
||||||
// Open the code pane.
|
// Open the code pane.
|
||||||
|
@ -38,7 +38,7 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
path.resolve(
|
path.resolve(
|
||||||
__dirname,
|
__dirname,
|
||||||
'../../',
|
'../../',
|
||||||
'./rust/kcl-lib/e2e/executor/inputs/boolean-setup-with'
|
'./rust/kcl-lib/e2e/executor/inputs/boolean-setup-with-sketch-on-faces.kcl'
|
||||||
),
|
),
|
||||||
'utf-8'
|
'utf-8'
|
||||||
)
|
)
|
||||||
@ -46,8 +46,6 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
|
||||||
|
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Test coordinates for selection - these might need adjustment based on actual scene layout
|
// Test coordinates for selection - these might need adjustment based on actual scene layout
|
||||||
@ -77,6 +75,7 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
|
|
||||||
// Select first object in the scene, expect there to be a pixel diff from the selection color change
|
// Select first object in the scene, expect there to be a pixel diff from the selection color change
|
||||||
await clickFirstObject({ pixelDiff: 50 })
|
await clickFirstObject({ pixelDiff: 50 })
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
// For subtract, we need to proceed to the next step before selecting the second object
|
// For subtract, we need to proceed to the next step before selecting the second object
|
||||||
if (operationName !== 'subtract') {
|
if (operationName !== 'subtract') {
|
||||||
@ -87,6 +86,8 @@ test.describe('Point and click for boolean workflows', () => {
|
|||||||
// Select second object
|
// Select second object
|
||||||
await clickSecondObject({ pixelDiff: 50 })
|
await clickSecondObject({ pixelDiff: 50 })
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
// Confirm the operation in the command bar
|
// Confirm the operation in the command bar
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import { uuidv4 } from '@src/lib/utils'
|
|||||||
|
|
||||||
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
|
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
|
||||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
||||||
|
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
||||||
import { getUtils } from '@e2e/playwright/test-utils'
|
import { getUtils } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ test.describe(
|
|||||||
page: Page,
|
page: Page,
|
||||||
homePage: HomePageFixture,
|
homePage: HomePageFixture,
|
||||||
scene: SceneFixture,
|
scene: SceneFixture,
|
||||||
|
toolbar: ToolbarFixture,
|
||||||
plane: string,
|
plane: string,
|
||||||
clickCoords: { x: number; y: number }
|
clickCoords: { x: number; y: number }
|
||||||
) => {
|
) => {
|
||||||
@ -59,9 +61,12 @@ test.describe(
|
|||||||
await u.sendCustomCmd(updateCamCommand)
|
await u.sendCustomCmd(updateCamCommand)
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
await page.mouse.click(clickCoords.x, clickCoords.y)
|
await page.mouse.click(clickCoords.x, clickCoords.y)
|
||||||
await page.waitForTimeout(600) // wait for animation
|
await page.waitForTimeout(600) // wait for animation
|
||||||
|
|
||||||
|
await toolbar.waitUntilSketchingReady()
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'line Line', exact: true })
|
page.getByRole('button', { name: 'line Line', exact: true })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
@ -117,11 +122,12 @@ test.describe(
|
|||||||
]
|
]
|
||||||
|
|
||||||
for (const config of planeConfigs) {
|
for (const config of planeConfigs) {
|
||||||
test(config.plane, async ({ page, homePage, scene }) => {
|
test(config.plane, async ({ page, homePage, scene, toolbar }) => {
|
||||||
await sketchOnPlaneAndBackSideTest(
|
await sketchOnPlaneAndBackSideTest(
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
scene,
|
scene,
|
||||||
|
toolbar,
|
||||||
config.plane,
|
config.plane,
|
||||||
config.coords
|
config.coords
|
||||||
)
|
)
|
||||||
|
@ -15,6 +15,7 @@ test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
|
|||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
scene,
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Ensure no badge is present
|
// Ensure no badge is present
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
@ -171,6 +172,8 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
context,
|
context,
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
// Load the app with the working starter code
|
// Load the app with the working starter code
|
||||||
await context.addInitScript((code) => {
|
await context.addInitScript((code) => {
|
||||||
@ -180,9 +183,7 @@ extrude001 = extrude(sketch001, length = 5)`
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
// FIXME: await scene.waitForExecutionDone() does not work. It still fails.
|
await scene.settled(cmdBar)
|
||||||
// I needed to increase this timeout to get this to pass.
|
|
||||||
await page.waitForTimeout(10000)
|
|
||||||
|
|
||||||
// Ensure badge is present
|
// Ensure badge is present
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
|
@ -317,9 +317,13 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
|
|||||||
test('Can switch between sketch tools via command bar', async ({
|
test('Can switch between sketch tools via command bar', async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
|
toolbar,
|
||||||
}) => {
|
}) => {
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
||||||
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
||||||
@ -343,7 +347,9 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
|
|||||||
|
|
||||||
// Start a sketch
|
// Start a sketch
|
||||||
await sketchButton.click()
|
await sketchButton.click()
|
||||||
|
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
|
await toolbar.waitUntilSketchingReady()
|
||||||
|
|
||||||
// Switch between sketch tools via the command bar
|
// Switch between sketch tools via the command bar
|
||||||
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
@ -11,7 +11,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
|
|||||||
test(
|
test(
|
||||||
'export works on the first try',
|
'export works on the first try',
|
||||||
{ tag: ['@electron', '@skipLocalEngine'] },
|
{ tag: ['@electron', '@skipLocalEngine'] },
|
||||||
async ({ page, context, scene, tronApp }, testInfo) => {
|
async ({ page, context, scene, tronApp, cmdBar }, testInfo) => {
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
@ -37,8 +37,7 @@ test(
|
|||||||
const projectName = page.getByText(`bracket`)
|
const projectName = page.getByText(`bracket`)
|
||||||
await expect(projectName).toBeVisible()
|
await expect(projectName).toBeVisible()
|
||||||
await projectName.click()
|
await projectName.click()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
await page.waitForTimeout(1_000) // wait for panel buttons to be available
|
|
||||||
|
|
||||||
// Expect zero errors in gutter
|
// Expect zero errors in gutter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
@ -47,10 +46,9 @@ test(
|
|||||||
const exportButton = page.getByTestId('export-pane-button')
|
const exportButton = page.getByTestId('export-pane-button')
|
||||||
await expect(exportButton).toBeVisible()
|
await expect(exportButton).toBeVisible()
|
||||||
await exportButton.click()
|
await exportButton.click()
|
||||||
await page.waitForTimeout(1_000) // wait for export options to be available
|
|
||||||
|
|
||||||
// Select the first format option
|
// Select the first format option
|
||||||
const gltfOption = page.getByText('glTF')
|
const gltfOption = cmdBar.selectOption({ name: 'glTF' })
|
||||||
const exportFileName = `main.gltf` // source file is named `main.kcl`
|
const exportFileName = `main.gltf` // source file is named `main.kcl`
|
||||||
await expect(gltfOption).toBeVisible()
|
await expect(gltfOption).toBeVisible()
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
@ -58,7 +56,6 @@ test(
|
|||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
const submitButton = page.getByText('Confirm Export')
|
const submitButton = page.getByText('Confirm Export')
|
||||||
await expect(submitButton).toBeVisible()
|
await expect(submitButton).toBeVisible()
|
||||||
await page.waitForTimeout(500)
|
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
@ -110,8 +107,7 @@ test(
|
|||||||
|
|
||||||
// Close the file pane
|
// Close the file pane
|
||||||
await u.closeFilePanel()
|
await u.closeFilePanel()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
await page.waitForTimeout(1_000) // wait for panel buttons to be available
|
|
||||||
|
|
||||||
// Expect zero errors in gutter
|
// Expect zero errors in gutter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
@ -120,10 +116,9 @@ test(
|
|||||||
const exportButton = page.getByTestId('export-pane-button')
|
const exportButton = page.getByTestId('export-pane-button')
|
||||||
await expect(exportButton).toBeVisible()
|
await expect(exportButton).toBeVisible()
|
||||||
await exportButton.click()
|
await exportButton.click()
|
||||||
await page.waitForTimeout(1_000) // wait for export options to be available
|
|
||||||
|
|
||||||
// Select the first format option
|
// Select the first format option
|
||||||
const gltfOption = page.getByText('glTF')
|
const gltfOption = cmdBar.selectOption({ name: 'glTF' })
|
||||||
const exportFileName = `other.gltf` // source file is named `other.kcl`
|
const exportFileName = `other.gltf` // source file is named `other.kcl`
|
||||||
await expect(gltfOption).toBeVisible()
|
await expect(gltfOption).toBeVisible()
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
@ -131,7 +126,6 @@ test(
|
|||||||
// Click the checkbox
|
// Click the checkbox
|
||||||
const submitButton = page.getByText('Confirm Export')
|
const submitButton = page.getByText('Confirm Export')
|
||||||
await expect(submitButton).toBeVisible()
|
await expect(submitButton).toBeVisible()
|
||||||
await page.waitForTimeout(500)
|
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
|
@ -78,12 +78,14 @@ sketch001 = startSketchOn(XY)
|
|||||||
|
|
||||||
// Ensure we execute the first time.
|
// Ensure we execute the first time.
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
await expect(
|
await expect
|
||||||
page.locator('[data-receive-command-type="scene_clear_all"]')
|
.poll(() =>
|
||||||
).toHaveCount(1)
|
page.locator('[data-receive-command-type="scene_clear_all"]').count()
|
||||||
await expect(
|
)
|
||||||
page.locator('[data-message-type="execution-done"]')
|
.toBe(1)
|
||||||
).toHaveCount(2)
|
await expect
|
||||||
|
.poll(() => page.locator('[data-message-type="execution-done"]').count())
|
||||||
|
.toBe(2)
|
||||||
|
|
||||||
// Add whitespace to the end of the code.
|
// Add whitespace to the end of the code.
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
@ -110,12 +112,14 @@ sketch001 = startSketchOn(XY)
|
|||||||
test('ensure we use the cache, and do not clear on append', async ({
|
test('ensure we use the cache, and do not clear on append', async ({
|
||||||
homePage,
|
homePage,
|
||||||
page,
|
page,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await page.keyboard.type(`sketch001 = startSketchOn(XY)
|
await page.keyboard.type(`sketch001 = startSketchOn(XY)
|
||||||
@ -499,7 +503,7 @@ sketch_001 = startSketchOn(XY)
|
|||||||
await page.keyboard.press('ArrowLeft')
|
await page.keyboard.press('ArrowLeft')
|
||||||
await page.keyboard.press('ArrowRight')
|
await page.keyboard.press('ArrowRight')
|
||||||
|
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// error in guter
|
// error in guter
|
||||||
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
|
||||||
@ -1349,4 +1353,51 @@ sketch001 = startSketchOn(XZ)
|
|||||||
15
|
15
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test(`test-toolbar-buttons`, async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
toolbar,
|
||||||
|
scene,
|
||||||
|
cmdBar,
|
||||||
|
}) => {
|
||||||
|
await test.step('Load an empty file', async () => {
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem('persistCode', '')
|
||||||
|
})
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
// wait until scene is ready to be interacted with
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Test toolbar button correct selection', async () => {
|
||||||
|
await toolbar.expectToolbarMode.toBe('modeling')
|
||||||
|
|
||||||
|
await toolbar.startSketchPlaneSelection()
|
||||||
|
|
||||||
|
// Click on a default plane
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
|
// tools cannot be selected immediately, couldn't find an event to await instead.
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
|
await toolbar.selectCenterRectangle()
|
||||||
|
|
||||||
|
await expect(page.getByTestId('center-rectangle')).toHaveAttribute(
|
||||||
|
'aria-pressed',
|
||||||
|
'true'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Test Toolbar dropdown remembering last selection', async () => {
|
||||||
|
// Select another tool
|
||||||
|
await page.getByTestId('circle-center').click()
|
||||||
|
|
||||||
|
// center-rectangle should still be the active option in the rectangle dropdown
|
||||||
|
await expect(page.getByTestId('center-rectangle')).toBeVisible()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -19,7 +19,7 @@ length001 = timesFive(1) * 5
|
|||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([20, 10], %)
|
|> startProfileAt([20, 10], %)
|
||||||
|> line(end = [10, 10])
|
|> line(end = [10, 10])
|
||||||
|> angledLine([-45, length001], %)
|
|> angledLine(angle = -45, length = length001)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
revolve001 = revolve(sketch001, axis = X)
|
revolve001 = revolve(sketch001, axis = X)
|
||||||
@ -38,15 +38,9 @@ extrude001 = extrude(sketch002, length = 10)
|
|||||||
|
|
||||||
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn(XZ)
|
const FEATURE_TREE_SKETCH_CODE = `sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine([0, 4], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2, tag = $rectangleSegmentB001)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
2
|
|
||||||
], %, $rectangleSegmentB001)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close(%)
|
|> close(%)
|
||||||
extrude001 = extrude(sketch001, length = 10)
|
extrude001 = extrude(sketch001, length = 10)
|
||||||
@ -64,7 +58,7 @@ test.describe('Feature Tree pane', () => {
|
|||||||
test(
|
test(
|
||||||
'User can go to definition and go to function definition',
|
'User can go to definition and go to function definition',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, homePage, scene, editor, toolbar }) => {
|
async ({ context, homePage, scene, editor, toolbar, cmdBar, page }) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = join(dir, 'test-sample')
|
const bracketDir = join(dir, 'test-sample')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
@ -86,9 +80,13 @@ test.describe('Feature Tree pane', () => {
|
|||||||
sortBy: 'last-modified-desc',
|
sortBy: 'last-modified-desc',
|
||||||
})
|
})
|
||||||
await homePage.openProject('test-sample')
|
await homePage.openProject('test-sample')
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
await editor.closePane()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
await toolbar.openFeatureTreePane()
|
await toolbar.openFeatureTreePane()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Feature tree').count())
|
||||||
|
.toBeGreaterThan(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
async function testViewSource({
|
async function testViewSource({
|
||||||
@ -254,7 +252,7 @@ test.describe('Feature Tree pane', () => {
|
|||||||
sortBy: 'last-modified-desc',
|
sortBy: 'last-modified-desc',
|
||||||
})
|
})
|
||||||
await homePage.openProject('test-sample')
|
await homePage.openProject('test-sample')
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
await toolbar.openFeatureTreePane()
|
await toolbar.openFeatureTreePane()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -339,7 +337,7 @@ test.describe('Feature Tree pane', () => {
|
|||||||
sortBy: 'last-modified-desc',
|
sortBy: 'last-modified-desc',
|
||||||
})
|
})
|
||||||
await homePage.openProject('test-sample')
|
await homePage.openProject('test-sample')
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
await toolbar.openFeatureTreePane()
|
await toolbar.openFeatureTreePane()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -414,8 +412,7 @@ profile003 = startProfileAt([0, -4.93], sketch001)
|
|||||||
const planeColor: [number, number, number] = [74, 74, 74]
|
const planeColor: [number, number, number] = [74, 74, 74]
|
||||||
|
|
||||||
await homePage.openProject('test-sample')
|
await homePage.openProject('test-sample')
|
||||||
// FIXME: @lf94 has a better way to verify execution completion, in a PR rn
|
await scene.settled(cmdBar)
|
||||||
await scene.waitForExecutionDone()
|
|
||||||
|
|
||||||
await test.step(`Verify we see the sketch`, async () => {
|
await test.step(`Verify we see the sketch`, async () => {
|
||||||
await scene.expectPixelColor(sketchColor, testPoint, 10)
|
await scene.expectPixelColor(sketchColor, testPoint, 10)
|
||||||
|
@ -47,6 +47,7 @@ test.describe('integrations tests', () => {
|
|||||||
await scene.connectionEstablished()
|
await scene.connectionEstablished()
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
await clickObj()
|
await clickObj()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await scene.moveNoWhere()
|
await scene.moveNoWhere()
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
activeLines: [
|
activeLines: [
|
||||||
@ -72,11 +73,11 @@ test.describe('integrations tests', () => {
|
|||||||
})
|
})
|
||||||
await test.step('setup for next assertion', async () => {
|
await test.step('setup for next assertion', async () => {
|
||||||
await toolbar.openFile('main.kcl')
|
await toolbar.openFile('main.kcl')
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await scene.settled(cmdBar)
|
|
||||||
|
|
||||||
await clickObj()
|
await clickObj()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await scene.moveNoWhere()
|
await scene.moveNoWhere()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
activeLines: [
|
activeLines: [
|
||||||
'|>startProfileAt([75.8,317.2],%)//[$startCapTag,$EndCapTag]',
|
'|>startProfileAt([75.8,317.2],%)//[$startCapTag,$EndCapTag]',
|
||||||
@ -89,7 +90,7 @@ test.describe('integrations tests', () => {
|
|||||||
await toolbar.expectFileTreeState(['main.kcl', fileName])
|
await toolbar.expectFileTreeState(['main.kcl', fileName])
|
||||||
})
|
})
|
||||||
await test.step('check sketch mode is exited when opening a different file', async () => {
|
await test.step('check sketch mode is exited when opening a different file', async () => {
|
||||||
await toolbar.openFile(fileName, { wait: false })
|
await toolbar.openFile(fileName)
|
||||||
|
|
||||||
// check we're out of sketch mode
|
// check we're out of sketch mode
|
||||||
await expect(toolbar.exitSketchBtn).not.toBeVisible()
|
await expect(toolbar.exitSketchBtn).not.toBeVisible()
|
||||||
|
@ -112,10 +112,7 @@ export class CmdBarFixture {
|
|||||||
* and assumes we are past the `pickCommand` step.
|
* and assumes we are past the `pickCommand` step.
|
||||||
*/
|
*/
|
||||||
progressCmdBar = async (shouldFuzzProgressMethod = true) => {
|
progressCmdBar = async (shouldFuzzProgressMethod = true) => {
|
||||||
// FIXME: Progressing the command bar is a race condition. We have an async useEffect that reports the final state via useCalculateKclExpression. If this does not run quickly enough, it will not "fail" the continue because you can press continue if the state is not ready. E2E tests do not know this.
|
await this.page.waitForTimeout(2000)
|
||||||
// Wait 1250ms to assume the await executeAst of the KCL input field is finished
|
|
||||||
await this.page.waitForTimeout(1250)
|
|
||||||
if (shouldFuzzProgressMethod || Math.random() > 0.5) {
|
|
||||||
const arrowButton = this.page.getByRole('button', {
|
const arrowButton = this.page.getByRole('button', {
|
||||||
name: 'arrow right Continue',
|
name: 'arrow right Continue',
|
||||||
})
|
})
|
||||||
@ -126,9 +123,6 @@ export class CmdBarFixture {
|
|||||||
.getByRole('button', { name: 'checkmark Submit command' })
|
.getByRole('button', { name: 'checkmark Submit command' })
|
||||||
.click()
|
.click()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
await this.page.keyboard.press('Enter')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Added data-testid to the command bar buttons
|
// Added data-testid to the command bar buttons
|
||||||
|
@ -39,7 +39,8 @@ export class AuthenticatedApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async initialise(code = '') {
|
async initialise(code = '') {
|
||||||
await setup(this.context, this.page, this.testInfo)
|
const testDir = this.testInfo.outputPath('electron-test-projects-dir')
|
||||||
|
await setup(this.context, this.page, testDir, this.testInfo)
|
||||||
const u = await getUtils(this.page)
|
const u = await getUtils(this.page)
|
||||||
|
|
||||||
await this.page.addInitScript(async (code) => {
|
await this.page.addInitScript(async (code) => {
|
||||||
@ -102,11 +103,11 @@ export class ElectronZoo {
|
|||||||
return resolve(undefined)
|
return resolve(undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Date.now() - timeA > 10000) {
|
if (Date.now() - timeA > 3000) {
|
||||||
return resolve(undefined)
|
return resolve(undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(checkDisconnected, 0)
|
setTimeout(checkDisconnected, 1)
|
||||||
}
|
}
|
||||||
checkDisconnected()
|
checkDisconnected()
|
||||||
})
|
})
|
||||||
@ -128,11 +129,9 @@ export class ElectronZoo {
|
|||||||
const that = this
|
const that = this
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
timeout: 120000,
|
|
||||||
args: ['.', '--no-sandbox'],
|
args: ['.', '--no-sandbox'],
|
||||||
env: {
|
env: {
|
||||||
...process.env,
|
...process.env,
|
||||||
TEST_SETTINGS_FILE_KEY: this.projectDirName,
|
|
||||||
IS_PLAYWRIGHT: 'true',
|
IS_PLAYWRIGHT: 'true',
|
||||||
},
|
},
|
||||||
...(process.env.ELECTRON_OVERRIDE_DIST_PATH
|
...(process.env.ELECTRON_OVERRIDE_DIST_PATH
|
||||||
@ -200,7 +199,14 @@ export class ElectronZoo {
|
|||||||
|
|
||||||
await this.context.tracing.startChunk()
|
await this.context.tracing.startChunk()
|
||||||
|
|
||||||
await setup(this.context, this.page, testInfo)
|
// THIS IS ABSOLUTELY NECESSARY TO CHANGE THE PROJECT DIRECTORY BETWEEN
|
||||||
|
// TESTS BECAUSE OF THE ELECTRON INSTANCE REUSE.
|
||||||
|
await this.electron?.evaluate(({ app }, projectDirName) => {
|
||||||
|
// @ts-ignore can't declaration merge see main.ts
|
||||||
|
app.testProperty['TEST_SETTINGS_FILE_KEY'] = projectDirName
|
||||||
|
}, this.projectDirName)
|
||||||
|
|
||||||
|
await setup(this.context, this.page, this.projectDirName, testInfo)
|
||||||
|
|
||||||
await this.cleanProjectDir()
|
await this.cleanProjectDir()
|
||||||
|
|
||||||
@ -250,11 +256,6 @@ export class ElectronZoo {
|
|||||||
// return app.reuseWindowForTest();
|
// return app.reuseWindowForTest();
|
||||||
// });
|
// });
|
||||||
|
|
||||||
await this.electron?.evaluate(({ app }, projectDirName) => {
|
|
||||||
// @ts-ignore can't declaration merge see main.ts
|
|
||||||
app.testProperty['TEST_SETTINGS_FILE_KEY'] = projectDirName
|
|
||||||
}, this.projectDirName)
|
|
||||||
|
|
||||||
// Always start at the root view
|
// Always start at the root view
|
||||||
await this.page.goto(this.firstUrl)
|
await this.page.goto(this.firstUrl)
|
||||||
|
|
||||||
@ -278,8 +279,9 @@ export class ElectronZoo {
|
|||||||
// Not a problem if it already exists.
|
// Not a problem if it already exists.
|
||||||
}
|
}
|
||||||
|
|
||||||
const tempSettingsFilePath = path.join(
|
const tempSettingsFilePath = path.resolve(
|
||||||
this.projectDirName,
|
this.projectDirName,
|
||||||
|
'..',
|
||||||
SETTINGS_FILE_NAME
|
SETTINGS_FILE_NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -43,21 +43,15 @@ type DragFromHandler = (
|
|||||||
export class SceneFixture {
|
export class SceneFixture {
|
||||||
public page: Page
|
public page: Page
|
||||||
public streamWrapper!: Locator
|
public streamWrapper!: Locator
|
||||||
public loadingIndicator!: Locator
|
|
||||||
public networkToggleConnected!: Locator
|
public networkToggleConnected!: Locator
|
||||||
public startEditSketchBtn!: Locator
|
public startEditSketchBtn!: Locator
|
||||||
|
|
||||||
get exeIndicator() {
|
|
||||||
return this.page
|
|
||||||
.getByTestId('model-state-indicator-execution-done')
|
|
||||||
.or(this.page.getByTestId('model-state-indicator-receive-reliable'))
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page
|
this.page = page
|
||||||
this.streamWrapper = page.getByTestId('stream')
|
this.streamWrapper = page.getByTestId('stream')
|
||||||
this.networkToggleConnected = page.getByTestId('network-toggle-ok')
|
this.networkToggleConnected = page
|
||||||
this.loadingIndicator = this.streamWrapper.getByTestId('loading')
|
.getByTestId('network-toggle-ok')
|
||||||
|
.or(page.getByTestId('network-toggle-other'))
|
||||||
this.startEditSketchBtn = page
|
this.startEditSketchBtn = page
|
||||||
.getByRole('button', { name: 'Start Sketch' })
|
.getByRole('button', { name: 'Start Sketch' })
|
||||||
.or(page.getByRole('button', { name: 'Edit Sketch' }))
|
.or(page.getByRole('button', { name: 'Edit Sketch' }))
|
||||||
@ -231,10 +225,6 @@ export class SceneFixture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForExecutionDone = async () => {
|
|
||||||
await expect(this.exeIndicator).toBeVisible({ timeout: 30000 })
|
|
||||||
}
|
|
||||||
|
|
||||||
connectionEstablished = async () => {
|
connectionEstablished = async () => {
|
||||||
const timeout = 30000
|
const timeout = 30000
|
||||||
await expect(this.networkToggleConnected).toBeVisible({ timeout })
|
await expect(this.networkToggleConnected).toBeVisible({ timeout })
|
||||||
@ -243,6 +233,9 @@ export class SceneFixture {
|
|||||||
settled = async (cmdBar: CmdBarFixture) => {
|
settled = async (cmdBar: CmdBarFixture) => {
|
||||||
const u = await getUtils(this.page)
|
const u = await getUtils(this.page)
|
||||||
|
|
||||||
|
await expect(this.startEditSketchBtn).not.toBeDisabled()
|
||||||
|
await expect(this.startEditSketchBtn).toBeVisible()
|
||||||
|
|
||||||
await cmdBar.openCmdBar()
|
await cmdBar.openCmdBar()
|
||||||
await cmdBar.chooseCommand('Settings · app · show debug panel')
|
await cmdBar.chooseCommand('Settings · app · show debug panel')
|
||||||
await cmdBar.selectOption({ name: 'on' }).click()
|
await cmdBar.selectOption({ name: 'on' }).click()
|
||||||
@ -250,10 +243,6 @@ export class SceneFixture {
|
|||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
await this.waitForExecutionDone()
|
|
||||||
await expect(this.startEditSketchBtn).not.toBeDisabled()
|
|
||||||
await expect(this.startEditSketchBtn).toBeVisible()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expectPixelColor = async (
|
expectPixelColor = async (
|
||||||
|
@ -44,6 +44,7 @@ export class ToolbarFixture {
|
|||||||
featureTreePane!: Locator
|
featureTreePane!: Locator
|
||||||
gizmo!: Locator
|
gizmo!: Locator
|
||||||
gizmoDisabled!: Locator
|
gizmoDisabled!: Locator
|
||||||
|
insertButton!: Locator
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page
|
this.page = page
|
||||||
@ -78,18 +79,14 @@ export class ToolbarFixture {
|
|||||||
// element or two different elements can represent these states.
|
// element or two different elements can represent these states.
|
||||||
this.gizmo = page.getByTestId('gizmo')
|
this.gizmo = page.getByTestId('gizmo')
|
||||||
this.gizmoDisabled = page.getByTestId('gizmo-disabled')
|
this.gizmoDisabled = page.getByTestId('gizmo-disabled')
|
||||||
|
|
||||||
|
this.insertButton = page.getByTestId('insert-pane-button')
|
||||||
}
|
}
|
||||||
|
|
||||||
get logoLink() {
|
get logoLink() {
|
||||||
return this.page.getByTestId('app-logo')
|
return this.page.getByTestId('app-logo')
|
||||||
}
|
}
|
||||||
|
|
||||||
get exeIndicator() {
|
|
||||||
return this.page
|
|
||||||
.getByTestId('model-state-indicator-receive-reliable')
|
|
||||||
.or(this.page.getByTestId('model-state-indicator-execution-done'))
|
|
||||||
}
|
|
||||||
|
|
||||||
startSketchPlaneSelection = async () =>
|
startSketchPlaneSelection = async () =>
|
||||||
doAndWaitForImageDiff(this.page, () => this.startSketchBtn.click(), 500)
|
doAndWaitForImageDiff(this.page, () => this.startSketchBtn.click(), 500)
|
||||||
|
|
||||||
@ -165,20 +162,14 @@ export class ToolbarFixture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Opens file by it's name and waits for execution to finish
|
* Opens file by it's name
|
||||||
*/
|
*/
|
||||||
openFile = async (
|
openFile = async (fileName: string) => {
|
||||||
fileName: string,
|
|
||||||
{ wait }: { wait?: boolean } = { wait: true }
|
|
||||||
) => {
|
|
||||||
await this.filePane.getByText(fileName).click()
|
await this.filePane.getByText(fileName).click()
|
||||||
if (wait) {
|
|
||||||
await expect(this.exeIndicator).toBeVisible({ timeout: 15_000 })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
selectCenterRectangle = async () => {
|
selectCenterRectangle = async () => {
|
||||||
await this.page
|
await this.page
|
||||||
.getByRole('button', { name: 'caret down Corner rectangle:' })
|
.getByRole('button', { name: 'caret down rectangles:' })
|
||||||
.click()
|
.click()
|
||||||
await expect(
|
await expect(
|
||||||
this.page.getByTestId('dropdown-center-rectangle')
|
this.page.getByTestId('dropdown-center-rectangle')
|
||||||
@ -187,7 +178,7 @@ export class ToolbarFixture {
|
|||||||
}
|
}
|
||||||
selectBoolean = async (operation: 'union' | 'subtract' | 'intersect') => {
|
selectBoolean = async (operation: 'union' | 'subtract' | 'intersect') => {
|
||||||
await this.page
|
await this.page
|
||||||
.getByRole('button', { name: 'caret down Union: open menu' })
|
.getByRole('button', { name: 'caret down booleans: open menu' })
|
||||||
.click()
|
.click()
|
||||||
const operationTestId = `dropdown-boolean-${operation}`
|
const operationTestId = `dropdown-boolean-${operation}`
|
||||||
await expect(this.page.getByTestId(operationTestId)).toBeVisible()
|
await expect(this.page.getByTestId(operationTestId)).toBeVisible()
|
||||||
@ -195,25 +186,19 @@ export class ToolbarFixture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectCircleThreePoint = async () => {
|
selectCircleThreePoint = async () => {
|
||||||
await this.page
|
await this.page.getByRole('button', { name: 'caret down circles:' }).click()
|
||||||
.getByRole('button', { name: 'caret down Center circle:' })
|
|
||||||
.click()
|
|
||||||
await expect(
|
await expect(
|
||||||
this.page.getByTestId('dropdown-circle-three-points')
|
this.page.getByTestId('dropdown-circle-three-points')
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
await this.page.getByTestId('dropdown-circle-three-points').click()
|
await this.page.getByTestId('dropdown-circle-three-points').click()
|
||||||
}
|
}
|
||||||
selectArc = async () => {
|
selectArc = async () => {
|
||||||
await this.page
|
await this.page.getByRole('button', { name: 'caret down arcs:' }).click()
|
||||||
.getByRole('button', { name: 'caret down Tangential Arc:' })
|
|
||||||
.click()
|
|
||||||
await expect(this.page.getByTestId('dropdown-arc')).toBeVisible()
|
await expect(this.page.getByTestId('dropdown-arc')).toBeVisible()
|
||||||
await this.page.getByTestId('dropdown-arc').click()
|
await this.page.getByTestId('dropdown-arc').click()
|
||||||
}
|
}
|
||||||
selectThreePointArc = async () => {
|
selectThreePointArc = async () => {
|
||||||
await this.page
|
await this.page.getByRole('button', { name: 'caret down arcs:' }).click()
|
||||||
.getByRole('button', { name: 'caret down Tangential Arc:' })
|
|
||||||
.click()
|
|
||||||
await expect(
|
await expect(
|
||||||
this.page.getByTestId('dropdown-three-point-arc')
|
this.page.getByTestId('dropdown-three-point-arc')
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
@ -10,6 +10,7 @@ test.describe('Import UI tests', () => {
|
|||||||
toolbar,
|
toolbar,
|
||||||
scene,
|
scene,
|
||||||
editor,
|
editor,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const projectDir = path.join(dir, 'import-test')
|
const projectDir = path.join(dir, 'import-test')
|
||||||
@ -20,15 +21,9 @@ test.describe('Import UI tests', () => {
|
|||||||
path.join(projectDir, 'toBeImported.kcl'),
|
path.join(projectDir, 'toBeImported.kcl'),
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfileAt([281.54, 305.81], sketch001)
|
profile001 = startProfileAt([281.54, 305.81], sketch001)
|
||||||
|> angledLine([0, 123.43], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 123.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 85.99)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
85.99
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude(profile001, length = 100)`
|
extrude(profile001, length = 100)`
|
||||||
@ -43,15 +38,9 @@ importedCube
|
|||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfileAt([-134.53, -56.17], sketch001)
|
profile001 = startProfileAt([-134.53, -56.17], sketch001)
|
||||||
|> angledLine([0, 79.05], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 79.05, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 76.28)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg01)
|
||||||
76.28
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $seg01)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
|> close()
|
|> close()
|
||||||
extrude001 = extrude(profile001, length = 100)
|
extrude001 = extrude(profile001, length = 100)
|
||||||
@ -61,7 +50,7 @@ sketch002 = startSketchOn(extrude001, seg01)`
|
|||||||
})
|
})
|
||||||
|
|
||||||
await homePage.openProject('import-test')
|
await homePage.openProject('import-test')
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
await scene.moveCameraTo(
|
await scene.moveCameraTo(
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
|
|||||||
test(
|
test(
|
||||||
'When machine-api server not found butt is disabled and shows the reason',
|
'When machine-api server not found butt is disabled and shows the reason',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page, scene, cmdBar }, testInfo) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = join(dir, 'bracket')
|
const bracketDir = join(dir, 'bracket')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
@ -23,10 +23,7 @@ test(
|
|||||||
|
|
||||||
await page.getByText('bracket').click()
|
await page.getByText('bracket').click()
|
||||||
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
const notFoundText = 'Machine API server was not discovered'
|
const notFoundText = 'Machine API server was not discovered'
|
||||||
await expect(page.getByText(notFoundText).first()).not.toBeVisible()
|
await expect(page.getByText(notFoundText).first()).not.toBeVisible()
|
||||||
@ -47,7 +44,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'When machine-api server not found home screen & project status shows the reason',
|
'When machine-api server not found home screen & project status shows the reason',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page, scene, cmdBar }, testInfo) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = join(dir, 'bracket')
|
const bracketDir = join(dir, 'bracket')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
@ -71,10 +68,7 @@ test(
|
|||||||
|
|
||||||
await page.getByText('bracket').click()
|
await page.getByText('bracket').click()
|
||||||
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(page.getByText(notFoundText).nth(1)).not.toBeVisible()
|
await expect(page.getByText(notFoundText).nth(1)).not.toBeVisible()
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ function tomlStringOverWriteNamedViewUuids(toml: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test.describe('Named view tests', () => {
|
test.describe('Named view tests', () => {
|
||||||
|
test.skip() // TODO: Jace is working on these
|
||||||
test('Verify project.toml is not created', async ({ page }, testInfo) => {
|
test('Verify project.toml is not created', async ({ page }, testInfo) => {
|
||||||
// Create project and load it
|
// Create project and load it
|
||||||
const projectName = 'named-views'
|
const projectName = 'named-views'
|
||||||
@ -88,7 +89,7 @@ test.describe('Named view tests', () => {
|
|||||||
|
|
||||||
// Create and load project
|
// Create and load project
|
||||||
await createProject({ name: projectName, page })
|
await createProject({ name: projectName, page })
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Create named view
|
// Create named view
|
||||||
const projectDirName = testInfo.outputPath('electron-test-projects-dir')
|
const projectDirName = testInfo.outputPath('electron-test-projects-dir')
|
||||||
@ -110,14 +111,17 @@ test.describe('Named view tests', () => {
|
|||||||
expect(exists).toBe(true)
|
expect(exists).toBe(true)
|
||||||
}).toPass()
|
}).toPass()
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
// Read project.toml into memory
|
// Read project.toml into memory
|
||||||
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
||||||
|
|
||||||
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
||||||
tomlString = tomlStringOverWriteNamedViewUuids(tomlString)
|
tomlString = tomlStringOverWriteNamedViewUuids(tomlString)
|
||||||
|
|
||||||
// Write the entire tomlString to a snapshot.
|
// Write the entire tomlString to a snapshot.
|
||||||
// There are many key/value pairs to check this is a safer match.
|
// There are many key/value pairs to check this is a safer match.
|
||||||
expect(tomlString).toMatchSnapshot('verify-named-view-gets-created')
|
expect(tomlString).toMatchSnapshot('verify-named-view-gets-created')
|
||||||
|
}).toPass()
|
||||||
})
|
})
|
||||||
test('Verify named view gets deleted', async ({
|
test('Verify named view gets deleted', async ({
|
||||||
cmdBar,
|
cmdBar,
|
||||||
@ -130,7 +134,7 @@ test.describe('Named view tests', () => {
|
|||||||
|
|
||||||
// Create project and go into the project
|
// Create project and go into the project
|
||||||
await createProject({ name: projectName, page })
|
await createProject({ name: projectName, page })
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Create a new named view
|
// Create a new named view
|
||||||
await cmdBar.openCmdBar()
|
await cmdBar.openCmdBar()
|
||||||
@ -152,6 +156,7 @@ test.describe('Named view tests', () => {
|
|||||||
expect(exists).toBe(true)
|
expect(exists).toBe(true)
|
||||||
}).toPass()
|
}).toPass()
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
// Read project.toml into memory
|
// Read project.toml into memory
|
||||||
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
||||||
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
||||||
@ -160,6 +165,7 @@ test.describe('Named view tests', () => {
|
|||||||
// Write the entire tomlString to a snapshot.
|
// Write the entire tomlString to a snapshot.
|
||||||
// There are many key/value pairs to check this is a safer match.
|
// There are many key/value pairs to check this is a safer match.
|
||||||
expect(tomlString).toMatchSnapshot('verify-named-view-gets-created')
|
expect(tomlString).toMatchSnapshot('verify-named-view-gets-created')
|
||||||
|
}).toPass()
|
||||||
|
|
||||||
// Delete a named view
|
// Delete a named view
|
||||||
await cmdBar.openCmdBar()
|
await cmdBar.openCmdBar()
|
||||||
@ -167,14 +173,16 @@ test.describe('Named view tests', () => {
|
|||||||
cmdBar.selectOption({ name: myNamedView2 })
|
cmdBar.selectOption({ name: myNamedView2 })
|
||||||
await cmdBar.progressCmdBar(false)
|
await cmdBar.progressCmdBar(false)
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
// Read project.toml into memory again since we deleted a named view
|
// Read project.toml into memory again since we deleted a named view
|
||||||
tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
||||||
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
||||||
tomlString = tomlStringOverWriteNamedViewUuids(tomlString)
|
tomlString = tomlStringOverWriteNamedViewUuids(tomlString)
|
||||||
|
|
||||||
// // Write the entire tomlString to a snapshot.
|
// // Write the entire tomlString to a snapshot.
|
||||||
// // There are many key/value pairs to check this is a safer match.
|
// // There are many key/value pairs to check this is a safer match.
|
||||||
expect(tomlString).toMatchSnapshot('verify-named-view-gets-deleted')
|
expect(tomlString).toMatchSnapshot('verify-named-view-gets-deleted')
|
||||||
|
}).toPass()
|
||||||
})
|
})
|
||||||
test('Verify named view gets loaded', async ({
|
test('Verify named view gets loaded', async ({
|
||||||
cmdBar,
|
cmdBar,
|
||||||
@ -186,7 +194,7 @@ test.describe('Named view tests', () => {
|
|||||||
|
|
||||||
// Create project and go into the project
|
// Create project and go into the project
|
||||||
await createProject({ name: projectName, page })
|
await createProject({ name: projectName, page })
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Create a new named view
|
// Create a new named view
|
||||||
await cmdBar.openCmdBar()
|
await cmdBar.openCmdBar()
|
||||||
@ -208,6 +216,7 @@ test.describe('Named view tests', () => {
|
|||||||
expect(exists).toBe(true)
|
expect(exists).toBe(true)
|
||||||
}).toPass()
|
}).toPass()
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
// Read project.toml into memory
|
// Read project.toml into memory
|
||||||
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
||||||
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
||||||
@ -216,6 +225,7 @@ test.describe('Named view tests', () => {
|
|||||||
// Write the entire tomlString to a snapshot.
|
// Write the entire tomlString to a snapshot.
|
||||||
// There are many key/value pairs to check this is a safer match.
|
// There are many key/value pairs to check this is a safer match.
|
||||||
expect(tomlString).toMatchSnapshot('verify-named-view-gets-created')
|
expect(tomlString).toMatchSnapshot('verify-named-view-gets-created')
|
||||||
|
}).toPass()
|
||||||
|
|
||||||
// Create a load a named view
|
// Create a load a named view
|
||||||
await cmdBar.openCmdBar()
|
await cmdBar.openCmdBar()
|
||||||
@ -239,7 +249,7 @@ test.describe('Named view tests', () => {
|
|||||||
|
|
||||||
// Create and load project
|
// Create and load project
|
||||||
await createProject({ name: projectName, page })
|
await createProject({ name: projectName, page })
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Create named view
|
// Create named view
|
||||||
const projectDirName = testInfo.outputPath('electron-test-projects-dir')
|
const projectDirName = testInfo.outputPath('electron-test-projects-dir')
|
||||||
@ -282,6 +292,7 @@ test.describe('Named view tests', () => {
|
|||||||
expect(exists).toBe(true)
|
expect(exists).toBe(true)
|
||||||
}).toPass()
|
}).toPass()
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
// Read project.toml into memory
|
// Read project.toml into memory
|
||||||
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
let tomlString = await fsp.readFile(tempProjectSettingsFilePath, 'utf-8')
|
||||||
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
// Rewrite the uuids in the named views to match snapshot otherwise they will be randomly generated from rust and break
|
||||||
@ -290,5 +301,6 @@ test.describe('Named view tests', () => {
|
|||||||
// Write the entire tomlString to a snapshot.
|
// Write the entire tomlString to a snapshot.
|
||||||
// There are many key/value pairs to check this is a safer match.
|
// There are many key/value pairs to check this is a safer match.
|
||||||
expect(tomlString).toMatchSnapshot('verify-two-named-view-gets-created')
|
expect(tomlString).toMatchSnapshot('verify-two-named-view-gets-created')
|
||||||
|
}).toPass()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
[settings]
|
||||||
|
modeling = { }
|
||||||
|
text_editor = { }
|
||||||
|
command_bar = { }
|
||||||
|
|
||||||
|
[settings.app.named_views.0656fb1a-9640-473e-b334-591dc70c0138]
|
||||||
|
name = "uuid1"
|
||||||
|
eye_offset = 1_378.0059
|
||||||
|
fov_y = 45
|
||||||
|
is_ortho = false
|
||||||
|
ortho_scale_enabled = true
|
||||||
|
ortho_scale_factor = 1.6
|
||||||
|
pivot_position = [ 0, 0, 0 ]
|
||||||
|
pivot_rotation = [ 0.5380994, 0.0, 0.0, 0.8428814 ]
|
||||||
|
world_coord_system = "right_handed_up_z"
|
||||||
|
version = 1
|
@ -0,0 +1,28 @@
|
|||||||
|
[settings]
|
||||||
|
modeling = { }
|
||||||
|
text_editor = { }
|
||||||
|
command_bar = { }
|
||||||
|
|
||||||
|
[settings.app.named_views.0656fb1a-9640-473e-b334-591dc70c0138]
|
||||||
|
name = "uuid1"
|
||||||
|
eye_offset = 1_378.0059
|
||||||
|
fov_y = 45
|
||||||
|
is_ortho = false
|
||||||
|
ortho_scale_enabled = true
|
||||||
|
ortho_scale_factor = 1.6
|
||||||
|
pivot_position = [ 0, 0, 0 ]
|
||||||
|
pivot_rotation = [ 0.5380994, 0.0, 0.0, 0.8428814 ]
|
||||||
|
world_coord_system = "right_handed_up_z"
|
||||||
|
version = 1
|
||||||
|
|
||||||
|
[settings.app.named_views.c810cf04-c6cc-4a4a-8b11-17bf445dcab7]
|
||||||
|
name = "uuid2"
|
||||||
|
eye_offset = 1_378.0059
|
||||||
|
fov_y = 45
|
||||||
|
is_ortho = false
|
||||||
|
ortho_scale_enabled = true
|
||||||
|
ortho_scale_factor = 1.6
|
||||||
|
pivot_position = [ 1_826.5239, 0.0, 0.0 ]
|
||||||
|
pivot_rotation = [ 0.5380994, 0.0, 0.0, 0.8428814 ]
|
||||||
|
world_coord_system = "right_handed_up_z"
|
||||||
|
version = 1
|
@ -1,4 +1,5 @@
|
|||||||
import { throwTronAppMissing } from '@e2e/playwright/lib/electron-helpers'
|
import { throwTronAppMissing } from '@e2e/playwright/lib/electron-helpers'
|
||||||
|
import { orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6,19 +7,28 @@ import { expect, test } from '@e2e/playwright/zoo-test'
|
|||||||
* Test file menu actions that trigger something in the frontend
|
* Test file menu actions that trigger something in the frontend
|
||||||
*/
|
*/
|
||||||
test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
||||||
|
test.skip() // TODO: Reimplement native file menu tests
|
||||||
test.describe('Home page', () => {
|
test.describe('Home page', () => {
|
||||||
test.describe('File role', () => {
|
test.describe('File role', () => {
|
||||||
test('Home.File.Create project', async ({ tronApp, cmdBar, page }) => {
|
test('Home.File.Create project', async ({ tronApp, cmdBar, page }) => {
|
||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const newProject =
|
const newProject =
|
||||||
app.applicationMenu.getMenuItemById('File.New project')
|
app.applicationMenu.getMenuItemById('File.New project')
|
||||||
if (!newProject) fail()
|
if (!newProject) return false
|
||||||
newProject.click()
|
newProject.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Check that the command bar is opened
|
// Check that the command bar is opened
|
||||||
await expect(cmdBar.cmdBarElement).toBeVisible()
|
await expect(cmdBar.cmdBarElement).toBeVisible()
|
||||||
// Check the placeholder project name exists
|
// Check the placeholder project name exists
|
||||||
@ -32,13 +42,21 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const openProject =
|
const openProject =
|
||||||
app.applicationMenu.getMenuItemById('File.Open project')
|
app.applicationMenu.getMenuItemById('File.Open project')
|
||||||
if (!openProject) fail()
|
if (!openProject) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
openProject.click()
|
openProject.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Check that the command bar is opened
|
// Check that the command bar is opened
|
||||||
await expect(cmdBar.cmdBarElement).toBeVisible()
|
await expect(cmdBar.cmdBarElement).toBeVisible()
|
||||||
// Check the placeholder project name exists
|
// Check the placeholder project name exists
|
||||||
@ -56,14 +74,23 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
console.log(app)
|
||||||
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const userSettings = app.applicationMenu.getMenuItemById(
|
const userSettings = app.applicationMenu.getMenuItemById(
|
||||||
'File.Preferences.User settings'
|
'File.Preferences.User settings'
|
||||||
)
|
)
|
||||||
if (!userSettings) fail()
|
if (!userSettings) return false
|
||||||
userSettings.click()
|
userSettings.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
const settings = page.getByTestId('settings-dialog-panel')
|
const settings = page.getByTestId('settings-dialog-panel')
|
||||||
await expect(settings).toBeVisible()
|
await expect(settings).toBeVisible()
|
||||||
// You are viewing the user tab
|
// You are viewing the user tab
|
||||||
@ -77,17 +104,27 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
cmdBar,
|
cmdBar,
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
if (!tronApp) fail()
|
if (!tronApp) {
|
||||||
|
fail()
|
||||||
|
}
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const keybindings = app.applicationMenu.getMenuItemById(
|
const keybindings = app.applicationMenu.getMenuItemById(
|
||||||
'File.Preferences.Keybindings'
|
'File.Preferences.Keybindings'
|
||||||
)
|
)
|
||||||
if (!keybindings) fail()
|
if (!keybindings) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
keybindings.click()
|
keybindings.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
const settings = page.getByTestId('settings-dialog-panel')
|
const settings = page.getByTestId('settings-dialog-panel')
|
||||||
await expect(settings).toBeVisible()
|
await expect(settings).toBeVisible()
|
||||||
// You are viewing the keybindings tab
|
// You are viewing the keybindings tab
|
||||||
@ -102,14 +139,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'File.Preferences.User default units'
|
'File.Preferences.User default units'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) return false
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
const settings = page.getByTestId('settings-dialog-panel')
|
const settings = page.getByTestId('settings-dialog-panel')
|
||||||
await expect(settings).toBeVisible()
|
await expect(settings).toBeVisible()
|
||||||
const defaultUnit = settings.locator('#defaultUnit')
|
const defaultUnit = settings.locator('#defaultUnit')
|
||||||
@ -119,14 +164,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'File.Preferences.Theme'
|
'File.Preferences.Theme'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Check that the command bar is opened
|
// Check that the command bar is opened
|
||||||
await expect(cmdBar.cmdBarElement).toBeVisible()
|
await expect(cmdBar.cmdBarElement).toBeVisible()
|
||||||
// Check the placeholder project name exists
|
// Check the placeholder project name exists
|
||||||
@ -144,14 +197,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'File.Preferences.Theme color'
|
'File.Preferences.Theme color'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) return false
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
const settings = page.getByTestId('settings-dialog-panel')
|
const settings = page.getByTestId('settings-dialog-panel')
|
||||||
await expect(settings).toBeVisible()
|
await expect(settings).toBeVisible()
|
||||||
const defaultUnit = settings.locator('#themeColor')
|
const defaultUnit = settings.locator('#themeColor')
|
||||||
@ -165,13 +226,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const menu = app.applicationMenu.getMenuItemById('File.Sign out')
|
const menu =
|
||||||
if (!menu) fail()
|
app.applicationMenu.getMenuItemById('File.Sign out')
|
||||||
|
if (!menu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// FIXME: Add back when you can actually sign out
|
// FIXME: Add back when you can actually sign out
|
||||||
// menu.click()
|
// menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// FIXME: When signing out during E2E the page is not bound correctly.
|
// FIXME: When signing out during E2E the page is not bound correctly.
|
||||||
// It cannot find the button
|
// It cannot find the button
|
||||||
// const signIn = page.getByTestId('sign-in-button')
|
// const signIn = page.getByTestId('sign-in-button')
|
||||||
@ -184,14 +254,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'Edit.Rename project'
|
'Edit.Rename project'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) return false
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Check the placeholder project name exists
|
// Check the placeholder project name exists
|
||||||
const actual = await cmdBar.cmdBarElement
|
const actual = await cmdBar.cmdBarElement
|
||||||
.getByTestId('command-name')
|
.getByTestId('command-name')
|
||||||
@ -203,20 +281,27 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'Edit.Delete project'
|
'Edit.Delete project'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Check the placeholder project name exists
|
// Check the placeholder project name exists
|
||||||
const actual = await cmdBar.cmdBarElement
|
const actual = async () =>
|
||||||
.getByTestId('command-name')
|
cmdBar.cmdBarElement.getByTestId('command-name').textContent()
|
||||||
.textContent()
|
|
||||||
const expected = 'Delete project'
|
const expected = 'Delete project'
|
||||||
expect(actual).toBe(expected)
|
await expect.poll(async () => await actual()).toBe(expected)
|
||||||
})
|
})
|
||||||
test('Home.Edit.Change project directory', async ({
|
test('Home.Edit.Change project directory', async ({
|
||||||
tronApp,
|
tronApp,
|
||||||
@ -226,14 +311,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'Edit.Change project directory'
|
'Edit.Change project directory'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) return false
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
const settings = page.getByTestId('settings-dialog-panel')
|
const settings = page.getByTestId('settings-dialog-panel')
|
||||||
await expect(settings).toBeVisible()
|
await expect(settings).toBeVisible()
|
||||||
const projectDirectory = settings.locator('#projectDirectory')
|
const projectDirectory = settings.locator('#projectDirectory')
|
||||||
@ -249,14 +342,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'View.Command Palette...'
|
'View.Command Palette...'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Check the placeholder project name exists
|
// Check the placeholder project name exists
|
||||||
const actual = cmdBar.cmdBarElement.getByTestId('cmd-bar-search')
|
const actual = cmdBar.cmdBarElement.getByTestId('cmd-bar-search')
|
||||||
await expect(actual).toBeVisible()
|
await expect(actual).toBeVisible()
|
||||||
@ -267,14 +368,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'Help.Show all commands'
|
'Help.Show all commands'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) return false
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Check the placeholder project name exists
|
// Check the placeholder project name exists
|
||||||
const actual = cmdBar.cmdBarElement.getByTestId('cmd-bar-search')
|
const actual = cmdBar.cmdBarElement.getByTestId('cmd-bar-search')
|
||||||
await expect(actual).toBeVisible()
|
await expect(actual).toBeVisible()
|
||||||
@ -283,13 +392,21 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'Help.KCL code samples'
|
'Help.KCL code samples'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
})
|
})
|
||||||
test('Home.Help.Refresh and report a bug', async ({
|
test('Home.Help.Refresh and report a bug', async ({
|
||||||
tronApp,
|
tronApp,
|
||||||
@ -299,14 +416,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'Help.Refresh and report a bug'
|
'Help.Refresh and report a bug'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) return false
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Core dump and refresh magic number timeout
|
// Core dump and refresh magic number timeout
|
||||||
await page.waitForTimeout(7000)
|
await page.waitForTimeout(7000)
|
||||||
const actual = page.getByText(
|
const actual = page.getByText(
|
||||||
@ -318,14 +443,22 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'Help.Reset onboarding'
|
'Help.Reset onboarding'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
|
|
||||||
const actual = page.getByText(
|
const actual = page.getByText(
|
||||||
`This is a hardware design tool that lets you edit visually, with code, or both. It's powered by the KittyCAD Design API, the first API created for anyone to build hardware design tools.`
|
`This is a hardware design tool that lets you edit visually, with code, or both. It's powered by the KittyCAD Design API, the first API created for anyone to build hardware design tools.`
|
||||||
@ -345,7 +478,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
}) => {
|
}) => {
|
||||||
if (!tronApp) fail()
|
if (!tronApp) fail()
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -377,7 +510,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -413,7 +546,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -438,6 +571,43 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
const expected = 'Open sample'
|
const expected = 'Open sample'
|
||||||
expect(actual).toBe(expected)
|
expect(actual).toBe(expected)
|
||||||
})
|
})
|
||||||
|
test('Modeling.File.Insert from project file', async ({
|
||||||
|
tronApp,
|
||||||
|
cmdBar,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
}) => {
|
||||||
|
if (!tronApp) {
|
||||||
|
throwTronAppMissing()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
// Run electron snippet to find the Menu!
|
||||||
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
|
if (!app || !app.applicationMenu) {
|
||||||
|
throw new Error('app or app.applicationMenu is missing')
|
||||||
|
}
|
||||||
|
const openProject = app.applicationMenu.getMenuItemById(
|
||||||
|
'File.Insert from project file'
|
||||||
|
)
|
||||||
|
if (!openProject) {
|
||||||
|
throw new Error('File.Insert from project file')
|
||||||
|
}
|
||||||
|
openProject.click()
|
||||||
|
})
|
||||||
|
// Check that the command bar is opened
|
||||||
|
await expect(cmdBar.cmdBarElement).toBeVisible()
|
||||||
|
// Check the placeholder project name exists
|
||||||
|
const actual = await cmdBar.cmdBarElement
|
||||||
|
.getByTestId('command-name')
|
||||||
|
.textContent()
|
||||||
|
const expected = 'Insert'
|
||||||
|
expect(actual).toBe(expected)
|
||||||
|
})
|
||||||
test('Modeling.File.Export current part', async ({
|
test('Modeling.File.Export current part', async ({
|
||||||
tronApp,
|
tronApp,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
@ -450,7 +620,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -487,7 +657,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -523,7 +693,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -560,7 +730,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -596,7 +766,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -630,7 +800,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -663,7 +833,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -700,7 +870,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -733,21 +903,28 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) {
|
if (!app || !app.applicationMenu) {
|
||||||
throw new Error('app or app.applicationMenu is missing')
|
throw new Error('app or app.applicationMenu is missing')
|
||||||
}
|
}
|
||||||
const menu = app.applicationMenu.getMenuItemById('File.Sign out')
|
const menu =
|
||||||
|
app.applicationMenu.getMenuItemById('File.Sign out')
|
||||||
if (!menu) {
|
if (!menu) {
|
||||||
throw new Error('File.Sign out')
|
throw new Error('File.Sign out')
|
||||||
}
|
}
|
||||||
// FIXME: Add back when you can actually sign out
|
// FIXME: Add back when you can actually sign out
|
||||||
// menu.click()
|
// menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// FIXME: When signing out during E2E the page is not bound correctly.
|
// FIXME: When signing out during E2E the page is not bound correctly.
|
||||||
// It cannot find the button
|
// It cannot find the button
|
||||||
// const signIn = page.getByTestId('sign-in-button')
|
// const signIn = page.getByTestId('sign-in-button')
|
||||||
@ -767,7 +944,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -802,7 +979,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -837,7 +1014,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -867,7 +1044,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -902,7 +1079,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -937,7 +1114,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
@ -971,7 +1148,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1003,7 +1180,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1039,7 +1216,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1075,7 +1252,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1112,7 +1289,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1141,7 +1318,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1170,7 +1347,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1199,7 +1376,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1228,7 +1405,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1257,7 +1434,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1286,7 +1463,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1315,7 +1492,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1344,7 +1521,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1381,7 +1558,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1418,7 +1595,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1455,7 +1632,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1488,7 +1665,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1521,7 +1698,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1554,7 +1731,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1587,7 +1764,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1621,7 +1798,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1658,7 +1835,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1695,7 +1872,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1733,7 +1910,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1770,7 +1947,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1807,7 +1984,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1844,7 +2021,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1881,7 +2058,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1918,7 +2095,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1956,7 +2133,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -1994,7 +2171,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -2032,7 +2209,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -2071,7 +2248,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -2099,7 +2276,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
@ -2119,25 +2296,33 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
scene,
|
scene,
|
||||||
toolbar,
|
toolbar,
|
||||||
}) => {
|
}) => {
|
||||||
|
// TODO: this test has been dead dead on the idle stream branch
|
||||||
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
throwTronAppMissing()
|
throwTronAppMissing()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () =>
|
||||||
await tronApp.electron.evaluate(async ({ app }) => {
|
await tronApp.electron.evaluate(async ({ app }) => {
|
||||||
if (!app || !app.applicationMenu) fail()
|
if (!app || !app.applicationMenu) return false
|
||||||
const menu = app.applicationMenu.getMenuItemById(
|
const menu = app.applicationMenu.getMenuItemById(
|
||||||
'Help.Refresh and report a bug'
|
'Help.Refresh and report a bug'
|
||||||
)
|
)
|
||||||
if (!menu) fail()
|
if (!menu) return false
|
||||||
menu.click()
|
menu.click()
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
.toBe(true)
|
||||||
// Core dump and refresh magic number timeout
|
// Core dump and refresh magic number timeout
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
await expect(toolbar.startSketchBtn).toBeVisible()
|
await expect(toolbar.startSketchBtn).toBeVisible()
|
||||||
})
|
})
|
||||||
test('Modeling.Help.Reset onboarding', async ({
|
test('Modeling.Help.Reset onboarding', async ({
|
||||||
@ -2152,7 +2337,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Run electron snippet to find the Menu!
|
// Run electron snippet to find the Menu!
|
||||||
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
|
||||||
|
292
e2e/playwright/point-click-assemblies.spec.ts
Normal file
292
e2e/playwright/point-click-assemblies.spec.ts
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
import * as fsp from 'fs/promises'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
|
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
|
||||||
|
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
||||||
|
import {
|
||||||
|
executorInputPath,
|
||||||
|
getUtils,
|
||||||
|
testsInputPath,
|
||||||
|
} from '@e2e/playwright/test-utils'
|
||||||
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
import type { Page } from '@playwright/test'
|
||||||
|
|
||||||
|
async function insertPartIntoAssembly(
|
||||||
|
path: string,
|
||||||
|
alias: string,
|
||||||
|
toolbar: ToolbarFixture,
|
||||||
|
cmdBar: CmdBarFixture,
|
||||||
|
page: Page
|
||||||
|
) {
|
||||||
|
await toolbar.insertButton.click()
|
||||||
|
await cmdBar.selectOption({ name: path }).click()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'localName',
|
||||||
|
currentArgValue: '',
|
||||||
|
headerArguments: { Path: path, LocalName: '' },
|
||||||
|
highlightedHeaderArg: 'localName',
|
||||||
|
commandName: 'Insert',
|
||||||
|
})
|
||||||
|
await page.keyboard.insertText(alias)
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: { Path: path, LocalName: alias },
|
||||||
|
commandName: 'Insert',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
}
|
||||||
|
|
||||||
|
// test file is for testing point an click code gen functionality that's assemblies related
|
||||||
|
test.describe('Point-and-click assemblies tests', () => {
|
||||||
|
test(
|
||||||
|
`Insert kcl parts into assembly as whole module import`,
|
||||||
|
{ tag: ['@electron'] },
|
||||||
|
async ({
|
||||||
|
context,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
tronApp,
|
||||||
|
}) => {
|
||||||
|
if (!tronApp) {
|
||||||
|
fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
const midPoint = { x: 500, y: 250 }
|
||||||
|
const partPoint = { x: midPoint.x + 30, y: midPoint.y - 30 } // mid point, just off top right
|
||||||
|
const defaultPlanesColor: [number, number, number] = [180, 220, 180]
|
||||||
|
const partColor: [number, number, number] = [100, 100, 100]
|
||||||
|
const tolerance = 50
|
||||||
|
const u = await getUtils(page)
|
||||||
|
const gizmo = page.locator('[aria-label*=gizmo]')
|
||||||
|
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
||||||
|
|
||||||
|
await test.step('Setup parts and expect empty assembly scene', async () => {
|
||||||
|
const projectName = 'assembly'
|
||||||
|
await context.folderSetupFn(async (dir) => {
|
||||||
|
const bracketDir = path.join(dir, projectName)
|
||||||
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
|
await Promise.all([
|
||||||
|
fsp.copyFile(
|
||||||
|
executorInputPath('cylinder.kcl'),
|
||||||
|
path.join(bracketDir, 'cylinder.kcl')
|
||||||
|
),
|
||||||
|
fsp.copyFile(
|
||||||
|
executorInputPath('e2e-can-sketch-on-chamfer.kcl'),
|
||||||
|
path.join(bracketDir, 'bracket.kcl')
|
||||||
|
),
|
||||||
|
fsp.copyFile(
|
||||||
|
testsInputPath('cube.step'),
|
||||||
|
path.join(bracketDir, 'cube.step')
|
||||||
|
),
|
||||||
|
fsp.writeFile(path.join(bracketDir, 'main.kcl'), ''),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
await homePage.openProject(projectName)
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
await scene.expectPixelColor(defaultPlanesColor, midPoint, tolerance)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Insert kcl as first part as module', async () => {
|
||||||
|
await insertPartIntoAssembly(
|
||||||
|
'cylinder.kcl',
|
||||||
|
'cylinder',
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
page
|
||||||
|
)
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`
|
||||||
|
import "cylinder.kcl" as cylinder
|
||||||
|
cylinder
|
||||||
|
`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
// Check scene for changes
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
await u.doAndWaitForCmd(async () => {
|
||||||
|
await gizmo.click({ button: 'right' })
|
||||||
|
await resetCameraButton.click()
|
||||||
|
}, 'zoom_to_fit')
|
||||||
|
await toolbar.closePane('debug')
|
||||||
|
await scene.expectPixelColor(partColor, partPoint, tolerance)
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Insert kcl second part as module', async () => {
|
||||||
|
await insertPartIntoAssembly(
|
||||||
|
'bracket.kcl',
|
||||||
|
'bracket',
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
page
|
||||||
|
)
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`
|
||||||
|
import "cylinder.kcl" as cylinder
|
||||||
|
import "bracket.kcl" as bracket
|
||||||
|
cylinder
|
||||||
|
bracket
|
||||||
|
`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Insert a second time and expect error', async () => {
|
||||||
|
// TODO: revisit once we have clone with #6209
|
||||||
|
await insertPartIntoAssembly(
|
||||||
|
'bracket.kcl',
|
||||||
|
'bracket',
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
page
|
||||||
|
)
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`
|
||||||
|
import "cylinder.kcl" as cylinder
|
||||||
|
import "bracket.kcl" as bracket
|
||||||
|
import "bracket.kcl" as bracket
|
||||||
|
cylinder
|
||||||
|
bracket
|
||||||
|
bracket
|
||||||
|
`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
test(
|
||||||
|
`Insert foreign parts into assembly as whole module import`,
|
||||||
|
{ tag: ['@electron'] },
|
||||||
|
async ({
|
||||||
|
context,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
editor,
|
||||||
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
|
tronApp,
|
||||||
|
}) => {
|
||||||
|
if (!tronApp) {
|
||||||
|
fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
const midPoint = { x: 500, y: 250 }
|
||||||
|
const partPoint = { x: midPoint.x + 30, y: midPoint.y - 30 } // mid point, just off top right
|
||||||
|
const defaultPlanesColor: [number, number, number] = [180, 220, 180]
|
||||||
|
const partColor: [number, number, number] = [150, 150, 150]
|
||||||
|
const tolerance = 50
|
||||||
|
|
||||||
|
const complexPlmFileName = 'cube_Complex-PLM_Name_-001.sldprt'
|
||||||
|
const camelCasedSolidworksFileName = 'cubeComplexPLMName001'
|
||||||
|
|
||||||
|
await test.step('Setup parts and expect empty assembly scene', async () => {
|
||||||
|
const projectName = 'assembly'
|
||||||
|
await context.folderSetupFn(async (dir) => {
|
||||||
|
const bracketDir = path.join(dir, projectName)
|
||||||
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
|
await Promise.all([
|
||||||
|
fsp.copyFile(
|
||||||
|
testsInputPath('cube.step'),
|
||||||
|
path.join(bracketDir, 'cube.step')
|
||||||
|
),
|
||||||
|
fsp.copyFile(
|
||||||
|
testsInputPath('cube.sldprt'),
|
||||||
|
path.join(bracketDir, complexPlmFileName)
|
||||||
|
),
|
||||||
|
fsp.writeFile(path.join(bracketDir, 'main.kcl'), ''),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
await homePage.openProject(projectName)
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
await scene.expectPixelColor(defaultPlanesColor, midPoint, tolerance)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Insert step part as module', async () => {
|
||||||
|
await insertPartIntoAssembly('cube.step', 'cube', toolbar, cmdBar, page)
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`
|
||||||
|
import "cube.step" as cube
|
||||||
|
cube
|
||||||
|
`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
// TODO: remove this once #5780 is fixed
|
||||||
|
await page.reload()
|
||||||
|
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
await scene.expectPixelColor(partColor, partPoint, tolerance)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Insert second step part by clicking', async () => {
|
||||||
|
await toolbar.openPane('files')
|
||||||
|
await toolbar.expectFileTreeState([
|
||||||
|
complexPlmFileName,
|
||||||
|
'cube.step',
|
||||||
|
'main.kcl',
|
||||||
|
])
|
||||||
|
await toolbar.openFile(complexPlmFileName)
|
||||||
|
|
||||||
|
// Go through the ToastInsert prompt
|
||||||
|
await page.getByText('Insert into my current file').click()
|
||||||
|
|
||||||
|
// Check getPathFilenameInVariableCase output
|
||||||
|
const parsedValueFromFile =
|
||||||
|
await cmdBar.currentArgumentInput.inputValue()
|
||||||
|
expect(parsedValueFromFile).toEqual(camelCasedSolidworksFileName)
|
||||||
|
|
||||||
|
// Continue on with the flow
|
||||||
|
await page.keyboard.insertText('cubeSw')
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await cmdBar.expectState({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: { Path: complexPlmFileName, LocalName: 'cubeSw' },
|
||||||
|
commandName: 'Insert',
|
||||||
|
})
|
||||||
|
await cmdBar.progressCmdBar()
|
||||||
|
await toolbar.closePane('files')
|
||||||
|
await toolbar.openPane('code')
|
||||||
|
await editor.expectEditor.toContain(
|
||||||
|
`
|
||||||
|
import "cube.step" as cube
|
||||||
|
import "${complexPlmFileName}" as cubeSw
|
||||||
|
cube
|
||||||
|
cubeSw
|
||||||
|
`,
|
||||||
|
{ shouldNormalise: true }
|
||||||
|
)
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
// TODO: remove this once #5780 is fixed
|
||||||
|
await page.reload()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
await toolbar.closePane('code')
|
||||||
|
await scene.expectPixelColor(partColor, partPoint, tolerance)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
@ -5,13 +5,14 @@ import path from 'node:path'
|
|||||||
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
|
||||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
|
||||||
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
||||||
import { getUtils, orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
|
import { orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
// test file is for testing point an click code gen functionality that's not sketch mode related
|
// test file is for testing point an click code gen functionality that's not sketch mode related
|
||||||
|
|
||||||
test.describe('Point-and-click tests', () => {
|
test.describe('Point-and-click tests', () => {
|
||||||
test('verify extruding circle works', async ({
|
test('verify extruding circle works', async ({
|
||||||
|
page,
|
||||||
context,
|
context,
|
||||||
homePage,
|
homePage,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
@ -30,8 +31,9 @@ test.describe('Point-and-click tests', () => {
|
|||||||
await context.addInitScript((file) => {
|
await context.addInitScript((file) => {
|
||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
const [clickCircle, moveToCircle] = scene.makeMouseHelpers(582, 217)
|
const [clickCircle, moveToCircle] = scene.makeMouseHelpers(582, 217)
|
||||||
|
|
||||||
@ -72,7 +74,6 @@ test.describe('Point-and-click tests', () => {
|
|||||||
|
|
||||||
await test.step('do extrude flow and check extrude code is added to editor', async () => {
|
await test.step('do extrude flow and check extrude code is added to editor', async () => {
|
||||||
await toolbar.extrudeButton.click()
|
await toolbar.extrudeButton.click()
|
||||||
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'distance',
|
currentArgKey: 'distance',
|
||||||
@ -186,6 +187,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
editor,
|
editor,
|
||||||
toolbar,
|
toolbar,
|
||||||
scene,
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const file = await fs.readFile(
|
const file = await fs.readFile(
|
||||||
path.resolve(
|
path.resolve(
|
||||||
@ -200,9 +202,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
}, file)
|
}, file)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await expect(
|
await scene.settled(cmdBar)
|
||||||
page.getByTestId('model-state-indicator-receive-reliable')
|
|
||||||
).toBeVisible()
|
|
||||||
|
|
||||||
const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene)
|
const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene)
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
clickCoords: { x: 570, y: 220 },
|
clickCoords: { x: 570, y: 220 },
|
||||||
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
||||||
cameraTarget: { x: -150, y: -4500, z: -80 },
|
cameraTarget: { x: -150, y: -4500, z: -80 },
|
||||||
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
|
beforeChamferSnippet: `angledLine(angle=segAng(rectangleSegmentA001)-90,length=217.26,tag=$seg01)
|
||||||
chamfer(length = 30,tags = [
|
chamfer(length = 30,tags = [
|
||||||
seg01,
|
seg01,
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
@ -223,9 +223,9 @@ test.describe('Point-and-click tests', () => {
|
|||||||
'sketch002 = startSketchOn(extrude001, seg03)',
|
'sketch002 = startSketchOn(extrude001, seg03)',
|
||||||
afterRectangle1stClickSnippet:
|
afterRectangle1stClickSnippet:
|
||||||
'startProfileAt([205.96, 254.59], sketch002)',
|
'startProfileAt([205.96, 254.59], sketch002)',
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0,11.39],%,$rectangleSegmentA002)
|
afterRectangle2ndClickSnippet: `angledLine(angle=0,length=11.39,tag=$rectangleSegmentA002)
|
||||||
|>angledLine([segAng(rectangleSegmentA002)-90,105.26],%)
|
|>angledLine(angle=segAng(rectangleSegmentA002)-90,length=105.26)
|
||||||
|>angledLine([segAng(rectangleSegmentA002),-segLen(rectangleSegmentA002)],%)
|
|>angledLine(angle=segAng(rectangleSegmentA002),length=-segLen(rectangleSegmentA002))
|
||||||
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|>close()`,
|
|>close()`,
|
||||||
})
|
})
|
||||||
@ -234,10 +234,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
clickCoords: { x: 690, y: 250 },
|
clickCoords: { x: 690, y: 250 },
|
||||||
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
||||||
cameraTarget: { x: -150, y: -4500, z: -80 },
|
cameraTarget: { x: -150, y: -4500, z: -80 },
|
||||||
beforeChamferSnippet: `angledLine([
|
beforeChamferSnippet: `angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)chamfer(
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|
||||||
217.26
|
|
||||||
], %, $seg01)chamfer(
|
|
||||||
length = 30,
|
length = 30,
|
||||||
tags = [
|
tags = [
|
||||||
seg01,
|
seg01,
|
||||||
@ -250,9 +247,9 @@ test.describe('Point-and-click tests', () => {
|
|||||||
'sketch003 = startSketchOn(extrude001, seg04)',
|
'sketch003 = startSketchOn(extrude001, seg04)',
|
||||||
afterRectangle1stClickSnippet:
|
afterRectangle1stClickSnippet:
|
||||||
'startProfileAt([-209.64, 255.28], sketch003)',
|
'startProfileAt([-209.64, 255.28], sketch003)',
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0,11.56],%,$rectangleSegmentA003)
|
afterRectangle2ndClickSnippet: `angledLine(angle=0,length=11.56,tag=$rectangleSegmentA003)
|
||||||
|>angledLine([segAng(rectangleSegmentA003)-90,106.84],%)
|
|>angledLine(angle=segAng(rectangleSegmentA003)-90,length=106.84)
|
||||||
|>angledLine([segAng(rectangleSegmentA003),-segLen(rectangleSegmentA003)],%)
|
|>angledLine(angle=segAng(rectangleSegmentA003),length=-segLen(rectangleSegmentA003))
|
||||||
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|>close()`,
|
|>close()`,
|
||||||
})
|
})
|
||||||
@ -261,7 +258,7 @@ test.describe('Point-and-click tests', () => {
|
|||||||
clickCoords: { x: 677, y: 87 },
|
clickCoords: { x: 677, y: 87 },
|
||||||
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
cameraPos: { x: -6200, y: 1500, z: 6200 },
|
||||||
cameraTarget: { x: 8300, y: 1100, z: 4800 },
|
cameraTarget: { x: 8300, y: 1100, z: 4800 },
|
||||||
beforeChamferSnippet: `angledLine([0, 268.43], %, $rectangleSegmentA001)chamfer(
|
beforeChamferSnippet: `angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)chamfer(
|
||||||
length = 30,
|
length = 30,
|
||||||
tags = [
|
tags = [
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
@ -272,9 +269,9 @@ test.describe('Point-and-click tests', () => {
|
|||||||
'sketch004 = startSketchOn(extrude001, seg05)',
|
'sketch004 = startSketchOn(extrude001, seg05)',
|
||||||
afterRectangle1stClickSnippet:
|
afterRectangle1stClickSnippet:
|
||||||
'startProfileAt([82.57, 322.96], sketch004)',
|
'startProfileAt([82.57, 322.96], sketch004)',
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0,11.16],%,$rectangleSegmentA004)
|
afterRectangle2ndClickSnippet: `angledLine(angle=0,length=11.16,tag=$rectangleSegmentA004)
|
||||||
|>angledLine([segAng(rectangleSegmentA004)-90,103.07],%)
|
|>angledLine(angle=segAng(rectangleSegmentA004)-90,length=103.07)
|
||||||
|>angledLine([segAng(rectangleSegmentA004),-segLen(rectangleSegmentA004)],%)
|
|>angledLine(angle=segAng(rectangleSegmentA004),length=-segLen(rectangleSegmentA004))
|
||||||
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|>close()`,
|
|>close()`,
|
||||||
})
|
})
|
||||||
@ -290,9 +287,9 @@ test.describe('Point-and-click tests', () => {
|
|||||||
'sketch005 = startSketchOn(extrude001, seg06)',
|
'sketch005 = startSketchOn(extrude001, seg06)',
|
||||||
afterRectangle1stClickSnippet:
|
afterRectangle1stClickSnippet:
|
||||||
'startProfileAt([-23.43, 19.69], sketch005)',
|
'startProfileAt([-23.43, 19.69], sketch005)',
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0,9.1],%,$rectangleSegmentA005)
|
afterRectangle2ndClickSnippet: `angledLine(angle=0,length=9.1,tag=$rectangleSegmentA005)
|
||||||
|>angledLine([segAng(rectangleSegmentA005)-90,84.07],%)
|
|>angledLine(angle=segAng(rectangleSegmentA005)-90,length=84.07)
|
||||||
|>angledLine([segAng(rectangleSegmentA005),-segLen(rectangleSegmentA005)],%)
|
|>angledLine(angle=segAng(rectangleSegmentA005),length=-segLen(rectangleSegmentA005))
|
||||||
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|>close()`,
|
|>close()`,
|
||||||
})
|
})
|
||||||
@ -302,15 +299,9 @@ test.describe('Point-and-click tests', () => {
|
|||||||
`@settings(defaultLengthUnit = in)
|
`@settings(defaultLengthUnit = in)
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag]
|
|> startProfileAt([75.8, 317.2], %) // [$startCapTag, $EndCapTag]
|
||||||
|> angledLine([0, 268.43], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||||
217.26
|
|
||||||
], %, $seg01)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $yo)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
|> close()
|
|> close()
|
||||||
extrude001 = extrude(sketch001, length = 100)
|
extrude001 = extrude(sketch001, length = 100)
|
||||||
@ -320,48 +311,30 @@ extrude001 = extrude(sketch001, length = 100)
|
|||||||
|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06)
|
|> chamfer(length = 30, tags = [getNextAdjacentEdge(yo)], tag = $seg06)
|
||||||
sketch005 = startSketchOn(extrude001, seg06)
|
sketch005 = startSketchOn(extrude001, seg06)
|
||||||
profile004=startProfileAt([-23.43,19.69], sketch005)
|
profile004=startProfileAt([-23.43,19.69], sketch005)
|
||||||
|> angledLine([0, 9.1], %, $rectangleSegmentA005)
|
|> angledLine(angle = 0, length = 9.1, tag = $rectangleSegmentA005)
|
||||||
|> angledLine([segAng(rectangleSegmentA005) - 90, 84.07], %)
|
|> angledLine(angle = segAng(rectangleSegmentA005) - 90, length = 84.07)
|
||||||
|> angledLine([segAng(rectangleSegmentA005), -segLen(rectangleSegmentA005)], %)
|
|> angledLine(angle = segAng(rectangleSegmentA005), length = -segLen(rectangleSegmentA005))
|
||||||
|> line(endAbsolute=[profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute=[profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch004 = startSketchOn(extrude001, seg05)
|
sketch004 = startSketchOn(extrude001, seg05)
|
||||||
profile003 = startProfileAt([82.57, 322.96], sketch004)
|
profile003 = startProfileAt([82.57, 322.96], sketch004)
|
||||||
|> angledLine([0, 11.16], %, $rectangleSegmentA004)
|
|> angledLine(angle = 0, length = 11.16, tag = $rectangleSegmentA004)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA004) - 90, length = 103.07)
|
||||||
segAng(rectangleSegmentA004) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA004), length = -segLen(rectangleSegmentA004))
|
||||||
103.07
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA004),
|
|
||||||
-segLen(rectangleSegmentA004)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch003 = startSketchOn(extrude001, seg04)
|
sketch003 = startSketchOn(extrude001, seg04)
|
||||||
profile002 = startProfileAt([-209.64, 255.28], sketch003)
|
profile002 = startProfileAt([-209.64, 255.28], sketch003)
|
||||||
|> angledLine([0, 11.56], %, $rectangleSegmentA003)
|
|> angledLine(angle = 0, length = 11.56, tag = $rectangleSegmentA003)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA003) - 90, length = 106.84)
|
||||||
segAng(rectangleSegmentA003) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA003), length = -segLen(rectangleSegmentA003))
|
||||||
106.84
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA003),
|
|
||||||
-segLen(rectangleSegmentA003)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch002 = startSketchOn(extrude001, seg03)
|
sketch002 = startSketchOn(extrude001, seg03)
|
||||||
profile001 = startProfileAt([205.96, 254.59], sketch002)
|
profile001 = startProfileAt([205.96, 254.59], sketch002)
|
||||||
|> angledLine([0, 11.39], %, $rectangleSegmentA002)
|
|> angledLine(angle = 0, length = 11.39, tag = $rectangleSegmentA002)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
||||||
segAng(rectangleSegmentA002) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
105.26
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA002),
|
|
||||||
-segLen(rectangleSegmentA002)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
`,
|
`,
|
||||||
@ -377,6 +350,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
|||||||
editor,
|
editor,
|
||||||
toolbar,
|
toolbar,
|
||||||
scene,
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const file = await fs.readFile(
|
const file = await fs.readFile(
|
||||||
path.resolve(
|
path.resolve(
|
||||||
@ -392,7 +366,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
|||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene)
|
const sketchOnAChamfer = _sketchOnAChamfer(page, editor, toolbar, scene)
|
||||||
|
|
||||||
@ -400,7 +374,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
|||||||
clickCoords: { x: 570, y: 220 },
|
clickCoords: { x: 570, y: 220 },
|
||||||
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
cameraPos: { x: 16020, y: -2000, z: 10500 },
|
||||||
cameraTarget: { x: -150, y: -4500, z: -80 },
|
cameraTarget: { x: -150, y: -4500, z: -80 },
|
||||||
beforeChamferSnippet: `angledLine([segAng(rectangleSegmentA001)-90,217.26],%,$seg01)
|
beforeChamferSnippet: `angledLine(angle=segAng(rectangleSegmentA001)-90,length=217.26,tag=$seg01)
|
||||||
chamfer(extrude001,length=30,tags=[
|
chamfer(extrude001,length=30,tags=[
|
||||||
seg01,
|
seg01,
|
||||||
getNextAdjacentEdge(yo),
|
getNextAdjacentEdge(yo),
|
||||||
@ -412,9 +386,9 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
|||||||
'sketch002 = startSketchOn(extrude001, seg03)',
|
'sketch002 = startSketchOn(extrude001, seg03)',
|
||||||
afterRectangle1stClickSnippet:
|
afterRectangle1stClickSnippet:
|
||||||
'startProfileAt([205.96, 254.59], sketch002)',
|
'startProfileAt([205.96, 254.59], sketch002)',
|
||||||
afterRectangle2ndClickSnippet: `angledLine([0,11.39],%,$rectangleSegmentA002)
|
afterRectangle2ndClickSnippet: `angledLine(angle=0,length=11.39,tag=$rectangleSegmentA002)
|
||||||
|>angledLine([segAng(rectangleSegmentA002)-90,105.26],%)
|
|>angledLine(angle=segAng(rectangleSegmentA002)-90,length=105.26)
|
||||||
|>angledLine([segAng(rectangleSegmentA002),-segLen(rectangleSegmentA002)],%)
|
|>angledLine(angle=segAng(rectangleSegmentA002),length=-segLen(rectangleSegmentA002))
|
||||||
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
|>line(endAbsolute=[profileStartX(%),profileStartY(%)])
|
||||||
|>close()`,
|
|>close()`,
|
||||||
})
|
})
|
||||||
@ -422,15 +396,9 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
|||||||
`@settings(defaultLengthUnit = in)
|
`@settings(defaultLengthUnit = in)
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([75.8, 317.2], %)
|
|> startProfileAt([75.8, 317.2], %)
|
||||||
|> angledLine([0, 268.43], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 268.43, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 217.26, tag = $seg01)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $yo)
|
||||||
217.26
|
|
||||||
], %, $seg01)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $yo)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
||||||
|> close()
|
|> close()
|
||||||
extrude001 = extrude(sketch001, length = 100)
|
extrude001 = extrude(sketch001, length = 100)
|
||||||
@ -450,15 +418,9 @@ chamf = chamfer(
|
|||||||
)
|
)
|
||||||
sketch002 = startSketchOn(extrude001, seg03)
|
sketch002 = startSketchOn(extrude001, seg03)
|
||||||
profile001 = startProfileAt([205.96, 254.59], sketch002)
|
profile001 = startProfileAt([205.96, 254.59], sketch002)
|
||||||
|> angledLine([0, 11.39], %, $rectangleSegmentA002)
|
|> angledLine(angle = 0, length = 11.39, tag = $rectangleSegmentA002)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA002) - 90, length = 105.26)
|
||||||
segAng(rectangleSegmentA002) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA002), length = -segLen(rectangleSegmentA002))
|
||||||
105.26
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA002),
|
|
||||||
-segLen(rectangleSegmentA002)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
`,
|
`,
|
||||||
@ -479,6 +441,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
|||||||
await page.setBodyDimensions(viewPortSize)
|
await page.setBodyDimensions(viewPortSize)
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// Constants and locators
|
// Constants and locators
|
||||||
// These are mappings from screenspace to KCL coordinates,
|
// These are mappings from screenspace to KCL coordinates,
|
||||||
@ -537,8 +500,7 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
|||||||
await toolbar.startSketchPlaneSelection()
|
await toolbar.startSketchPlaneSelection()
|
||||||
await moveToXzPlane()
|
await moveToXzPlane()
|
||||||
await clickOnXzPlane()
|
await clickOnXzPlane()
|
||||||
// timeout wait for engine animation is unavoidable
|
await toolbar.waitUntilSketchingReady()
|
||||||
await page.waitForTimeout(600)
|
|
||||||
await editor.expectEditor.toContain(expectedCodeSnippets.sketchOnXzPlane)
|
await editor.expectEditor.toContain(expectedCodeSnippets.sketchOnXzPlane)
|
||||||
})
|
})
|
||||||
await test.step(`Place a point a few pixels off the middle, verify it still snaps to 0,0`, async () => {
|
await test.step(`Place a point a few pixels off the middle, verify it still snaps to 0,0`, async () => {
|
||||||
@ -580,9 +542,8 @@ profile001 = startProfileAt([205.96, 254.59], sketch002)
|
|||||||
editor,
|
editor,
|
||||||
toolbar,
|
toolbar,
|
||||||
scene,
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
|
||||||
|
|
||||||
const initialCode = `closedSketch = startSketchOn(XZ)
|
const initialCode = `closedSketch = startSketchOn(XZ)
|
||||||
|> circle(center = [8, 5], radius = 2)
|
|> circle(center = [8, 5], radius = 2)
|
||||||
openSketch = startSketchOn(XY)
|
openSketch = startSketchOn(XY)
|
||||||
@ -599,8 +560,6 @@ openSketch = startSketchOn(XY)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
|
|
||||||
const pointInsideCircle = {
|
const pointInsideCircle = {
|
||||||
x: viewPortSize.width * 0.63,
|
x: viewPortSize.width * 0.63,
|
||||||
@ -625,15 +584,16 @@ openSketch = startSketchOn(XY)
|
|||||||
const exitSketch = async () => {
|
const exitSketch = async () => {
|
||||||
await test.step(`Exit sketch mode`, async () => {
|
await test.step(`Exit sketch mode`, async () => {
|
||||||
await toolbar.exitSketchBtn.click()
|
await toolbar.exitSketchBtn.click()
|
||||||
await expect(toolbar.exitSketchBtn).not.toBeVisible()
|
|
||||||
await expect(toolbar.startSketchBtn).toBeEnabled()
|
await expect(toolbar.startSketchBtn).toBeEnabled()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await test.step(`Double-click on the closed sketch`, async () => {
|
await test.step(`Double-click on the closed sketch`, async () => {
|
||||||
|
await scene.settled(cmdBar)
|
||||||
await moveToCircle()
|
await moveToCircle()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await dblClickCircle()
|
await dblClickCircle()
|
||||||
await expect(toolbar.startSketchBtn).not.toBeVisible()
|
await page.waitForTimeout(1000)
|
||||||
await expect(toolbar.exitSketchBtn).toBeVisible()
|
await expect(toolbar.exitSketchBtn).toBeVisible()
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
activeLines: [`|>circle(center=[8,5],radius=2)`],
|
activeLines: [`|>circle(center=[8,5],radius=2)`],
|
||||||
@ -670,7 +630,6 @@ openSketch = startSketchOn(XY)
|
|||||||
// There is a full execution after exiting sketch that clears the scene.
|
// There is a full execution after exiting sketch that clears the scene.
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await dblClickOpenPath()
|
await dblClickOpenPath()
|
||||||
await expect(toolbar.startSketchBtn).not.toBeVisible()
|
|
||||||
await expect(toolbar.exitSketchBtn).toBeVisible()
|
await expect(toolbar.exitSketchBtn).toBeVisible()
|
||||||
// Wait for enter sketch mode to complete
|
// Wait for enter sketch mode to complete
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
@ -1031,6 +990,9 @@ openSketch = startSketchOn(XY)
|
|||||||
})
|
})
|
||||||
await test.step(`Go through the command bar flow`, async () => {
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
await toolbar.offsetPlaneButton.click()
|
await toolbar.offsetPlaneButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'plane',
|
currentArgKey: 'plane',
|
||||||
@ -1088,6 +1050,7 @@ openSketch = startSketchOn(XY)
|
|||||||
const expectedLine = `axis=X,`
|
const expectedLine = `axis=X,`
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
await test.step(`Go through the command bar flow`, async () => {
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
await toolbar.helixButton.click()
|
await toolbar.helixButton.click()
|
||||||
@ -1106,6 +1069,7 @@ openSketch = startSketchOn(XY)
|
|||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await expect.poll(() => page.getByText('Axis').count()).toBe(6)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -1233,6 +1197,7 @@ openSketch = startSketchOn(XY)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
await test.step(`Go through the command bar flow`, async () => {
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
await toolbar.closePane('code')
|
await toolbar.closePane('code')
|
||||||
@ -1252,15 +1217,22 @@ openSketch = startSketchOn(XY)
|
|||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
await cmdBar.selectOption({ name: 'Edge' }).click()
|
await cmdBar.selectOption({ name: 'Edge' }).click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await clickOnEdge()
|
await clickOnEdge()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await cmdBar.argumentInput.focus()
|
await cmdBar.argumentInput.focus()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await page.keyboard.insertText('20')
|
await page.keyboard.insertText('20')
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.keyboard.insertText('0')
|
await page.keyboard.insertText('0')
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.keyboard.insertText('1')
|
await page.keyboard.insertText('1')
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.keyboard.insertText('100')
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
@ -1274,6 +1246,7 @@ openSketch = startSketchOn(XY)
|
|||||||
commandName: 'Helix',
|
commandName: 'Helix',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
@ -1369,7 +1342,7 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 620, y: 257 }
|
const testPoint = { x: 620, y: 257 }
|
||||||
@ -1530,6 +1503,9 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
if (!shouldPreselect) {
|
if (!shouldPreselect) {
|
||||||
await test.step(`Go through the command bar flow without preselected sketches`, async () => {
|
await test.step(`Go through the command bar flow without preselected sketches`, async () => {
|
||||||
await toolbar.loftButton.click()
|
await toolbar.loftButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'selection',
|
currentArgKey: 'selection',
|
||||||
@ -1579,6 +1555,7 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
scene,
|
scene,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||||
|> circle(center = [0, 0], radius = 30)
|
|> circle(center = [0, 0], radius = 30)
|
||||||
@ -1592,7 +1569,7 @@ loft001 = loft([sketch001, sketch002])
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 575, y: 200 }
|
const testPoint = { x: 575, y: 200 }
|
||||||
@ -1655,15 +1632,9 @@ sketch002 = startSketchOn(XZ)
|
|||||||
initialCode: `@settings(defaultLengthUnit = in)
|
initialCode: `@settings(defaultLengthUnit = in)
|
||||||
sketch001 = startSketchOn(YZ)
|
sketch001 = startSketchOn(YZ)
|
||||||
profile001 = startProfileAt([-400, -400], sketch001)
|
profile001 = startProfileAt([-400, -400], sketch001)
|
||||||
|> angledLine([0, 800], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 800, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) + 90, length = 800)
|
||||||
segAng(rectangleSegmentA001) + 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
||||||
800
|
|
||||||
], %)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
sketch002 = startSketchOn(XZ)
|
sketch002 = startSketchOn(XZ)
|
||||||
@ -1687,7 +1658,7 @@ sketch002 = startSketchOn(XZ)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const [clickOnSketch1] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
const [clickOnSketch1] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||||
@ -1707,6 +1678,9 @@ sketch002 = startSketchOn(XZ)
|
|||||||
|
|
||||||
await test.step(`Go through the command bar flow`, async () => {
|
await test.step(`Go through the command bar flow`, async () => {
|
||||||
await toolbar.sweepButton.click()
|
await toolbar.sweepButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
currentArgKey: 'target',
|
currentArgKey: 'target',
|
||||||
@ -1826,7 +1800,7 @@ sketch002 = startSketchOn(XZ)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 700, y: 250 }
|
const testPoint = { x: 700, y: 250 }
|
||||||
@ -1843,6 +1817,9 @@ sketch002 = startSketchOn(XZ)
|
|||||||
|
|
||||||
await test.step(`Go through the command bar flow and fail validation with a toast`, async () => {
|
await test.step(`Go through the command bar flow and fail validation with a toast`, async () => {
|
||||||
await toolbar.sweepButton.click()
|
await toolbar.sweepButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Sweep',
|
commandName: 'Sweep',
|
||||||
currentArgKey: 'target',
|
currentArgKey: 'target',
|
||||||
@ -2059,6 +2036,9 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
await test.step(`Open fillet UI without selecting edges`, async () => {
|
await test.step(`Open fillet UI without selecting edges`, async () => {
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await toolbar.filletButton.click()
|
await toolbar.filletButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'selection',
|
currentArgKey: 'selection',
|
||||||
@ -2184,6 +2164,7 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
homePage,
|
homePage,
|
||||||
scene,
|
scene,
|
||||||
toolbar,
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const initialCode = `sketch001 = startSketchOn(XY)
|
const initialCode = `sketch001 = startSketchOn(XY)
|
||||||
profile001 = circle(
|
profile001 = circle(
|
||||||
@ -2200,7 +2181,7 @@ fillet001 = fillet(extrude001, radius = 5, tags = [getOppositeEdge(seg01)])
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
await test.step('Double-click in feature tree and expect error toast', async () => {
|
await test.step('Double-click in feature tree and expect error toast', async () => {
|
||||||
await toolbar.openPane('feature-tree')
|
await toolbar.openPane('feature-tree')
|
||||||
@ -2521,7 +2502,7 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Test 1: Command bar flow with preselected edges
|
// Test 1: Command bar flow with preselected edges
|
||||||
@ -2554,6 +2535,7 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Chamfer',
|
commandName: 'Chamfer',
|
||||||
highlightedHeaderArg: 'length',
|
highlightedHeaderArg: 'length',
|
||||||
@ -2565,7 +2547,10 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
},
|
},
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
})
|
})
|
||||||
|
await cmdBar.argumentInput.focus()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
commandName: 'Chamfer',
|
commandName: 'Chamfer',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
@ -2649,6 +2634,9 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
await test.step(`Open chamfer UI without selecting edges`, async () => {
|
await test.step(`Open chamfer UI without selecting edges`, async () => {
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await toolbar.chamferButton.click()
|
await toolbar.chamferButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'selection',
|
currentArgKey: 'selection',
|
||||||
@ -2771,6 +2759,7 @@ extrude001 = extrude(sketch001, length = -12)
|
|||||||
scene,
|
scene,
|
||||||
editor,
|
editor,
|
||||||
toolbar,
|
toolbar,
|
||||||
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
// Code samples
|
// Code samples
|
||||||
const initialCode = `@settings(defaultLengthUnit = in)
|
const initialCode = `@settings(defaultLengthUnit = in)
|
||||||
@ -2814,7 +2803,7 @@ chamfer04 = chamfer(extrude001, length = 5, tags = [getOppositeEdge(seg02)])
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// verify modeling scene is loaded
|
// verify modeling scene is loaded
|
||||||
await scene.expectPixelColor(
|
await scene.expectPixelColor(
|
||||||
@ -2936,9 +2925,11 @@ extrude001 = extrude(sketch001, length = 30)
|
|||||||
await context.addInitScript((initialCode) => {
|
await context.addInitScript((initialCode) => {
|
||||||
localStorage.setItem('persistCode', initialCode)
|
localStorage.setItem('persistCode', initialCode)
|
||||||
}, initialCode)
|
}, initialCode)
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 575, y: 200 }
|
const testPoint = { x: 575, y: 200 }
|
||||||
@ -2955,6 +2946,9 @@ extrude001 = extrude(sketch001, length = 30)
|
|||||||
if (!shouldPreselect) {
|
if (!shouldPreselect) {
|
||||||
await test.step(`Go through the command bar flow without preselected faces`, async () => {
|
await test.step(`Go through the command bar flow without preselected faces`, async () => {
|
||||||
await toolbar.shellButton.click()
|
await toolbar.shellButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'selection',
|
currentArgKey: 'selection',
|
||||||
@ -3015,7 +3009,6 @@ extrude001 = extrude(sketch001, length = 30)
|
|||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Edit shell via feature tree selection works', async () => {
|
await test.step('Edit shell via feature tree selection works', async () => {
|
||||||
await toolbar.closePane('code')
|
|
||||||
await toolbar.openPane('feature-tree')
|
await toolbar.openPane('feature-tree')
|
||||||
const operationButton = await toolbar.getFeatureTreeOperation(
|
const operationButton = await toolbar.getFeatureTreeOperation(
|
||||||
'Shell',
|
'Shell',
|
||||||
@ -3044,7 +3037,6 @@ extrude001 = extrude(sketch001, length = 30)
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await scene.expectPixelColor([150, 150, 150], testPoint, 15)
|
await scene.expectPixelColor([150, 150, 150], testPoint, 15)
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(editedShellDeclaration)
|
await editor.expectEditor.toContain(editedShellDeclaration)
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
@ -3079,7 +3071,7 @@ extrude001 = extrude(sketch001, length = 40)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 580, y: 180 }
|
const testPoint = { x: 580, y: 180 }
|
||||||
@ -3097,6 +3089,9 @@ extrude001 = extrude(sketch001, length = 40)
|
|||||||
|
|
||||||
await test.step(`Go through the command bar flow, selecting a wall and keeping default thickness`, async () => {
|
await test.step(`Go through the command bar flow, selecting a wall and keeping default thickness`, async () => {
|
||||||
await toolbar.shellButton.click()
|
await toolbar.shellButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'selection',
|
currentArgKey: 'selection',
|
||||||
@ -3108,6 +3103,9 @@ extrude001 = extrude(sketch001, length = 40)
|
|||||||
highlightedHeaderArg: 'selection',
|
highlightedHeaderArg: 'selection',
|
||||||
commandName: 'Shell',
|
commandName: 'Shell',
|
||||||
})
|
})
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await clickOnCap()
|
await clickOnCap()
|
||||||
await page.keyboard.down('Shift')
|
await page.keyboard.down('Shift')
|
||||||
await clickOnWall()
|
await clickOnWall()
|
||||||
@ -3116,6 +3114,7 @@ extrude001 = extrude(sketch001, length = 40)
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
@ -3124,7 +3123,9 @@ extrude001 = extrude(sketch001, length = 40)
|
|||||||
},
|
},
|
||||||
commandName: 'Shell',
|
commandName: 'Shell',
|
||||||
})
|
})
|
||||||
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(500)
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
await test.step(`Confirm code is added to the editor, scene has changed`, async () => {
|
||||||
@ -3139,7 +3140,6 @@ extrude001 = extrude(sketch001, length = 40)
|
|||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Edit shell via feature tree selection works', async () => {
|
await test.step('Edit shell via feature tree selection works', async () => {
|
||||||
await editor.closePane()
|
|
||||||
const operationButton = await toolbar.getFeatureTreeOperation('Shell', 0)
|
const operationButton = await toolbar.getFeatureTreeOperation('Shell', 0)
|
||||||
await operationButton.dblclick({ button: 'left' })
|
await operationButton.dblclick({ button: 'left' })
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
@ -3154,6 +3154,7 @@ extrude001 = extrude(sketch001, length = 40)
|
|||||||
})
|
})
|
||||||
await page.keyboard.insertText('1')
|
await page.keyboard.insertText('1')
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await page.waitForTimeout(500)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
@ -3164,7 +3165,6 @@ extrude001 = extrude(sketch001, length = 40)
|
|||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await scene.expectPixelColor([150, 150, 150], testPoint, 15)
|
await scene.expectPixelColor([150, 150, 150], testPoint, 15)
|
||||||
await toolbar.openPane('code')
|
|
||||||
await editor.expectEditor.toContain(editedShellDeclaration)
|
await editor.expectEditor.toContain(editedShellDeclaration)
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
diagnostics: [],
|
diagnostics: [],
|
||||||
@ -3218,7 +3218,7 @@ extrude002 = extrude(sketch002, length = 50)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 580, y: 320 }
|
const testPoint = { x: 580, y: 320 }
|
||||||
@ -3243,12 +3243,13 @@ extrude002 = extrude(sketch002, length = 50)
|
|||||||
highlightedHeaderArg: 'selection',
|
highlightedHeaderArg: 'selection',
|
||||||
commandName: 'Shell',
|
commandName: 'Shell',
|
||||||
})
|
})
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await clickOnCap()
|
await clickOnCap()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(1000)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.waitForTimeout(500)
|
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await page.waitForTimeout(500)
|
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'review',
|
stage: 'review',
|
||||||
headerArguments: {
|
headerArguments: {
|
||||||
@ -3306,7 +3307,7 @@ profile001 = startProfileAt([-20, 20], sketch001)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
await toolbar.openPane('feature-tree')
|
await toolbar.openPane('feature-tree')
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
@ -3386,7 +3387,7 @@ sweep001 = sweep(sketch001, path = sketch002)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 500, y: 250 }
|
const testPoint = { x: 500, y: 250 }
|
||||||
@ -3399,6 +3400,9 @@ sweep001 = sweep(sketch001, path = sketch002)
|
|||||||
|
|
||||||
await test.step(`Go through the Shell flow and fail validation with a toast`, async () => {
|
await test.step(`Go through the Shell flow and fail validation with a toast`, async () => {
|
||||||
await toolbar.shellButton.click()
|
await toolbar.shellButton.click()
|
||||||
|
await expect
|
||||||
|
.poll(() => page.getByText('Please select one').count())
|
||||||
|
.toBe(1)
|
||||||
await cmdBar.expectState({
|
await cmdBar.expectState({
|
||||||
stage: 'arguments',
|
stage: 'arguments',
|
||||||
currentArgKey: 'selection',
|
currentArgKey: 'selection',
|
||||||
@ -3433,26 +3437,29 @@ sweep001 = sweep(sketch001, path = sketch002)
|
|||||||
const initialCode = `
|
const initialCode = `
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([-100.0, 100.0], %)
|
|> startProfileAt([-100.0, 100.0], %)
|
||||||
|> angledLine([0, 200.0], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 200.0, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([segAng(rectangleSegmentA001) - 90, 200], %, $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 200, tag = $rectangleSegmentB001)
|
||||||
|> angledLine([
|
|> angledLine(
|
||||||
segAng(rectangleSegmentA001),
|
angle=segAng(rectangleSegmentA001),
|
||||||
-segLen(rectangleSegmentA001)
|
length=-segLen(rectangleSegmentA001),
|
||||||
], %, $rectangleSegmentC001)
|
tag=$rectangleSegmentC001,
|
||||||
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude001 = extrude(sketch001, length = 200)
|
extrude001 = extrude(sketch001, length = 200)
|
||||||
sketch002 = startSketchOn(extrude001, rectangleSegmentA001)
|
sketch002 = startSketchOn(extrude001, rectangleSegmentA001)
|
||||||
|> startProfileAt([-66.77, 84.81], %)
|
|> startProfileAt([-66.77, 84.81], %)
|
||||||
|> angledLine([180, 27.08], %, $rectangleSegmentA002)
|
|> angledLine(angle = 180, length = 27.08, tag = $rectangleSegmentA002)
|
||||||
|> angledLine([
|
|> angledLine(
|
||||||
segAng(rectangleSegmentA002) - 90,
|
angle=segAng(rectangleSegmentA002) - 90,
|
||||||
27.8
|
length=27.8,
|
||||||
], %, $rectangleSegmentB002)
|
tag=$rectangleSegmentB002,
|
||||||
|> angledLine([
|
)
|
||||||
segAng(rectangleSegmentA002),
|
|> angledLine(
|
||||||
-segLen(rectangleSegmentA002)
|
angle=segAng(rectangleSegmentA002),
|
||||||
], %, $rectangleSegmentC002)
|
length=-segLen(rectangleSegmentA002),
|
||||||
|
tag=$rectangleSegmentC002,
|
||||||
|
)
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
`
|
`
|
||||||
@ -3462,12 +3469,13 @@ segAng(rectangleSegmentA002),
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// select line of code
|
// select line of code
|
||||||
const codeToSelecton = `segAng(rectangleSegmentA002) - 90,`
|
const codeToSelection = `segAng(rectangleSegmentA002) - 90,`
|
||||||
// revolve
|
// revolve
|
||||||
await page.getByText(codeToSelecton).click()
|
await editor.scrollToText(codeToSelection)
|
||||||
|
await page.getByText(codeToSelection).click()
|
||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -3521,35 +3529,32 @@ segAng(rectangleSegmentA002),
|
|||||||
}) => {
|
}) => {
|
||||||
const initialCode = `sketch001 = startSketchOn(XZ)
|
const initialCode = `sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([-102.57, 101.72], %)
|
|> startProfileAt([-102.57, 101.72], %)
|
||||||
|> angledLine([0, 202.6], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 202.6, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 202.6, tag = $rectangleSegmentB001)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
202.6
|
|
||||||
], %, $rectangleSegmentB001)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude001 = extrude(sketch001, length = 50)
|
extrude001 = extrude(sketch001, length = 50)
|
||||||
sketch002 = startSketchOn(extrude001, rectangleSegmentA001)
|
sketch002 = startSketchOn(extrude001, rectangleSegmentA001)
|
||||||
|> circle(center = [-11.34, 10.0], radius = 8.69)
|
|> circle(center = [-11.34, 10.0], radius = 8.69)
|
||||||
|
|
||||||
`
|
`
|
||||||
await context.addInitScript((initialCode) => {
|
await context.addInitScript((initialCode) => {
|
||||||
localStorage.setItem('persistCode', initialCode)
|
localStorage.setItem('persistCode', initialCode)
|
||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// select line of code
|
// select line of code
|
||||||
const codeToSelecton = `center = [-11.34, 10.0]`
|
const codeToSelection = `center = [-11.34, 10.0]`
|
||||||
// revolve
|
// revolve
|
||||||
await page.getByText(codeToSelecton).click()
|
await editor.scrollToText(codeToSelection)
|
||||||
|
await page.getByText(codeToSelection).click()
|
||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
await page.getByText('Edge', { exact: true }).click()
|
await page.getByText('Edge', { exact: true }).click()
|
||||||
const lineCodeToSelection = `|> angledLine([0, 202.6], %, $rectangleSegmentA001)`
|
const lineCodeToSelection = `angledLine(angle = 0, length = 202.6, tag = $rectangleSegmentA001)`
|
||||||
await page.getByText(lineCodeToSelection).click()
|
await page.getByText(lineCodeToSelection).click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -3595,6 +3600,7 @@ sketch002 = startSketchOn(extrude001, rectangleSegmentA001)
|
|||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
newCodeToFind.replace('angle = 360', 'angle = angle001')
|
newCodeToFind.replace('angle = 360', 'angle = angle001')
|
||||||
)
|
)
|
||||||
|
expect(editor.expectEditor.toContain(newCodeToFind)).toBeTruthy()
|
||||||
})
|
})
|
||||||
test('revolve sketch circle around line segment from startProfileAt sketch', async ({
|
test('revolve sketch circle around line segment from startProfileAt sketch', async ({
|
||||||
context,
|
context,
|
||||||
@ -3605,22 +3611,23 @@ sketch002 = startSketchOn(extrude001, rectangleSegmentA001)
|
|||||||
toolbar,
|
toolbar,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
}) => {
|
}) => {
|
||||||
const initialCode = `sketch002 = startSketchOn(XY)
|
const initialCode = `
|
||||||
|
sketch002 = startSketchOn(XY)
|
||||||
|> startProfileAt([-2.02, 1.79], %)
|
|> startProfileAt([-2.02, 1.79], %)
|
||||||
|> xLine(length = 2.6)
|
|> xLine(length = 2.6)
|
||||||
sketch001 = startSketchOn(-XY)
|
sketch001 = startSketchOn('-XY')
|
||||||
|> startProfileAt([-0.48, 1.25], %)
|
|> startProfileAt([-0.48, 1.25], %)
|
||||||
|> angledLine([0, 2.38], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 2.38, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([segAng(rectangleSegmentA001) - 90, 2.4], %, $rectangleSegmentB001)
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 2.4, tag = $rectangleSegmentB001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude001 = extrude(sketch001, length = 5)
|
extrude001 = extrude(sketch001, length = 5)
|
||||||
sketch003 = startSketchOn(extrude001, 'START')
|
sketch003 = startSketchOn(extrude001, 'START')
|
||||||
|> circle(center = [-0.69, 0.56], radius = 0.28)
|
|> circle(
|
||||||
|
center = [-0.69, 0.56],
|
||||||
|
radius = 0.28
|
||||||
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
await context.addInitScript((initialCode) => {
|
await context.addInitScript((initialCode) => {
|
||||||
@ -3628,15 +3635,20 @@ sketch003 = startSketchOn(extrude001, 'START')
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.connectionEstablished()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// select line of code
|
// select line of code
|
||||||
const codeToSelecton = `center = [-0.69, 0.56]`
|
const codeToSelection = `center = [-0.69, 0.56]`
|
||||||
// revolve
|
// revolve
|
||||||
await page.getByText(codeToSelecton).click()
|
|
||||||
await toolbar.revolveButton.click()
|
await toolbar.revolveButton.click()
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
await editor.scrollToText(codeToSelection)
|
||||||
|
await page.getByText(codeToSelection).click()
|
||||||
|
await expect.poll(() => page.getByText('AxisOrEdge').count()).toBe(2)
|
||||||
await page.getByText('Edge', { exact: true }).click()
|
await page.getByText('Edge', { exact: true }).click()
|
||||||
const lineCodeToSelection = `|> xLine(length = 2.6)`
|
const lineCodeToSelection = `length = 2.6`
|
||||||
|
await editor.scrollToText(lineCodeToSelection)
|
||||||
await page.getByText(lineCodeToSelection).click()
|
await page.getByText(lineCodeToSelection).click()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
@ -3703,21 +3715,22 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
}, initialCode)
|
}, initialCode)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// One dumb hardcoded screen pixel value
|
// One dumb hardcoded screen pixel value
|
||||||
const testPoint = { x: 500, y: 250 }
|
const testPoint = { x: 500, y: 250 }
|
||||||
const initialColor: [number, number, number] = [123, 123, 123]
|
const initialColor: [number, number, number] = [123, 123, 123]
|
||||||
|
const tolerance = 50
|
||||||
|
|
||||||
await test.step(`Confirm extrude exists with default appearance`, async () => {
|
await test.step(`Confirm extrude exists with default appearance`, async () => {
|
||||||
await toolbar.closePane('code')
|
await toolbar.closePane('code')
|
||||||
await scene.expectPixelColor(initialColor, testPoint, 15)
|
await scene.expectPixelColor(initialColor, testPoint, tolerance)
|
||||||
})
|
})
|
||||||
|
|
||||||
async function setApperanceAndCheck(
|
async function setApperanceAndCheck(
|
||||||
option: string,
|
option: string,
|
||||||
hex: string,
|
hex: string,
|
||||||
shapeColor: [number, number, number]
|
shapeColor?: [number, number, number]
|
||||||
) {
|
) {
|
||||||
await toolbar.openPane('feature-tree')
|
await toolbar.openPane('feature-tree')
|
||||||
const enterAppearanceFlow = async (stepName: string) =>
|
const enterAppearanceFlow = async (stepName: string) =>
|
||||||
@ -3766,7 +3779,9 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
})
|
})
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
await toolbar.closePane('feature-tree')
|
await toolbar.closePane('feature-tree')
|
||||||
await scene.expectPixelColor(shapeColor, testPoint, 10)
|
if (shapeColor) {
|
||||||
|
await scene.expectPixelColor(shapeColor, testPoint, tolerance)
|
||||||
|
}
|
||||||
await toolbar.openPane('code')
|
await toolbar.openPane('code')
|
||||||
if (hex === 'default') {
|
if (hex === 'default') {
|
||||||
const anyAppearanceDeclaration = `|> appearance(`
|
const anyAppearanceDeclaration = `|> appearance(`
|
||||||
@ -3785,16 +3800,17 @@ extrude001 = extrude(profile001, length = 100)
|
|||||||
}
|
}
|
||||||
|
|
||||||
await test.step(`Go through the Set Appearance flow for all options`, async () => {
|
await test.step(`Go through the Set Appearance flow for all options`, async () => {
|
||||||
await setApperanceAndCheck('Red', '#FF0000', [180, 0, 0])
|
await setApperanceAndCheck('Red', '#FF0000', [180, 30, 30])
|
||||||
await setApperanceAndCheck('Green', '#00FF00', [0, 180, 0])
|
// Not checking the scene color every time cause that's not really deterministic. Red seems reliable though
|
||||||
await setApperanceAndCheck('Blue', '#0000FF', [0, 0, 180])
|
await setApperanceAndCheck('Green', '#00FF00')
|
||||||
await setApperanceAndCheck('Turquoise', '#00FFFF', [0, 180, 180])
|
await setApperanceAndCheck('Blue', '#0000FF')
|
||||||
await setApperanceAndCheck('Purple', '#FF00FF', [180, 0, 180])
|
await setApperanceAndCheck('Turquoise', '#00FFFF')
|
||||||
await setApperanceAndCheck('Yellow', '#FFFF00', [180, 180, 0])
|
await setApperanceAndCheck('Purple', '#FF00FF')
|
||||||
await setApperanceAndCheck('Black', '#000000', [0, 0, 0])
|
await setApperanceAndCheck('Yellow', '#FFFF00')
|
||||||
await setApperanceAndCheck('Dark Grey', '#080808', [0x33, 0x33, 0x33])
|
await setApperanceAndCheck('Black', '#000000')
|
||||||
await setApperanceAndCheck('Light Grey', '#D3D3D3', [176, 176, 176])
|
await setApperanceAndCheck('Dark Grey', '#080808')
|
||||||
await setApperanceAndCheck('White', '#FFFFFF', [184, 184, 184])
|
await setApperanceAndCheck('Light Grey', '#D3D3D3')
|
||||||
|
await setApperanceAndCheck('White', '#FFFFFF')
|
||||||
await setApperanceAndCheck(
|
await setApperanceAndCheck(
|
||||||
'Default (clear appearance)',
|
'Default (clear appearance)',
|
||||||
'default',
|
'default',
|
||||||
|
@ -83,7 +83,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'click help/keybindings from project page',
|
'click help/keybindings from project page',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ scene, cmdBar, context, page }, testInfo) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = path.join(dir, 'bracket')
|
const bracketDir = path.join(dir, 'bracket')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
@ -95,17 +95,11 @@ test(
|
|||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
page.on('console', console.log)
|
|
||||||
|
|
||||||
// expect to see the text bracket
|
// expect to see the text bracket
|
||||||
await expect(page.getByText('bracket')).toBeVisible()
|
await expect(page.getByText('bracket')).toBeVisible()
|
||||||
|
|
||||||
await page.getByText('bracket').click()
|
await page.getByText('bracket').click()
|
||||||
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
// click ? button
|
// click ? button
|
||||||
await page.getByTestId('help-button').click()
|
await page.getByTestId('help-button').click()
|
||||||
@ -120,7 +114,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'open a file in a project works and renders, open another file in different project with errors, it should clear the scene',
|
'open a file in a project works and renders, open another file in different project with errors, it should clear the scene',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page, editor }, testInfo) => {
|
async ({ scene, cmdBar, context, page, editor }, testInfo) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = path.join(dir, 'bracket')
|
const bracketDir = path.join(dir, 'bracket')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
@ -149,24 +143,7 @@ test(
|
|||||||
|
|
||||||
await page.getByText('bracket').click()
|
await page.getByText('bracket').click()
|
||||||
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
).toBeEnabled({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
// gray at this pixel means the stream has loaded in the most
|
|
||||||
// user way we can verify it (pixel color)
|
|
||||||
await expect
|
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [110, 110, 110]), {
|
|
||||||
timeout: 10_000,
|
|
||||||
})
|
|
||||||
.toBeLessThan(20)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
|
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
|
||||||
@ -209,7 +186,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'open a file in a project works and renders, open another file in different project that is empty, it should clear the scene',
|
'open a file in a project works and renders, open another file in different project that is empty, it should clear the scene',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ scene, cmdBar, context, page }, testInfo) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const bracketDir = path.join(dir, 'bracket')
|
const bracketDir = path.join(dir, 'bracket')
|
||||||
await fsp.mkdir(bracketDir, { recursive: true })
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
@ -235,24 +212,7 @@ test(
|
|||||||
|
|
||||||
await page.getByText('bracket').click()
|
await page.getByText('bracket').click()
|
||||||
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
).toBeEnabled({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
// gray at this pixel means the stream has loaded in the most
|
|
||||||
// user way we can verify it (pixel color)
|
|
||||||
await expect
|
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), {
|
|
||||||
timeout: 10_000,
|
|
||||||
})
|
|
||||||
.toBeLessThan(15)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
|
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
|
||||||
@ -352,7 +312,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'open a file in a project works and renders, open another file in the same project with errors, it should clear the scene',
|
'open a file in a project works and renders, open another file in the same project with errors, it should clear the scene',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ scene, cmdBar, context, page }, testInfo) => {
|
||||||
if (runningOnWindows()) {
|
if (runningOnWindows()) {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
}
|
}
|
||||||
@ -380,10 +340,7 @@ test(
|
|||||||
|
|
||||||
await page.getByText('bracket').click()
|
await page.getByText('bracket').click()
|
||||||
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
@ -443,10 +400,10 @@ test(
|
|||||||
await expect(page.getByText('broken-code')).toBeVisible()
|
await expect(page.getByText('broken-code')).toBeVisible()
|
||||||
await page.getByText('broken-code').click()
|
await page.getByText('broken-code').click()
|
||||||
|
|
||||||
// Gotcha: You can not use scene.waitForExecutionDone() since the KCL code is going to fail
|
// Gotcha: You can not use scene.settled() since the KCL code is going to fail
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
await expect(
|
||||||
timeout: 20_000,
|
page.getByTestId('model-state-indicator-playing')
|
||||||
})
|
).toBeAttached()
|
||||||
|
|
||||||
// Gotcha: Scroll to the text content in code mirror because CodeMirror lazy loads DOM content
|
// Gotcha: Scroll to the text content in code mirror because CodeMirror lazy loads DOM content
|
||||||
await editor.scrollToText(
|
await editor.scrollToText(
|
||||||
@ -469,7 +426,7 @@ test.describe('Can export from electron app', () => {
|
|||||||
test(
|
test(
|
||||||
`Can export using ${method}`,
|
`Can export using ${method}`,
|
||||||
{ tag: ['@electron', '@skipLocalEngine'] },
|
{ tag: ['@electron', '@skipLocalEngine'] },
|
||||||
async ({ context, page, tronApp }, testInfo) => {
|
async ({ scene, cmdBar, context, page, tronApp }, testInfo) => {
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
@ -499,10 +456,7 @@ test.describe('Can export from electron app', () => {
|
|||||||
|
|
||||||
await page.getByText('bracket').click()
|
await page.getByText('bracket').click()
|
||||||
|
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
@ -812,7 +766,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
test(
|
test(
|
||||||
`Rename from project page`,
|
`Rename from project page`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page, scene, cmdBar }, testInfo) => {
|
||||||
const projectName = `my_project_to_rename`
|
const projectName = `my_project_to_rename`
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
||||||
@ -821,7 +775,6 @@ test.describe(`Project management commands`, () => {
|
|||||||
`${dir}/${projectName}/main.kcl`
|
`${dir}/${projectName}/main.kcl`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
const u = await getUtils(page)
|
|
||||||
|
|
||||||
// Constants and locators
|
// Constants and locators
|
||||||
const projectHomeLink = page.getByTestId('project-link')
|
const projectHomeLink = page.getByTestId('project-link')
|
||||||
@ -843,7 +796,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
page.on('console', console.log)
|
page.on('console', console.log)
|
||||||
|
|
||||||
await projectHomeLink.click()
|
await projectHomeLink.click()
|
||||||
await u.waitForPageLoad()
|
await scene.settled(cmdBar)
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Run rename command via command palette`, async () => {
|
await test.step(`Run rename command via command palette`, async () => {
|
||||||
@ -882,7 +835,6 @@ test.describe(`Project management commands`, () => {
|
|||||||
`${dir}/${projectName}/main.kcl`
|
`${dir}/${projectName}/main.kcl`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
const u = await getUtils(page)
|
|
||||||
|
|
||||||
// Constants and locators
|
// Constants and locators
|
||||||
const projectHomeLink = page.getByTestId('project-link')
|
const projectHomeLink = page.getByTestId('project-link')
|
||||||
@ -900,9 +852,9 @@ test.describe(`Project management commands`, () => {
|
|||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
page.on('console', console.log)
|
page.on('console', console.log)
|
||||||
|
|
||||||
|
await page.waitForTimeout(3000)
|
||||||
|
|
||||||
await projectHomeLink.click()
|
await projectHomeLink.click()
|
||||||
await u.waitForPageLoad()
|
|
||||||
await scene.connectionEstablished()
|
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -926,7 +878,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
test(
|
test(
|
||||||
`Rename from home page`,
|
`Rename from home page`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page, homePage }, testInfo) => {
|
async ({ context, page, homePage, scene, cmdBar }, testInfo) => {
|
||||||
const projectName = `my_project_to_rename`
|
const projectName = `my_project_to_rename`
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
||||||
@ -982,7 +934,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
test(
|
test(
|
||||||
`Delete from home page`,
|
`Delete from home page`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page, scene, cmdBar }, testInfo) => {
|
||||||
const projectName = `my_project_to_delete`
|
const projectName = `my_project_to_delete`
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
await fsp.mkdir(`${dir}/${projectName}`, { recursive: true })
|
||||||
@ -1033,6 +985,7 @@ test.describe(`Project management commands`, () => {
|
|||||||
homePage,
|
homePage,
|
||||||
toolbar,
|
toolbar,
|
||||||
cmdBar,
|
cmdBar,
|
||||||
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
const projectName = 'test-project'
|
const projectName = 'test-project'
|
||||||
await test.step(`Setup`, async () => {
|
await test.step(`Setup`, async () => {
|
||||||
@ -1072,10 +1025,11 @@ test.describe(`Project management commands`, () => {
|
|||||||
})
|
})
|
||||||
await cmdBar.argumentInput.fill(projectName)
|
await cmdBar.argumentInput.fill(projectName)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await toolbar.logoLink.click()
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Check the project was created with a non-colliding name`, async () => {
|
await test.step(`Check the project was created with a non-colliding name`, async () => {
|
||||||
await toolbar.logoLink.click()
|
|
||||||
await homePage.expectState({
|
await homePage.expectState({
|
||||||
projectCards: [
|
projectCards: [
|
||||||
{
|
{
|
||||||
@ -1106,10 +1060,11 @@ test.describe(`Project management commands`, () => {
|
|||||||
})
|
})
|
||||||
await cmdBar.argumentInput.fill(projectName)
|
await cmdBar.argumentInput.fill(projectName)
|
||||||
await cmdBar.progressCmdBar()
|
await cmdBar.progressCmdBar()
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
await toolbar.logoLink.click()
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step(`Check the second project was created with a non-colliding name`, async () => {
|
await test.step(`Check the second project was created with a non-colliding name`, async () => {
|
||||||
await toolbar.logoLink.click()
|
|
||||||
await homePage.expectState({
|
await homePage.expectState({
|
||||||
projectCards: [
|
projectCards: [
|
||||||
{
|
{
|
||||||
@ -1195,7 +1150,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'Nested directories in project without main.kcl do not create main.kcl',
|
'Nested directories in project without main.kcl do not create main.kcl',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ scene, cmdBar, context, page }, testInfo) => {
|
||||||
let testDir: string | undefined
|
let testDir: string | undefined
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
await fsp.mkdir(path.join(dir, 'router-template-slate', 'nested'), {
|
await fsp.mkdir(path.join(dir, 'router-template-slate', 'nested'), {
|
||||||
@ -1218,10 +1173,7 @@ test(
|
|||||||
|
|
||||||
await test.step('Open the project', async () => {
|
await test.step('Open the project', async () => {
|
||||||
await page.getByText('router-template-slate').click()
|
await page.getByText('router-template-slate').click()
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
// It actually loads.
|
// It actually loads.
|
||||||
await expect(u.codeLocator).toContainText('mounting bracket')
|
await expect(u.codeLocator).toContainText('mounting bracket')
|
||||||
@ -1334,7 +1286,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'Can load a file with CRLF line endings',
|
'Can load a file with CRLF line endings',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page, scene, cmdBar }, testInfo) => {
|
||||||
if (runningOnWindows()) {
|
if (runningOnWindows()) {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
}
|
}
|
||||||
@ -1357,13 +1309,8 @@ test(
|
|||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
page.on('console', console.log)
|
|
||||||
|
|
||||||
await page.getByText('router-template-slate').click()
|
await page.getByText('router-template-slate').click()
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
await scene.settled(cmdBar)
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
await expect(u.codeLocator).toContainText('routerDiameter')
|
await expect(u.codeLocator).toContainText('routerDiameter')
|
||||||
await expect(u.codeLocator).toContainText('templateGap')
|
await expect(u.codeLocator).toContainText('templateGap')
|
||||||
@ -1578,7 +1525,7 @@ extrude001 = extrude(sketch001, length = 200)`)
|
|||||||
test(
|
test(
|
||||||
'Opening a project should successfully load the stream, (regression test that this also works when switching between projects)',
|
'Opening a project should successfully load the stream, (regression test that this also works when switching between projects)',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page, cmdBar, homePage }, testInfo) => {
|
async ({ context, page, cmdBar, homePage, scene }, testInfo) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
await fsp.mkdir(path.join(dir, 'router-template-slate'), {
|
await fsp.mkdir(path.join(dir, 'router-template-slate'), {
|
||||||
recursive: true,
|
recursive: true,
|
||||||
@ -1607,13 +1554,10 @@ test(
|
|||||||
path.join(dir, 'bracket', 'main.kcl')
|
path.join(dir, 'bracket', 'main.kcl')
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
page.on('console', console.log)
|
page.on('console', console.log)
|
||||||
|
|
||||||
const pointOnModel = { x: 630, y: 280 }
|
|
||||||
|
|
||||||
await test.step('Opening the bracket project via command palette should load the stream', async () => {
|
await test.step('Opening the bracket project via command palette should load the stream', async () => {
|
||||||
await homePage.expectState({
|
await homePage.expectState({
|
||||||
projectCards: [
|
projectCards: [
|
||||||
@ -1647,15 +1591,7 @@ test(
|
|||||||
stage: 'commandBarClosed',
|
stage: 'commandBarClosed',
|
||||||
})
|
})
|
||||||
|
|
||||||
await u.waitForPageLoad()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// gray at this pixel means the stream has loaded in the most
|
|
||||||
// user way we can verify it (pixel color)
|
|
||||||
await expect
|
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [85, 85, 85]), {
|
|
||||||
timeout: 10_000,
|
|
||||||
})
|
|
||||||
.toBeLessThan(15)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
|
await test.step('Clicking the logo takes us back to the projects page / home', async () => {
|
||||||
@ -1672,15 +1608,7 @@ test(
|
|||||||
|
|
||||||
await page.getByText('router-template-slate').click()
|
await page.getByText('router-template-slate').click()
|
||||||
|
|
||||||
await u.waitForPageLoad()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// gray at this pixel means the stream has loaded in the most
|
|
||||||
// user way we can verify it (pixel color)
|
|
||||||
await expect
|
|
||||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [143, 143, 143]), {
|
|
||||||
timeout: 10_000,
|
|
||||||
})
|
|
||||||
.toBeLessThan(15)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await test.step('The projects on the home page should still be normal', async () => {
|
await test.step('The projects on the home page should still be normal', async () => {
|
||||||
@ -1733,8 +1661,6 @@ test(
|
|||||||
})
|
})
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
page.on('console', console.log)
|
|
||||||
|
|
||||||
// we'll grab this from the settings on screen before we switch
|
// we'll grab this from the settings on screen before we switch
|
||||||
let originalProjectDirName: string
|
let originalProjectDirName: string
|
||||||
const newProjectDirName = testInfo.outputPath(
|
const newProjectDirName = testInfo.outputPath(
|
||||||
@ -1875,7 +1801,7 @@ test(
|
|||||||
test(
|
test(
|
||||||
'file pane is scrollable when there are many files',
|
'file pane is scrollable when there are many files',
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ scene, cmdBar, context, page }, testInfo) => {
|
||||||
await context.folderSetupFn(async (dir) => {
|
await context.folderSetupFn(async (dir) => {
|
||||||
const testDir = path.join(dir, 'testProject')
|
const testDir = path.join(dir, 'testProject')
|
||||||
await fsp.mkdir(testDir, { recursive: true })
|
await fsp.mkdir(testDir, { recursive: true })
|
||||||
@ -1954,10 +1880,8 @@ test(
|
|||||||
|
|
||||||
await test.step('setup, open file pane', async () => {
|
await test.step('setup, open file pane', async () => {
|
||||||
await page.getByText('testProject').click()
|
await page.getByText('testProject').click()
|
||||||
await expect(page.getByTestId('loading')).toBeAttached()
|
|
||||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
await scene.settled(cmdBar)
|
||||||
timeout: 20_000,
|
|
||||||
})
|
|
||||||
|
|
||||||
await page.getByTestId('files-pane-button').click()
|
await page.getByTestId('files-pane-button').click()
|
||||||
})
|
})
|
||||||
|
@ -41,15 +41,13 @@ sketch002 = startSketchOn(XZ)
|
|||||||
extrude002 = extrude(sketch002, length = 50)
|
extrude002 = extrude(sketch002, length = 50)
|
||||||
sketch003 = startSketchOn(XY)
|
sketch003 = startSketchOn(XY)
|
||||||
|> startProfileAt([52.92, 157.81], %)
|
|> startProfileAt([52.92, 157.81], %)
|
||||||
|> angledLine([0, 176.4], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 176.4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(
|
||||||
segAng(rectangleSegmentA001) - 90,
|
angle = segAng(rectangleSegmentA001) - 90,
|
||||||
53.4
|
length = 53.4,
|
||||||
], %, $rectangleSegmentB001)
|
tag = $rectangleSegmentB001,
|
||||||
|> angledLine([
|
)
|
||||||
segAng(rectangleSegmentA001),
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude003 = extrude(sketch003, length = 20)
|
extrude003 = extrude(sketch003, length = 20)
|
||||||
@ -63,7 +61,7 @@ test.describe('edit with AI example snapshots', () => {
|
|||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
const body1CapCoords = { x: 571, y: 351 }
|
const body1CapCoords = { x: 571, y: 351 }
|
||||||
const [clickBody1Cap] = scene.makeMouseHelpers(
|
const [clickBody1Cap] = scene.makeMouseHelpers(
|
||||||
@ -74,7 +72,6 @@ test.describe('edit with AI example snapshots', () => {
|
|||||||
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
||||||
|
|
||||||
await test.step('wait for scene to load select body and check selection came through', async () => {
|
await test.step('wait for scene to load select body and check selection came through', async () => {
|
||||||
await scene.expectPixelColor([134, 134, 134], body1CapCoords, 15)
|
|
||||||
await clickBody1Cap()
|
await clickBody1Cap()
|
||||||
await scene.expectPixelColor(yellow, body1CapCoords, 20)
|
await scene.expectPixelColor(yellow, body1CapCoords, 20)
|
||||||
await editor.expectState({
|
await editor.expectState({
|
||||||
|
@ -22,15 +22,9 @@ sketch002 = startSketchOn(XZ)
|
|||||||
extrude002 = extrude(sketch002, length = 50)
|
extrude002 = extrude(sketch002, length = 50)
|
||||||
sketch003 = startSketchOn(XY)
|
sketch003 = startSketchOn(XY)
|
||||||
|> startProfileAt([52.92, 157.81], %)
|
|> startProfileAt([52.92, 157.81], %)
|
||||||
|> angledLine([0, 176.4], %, $rectangleSegmentA001)
|
|> angledLine(angle = 0, length = 176.4, tag = $rectangleSegmentA001)
|
||||||
|> angledLine([
|
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 53.4, tag = $rectangleSegmentB001)
|
||||||
segAng(rectangleSegmentA001) - 90,
|
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $rectangleSegmentC001)
|
||||||
53.4
|
|
||||||
], %, $rectangleSegmentB001)
|
|
||||||
|> angledLine([
|
|
||||||
segAng(rectangleSegmentA001),
|
|
||||||
-segLen(rectangleSegmentA001)
|
|
||||||
], %, $rectangleSegmentC001)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
||||||
|> close()
|
|> close()
|
||||||
extrude003 = extrude(sketch003, length = 20)
|
extrude003 = extrude(sketch003, length = 20)
|
||||||
@ -57,11 +51,12 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
page,
|
page,
|
||||||
scene,
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
await context.addInitScript((file) => {
|
await context.addInitScript((file) => {
|
||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
const body1CapCoords = { x: 571, y: 311 }
|
const body1CapCoords = { x: 571, y: 311 }
|
||||||
const greenCheckCoords = { x: 565, y: 305 }
|
const greenCheckCoords = { x: 565, y: 305 }
|
||||||
@ -156,7 +151,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
const body1CapCoords = { x: 571, y: 311 }
|
const body1CapCoords = { x: 571, y: 311 }
|
||||||
const [clickBody1Cap] = scene.makeMouseHelpers(
|
const [clickBody1Cap] = scene.makeMouseHelpers(
|
||||||
@ -212,7 +207,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
||||||
const successToast = page.getByText('Prompt to edit successful')
|
const successToast = page.getByText('Prompt to edit successful')
|
||||||
@ -265,6 +260,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
page,
|
page,
|
||||||
scene,
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
const body1CapCoords = { x: 571, y: 311 }
|
const body1CapCoords = { x: 571, y: 311 }
|
||||||
const body2WallCoords = { x: 620, y: 152 }
|
const body2WallCoords = { x: 620, y: 152 }
|
||||||
const [clickBody1Cap] = scene.makeMouseHelpers(
|
const [clickBody1Cap] = scene.makeMouseHelpers(
|
||||||
@ -281,7 +277,7 @@ test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
|||||||
localStorage.setItem('persistCode', file)
|
localStorage.setItem('persistCode', file)
|
||||||
}, file)
|
}, file)
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await scene.waitForExecutionDone()
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
const submittingToast = page.getByText('Submitting to Text-to-CAD API...')
|
||||||
const successToast = page.getByText('Prompt to edit successful')
|
const successToast = page.getByText('Prompt to edit successful')
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user