Compare commits
1 Commits
v0.24.12
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
6e2274a6c4 |
12
.github/workflows/playwright.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
|||||||
|
|
||||||
playwright-ubuntu:
|
playwright-ubuntu:
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8-cores
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@ -112,7 +112,7 @@ jobs:
|
|||||||
run: yarn build:local
|
run: yarn build:local
|
||||||
- name: Run ubuntu/chrome snapshots
|
- name: Run ubuntu/chrome snapshots
|
||||||
run: |
|
run: |
|
||||||
yarn playwright test --project="Google Chrome" --config=playwright.ci.config.ts --retries="3" --update-snapshots --grep=@snapshot --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
yarn playwright test --project="Google Chrome" --retries="3" --update-snapshots --grep=@snapshot --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||||
env:
|
env:
|
||||||
CI: true
|
CI: true
|
||||||
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
|
||||||
@ -171,7 +171,7 @@ jobs:
|
|||||||
if [[ ! -f "test-results/.last-run.json" ]]; then
|
if [[ ! -f "test-results/.last-run.json" ]]; then
|
||||||
# if no last run artifact, than run plawright normally
|
# if no last run artifact, than run plawright normally
|
||||||
echo "run playwright normally"
|
echo "run playwright normally"
|
||||||
yarn playwright test --project="Google Chrome" --config=playwright.ci.config.ts --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert=@snapshot || true
|
yarn playwright test --project="Google Chrome" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert=@snapshot || true
|
||||||
# # send to axiom
|
# # send to axiom
|
||||||
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
@ -186,7 +186,7 @@ jobs:
|
|||||||
if [[ $failed_tests -gt 0 ]]; then
|
if [[ $failed_tests -gt 0 ]]; then
|
||||||
echo "retried=true" >>$GITHUB_OUTPUT
|
echo "retried=true" >>$GITHUB_OUTPUT
|
||||||
echo "run playwright with last failed tests and retry $retry"
|
echo "run playwright with last failed tests and retry $retry"
|
||||||
yarn playwright test --project="Google Chrome" --config=playwright.ci.config.ts --last-failed --grep-invert=@snapshot || true
|
yarn playwright test --project="Google Chrome" --last-failed --grep-invert=@snapshot || true
|
||||||
# send to axiom
|
# send to axiom
|
||||||
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
||||||
retry=$((retry + 1))
|
retry=$((retry + 1))
|
||||||
@ -325,7 +325,7 @@ jobs:
|
|||||||
if [[ ! -f "test-results/.last-run.json" ]]; then
|
if [[ ! -f "test-results/.last-run.json" ]]; then
|
||||||
# if no last run artifact, than run plawright normally
|
# if no last run artifact, than run plawright normally
|
||||||
echo "run playwright normally"
|
echo "run playwright normally"
|
||||||
yarn playwright test --project="webkit" --config=playwright.ci.config.ts --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert=@snapshot || true
|
yarn playwright test --project="webkit" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert=@snapshot || true
|
||||||
# # send to axiom
|
# # send to axiom
|
||||||
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
@ -340,7 +340,7 @@ jobs:
|
|||||||
if [[ $failed_tests -gt 0 ]]; then
|
if [[ $failed_tests -gt 0 ]]; then
|
||||||
echo "retried=true" >>$GITHUB_OUTPUT
|
echo "retried=true" >>$GITHUB_OUTPUT
|
||||||
echo "run playwright with last failed tests and retry $retry"
|
echo "run playwright with last failed tests and retry $retry"
|
||||||
yarn playwright test --project="webkit" --config=playwright.ci.config.ts --last-failed --grep-invert=@snapshot || true
|
yarn playwright test --project="webkit" --last-failed --grep-invert=@snapshot || true
|
||||||
# send to axiom
|
# send to axiom
|
||||||
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
|
||||||
retry=$((retry + 1))
|
retry=$((retry + 1))
|
||||||
|
@ -117,7 +117,6 @@ Which commands from setup are one off vs need to be run every time?
|
|||||||
The following will need to be run when checking out a new commit and guarantees the build is not stale:
|
The following will need to be run when checking out a new commit and guarantees the build is not stale:
|
||||||
```bash
|
```bash
|
||||||
yarn install
|
yarn install
|
||||||
yarn wasm-prep
|
|
||||||
yarn build:wasm-dev # or yarn build:wasm for slower but more production-like build
|
yarn build:wasm-dev # or yarn build:wasm for slower but more production-like build
|
||||||
yarn start # or yarn build:local && yarn serve for slower but more production-like build
|
yarn start # or yarn build:local && yarn serve for slower but more production-like build
|
||||||
```
|
```
|
||||||
|
@ -25,5 +25,5 @@ once fixed in engine will just start working here with no language changes.
|
|||||||
|
|
||||||
Sketching on the chamfered face does not currently work.
|
Sketching on the chamfered face does not currently work.
|
||||||
|
|
||||||
- **Shell**: Shell sometimes does not work when arcs or fillets are involved.
|
- **Shell**: Shell is only working for `end` faces, not for `side` or `start`
|
||||||
We are tracking the engine side bug on this.
|
faces. We are tracking the engine side bug on this.
|
||||||
|
1352
docs/kcl/std.json
@ -98,16 +98,14 @@ const extrude001 = extrude(-10, sketch001)`
|
|||||||
|
|
||||||
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
||||||
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||||
const commandName = 'debug panel'
|
const themeOption = page.getByRole('option', {
|
||||||
const commandOption = page.getByRole('option', {
|
name: 'theme',
|
||||||
name: commandName,
|
|
||||||
exact: false,
|
exact: false,
|
||||||
})
|
})
|
||||||
const commandLevelArgButton = page.getByRole('button', { name: 'level' })
|
const commandLevelArgButton = page.getByRole('button', { name: 'level' })
|
||||||
const commandThemeArgButton = page.getByRole('button', { name: 'value' })
|
const commandThemeArgButton = page.getByRole('button', { name: 'value' })
|
||||||
const paneSelector = page.getByRole('button', { name: 'debug panel' })
|
|
||||||
// This selector changes after we set the setting
|
// This selector changes after we set the setting
|
||||||
let commandOptionInput = page.getByPlaceholder('On')
|
let commandOptionInput = page.getByPlaceholder('Select an option')
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
@ -129,16 +127,17 @@ const extrude001 = extrude(-10, sketch001)`
|
|||||||
await expect(cmdSearchBar).toBeFocused()
|
await expect(cmdSearchBar).toBeFocused()
|
||||||
|
|
||||||
// Try typing in the command bar
|
// Try typing in the command bar
|
||||||
await cmdSearchBar.fill(commandName)
|
await cmdSearchBar.fill('theme')
|
||||||
await expect(commandOption).toBeVisible()
|
await expect(themeOption).toBeVisible()
|
||||||
await commandOption.click()
|
await themeOption.click()
|
||||||
const toggleInput = page.getByPlaceholder('On')
|
const themeInput = page.getByPlaceholder('Select an option')
|
||||||
await expect(toggleInput).toBeVisible()
|
await expect(themeInput).toBeVisible()
|
||||||
await expect(toggleInput).toBeFocused()
|
await expect(themeInput).toBeFocused()
|
||||||
// Select On
|
// Select dark theme
|
||||||
await page.keyboard.press('ArrowDown')
|
await page.keyboard.press('ArrowDown')
|
||||||
await page.keyboard.press('ArrowDown')
|
await page.keyboard.press('ArrowDown')
|
||||||
await expect(page.getByRole('option', { name: 'Off' })).toHaveAttribute(
|
await page.keyboard.press('ArrowDown')
|
||||||
|
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
|
||||||
'data-headlessui-state',
|
'data-headlessui-state',
|
||||||
'active'
|
'active'
|
||||||
)
|
)
|
||||||
@ -146,21 +145,21 @@ const extrude001 = extrude(-10, sketch001)`
|
|||||||
|
|
||||||
// Check the toast appeared
|
// Check the toast appeared
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(`Set show debug panel to "false" for this project`)
|
page.getByText(`Set theme to "system" for this project`)
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
// Check that the visibility changed
|
// Check that the theme changed
|
||||||
await expect(paneSelector).not.toBeVisible()
|
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||||
|
|
||||||
commandOptionInput = page.getByPlaceholder('off')
|
commandOptionInput = page.getByPlaceholder('system')
|
||||||
|
|
||||||
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
|
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
|
||||||
await commandBarButton.click()
|
await commandBarButton.click()
|
||||||
await cmdSearchBar.focus()
|
await cmdSearchBar.focus()
|
||||||
await cmdSearchBar.fill(commandName)
|
await cmdSearchBar.fill('theme')
|
||||||
await commandOption.click()
|
await themeOption.click()
|
||||||
await expect(commandThemeArgButton).toBeDisabled()
|
await expect(commandThemeArgButton).toBeDisabled()
|
||||||
await commandOptionInput.focus()
|
await commandOptionInput.focus()
|
||||||
await commandOptionInput.fill('on')
|
await commandOptionInput.fill('lig')
|
||||||
await commandLevelArgButton.click()
|
await commandLevelArgButton.click()
|
||||||
await expect(commandLevelArgButton).toBeDisabled()
|
await expect(commandLevelArgButton).toBeDisabled()
|
||||||
|
|
||||||
@ -198,7 +197,7 @@ const extrude001 = extrude(-10, sketch001)`
|
|||||||
})
|
})
|
||||||
await expect(themeOption).toBeVisible()
|
await expect(themeOption).toBeVisible()
|
||||||
await themeOption.click()
|
await themeOption.click()
|
||||||
const themeInput = page.getByPlaceholder('dark')
|
const themeInput = page.getByPlaceholder('Select an option')
|
||||||
await expect(themeInput).toBeVisible()
|
await expect(themeInput).toBeVisible()
|
||||||
await expect(themeInput).toBeFocused()
|
await expect(themeInput).toBeFocused()
|
||||||
// Select dark theme
|
// Select dark theme
|
||||||
@ -213,7 +212,7 @@ const extrude001 = extrude(-10, sketch001)`
|
|||||||
|
|
||||||
// Check the toast appeared
|
// Check the toast appeared
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(`Set theme to "system" as a user default`)
|
page.getByText(`Set theme to "system" for this project`)
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
// Check that the theme changed
|
// Check that the theme changed
|
||||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||||
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 171 KiB |
@ -1,12 +1,6 @@
|
|||||||
import { test, expect, Page } from '@playwright/test'
|
import { test, expect } from '@playwright/test'
|
||||||
|
|
||||||
import { getUtils, setup, tearDown } from './test-utils'
|
import { getUtils, setup, tearDown } from './test-utils'
|
||||||
import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from './storageStates'
|
|
||||||
import { bracket } from 'lib/exampleKcl'
|
|
||||||
import {
|
|
||||||
PLAYWRIGHT_MOCK_EXPORT_DURATION,
|
|
||||||
PLAYWRIGHT_TOAST_DURATION,
|
|
||||||
} from 'lib/constants'
|
|
||||||
|
|
||||||
test.beforeEach(async ({ context, page }) => {
|
test.beforeEach(async ({ context, page }) => {
|
||||||
await setup(context, page)
|
await setup(context, page)
|
||||||
@ -170,7 +164,7 @@ const sketch001 = startSketchAt([-0, -0])
|
|||||||
|> yLineTo(0, %)
|
|> yLineTo(0, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|>
|
|>
|
||||||
|
|
||||||
const example = extrude(5, exampleSketch)
|
const example = extrude(5, exampleSketch)
|
||||||
shell({ faces: ['end'], thickness: 0.25 }, exampleSketch)`
|
shell({ faces: ['end'], thickness: 0.25 }, exampleSketch)`
|
||||||
)
|
)
|
||||||
@ -229,212 +223,4 @@ const sketch001 = startSketchAt([-0, -0])
|
|||||||
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||||
})
|
})
|
||||||
test('when engine fails export we handle the failure and alert the user', async ({
|
|
||||||
page,
|
|
||||||
}) => {
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.addInitScript(async (code) => {
|
|
||||||
localStorage.setItem('persistCode', code)
|
|
||||||
}, TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR)
|
|
||||||
|
|
||||||
await page.setViewportSize({ width: 1000, height: 500 })
|
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
|
||||||
|
|
||||||
// wait for execution done
|
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
// expect zero errors in guter
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
|
||||||
|
|
||||||
// export the model
|
|
||||||
const exportButton = page.getByTestId('export-pane-button')
|
|
||||||
await expect(exportButton).toBeVisible()
|
|
||||||
|
|
||||||
// Click the export button
|
|
||||||
await exportButton.click()
|
|
||||||
|
|
||||||
// Click the stl.
|
|
||||||
const stlOption = page.getByText('glTF')
|
|
||||||
await expect(stlOption).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Click the checkbox
|
|
||||||
const submitButton = page.getByText('Confirm Export')
|
|
||||||
await expect(submitButton).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Find the toast.
|
|
||||||
// Look out for the toast message
|
|
||||||
const exportingToastMessage = page.getByText(`Exporting...`)
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
|
||||||
await expect(errorToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
|
||||||
await expect(engineErrorToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
// Make sure the exporting toast is gone
|
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
|
||||||
|
|
||||||
// Click the code editor
|
|
||||||
await page.locator('.cm-content').click()
|
|
||||||
|
|
||||||
await page.waitForTimeout(2000)
|
|
||||||
|
|
||||||
// Expect the toast to be gone
|
|
||||||
await expect(errorToastMessage).not.toBeVisible()
|
|
||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
|
||||||
|
|
||||||
// Now add in code that works.
|
|
||||||
await page.locator('.cm-content').fill(bracket)
|
|
||||||
await page.keyboard.press('End')
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// wait for execution done
|
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.clearCommandLogs()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
// Now try exporting
|
|
||||||
|
|
||||||
// Click the export button
|
|
||||||
await exportButton.click()
|
|
||||||
|
|
||||||
// Click the stl.
|
|
||||||
await expect(stlOption).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Click the checkbox
|
|
||||||
await expect(submitButton).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Find the toast.
|
|
||||||
// Look out for the toast message
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
// Expect it to succeed.
|
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
|
||||||
await expect(errorToastMessage).not.toBeVisible()
|
|
||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
|
||||||
|
|
||||||
const successToastMessage = page.getByText(`Exported successfully`)
|
|
||||||
await expect(successToastMessage).toBeVisible()
|
|
||||||
})
|
|
||||||
test('ensure you can not export while an export is already going', async ({
|
|
||||||
page,
|
|
||||||
}) => {
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await test.step('Set up the code and durations', async () => {
|
|
||||||
await page.addInitScript(
|
|
||||||
async ({ code, toastDurationKey, exportDurationKey }) => {
|
|
||||||
localStorage.setItem('persistCode', code)
|
|
||||||
// Normally we make these durations short to speed up PW tests
|
|
||||||
// to superhuman speeds. But in this case we want to make sure
|
|
||||||
// the export toast is visible for a while, and the export
|
|
||||||
// duration is long enough to make sure the export toast is visible
|
|
||||||
localStorage.setItem(toastDurationKey, '1500')
|
|
||||||
localStorage.setItem(exportDurationKey, '750')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
code: bracket,
|
|
||||||
toastDurationKey: PLAYWRIGHT_TOAST_DURATION,
|
|
||||||
exportDurationKey: PLAYWRIGHT_MOCK_EXPORT_DURATION,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await page.setViewportSize({ width: 1000, height: 500 })
|
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
|
||||||
|
|
||||||
// wait for execution done
|
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
// expect zero errors in guter
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
|
||||||
const exportingToastMessage = page.getByText(`Exporting...`)
|
|
||||||
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
|
||||||
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
|
||||||
const successToastMessage = page.getByText(`Exported successfully`)
|
|
||||||
|
|
||||||
await test.step('Blocked second export', async () => {
|
|
||||||
await clickExportButton(page)
|
|
||||||
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
await clickExportButton(page)
|
|
||||||
|
|
||||||
await test.step('The second export is blocked', async () => {
|
|
||||||
// Find the toast.
|
|
||||||
// Look out for the toast message
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
|
||||||
await expect(alreadyExportingToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('The first export still succeeds', async () => {
|
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
|
||||||
await expect(errorToastMessage).not.toBeVisible()
|
|
||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
|
||||||
|
|
||||||
await expect(successToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
await expect(alreadyExportingToastMessage).not.toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Successful, unblocked export', async () => {
|
|
||||||
// Try exporting again.
|
|
||||||
await clickExportButton(page)
|
|
||||||
|
|
||||||
// Find the toast.
|
|
||||||
// Look out for the toast message
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
// Expect it to succeed.
|
|
||||||
await expect(exportingToastMessage).not.toBeVisible()
|
|
||||||
await expect(errorToastMessage).not.toBeVisible()
|
|
||||||
await expect(engineErrorToastMessage).not.toBeVisible()
|
|
||||||
await expect(alreadyExportingToastMessage).not.toBeVisible()
|
|
||||||
|
|
||||||
await expect(successToastMessage).toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
async function clickExportButton(page: Page) {
|
|
||||||
await test.step('Running export flow', async () => {
|
|
||||||
// export the model
|
|
||||||
const exportButton = page.getByTestId('export-pane-button')
|
|
||||||
await expect(exportButton).toBeEnabled()
|
|
||||||
|
|
||||||
// Click the export button
|
|
||||||
await exportButton.click()
|
|
||||||
|
|
||||||
// Click the stl.
|
|
||||||
const gltfOption = page.getByRole('option', { name: 'glTF' })
|
|
||||||
await expect(gltfOption).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Click the checkbox
|
|
||||||
const submitButton = page.getByText('Confirm Export')
|
|
||||||
await expect(submitButton).toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
@ -151,12 +151,11 @@ test.describe('Sketch tests', () => {
|
|||||||
|
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
await expect.poll(u.normalisedEditorCode)
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
.toBe(`const sketch001 = startSketchOn('XZ')
|
`const sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([12.34, -12.34], %)
|
|> startProfileAt([4.61, -14.01], %)
|
||||||
|> line([-12.34, 12.34], %)
|
|> line([0.31, 16.47], %)`
|
||||||
|
)
|
||||||
`)
|
|
||||||
})
|
})
|
||||||
test('Can exit selection of face', async ({ page }) => {
|
test('Can exit selection of face', async ({ page }) => {
|
||||||
// Load the app with the code panes
|
// Load the app with the code panes
|
||||||
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
@ -368,5 +368,3 @@ startSketchOn(keychain, 'end')
|
|||||||
height - (keychainHoleSize + 1.5)
|
height - (keychainHoleSize + 1.5)
|
||||||
], keychainHoleSize, %)
|
], keychainHoleSize, %)
|
||||||
|> extrude(-thickness, %)`
|
|> extrude(-thickness, %)`
|
||||||
|
|
||||||
export const TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR = `const thing = 1`
|
|
||||||
|
@ -204,24 +204,19 @@ test.describe('Test network and connection issues', () => {
|
|||||||
|
|
||||||
// Ensure we can continue sketching
|
// Ensure we can continue sketching
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||||
await expect.poll(u.normalisedEditorCode)
|
await expect(page.locator('.cm-content'))
|
||||||
.toBe(`const sketch001 = startSketchOn('XZ')
|
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([12.34, -12.34], %)
|
|> startProfileAt(${commonPoints.startAt}, %)
|
||||||
|> line([12.34, 0], %)
|
|> line([${commonPoints.num1}, 0], %)
|
||||||
|> line([-12.34, 12.34], %)
|
|> line([-8.84, 8.75], %)`)
|
||||||
|
|
||||||
`)
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.mouse.click(startXPx, 500 - PUR * 20)
|
await page.mouse.click(startXPx, 500 - PUR * 20)
|
||||||
|
await expect(page.locator('.cm-content'))
|
||||||
await expect.poll(u.normalisedEditorCode)
|
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||||
.toBe(`const sketch001 = startSketchOn('XZ')
|
|> startProfileAt(${commonPoints.startAt}, %)
|
||||||
|> startProfileAt([12.34, -12.34], %)
|
|> line([${commonPoints.num1}, 0], %)
|
||||||
|> line([12.34, 0], %)
|
|> line([-8.84, 8.75], %)
|
||||||
|> line([-12.34, 12.34], %)
|
|> line([-5.6, 0], %)`)
|
||||||
|> line([-12.34, 0], %)
|
|
||||||
|
|
||||||
`)
|
|
||||||
|
|
||||||
// Unequip line tool
|
// Unequip line tool
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
|
@ -12,7 +12,7 @@ import pixelMatch from 'pixelmatch'
|
|||||||
import { PNG } from 'pngjs'
|
import { PNG } from 'pngjs'
|
||||||
import { Protocol } from 'playwright-core/types/protocol'
|
import { Protocol } from 'playwright-core/types/protocol'
|
||||||
import type { Models } from '@kittycad/lib'
|
import type { Models } from '@kittycad/lib'
|
||||||
import { APP_NAME, COOKIE_NAME } from 'lib/constants'
|
import { APP_NAME } from 'lib/constants'
|
||||||
import waitOn from 'wait-on'
|
import waitOn from 'wait-on'
|
||||||
import { secrets } from './secrets'
|
import { secrets } from './secrets'
|
||||||
import { TEST_SETTINGS_KEY, TEST_SETTINGS } from './storageStates'
|
import { TEST_SETTINGS_KEY, TEST_SETTINGS } from './storageStates'
|
||||||
@ -268,18 +268,6 @@ async function waitForAuthAndLsp(page: Page) {
|
|||||||
return waitForLspPromise
|
return waitForLspPromise
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normaliseKclNumbers(code: string, ignoreZero = true): string {
|
|
||||||
const numberRegexp = /(?<!\w)-?\b\d+(\.\d+)?\b(?!\w)/g
|
|
||||||
const replaceNumber = (number: string) => {
|
|
||||||
if (ignoreZero && (number === '0' || number === '-0')) return number
|
|
||||||
const sign = number.startsWith('-') ? '-' : ''
|
|
||||||
return `${sign}12.34`
|
|
||||||
}
|
|
||||||
const replaceNumbers = (text: string) =>
|
|
||||||
text.replace(numberRegexp, replaceNumber)
|
|
||||||
return replaceNumbers(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getUtils(page: Page) {
|
export async function getUtils(page: Page) {
|
||||||
// Chrome devtools protocol session only works in Chromium
|
// Chrome devtools protocol session only works in Chromium
|
||||||
const browserType = page.context().browser()?.browserType().name()
|
const browserType = page.context().browser()?.browserType().name()
|
||||||
@ -342,11 +330,6 @@ export async function getUtils(page: Page) {
|
|||||||
.boundingBox()
|
.boundingBox()
|
||||||
.then((box) => ({ ...box, x: box?.x || 0, y: box?.y || 0 })),
|
.then((box) => ({ ...box, x: box?.x || 0, y: box?.y || 0 })),
|
||||||
codeLocator: page.locator('.cm-content'),
|
codeLocator: page.locator('.cm-content'),
|
||||||
normalisedEditorCode: async () => {
|
|
||||||
const code = await page.locator('.cm-content').innerText()
|
|
||||||
return normaliseKclNumbers(code)
|
|
||||||
},
|
|
||||||
normalisedCode: (code: string) => normaliseKclNumbers(code),
|
|
||||||
canvasLocator: page.getByTestId('client-side-scene'),
|
canvasLocator: page.getByTestId('client-side-scene'),
|
||||||
doAndWaitForCmd: async (
|
doAndWaitForCmd: async (
|
||||||
fn: () => Promise<void>,
|
fn: () => Promise<void>,
|
||||||
@ -643,16 +626,6 @@ export async function setup(context: BrowserContext, page: Page) {
|
|||||||
settings: TOML.stringify({ settings: TEST_SETTINGS }),
|
settings: TOML.stringify({ settings: TEST_SETTINGS }),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
await context.addCookies([
|
|
||||||
{
|
|
||||||
name: COOKIE_NAME,
|
|
||||||
value: secrets.token,
|
|
||||||
path: '/',
|
|
||||||
domain: 'localhost',
|
|
||||||
secure: true,
|
|
||||||
},
|
|
||||||
])
|
|
||||||
// kill animations, speeds up tests and reduced flakiness
|
// kill animations, speeds up tests and reduced flakiness
|
||||||
await page.emulateMedia({ reducedMotion: 'reduce' })
|
await page.emulateMedia({ reducedMotion: 'reduce' })
|
||||||
}
|
}
|
||||||
|