fmt
This commit is contained in:
@ -9,7 +9,11 @@ import { HomePageFixture } from './fixtures/homePageFixture'
|
|||||||
|
|
||||||
test.setTimeout(120000)
|
test.setTimeout(120000)
|
||||||
|
|
||||||
async function doBasicSketch(page: Page, homePage: HomePageFixture, openPanes: string[]) {
|
async function doBasicSketch(
|
||||||
|
page: Page,
|
||||||
|
homePage: HomePageFixture,
|
||||||
|
openPanes: string[]
|
||||||
|
) {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
@ -139,16 +143,19 @@ async function doBasicSketch(page: Page, homePage: HomePageFixture, openPanes: s
|
|||||||
}
|
}
|
||||||
|
|
||||||
test.describe('Basic sketch', () => {
|
test.describe('Basic sketch', () => {
|
||||||
test('code pane open at start', async ({ page, homePage }) => { // Skip on windows it is being weird.
|
test('code pane open at start', async ({ page, homePage }) => {
|
||||||
|
// Skip on windows it is being weird.
|
||||||
await doBasicSketch(page, homePage, ['code'])
|
await doBasicSketch(page, homePage, ['code'])
|
||||||
})
|
})
|
||||||
|
|
||||||
test('code pane closed at start', async ({ page, homePage }) => { // Load the app with the code panes
|
test('code pane closed at start', async ({ page, homePage }) => {
|
||||||
await page.addInitScript(async (persistModelingContext) => {
|
// Load the app with the code panes
|
||||||
localStorage.setItem(
|
await page.addInitScript(async (persistModelingContext) => {
|
||||||
persistModelingContext,
|
localStorage.setItem(
|
||||||
JSON.stringify({ openPanes: [] })
|
persistModelingContext,
|
||||||
)
|
JSON.stringify({ openPanes: [] })
|
||||||
}, PERSIST_MODELING_CONTEXT)
|
)
|
||||||
await doBasicSketch(page, homePage, []) })
|
}, PERSIST_MODELING_CONTEXT)
|
||||||
|
await doBasicSketch(page, homePage, [])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -79,12 +79,13 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
}
|
}
|
||||||
test('XY', async ({ page, homePage }) => {
|
test('XY', async ({ page, homePage }) => {
|
||||||
await sketchOnPlaneAndBackSideTest(
|
await sketchOnPlaneAndBackSideTest(
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
'XY',
|
'XY',
|
||||||
{ x: 600, y: 388 } // red plane
|
{ x: 600, y: 388 } // red plane
|
||||||
// { x: 600, y: 400 }, // red plane // clicks grid helper and that causes problems, should fix so that these coords work too.
|
// { x: 600, y: 400 }, // red plane // clicks grid helper and that causes problems, should fix so that these coords work too.
|
||||||
) })
|
)
|
||||||
|
})
|
||||||
|
|
||||||
test('YZ', async ({ page, homePage }) => {
|
test('YZ', async ({ page, homePage }) => {
|
||||||
await sketchOnPlaneAndBackSideTest(page, homePage, 'YZ', { x: 700, y: 250 }) // green plane
|
await sketchOnPlaneAndBackSideTest(page, homePage, 'YZ', { x: 700, y: 250 }) // green plane
|
||||||
@ -95,11 +96,17 @@ test.describe('Can create sketches on all planes and their back sides', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('-XY', async ({ page, homePage }) => {
|
test('-XY', async ({ page, homePage }) => {
|
||||||
await sketchOnPlaneAndBackSideTest(page, homePage, '-XY', { x: 600, y: 118 }) // back of red plane
|
await sketchOnPlaneAndBackSideTest(page, homePage, '-XY', {
|
||||||
|
x: 600,
|
||||||
|
y: 118,
|
||||||
|
}) // back of red plane
|
||||||
})
|
})
|
||||||
|
|
||||||
test('-YZ', async ({ page, homePage }) => {
|
test('-YZ', async ({ page, homePage }) => {
|
||||||
await sketchOnPlaneAndBackSideTest(page, homePage, '-YZ', { x: 700, y: 219 }) // back of green plan
|
await sketchOnPlaneAndBackSideTest(page, homePage, '-YZ', {
|
||||||
|
x: 700,
|
||||||
|
y: 219,
|
||||||
|
}) // back of green plan
|
||||||
})
|
})
|
||||||
|
|
||||||
test('-XZ', async ({ page, homePage }) => {
|
test('-XZ', async ({ page, homePage }) => {
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
import { test, expect } from './zoo-test'
|
import { test, expect } from './zoo-test'
|
||||||
|
|
||||||
import {
|
import { getUtils, executorInputPath } from './test-utils'
|
||||||
getUtils,
|
|
||||||
executorInputPath,
|
|
||||||
} from './test-utils'
|
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { bracket } from 'lib/exampleKcl'
|
import { bracket } from 'lib/exampleKcl'
|
||||||
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates'
|
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates'
|
||||||
import fsp from 'fs/promises'
|
import fsp from 'fs/promises'
|
||||||
|
|
||||||
test.describe('Code pane and errors', () => {
|
test.describe('Code pane and errors', () => {
|
||||||
test('Typing KCL errors induces a badge on the code pane button', async ({ page, homePage }) => { const u = await getUtils(page)
|
test('Typing KCL errors induces a badge on the code pane button', async ({
|
||||||
|
page,
|
||||||
// Load the app with the working starter code
|
homePage,
|
||||||
await page.addInitScript(() => {
|
}) => {
|
||||||
localStorage.setItem(
|
const u = await getUtils(page)
|
||||||
'persistCode',
|
|
||||||
`// Extruded Triangle
|
// Load the app with the working starter code
|
||||||
|
await page.addInitScript(() => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`// Extruded Triangle
|
||||||
sketch001 = startSketchOn('XZ')
|
sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
@ -24,191 +25,207 @@ test.describe('Code pane and errors', () => {
|
|||||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
extrude001 = extrude(5, sketch001)`
|
extrude001 = extrude(5, sketch001)`
|
||||||
)
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
// wait for execution done
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
// Ensure no badge is present
|
||||||
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
|
await expect(codePaneButtonHolder).not.toContainText('notification')
|
||||||
|
|
||||||
|
// Delete a character to break the KCL
|
||||||
|
await u.openKclCodePanel()
|
||||||
|
await page.getByText('extrude(').click()
|
||||||
|
await page.keyboard.press('Backspace')
|
||||||
|
|
||||||
|
// Ensure that a badge appears on the button
|
||||||
|
await expect(codePaneButtonHolder).toContainText('notification')
|
||||||
})
|
})
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
|
|
||||||
// wait for execution done
|
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
// Ensure no badge is present
|
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
|
||||||
await expect(codePaneButtonHolder).not.toContainText('notification')
|
|
||||||
|
|
||||||
// Delete a character to break the KCL
|
|
||||||
await u.openKclCodePanel()
|
|
||||||
await page.getByText('extrude(').click()
|
|
||||||
await page.keyboard.press('Backspace')
|
|
||||||
|
|
||||||
// Ensure that a badge appears on the button
|
|
||||||
await expect(codePaneButtonHolder).toContainText('notification') })
|
|
||||||
|
|
||||||
test('Opening and closing the code pane will consistently show error diagnostics', async ({ page, homePage }) => {
|
test('Opening and closing the code pane will consistently show error diagnostics', async ({
|
||||||
|
page,
|
||||||
const u = await getUtils(page)
|
homePage,
|
||||||
|
}) => {
|
||||||
// Load the app with the working starter code
|
const u = await getUtils(page)
|
||||||
await page.addInitScript((code) => {
|
|
||||||
localStorage.setItem('persistCode', code)
|
|
||||||
}, bracket)
|
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 900 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
|
|
||||||
// wait for execution done
|
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
// Ensure we have no errors in the gutter.
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
|
||||||
|
|
||||||
// Ensure no badge is present
|
|
||||||
const codePaneButton = page.getByRole('button', { name: 'KCL Code pane' })
|
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
|
||||||
await expect(codePaneButtonHolder).not.toContainText('notification')
|
|
||||||
|
|
||||||
// Delete a character to break the KCL
|
|
||||||
await u.openKclCodePanel()
|
|
||||||
await page.getByText('thickness, bracketLeg1Sketch)').click()
|
|
||||||
await page.keyboard.press('Backspace')
|
|
||||||
|
|
||||||
// Ensure that a badge appears on the button
|
|
||||||
await expect(codePaneButtonHolder).toContainText('notification')
|
|
||||||
|
|
||||||
// Ensure we have an error diagnostic.
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
|
||||||
|
|
||||||
// error text on hover
|
|
||||||
await page.hover('.cm-lint-marker-error')
|
|
||||||
await expect(page.locator('.cm-tooltip').first()).toBeVisible()
|
|
||||||
|
|
||||||
// Close the code pane
|
|
||||||
await codePaneButton.click()
|
|
||||||
|
|
||||||
await page.waitForTimeout(500)
|
|
||||||
|
|
||||||
// Ensure that a badge appears on the button
|
|
||||||
await expect(codePaneButtonHolder).toContainText('notification')
|
|
||||||
// Ensure we have no errors in the gutter.
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
|
||||||
|
|
||||||
// Open the code pane
|
|
||||||
await u.openKclCodePanel()
|
|
||||||
|
|
||||||
// Ensure that a badge appears on the button
|
|
||||||
await expect(codePaneButtonHolder).toContainText('notification')
|
|
||||||
|
|
||||||
// Ensure we have an error diagnostic.
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
|
||||||
|
|
||||||
// error text on hover
|
|
||||||
await page.hover('.cm-lint-marker-error')
|
|
||||||
await expect(page.locator('.cm-tooltip').first()).toBeVisible() })
|
|
||||||
|
|
||||||
test('When error is not in view you can click the badge to scroll to it', async ({ page, homePage, context }) => { const u = await getUtils(page)
|
// Load the app with the working starter code
|
||||||
|
await page.addInitScript((code) => {
|
||||||
// Load the app with the working starter code
|
localStorage.setItem('persistCode', code)
|
||||||
await context.addInitScript((code) => {
|
}, bracket)
|
||||||
localStorage.setItem('persistCode', code)
|
|
||||||
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
|
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
|
|
||||||
// Ensure badge is present
|
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
|
||||||
await expect(codePaneButtonHolder).toContainText('notification')
|
|
||||||
|
|
||||||
// Ensure we have no errors in the gutter, since error out of view.
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
|
||||||
|
|
||||||
// Click the badge.
|
|
||||||
const badge = page.locator('#code-badge')
|
|
||||||
await expect(badge).toBeVisible()
|
|
||||||
await badge.click()
|
|
||||||
|
|
||||||
// Ensure we have an error diagnostic.
|
|
||||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
|
||||||
|
|
||||||
// Hover over the error to see the error message
|
|
||||||
await page.hover('.cm-lint-marker-error')
|
|
||||||
await expect(
|
|
||||||
page
|
|
||||||
.getByText(
|
|
||||||
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
|
|
||||||
)
|
|
||||||
.first()
|
|
||||||
).toBeVisible() })
|
|
||||||
|
|
||||||
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({ context, page, homePage }) => { const u = await getUtils(page)
|
await page.setBodyDimensions({ width: 1200, height: 900 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
// Load the app with the working starter code
|
|
||||||
await context.addInitScript((code) => {
|
// wait for execution done
|
||||||
localStorage.setItem('persistCode', code)
|
await u.openDebugPanel()
|
||||||
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
// Ensure we have no errors in the gutter.
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
|
// Ensure no badge is present
|
||||||
// Ensure badge is present
|
const codePaneButton = page.getByRole('button', { name: 'KCL Code pane' })
|
||||||
const codePaneButtonHolder = page.locator('#code-button-holder')
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
await expect(codePaneButtonHolder).toContainText('notification')
|
await expect(codePaneButtonHolder).not.toContainText('notification')
|
||||||
|
|
||||||
// Ensure we have no errors in the gutter, since error out of view.
|
// Delete a character to break the KCL
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await u.openKclCodePanel()
|
||||||
|
await page.getByText('thickness, bracketLeg1Sketch)').click()
|
||||||
// click in the editor to focus it
|
await page.keyboard.press('Backspace')
|
||||||
await page.locator('.cm-content').click()
|
|
||||||
|
// Ensure that a badge appears on the button
|
||||||
await page.waitForTimeout(500)
|
await expect(codePaneButtonHolder).toContainText('notification')
|
||||||
|
|
||||||
// go to the start of the editor and enter more text which will trigger
|
// Ensure we have an error diagnostic.
|
||||||
// a lint error.
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||||
// GO to the start of the editor.
|
|
||||||
await page.keyboard.press('ArrowUp')
|
// error text on hover
|
||||||
await page.keyboard.press('ArrowUp')
|
await page.hover('.cm-lint-marker-error')
|
||||||
await page.keyboard.press('ArrowUp')
|
await expect(page.locator('.cm-tooltip').first()).toBeVisible()
|
||||||
await page.keyboard.press('ArrowUp')
|
|
||||||
await page.keyboard.press('ArrowUp')
|
// Close the code pane
|
||||||
await page.keyboard.press('ArrowUp')
|
await codePaneButton.click()
|
||||||
await page.keyboard.press('ArrowUp')
|
|
||||||
await page.keyboard.press('ArrowUp')
|
await page.waitForTimeout(500)
|
||||||
await page.keyboard.press('ArrowUp')
|
|
||||||
await page.keyboard.press('ArrowUp')
|
// Ensure that a badge appears on the button
|
||||||
await page.keyboard.press('Home')
|
await expect(codePaneButtonHolder).toContainText('notification')
|
||||||
await page.keyboard.type('foo_bar = 1')
|
// Ensure we have no errors in the gutter.
|
||||||
await page.waitForTimeout(500)
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
// Open the code pane
|
||||||
// ensure we have a lint error
|
await u.openKclCodePanel()
|
||||||
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
|
|
||||||
|
// Ensure that a badge appears on the button
|
||||||
// Click the badge.
|
await expect(codePaneButtonHolder).toContainText('notification')
|
||||||
const badge = page.locator('#code-badge')
|
|
||||||
await expect(badge).toBeVisible()
|
// Ensure we have an error diagnostic.
|
||||||
await badge.click()
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||||
|
|
||||||
// Ensure we have an error diagnostic.
|
// error text on hover
|
||||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
await page.hover('.cm-lint-marker-error')
|
||||||
|
await expect(page.locator('.cm-tooltip').first()).toBeVisible()
|
||||||
// Hover over the error to see the error message
|
})
|
||||||
await page.hover('.cm-lint-marker-error')
|
|
||||||
await expect(
|
test('When error is not in view you can click the badge to scroll to it', async ({
|
||||||
page
|
page,
|
||||||
.getByText(
|
homePage,
|
||||||
'sketch profile must lie entirely on one side of the revolution axis'
|
context,
|
||||||
)
|
}) => {
|
||||||
.first()
|
const u = await getUtils(page)
|
||||||
).toBeVisible() })
|
|
||||||
|
// Load the app with the working starter code
|
||||||
|
await context.addInitScript((code) => {
|
||||||
|
localStorage.setItem('persistCode', code)
|
||||||
|
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
|
||||||
|
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
|
// Ensure badge is present
|
||||||
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
|
await expect(codePaneButtonHolder).toContainText('notification')
|
||||||
|
|
||||||
|
// Ensure we have no errors in the gutter, since error out of view.
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
|
||||||
|
// Click the badge.
|
||||||
|
const badge = page.locator('#code-badge')
|
||||||
|
await expect(badge).toBeVisible()
|
||||||
|
await badge.click()
|
||||||
|
|
||||||
|
// Ensure we have an error diagnostic.
|
||||||
|
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||||
|
|
||||||
|
// Hover over the error to see the error message
|
||||||
|
await page.hover('.cm-lint-marker-error')
|
||||||
|
await expect(
|
||||||
|
page
|
||||||
|
.getByText(
|
||||||
|
'Modeling command failed: [ApiError { error_code: InternalEngine, message: "Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis" }]'
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
).toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('When error is not in view WITH LINTS you can click the badge to scroll to it', async ({
|
||||||
|
context,
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
|
||||||
|
// Load the app with the working starter code
|
||||||
|
await context.addInitScript((code) => {
|
||||||
|
localStorage.setItem('persistCode', code)
|
||||||
|
}, TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW)
|
||||||
|
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
|
||||||
|
// Ensure badge is present
|
||||||
|
const codePaneButtonHolder = page.locator('#code-button-holder')
|
||||||
|
await expect(codePaneButtonHolder).toContainText('notification')
|
||||||
|
|
||||||
|
// Ensure we have no errors in the gutter, since error out of view.
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
|
||||||
|
// click in the editor to focus it
|
||||||
|
await page.locator('.cm-content').click()
|
||||||
|
|
||||||
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
|
// go to the start of the editor and enter more text which will trigger
|
||||||
|
// a lint error.
|
||||||
|
// GO to the start of the editor.
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('Home')
|
||||||
|
await page.keyboard.type('foo_bar = 1')
|
||||||
|
await page.waitForTimeout(500)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
|
// ensure we have a lint error
|
||||||
|
await expect(page.locator('.cm-lint-marker-info').first()).toBeVisible()
|
||||||
|
|
||||||
|
// Click the badge.
|
||||||
|
const badge = page.locator('#code-badge')
|
||||||
|
await expect(badge).toBeVisible()
|
||||||
|
await badge.click()
|
||||||
|
|
||||||
|
// Ensure we have an error diagnostic.
|
||||||
|
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||||
|
|
||||||
|
// Hover over the error to see the error message
|
||||||
|
await page.hover('.cm-lint-marker-error')
|
||||||
|
await expect(
|
||||||
|
page
|
||||||
|
.getByText(
|
||||||
|
'sketch profile must lie entirely on one side of the revolution axis'
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
).toBeVisible()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@ -287,7 +304,7 @@ test(
|
|||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
async ({ context, browserName, page }, testInfo) => {
|
async ({ context, browserName, page }, testInfo) => {
|
||||||
const PROJECT_DIR_NAME = 'lee-was-here'
|
const PROJECT_DIR_NAME = 'lee-was-here'
|
||||||
const { dir: projectsDir, } = await context.folderSetupFn(async (dir) => {
|
const { dir: projectsDir } = await context.folderSetupFn(async (dir) => {
|
||||||
const aProjectDir = join(dir, PROJECT_DIR_NAME)
|
const aProjectDir = join(dir, PROJECT_DIR_NAME)
|
||||||
await fsp.mkdir(aProjectDir, { recursive: true })
|
await fsp.mkdir(aProjectDir, { recursive: true })
|
||||||
})
|
})
|
||||||
|
@ -5,46 +5,52 @@ import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
|||||||
import { normalizeLineEndings } from 'lib/codeEditor'
|
import { normalizeLineEndings } from 'lib/codeEditor'
|
||||||
|
|
||||||
test.describe('Command bar tests', () => {
|
test.describe('Command bar tests', () => {
|
||||||
test('Extrude from command bar selects extrude line after', async ({ page, homePage }) => { await page.addInitScript(async () => {
|
test('Extrude from command bar selects extrude line after', async ({
|
||||||
localStorage.setItem(
|
page,
|
||||||
'persistCode',
|
homePage,
|
||||||
`sketch001 = startSketchOn('XY')
|
}) => {
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`sketch001 = startSketchOn('XY')
|
||||||
|> startProfileAt([-10, -10], %)
|
|> startProfileAt([-10, -10], %)
|
||||||
|> line([20, 0], %)
|
|> line([20, 0], %)
|
||||||
|> line([0, 20], %)
|
|> line([0, 20], %)
|
||||||
|> xLine(-20, %)
|
|> xLine(-20, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
`
|
`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
// Click the line of code for xLine.
|
||||||
|
await page.getByText(`close(%)`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Extrude' }).click()
|
||||||
|
await page.waitForTimeout(200)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
await page.waitForTimeout(200)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
await page.waitForTimeout(200)
|
||||||
|
await expect(page.locator('.cm-activeLine')).toHaveText(
|
||||||
|
`extrude001 = extrude(${KCL_DEFAULT_LENGTH}, sketch001)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
|
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
// Click the line of code for xLine.
|
|
||||||
await page.getByText(`close(%)`).click() // TODO remove this and reinstate // await topHorzSegmentClick()
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Extrude' }).click()
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
await page.waitForTimeout(200)
|
|
||||||
await expect(page.locator('.cm-activeLine')).toHaveText(
|
|
||||||
`extrude001 = extrude(${KCL_DEFAULT_LENGTH}, sketch001)`
|
|
||||||
) })
|
|
||||||
|
|
||||||
test('Fillet from command bar', async ({ page, homePage }) => { await page.addInitScript(async () => {
|
test('Fillet from command bar', async ({ page, homePage }) => {
|
||||||
localStorage.setItem(
|
await page.addInitScript(async () => {
|
||||||
'persistCode',
|
localStorage.setItem(
|
||||||
`sketch001 = startSketchOn('XY')
|
'persistCode',
|
||||||
|
`sketch001 = startSketchOn('XY')
|
||||||
|> startProfileAt([-5, -5], %)
|
|> startProfileAt([-5, -5], %)
|
||||||
|> line([0, 10], %)
|
|> line([0, 10], %)
|
||||||
|> line([10, 0], %)
|
|> line([10, 0], %)
|
||||||
@ -52,158 +58,170 @@ test.describe('Command bar tests', () => {
|
|||||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
extrude001 = extrude(-10, sketch001)`
|
extrude001 = extrude(-10, sketch001)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
const selectSegment = () => page.getByText(`line([0, -10], %)`).click()
|
||||||
|
|
||||||
|
await selectSegment()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.getByRole('button', { name: 'Fillet' }).click()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.keyboard.press('Enter') // skip selection
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.keyboard.press('Enter') // accept default radius
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.keyboard.press('Enter') // submit
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await expect(page.locator('.cm-activeLine')).toContainText(
|
||||||
|
`fillet({ radius: ${KCL_DEFAULT_LENGTH}, tags: [seg01] }, %)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
const selectSegment = () => page.getByText(`line([0, -10], %)`).click()
|
|
||||||
|
|
||||||
await selectSegment()
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await page.getByRole('button', { name: 'Fillet' }).click()
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await page.keyboard.press('Enter') // skip selection
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await page.keyboard.press('Enter') // accept default radius
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await page.keyboard.press('Enter') // submit
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await expect(page.locator('.cm-activeLine')).toContainText(
|
|
||||||
`fillet({ radius: ${KCL_DEFAULT_LENGTH}, tags: [seg01] }, %)`
|
|
||||||
) })
|
|
||||||
|
|
||||||
test('Command bar can change a setting, and switch back and forth between arguments', async ({ page, homePage }) => { const u = await getUtils(page)
|
test('Command bar can change a setting, and switch back and forth between arguments', async ({
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
page,
|
||||||
await homePage.goToModelingScene()
|
homePage,
|
||||||
|
}) => {
|
||||||
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
const u = await getUtils(page)
|
||||||
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
const commandName = 'debug panel'
|
await homePage.goToModelingScene()
|
||||||
const commandOption = page.getByRole('option', {
|
|
||||||
name: commandName,
|
const commandBarButton = page.getByRole('button', { name: 'Commands' })
|
||||||
exact: false,
|
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||||
|
const commandName = 'debug panel'
|
||||||
|
const commandOption = page.getByRole('option', {
|
||||||
|
name: commandName,
|
||||||
|
exact: false,
|
||||||
|
})
|
||||||
|
const commandLevelArgButton = page.getByRole('button', { name: 'level' })
|
||||||
|
const commandThemeArgButton = page.getByRole('button', { name: 'value' })
|
||||||
|
const paneSelector = page.getByRole('button', { name: 'debug panel' })
|
||||||
|
// This selector changes after we set the setting
|
||||||
|
let commandOptionInput = page.getByPlaceholder('On')
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).not.toBeDisabled()
|
||||||
|
|
||||||
|
// First try opening the command bar and closing it
|
||||||
|
await page
|
||||||
|
.getByRole('button', { name: 'Commands', exact: false })
|
||||||
|
.or(page.getByRole('button', { name: '⌘K' }))
|
||||||
|
.click()
|
||||||
|
|
||||||
|
await expect(cmdSearchBar).toBeVisible()
|
||||||
|
await page.keyboard.press('Escape')
|
||||||
|
await expect(cmdSearchBar).not.toBeVisible()
|
||||||
|
|
||||||
|
// Now try the same, but with the keyboard shortcut, check focus
|
||||||
|
await page.keyboard.press('ControlOrMeta+K')
|
||||||
|
await expect(cmdSearchBar).toBeVisible()
|
||||||
|
await expect(cmdSearchBar).toBeFocused()
|
||||||
|
|
||||||
|
// Try typing in the command bar
|
||||||
|
await cmdSearchBar.fill(commandName)
|
||||||
|
await expect(commandOption).toBeVisible()
|
||||||
|
await commandOption.click()
|
||||||
|
const toggleInput = page.getByPlaceholder('On')
|
||||||
|
await expect(toggleInput).toBeVisible()
|
||||||
|
await expect(toggleInput).toBeFocused()
|
||||||
|
// Select On
|
||||||
|
await page.keyboard.press('ArrowDown')
|
||||||
|
await page.keyboard.press('ArrowDown')
|
||||||
|
await expect(page.getByRole('option', { name: 'Off' })).toHaveAttribute(
|
||||||
|
'data-headlessui-state',
|
||||||
|
'active'
|
||||||
|
)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
|
// Check the toast appeared
|
||||||
|
await expect(
|
||||||
|
page.getByText(`Set show debug panel to "false" for this project`)
|
||||||
|
).toBeVisible()
|
||||||
|
// Check that the visibility changed
|
||||||
|
await expect(paneSelector).not.toBeVisible()
|
||||||
|
|
||||||
|
commandOptionInput = page.locator('[id="option-input"]')
|
||||||
|
|
||||||
|
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
|
||||||
|
await commandBarButton.click()
|
||||||
|
await cmdSearchBar.focus()
|
||||||
|
await cmdSearchBar.fill(commandName)
|
||||||
|
await commandOption.click()
|
||||||
|
await expect(commandThemeArgButton).toBeDisabled()
|
||||||
|
await commandOptionInput.focus()
|
||||||
|
await commandOptionInput.fill('on')
|
||||||
|
await commandLevelArgButton.click()
|
||||||
|
await expect(commandLevelArgButton).toBeDisabled()
|
||||||
|
|
||||||
|
// Test case for https://github.com/KittyCAD/modeling-app/issues/2881
|
||||||
|
await commandThemeArgButton.click()
|
||||||
|
await expect(commandThemeArgButton).toBeDisabled()
|
||||||
|
await expect(commandLevelArgButton).toHaveText('level: project')
|
||||||
})
|
})
|
||||||
const commandLevelArgButton = page.getByRole('button', { name: 'level' })
|
|
||||||
const commandThemeArgButton = page.getByRole('button', { name: 'value' })
|
|
||||||
const paneSelector = page.getByRole('button', { name: 'debug panel' })
|
|
||||||
// This selector changes after we set the setting
|
|
||||||
let commandOptionInput = page.getByPlaceholder('On')
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
).not.toBeDisabled()
|
|
||||||
|
|
||||||
// First try opening the command bar and closing it
|
|
||||||
await page
|
|
||||||
.getByRole('button', { name: 'Commands', exact: false })
|
|
||||||
.or(page.getByRole('button', { name: '⌘K' }))
|
|
||||||
.click()
|
|
||||||
|
|
||||||
await expect(cmdSearchBar).toBeVisible()
|
|
||||||
await page.keyboard.press('Escape')
|
|
||||||
await expect(cmdSearchBar).not.toBeVisible()
|
|
||||||
|
|
||||||
// Now try the same, but with the keyboard shortcut, check focus
|
|
||||||
await page.keyboard.press('ControlOrMeta+K')
|
|
||||||
await expect(cmdSearchBar).toBeVisible()
|
|
||||||
await expect(cmdSearchBar).toBeFocused()
|
|
||||||
|
|
||||||
// Try typing in the command bar
|
|
||||||
await cmdSearchBar.fill(commandName)
|
|
||||||
await expect(commandOption).toBeVisible()
|
|
||||||
await commandOption.click()
|
|
||||||
const toggleInput = page.getByPlaceholder('On')
|
|
||||||
await expect(toggleInput).toBeVisible()
|
|
||||||
await expect(toggleInput).toBeFocused()
|
|
||||||
// Select On
|
|
||||||
await page.keyboard.press('ArrowDown')
|
|
||||||
await page.keyboard.press('ArrowDown')
|
|
||||||
await expect(page.getByRole('option', { name: 'Off' })).toHaveAttribute(
|
|
||||||
'data-headlessui-state',
|
|
||||||
'active'
|
|
||||||
)
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Check the toast appeared
|
|
||||||
await expect(
|
|
||||||
page.getByText(`Set show debug panel to "false" for this project`)
|
|
||||||
).toBeVisible()
|
|
||||||
// Check that the visibility changed
|
|
||||||
await expect(paneSelector).not.toBeVisible()
|
|
||||||
|
|
||||||
commandOptionInput = page.locator('[id="option-input"]')
|
|
||||||
|
|
||||||
// Test case for https://github.com/KittyCAD/modeling-app/issues/2882
|
|
||||||
await commandBarButton.click()
|
|
||||||
await cmdSearchBar.focus()
|
|
||||||
await cmdSearchBar.fill(commandName)
|
|
||||||
await commandOption.click()
|
|
||||||
await expect(commandThemeArgButton).toBeDisabled()
|
|
||||||
await commandOptionInput.focus()
|
|
||||||
await commandOptionInput.fill('on')
|
|
||||||
await commandLevelArgButton.click()
|
|
||||||
await expect(commandLevelArgButton).toBeDisabled()
|
|
||||||
|
|
||||||
// Test case for https://github.com/KittyCAD/modeling-app/issues/2881
|
|
||||||
await commandThemeArgButton.click()
|
|
||||||
await expect(commandThemeArgButton).toBeDisabled()
|
|
||||||
await expect(commandLevelArgButton).toHaveText('level: project') })
|
|
||||||
|
|
||||||
test('Command bar keybinding works from code editor and can change a setting', async ({ page, homePage }) => { const u = await getUtils(page)
|
test('Command bar keybinding works from code editor and can change a setting', async ({
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
page,
|
||||||
await homePage.goToModelingScene()
|
homePage,
|
||||||
|
}) => {
|
||||||
await expect(
|
const u = await getUtils(page)
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
).not.toBeDisabled()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
// Put the cursor in the code editor
|
await expect(
|
||||||
await page.locator('.cm-content').click()
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).not.toBeDisabled()
|
||||||
// Now try the same, but with the keyboard shortcut, check focus
|
|
||||||
await page.keyboard.press('ControlOrMeta+K')
|
// Put the cursor in the code editor
|
||||||
|
await page.locator('.cm-content').click()
|
||||||
let cmdSearchBar = page.getByPlaceholder('Search commands')
|
|
||||||
await expect(cmdSearchBar).toBeVisible()
|
// Now try the same, but with the keyboard shortcut, check focus
|
||||||
await expect(cmdSearchBar).toBeFocused()
|
await page.keyboard.press('ControlOrMeta+K')
|
||||||
|
|
||||||
// Try typing in the command bar
|
let cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||||
await cmdSearchBar.fill('theme')
|
await expect(cmdSearchBar).toBeVisible()
|
||||||
const themeOption = page.getByRole('option', {
|
await expect(cmdSearchBar).toBeFocused()
|
||||||
name: 'Settings · app · theme',
|
|
||||||
|
// Try typing in the command bar
|
||||||
|
await cmdSearchBar.fill('theme')
|
||||||
|
const themeOption = page.getByRole('option', {
|
||||||
|
name: 'Settings · app · theme',
|
||||||
|
})
|
||||||
|
await expect(themeOption).toBeVisible()
|
||||||
|
await themeOption.click()
|
||||||
|
const themeInput = page.getByPlaceholder('dark')
|
||||||
|
await expect(themeInput).toBeVisible()
|
||||||
|
await expect(themeInput).toBeFocused()
|
||||||
|
// Select dark theme
|
||||||
|
await page.keyboard.press('ArrowDown')
|
||||||
|
await page.keyboard.press('ArrowDown')
|
||||||
|
await page.keyboard.press('ArrowDown')
|
||||||
|
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
|
||||||
|
'data-headlessui-state',
|
||||||
|
'active'
|
||||||
|
)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
|
// Check the toast appeared
|
||||||
|
await expect(
|
||||||
|
page.getByText(`Set theme to "system" as a user default`)
|
||||||
|
).toBeVisible()
|
||||||
|
// Check that the theme changed
|
||||||
|
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||||
})
|
})
|
||||||
await expect(themeOption).toBeVisible()
|
|
||||||
await themeOption.click()
|
|
||||||
const themeInput = page.getByPlaceholder('dark')
|
|
||||||
await expect(themeInput).toBeVisible()
|
|
||||||
await expect(themeInput).toBeFocused()
|
|
||||||
// Select dark theme
|
|
||||||
await page.keyboard.press('ArrowDown')
|
|
||||||
await page.keyboard.press('ArrowDown')
|
|
||||||
await page.keyboard.press('ArrowDown')
|
|
||||||
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
|
|
||||||
'data-headlessui-state',
|
|
||||||
'active'
|
|
||||||
)
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Check the toast appeared
|
|
||||||
await expect(
|
|
||||||
page.getByText(`Set theme to "system" as a user default`)
|
|
||||||
).toBeVisible()
|
|
||||||
// Check that the theme changed
|
|
||||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`) })
|
|
||||||
|
|
||||||
test('Can extrude from the command bar', async ({ page, homePage }) => { await page.addInitScript(async () => {
|
test('Can extrude from the command bar', async ({ page, homePage }) => {
|
||||||
localStorage.setItem(
|
await page.addInitScript(async () => {
|
||||||
'persistCode',
|
localStorage.setItem(
|
||||||
`distance = sqrt(20)
|
'persistCode',
|
||||||
|
`distance = sqrt(20)
|
||||||
sketch001 = startSketchOn('XZ')
|
sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([-6.95, 10.98], %)
|
|> startProfileAt([-6.95, 10.98], %)
|
||||||
|> line([25.1, 0.41], %)
|
|> line([25.1, 0.41], %)
|
||||||
@ -211,117 +229,123 @@ test.describe('Command bar tests', () => {
|
|||||||
|> line([-23.44, 0.52], %)
|
|> line([-23.44, 0.52], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
`
|
`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
// Make sure the stream is up
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).not.toBeDisabled()
|
||||||
|
await u.clearCommandLogs()
|
||||||
|
await page.getByRole('button', { name: 'Extrude' }).isEnabled()
|
||||||
|
|
||||||
|
let cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||||
|
await page.keyboard.press('ControlOrMeta+K')
|
||||||
|
await expect(cmdSearchBar).toBeVisible()
|
||||||
|
|
||||||
|
// Search for extrude command and choose it
|
||||||
|
await page.getByRole('option', { name: 'Extrude' }).click()
|
||||||
|
|
||||||
|
// Assert that we're on the selection step
|
||||||
|
await expect(page.getByRole('button', { name: 'selection' })).toBeDisabled()
|
||||||
|
// Select a face
|
||||||
|
await page.mouse.move(700, 200)
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
|
// Assert that we're on the distance step
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'distance', exact: false })
|
||||||
|
).toBeDisabled()
|
||||||
|
|
||||||
|
// Assert that the an alternative variable name is chosen,
|
||||||
|
// since the default variable name is already in use (distance)
|
||||||
|
await page.getByRole('button', { name: 'Create new variable' }).click()
|
||||||
|
await expect(page.getByPlaceholder('Variable name')).toHaveValue(
|
||||||
|
'distance001'
|
||||||
|
)
|
||||||
|
|
||||||
|
const continueButton = page.getByRole('button', { name: 'Continue' })
|
||||||
|
const submitButton = page.getByRole('button', { name: 'Submit command' })
|
||||||
|
await continueButton.click()
|
||||||
|
|
||||||
|
// Review step and argument hotkeys
|
||||||
|
await expect(submitButton).toBeEnabled()
|
||||||
|
await expect(submitButton).toBeFocused()
|
||||||
|
await submitButton.press('Backspace')
|
||||||
|
|
||||||
|
// Assert we're back on the distance step
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'distance', exact: false })
|
||||||
|
).toBeDisabled()
|
||||||
|
|
||||||
|
await continueButton.click()
|
||||||
|
await submitButton.click()
|
||||||
|
|
||||||
|
await u.waitForCmdReceive('extrude')
|
||||||
|
|
||||||
|
await expect(page.locator('.cm-content')).toContainText(
|
||||||
|
'extrude001 = extrude(distance001, sketch001)'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
|
|
||||||
// Make sure the stream is up
|
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
).not.toBeDisabled()
|
|
||||||
await u.clearCommandLogs()
|
|
||||||
await page.getByRole('button', { name: 'Extrude' }).isEnabled()
|
|
||||||
|
|
||||||
let cmdSearchBar = page.getByPlaceholder('Search commands')
|
|
||||||
await page.keyboard.press('ControlOrMeta+K')
|
|
||||||
await expect(cmdSearchBar).toBeVisible()
|
|
||||||
|
|
||||||
// Search for extrude command and choose it
|
|
||||||
await page.getByRole('option', { name: 'Extrude' }).click()
|
|
||||||
|
|
||||||
// Assert that we're on the selection step
|
|
||||||
await expect(page.getByRole('button', { name: 'selection' })).toBeDisabled()
|
|
||||||
// Select a face
|
|
||||||
await page.mouse.move(700, 200)
|
|
||||||
await page.mouse.click(700, 200)
|
|
||||||
|
|
||||||
// Assert that we're on the distance step
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'distance', exact: false })
|
|
||||||
).toBeDisabled()
|
|
||||||
|
|
||||||
// Assert that the an alternative variable name is chosen,
|
|
||||||
// since the default variable name is already in use (distance)
|
|
||||||
await page.getByRole('button', { name: 'Create new variable' }).click()
|
|
||||||
await expect(page.getByPlaceholder('Variable name')).toHaveValue(
|
|
||||||
'distance001'
|
|
||||||
)
|
|
||||||
|
|
||||||
const continueButton = page.getByRole('button', { name: 'Continue' })
|
|
||||||
const submitButton = page.getByRole('button', { name: 'Submit command' })
|
|
||||||
await continueButton.click()
|
|
||||||
|
|
||||||
// Review step and argument hotkeys
|
|
||||||
await expect(submitButton).toBeEnabled()
|
|
||||||
await expect(submitButton).toBeFocused()
|
|
||||||
await submitButton.press('Backspace')
|
|
||||||
|
|
||||||
// Assert we're back on the distance step
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'distance', exact: false })
|
|
||||||
).toBeDisabled()
|
|
||||||
|
|
||||||
await continueButton.click()
|
|
||||||
await submitButton.click()
|
|
||||||
|
|
||||||
await u.waitForCmdReceive('extrude')
|
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toContainText('extrude001 = extrude(distance001, sketch001)')
|
test('Can switch between sketch tools via command bar', async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
})
|
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
||||||
|
const rectangleToolCommand = page.getByRole('option', {
|
||||||
|
name: 'rectangle',
|
||||||
|
})
|
||||||
|
const rectangleToolButton = page.getByRole('button', {
|
||||||
|
name: 'rectangle Corner rectangle',
|
||||||
|
})
|
||||||
|
const lineToolCommand = page.getByRole('option', {
|
||||||
|
name: 'Line',
|
||||||
|
})
|
||||||
|
const lineToolButton = page.getByRole('button', {
|
||||||
|
name: 'line Line',
|
||||||
|
exact: true,
|
||||||
|
})
|
||||||
|
const arcToolCommand = page.getByRole('option', { name: 'Tangential Arc' })
|
||||||
|
const arcToolButton = page.getByRole('button', {
|
||||||
|
name: 'arc Tangential Arc',
|
||||||
|
})
|
||||||
|
|
||||||
test('Can switch between sketch tools via command bar', async ({ page, homePage }) => { const u = await getUtils(page)
|
// Start a sketch
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await sketchButton.click()
|
||||||
await homePage.goToModelingScene()
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
const sketchButton = page.getByRole('button', { name: 'Start Sketch' })
|
// Switch between sketch tools via the command bar
|
||||||
const cmdBarButton = page.getByRole('button', { name: 'Commands' })
|
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
const rectangleToolCommand = page.getByRole('option', {
|
await cmdBarButton.click()
|
||||||
name: 'rectangle',
|
await rectangleToolCommand.click()
|
||||||
|
await expect(rectangleToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
await cmdBarButton.click()
|
||||||
|
await lineToolCommand.click()
|
||||||
|
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
|
// Click in the scene a couple times to draw a line
|
||||||
|
// so tangential arc is valid
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
await page.mouse.move(700, 300, { steps: 5 })
|
||||||
|
await page.mouse.click(700, 300)
|
||||||
|
|
||||||
|
// switch to tangential arc via command bar
|
||||||
|
await cmdBarButton.click()
|
||||||
|
await arcToolCommand.click()
|
||||||
|
await expect(arcToolButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
})
|
})
|
||||||
const rectangleToolButton = page.getByRole('button', {
|
|
||||||
name: 'rectangle Corner rectangle',
|
|
||||||
})
|
|
||||||
const lineToolCommand = page.getByRole('option', {
|
|
||||||
name: 'Line',
|
|
||||||
})
|
|
||||||
const lineToolButton = page.getByRole('button', {
|
|
||||||
name: 'line Line',
|
|
||||||
exact: true,
|
|
||||||
})
|
|
||||||
const arcToolCommand = page.getByRole('option', { name: 'Tangential Arc' })
|
|
||||||
const arcToolButton = page.getByRole('button', {
|
|
||||||
name: 'arc Tangential Arc',
|
|
||||||
})
|
|
||||||
|
|
||||||
// Start a sketch
|
|
||||||
await sketchButton.click()
|
|
||||||
await page.mouse.click(700, 200)
|
|
||||||
|
|
||||||
// Switch between sketch tools via the command bar
|
|
||||||
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
|
||||||
await cmdBarButton.click()
|
|
||||||
await rectangleToolCommand.click()
|
|
||||||
await expect(rectangleToolButton).toHaveAttribute('aria-pressed', 'true')
|
|
||||||
await cmdBarButton.click()
|
|
||||||
await lineToolCommand.click()
|
|
||||||
await expect(lineToolButton).toHaveAttribute('aria-pressed', 'true')
|
|
||||||
|
|
||||||
// Click in the scene a couple times to draw a line
|
|
||||||
// so tangential arc is valid
|
|
||||||
await page.mouse.click(700, 200)
|
|
||||||
await page.mouse.move(700, 300, { steps: 5 })
|
|
||||||
await page.mouse.click(700, 300)
|
|
||||||
|
|
||||||
// switch to tangential arc via command bar
|
|
||||||
await cmdBarButton.click()
|
|
||||||
await arcToolCommand.click()
|
|
||||||
await expect(arcToolButton).toHaveAttribute('aria-pressed', 'true') })
|
|
||||||
})
|
})
|
||||||
|
@ -1,23 +1,16 @@
|
|||||||
import { test, expect } from '@playwright/test'
|
import { test, expect } from './zoo-test'
|
||||||
import { getUtils, setup, tearDown } from './test-utils'
|
import { getUtils } from './test-utils'
|
||||||
|
|
||||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
|
||||||
await setup(context, page, testInfo)
|
|
||||||
})
|
|
||||||
|
|
||||||
test.afterEach(async ({ page }, testInfo) => {
|
|
||||||
await tearDown(page, testInfo)
|
|
||||||
})
|
|
||||||
test.describe('Copilot ghost text', () => {
|
test.describe('Copilot ghost text', () => {
|
||||||
// eslint-disable-next-line jest/valid-title
|
// eslint-disable-next-line jest/valid-title
|
||||||
test.skip(true, 'Needs to get covered again')
|
test.skip(true, 'Needs to get covered again')
|
||||||
|
|
||||||
test('completes code in empty file', async ({ page }) => {
|
test('completes code in empty file', async ({ page, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -55,9 +48,9 @@ test.describe('Copilot ghost text', () => {
|
|||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -101,12 +94,13 @@ test.describe('Copilot ghost text', () => {
|
|||||||
|
|
||||||
test('copilot disabled in sketch mode after selecting plane', async ({
|
test('copilot disabled in sketch mode after selecting plane', async ({
|
||||||
page,
|
page,
|
||||||
|
homePage,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -184,12 +178,12 @@ test.describe('Copilot ghost text', () => {
|
|||||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('ArrowUp in code rejects the suggestion', async ({ page }) => {
|
test('ArrowUp in code rejects the suggestion', async ({ page, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -212,12 +206,15 @@ test.describe('Copilot ghost text', () => {
|
|||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('ArrowDown in code rejects the suggestion', async ({ page }) => {
|
test('ArrowDown in code rejects the suggestion', async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -240,12 +237,15 @@ test.describe('Copilot ghost text', () => {
|
|||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('ArrowLeft in code rejects the suggestion', async ({ page }) => {
|
test('ArrowLeft in code rejects the suggestion', async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -268,12 +268,15 @@ test.describe('Copilot ghost text', () => {
|
|||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('ArrowRight in code rejects the suggestion', async ({ page }) => {
|
test('ArrowRight in code rejects the suggestion', async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -296,12 +299,12 @@ test.describe('Copilot ghost text', () => {
|
|||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Enter in code scoots it down', async ({ page }) => {
|
test('Enter in code scoots it down', async ({ page, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -326,12 +329,15 @@ test.describe('Copilot ghost text', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Ctrl+shift+z in code rejects the suggestion', async ({ page }) => {
|
test('Ctrl+shift+z in code rejects the suggestion', async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
@ -360,12 +366,13 @@ test.describe('Copilot ghost text', () => {
|
|||||||
|
|
||||||
test('Ctrl+z in code rejects the suggestion and undos the last code', async ({
|
test('Ctrl+z in code rejects the suggestion and undos the last code', async ({
|
||||||
page,
|
page,
|
||||||
|
homePage,
|
||||||
}) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await page.waitForTimeout(800)
|
await page.waitForTimeout(800)
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
@ -420,98 +427,107 @@ test.describe('Copilot ghost text', () => {
|
|||||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||||
|
|
||||||
// TODO when we make codemirror a widget, we can test this.
|
// TODO when we make codemirror a widget, we can test this.
|
||||||
//await expect(page.locator('.cm-content')).toHaveText(``)
|
//await expect(page.locator('.cm-content')).toHaveText(``) })
|
||||||
})
|
|
||||||
|
|
||||||
test('delete in code rejects the suggestion', async ({ page }) => {
|
test('delete in code rejects the suggestion', async ({
|
||||||
const u = await getUtils(page)
|
page,
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
homePage,
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
|
|
||||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||||
)
|
)
|
||||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||||
`fn cube = (pos, scale) => {`
|
`fn cube = (pos, scale) => {`
|
||||||
)
|
)
|
||||||
|
|
||||||
// Going elsewhere in the code should hide the ghost text.
|
// Going elsewhere in the code should hide the ghost text.
|
||||||
await page.keyboard.press('Delete')
|
await page.keyboard.press('Delete')
|
||||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('backspace in code rejects the suggestion', async ({ page }) => {
|
test('backspace in code rejects the suggestion', async ({
|
||||||
const u = await getUtils(page)
|
page,
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
homePage,
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
|
|
||||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||||
)
|
)
|
||||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||||
`fn cube = (pos, scale) => {`
|
`fn cube = (pos, scale) => {`
|
||||||
)
|
)
|
||||||
|
|
||||||
// Going elsewhere in the code should hide the ghost text.
|
// Going elsewhere in the code should hide the ghost text.
|
||||||
await page.keyboard.press('Backspace')
|
await page.keyboard.press('Backspace')
|
||||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('focus outside code pane rejects the suggestion', async ({ page }) => {
|
test('focus outside code pane rejects the suggestion', async ({
|
||||||
const u = await getUtils(page)
|
page,
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
homePage,
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await u.waitForAuthSkipAppStart()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await u.codeLocator.click()
|
await u.codeLocator.click()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
|
|
||||||
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText')).not.toBeVisible()
|
||||||
await page.waitForTimeout(500)
|
await page.waitForTimeout(500)
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
await expect(page.locator('.cm-ghostText').first()).toBeVisible()
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
`fn cube = (pos, scale) => { sg = startSketchOn('XY') |> startProfileAt(pos, %) |> line([0, scale], %) |> line([scale, 0], %) |> line([0, -scale], %) return sg}part001 = cube([0,0], 20) |> close(%) |> extrude(20, %)`
|
||||||
)
|
)
|
||||||
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
await expect(page.locator('.cm-ghostText').first()).toHaveText(
|
||||||
`fn cube = (pos, scale) => {`
|
`fn cube = (pos, scale) => {`
|
||||||
)
|
)
|
||||||
|
|
||||||
// Going outside the editor should hide the ghost text.
|
// Going outside the editor should hide the ghost text.
|
||||||
await page.mouse.move(0, 0)
|
await page.mouse.move(0, 0)
|
||||||
await page
|
await page
|
||||||
.getByRole('button', { name: 'Start Sketch' })
|
.getByRole('button', { name: 'Start Sketch' })
|
||||||
.waitFor({ state: 'visible' })
|
.waitFor({ state: 'visible' })
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||||
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
await expect(page.locator('.cm-ghostText').first()).not.toBeVisible()
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(``)
|
await expect(page.locator('.cm-content')).toHaveText(``)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -65,7 +65,7 @@ export class AuthenticatedTronApp {
|
|||||||
public readonly testInfo: TestInfo
|
public readonly testInfo: TestInfo
|
||||||
public electronApp?: ElectronApplication
|
public electronApp?: ElectronApplication
|
||||||
public readonly viewPortSize = { width: 1200, height: 500 }
|
public readonly viewPortSize = { width: 1200, height: 500 }
|
||||||
public dir: string = ""
|
public dir: string = ''
|
||||||
|
|
||||||
constructor(context: BrowserContext, page: Page, testInfo: TestInfo) {
|
constructor(context: BrowserContext, page: Page, testInfo: TestInfo) {
|
||||||
this._page = page
|
this._page = page
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -418,7 +418,7 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
|||||||
codeLocator: page.locator('.cm-content'),
|
codeLocator: page.locator('.cm-content'),
|
||||||
crushKclCodeIntoOneLineAndThenMaybeSome: async () => {
|
crushKclCodeIntoOneLineAndThenMaybeSome: async () => {
|
||||||
const code = await page.locator('.cm-content').innerText()
|
const code = await page.locator('.cm-content').innerText()
|
||||||
return code.replaceAll(' ', '').replaceAll("\n", '')
|
return code.replaceAll(' ', '').replaceAll('\n', '')
|
||||||
},
|
},
|
||||||
normalisedEditorCode: async () => {
|
normalisedEditorCode: async () => {
|
||||||
const code = await page.locator('.cm-content').innerText()
|
const code = await page.locator('.cm-content').innerText()
|
||||||
@ -687,14 +687,16 @@ const moveDownloadedFileTo = async (page: Page, toLocation: string) => {
|
|||||||
|
|
||||||
const downloadDir = path.resolve(
|
const downloadDir = path.resolve(
|
||||||
page.TEST_SETTINGS_FILE_KEY,
|
page.TEST_SETTINGS_FILE_KEY,
|
||||||
"downloads-during-playwright"
|
'downloads-during-playwright'
|
||||||
)
|
)
|
||||||
|
|
||||||
// Expect there to be at least one file
|
// Expect there to be at least one file
|
||||||
expect.poll(async () => {
|
expect
|
||||||
const files = await fsp.readdir(downloadDir)
|
.poll(async () => {
|
||||||
return files.length
|
const files = await fsp.readdir(downloadDir)
|
||||||
}).toBe(1)
|
return files.length
|
||||||
|
})
|
||||||
|
.toBe(1)
|
||||||
|
|
||||||
// Go through the downloads dir and move files to new location
|
// Go through the downloads dir and move files to new location
|
||||||
const files = await fsp.readdir(downloadDir)
|
const files = await fsp.readdir(downloadDir)
|
||||||
@ -832,7 +834,13 @@ export async function setup(
|
|||||||
testInfo?: TestInfo
|
testInfo?: TestInfo
|
||||||
) {
|
) {
|
||||||
await context.addInitScript(
|
await context.addInitScript(
|
||||||
async ({ token, settingsKey, settings, IS_PLAYWRIGHT_KEY, PLAYWRIGHT_TEST_DIR }) => {
|
async ({
|
||||||
|
token,
|
||||||
|
settingsKey,
|
||||||
|
settings,
|
||||||
|
IS_PLAYWRIGHT_KEY,
|
||||||
|
PLAYWRIGHT_TEST_DIR,
|
||||||
|
}) => {
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
localStorage.setItem('TOKEN_PERSIST_KEY', token)
|
localStorage.setItem('TOKEN_PERSIST_KEY', token)
|
||||||
localStorage.setItem('persistCode', ``)
|
localStorage.setItem('persistCode', ``)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,42 +4,44 @@ import { doExport, getUtils, makeTemplate } from './test-utils'
|
|||||||
|
|
||||||
test.fixme('Units menu', async ({ page, homePage }) => {
|
test.fixme('Units menu', async ({ page, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
const unitsMenuButton = page.getByRole('button', {
|
const unitsMenuButton = page.getByRole('button', {
|
||||||
name: 'Current Units',
|
name: 'Current Units',
|
||||||
exact: false,
|
exact: false,
|
||||||
|
})
|
||||||
|
await expect(unitsMenuButton).toBeVisible()
|
||||||
|
await expect(unitsMenuButton).toContainText('in')
|
||||||
|
|
||||||
|
await unitsMenuButton.click()
|
||||||
|
const millimetersButton = page.getByRole('button', { name: 'Millimeters' })
|
||||||
|
|
||||||
|
await expect(millimetersButton).toBeVisible()
|
||||||
|
await millimetersButton.click()
|
||||||
|
|
||||||
|
// Look out for the toast message
|
||||||
|
const toastMessage = page.getByText(
|
||||||
|
`Set default unit to "mm" for this project`
|
||||||
|
)
|
||||||
|
await expect(toastMessage).toBeVisible()
|
||||||
|
|
||||||
|
// Verify that the popover has closed
|
||||||
|
await expect(millimetersButton).not.toBeAttached()
|
||||||
|
|
||||||
|
// Verify that the button label has updated
|
||||||
|
await expect(unitsMenuButton).toContainText('mm')
|
||||||
})
|
})
|
||||||
await expect(unitsMenuButton).toBeVisible()
|
|
||||||
await expect(unitsMenuButton).toContainText('in')
|
|
||||||
|
|
||||||
await unitsMenuButton.click()
|
test('Successful export shows a success toast', async ({ page, homePage }) => {
|
||||||
const millimetersButton = page.getByRole('button', { name: 'Millimeters' })
|
// FYI this test doesn't work with only engine running locally
|
||||||
|
// And you will need to have the KittyCAD CLI installed
|
||||||
await expect(millimetersButton).toBeVisible()
|
const u = await getUtils(page)
|
||||||
await millimetersButton.click()
|
await page.addInitScript(async () => {
|
||||||
|
;(window as any).playwrightSkipFilePicker = true
|
||||||
// Look out for the toast message
|
localStorage.setItem(
|
||||||
const toastMessage = page.getByText(
|
'persistCode',
|
||||||
`Set default unit to "mm" for this project`
|
`topAng = 25
|
||||||
)
|
|
||||||
await expect(toastMessage).toBeVisible()
|
|
||||||
|
|
||||||
// Verify that the popover has closed
|
|
||||||
await expect(millimetersButton).not.toBeAttached()
|
|
||||||
|
|
||||||
// Verify that the button label has updated
|
|
||||||
await expect(unitsMenuButton).toContainText('mm') })
|
|
||||||
|
|
||||||
test('Successful export shows a success toast', async ({ page, homePage }) => { // FYI this test doesn't work with only engine running locally
|
|
||||||
// And you will need to have the KittyCAD CLI installed
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.addInitScript(async () => {
|
|
||||||
;(window as any).playwrightSkipFilePicker = true
|
|
||||||
localStorage.setItem(
|
|
||||||
'persistCode',
|
|
||||||
`topAng = 25
|
|
||||||
bottomAng = 35
|
bottomAng = 35
|
||||||
baseLen = 3.5
|
baseLen = 3.5
|
||||||
baseHeight = 1
|
baseHeight = 1
|
||||||
@ -77,158 +79,172 @@ part001 = startSketchOn('-XZ')
|
|||||||
|> xLineTo(ZERO, %)
|
|> xLineTo(ZERO, %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> extrude(4, %)`
|
|> extrude(4, %)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.waitForCmdReceive('extrude')
|
||||||
|
await page.waitForTimeout(1000)
|
||||||
|
await u.clearAndCloseDebugPanel()
|
||||||
|
|
||||||
|
await doExport(
|
||||||
|
{
|
||||||
|
type: 'gltf',
|
||||||
|
storage: 'embedded',
|
||||||
|
presentation: 'pretty',
|
||||||
|
},
|
||||||
|
page
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
test('Paste should not work unless an input is focused', async ({
|
||||||
await u.openDebugPanel()
|
page,
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
browserName,
|
||||||
await u.waitForCmdReceive('extrude')
|
homePage,
|
||||||
await page.waitForTimeout(1000)
|
}) => {
|
||||||
await u.clearAndCloseDebugPanel()
|
// To run this test locally, uncomment Firefox in playwright.config.ts
|
||||||
|
test.skip(
|
||||||
await doExport(
|
browserName !== 'firefox',
|
||||||
{
|
"This bug is really Firefox-only, which we don't run in CI."
|
||||||
type: 'gltf',
|
|
||||||
storage: 'embedded',
|
|
||||||
presentation: 'pretty',
|
|
||||||
},
|
|
||||||
page
|
|
||||||
)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Paste should not work unless an input is focused', async ({ page, browserName, homePage }) => { // To run this test locally, uncomment Firefox in playwright.config.ts
|
|
||||||
test.skip(
|
|
||||||
browserName !== 'firefox',
|
|
||||||
"This bug is really Firefox-only, which we don't run in CI."
|
|
||||||
)
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
await homePage.goToModelingScene()
|
|
||||||
await page
|
|
||||||
.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
.waitFor({ state: 'visible' })
|
|
||||||
|
|
||||||
const codeEditorText = page.locator('.cm-content')
|
|
||||||
const pasteContent = `// was this pasted?`
|
|
||||||
const typeContent = `// this should be typed`
|
|
||||||
|
|
||||||
// Load text into the clipboard
|
|
||||||
await page.evaluate((t) => navigator.clipboard.writeText(t), pasteContent)
|
|
||||||
|
|
||||||
// Focus the text editor
|
|
||||||
await codeEditorText.focus()
|
|
||||||
|
|
||||||
// Show that we can type into it
|
|
||||||
await page.keyboard.type(typeContent)
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
|
|
||||||
// Paste without the code pane focused
|
|
||||||
await codeEditorText.blur()
|
|
||||||
await page.keyboard.press('ControlOrMeta+KeyV')
|
|
||||||
|
|
||||||
// Show that the paste didn't work but typing did
|
|
||||||
await expect(codeEditorText).not.toContainText(pasteContent)
|
|
||||||
await expect(codeEditorText).toContainText(typeContent)
|
|
||||||
|
|
||||||
// Paste with the code editor focused
|
|
||||||
// Following this guidance: https://github.com/microsoft/playwright/issues/8114
|
|
||||||
await codeEditorText.focus()
|
|
||||||
await page.keyboard.press('ControlOrMeta+KeyV')
|
|
||||||
await expect(
|
|
||||||
await page.evaluate(
|
|
||||||
() => document.querySelector('.cm-content')?.textContent
|
|
||||||
)
|
)
|
||||||
).toContain(pasteContent) })
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await page
|
||||||
|
.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
.waitFor({ state: 'visible' })
|
||||||
|
|
||||||
test('Keyboard shortcuts can be viewed through the help menu', async ({ page, homePage }) => { const u = await getUtils(page)
|
const codeEditorText = page.locator('.cm-content')
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
const pasteContent = `// was this pasted?`
|
||||||
await homePage.goToModelingScene()
|
const typeContent = `// this should be typed`
|
||||||
|
|
||||||
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
|
// Load text into the clipboard
|
||||||
await page
|
await page.evaluate((t) => navigator.clipboard.writeText(t), pasteContent)
|
||||||
.getByRole('button', { name: 'Start Sketch' })
|
|
||||||
.waitFor({ state: 'visible' })
|
|
||||||
|
|
||||||
// Open the help menu
|
// Focus the text editor
|
||||||
await page.getByRole('button', { name: 'Help and resources' }).click()
|
await codeEditorText.focus()
|
||||||
|
|
||||||
// Open the keyboard shortcuts
|
// Show that we can type into it
|
||||||
await page.getByRole('button', { name: 'Keyboard Shortcuts' }).click()
|
await page.keyboard.type(typeContent)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Verify the URL and that you can see a list of shortcuts
|
// Paste without the code pane focused
|
||||||
await expect.poll(() => page.url()).toContain('?tab=keybindings')
|
await codeEditorText.blur()
|
||||||
await expect(
|
await page.keyboard.press('ControlOrMeta+KeyV')
|
||||||
page.getByRole('heading', { name: 'Enter Sketch Mode' })
|
|
||||||
).toBeAttached()
|
// Show that the paste didn't work but typing did
|
||||||
|
await expect(codeEditorText).not.toContainText(pasteContent)
|
||||||
|
await expect(codeEditorText).toContainText(typeContent)
|
||||||
|
|
||||||
|
// Paste with the code editor focused
|
||||||
|
// Following this guidance: https://github.com/microsoft/playwright/issues/8114
|
||||||
|
await codeEditorText.focus()
|
||||||
|
await page.keyboard.press('ControlOrMeta+KeyV')
|
||||||
|
await expect(
|
||||||
|
await page.evaluate(
|
||||||
|
() => document.querySelector('.cm-content')?.textContent
|
||||||
|
)
|
||||||
|
).toContain(pasteContent)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('First escape in tool pops you out of tool, second exits sketch mode', async ({ page, homePage }) => { // Wait for the app to be ready for use
|
test('Keyboard shortcuts can be viewed through the help menu', async ({
|
||||||
const u = await getUtils(page)
|
page,
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
homePage,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
|
||||||
await u.openDebugPanel()
|
await page
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
.getByRole('button', { name: 'Start Sketch' })
|
||||||
await u.closeDebugPanel()
|
.waitFor({ state: 'visible' })
|
||||||
|
|
||||||
const lineButton = page.getByRole('button', {
|
// Open the help menu
|
||||||
name: 'line Line',
|
await page.getByRole('button', { name: 'Help and resources' }).click()
|
||||||
exact: true,
|
|
||||||
})
|
// Open the keyboard shortcuts
|
||||||
const arcButton = page.getByRole('button', {
|
await page.getByRole('button', { name: 'Keyboard Shortcuts' }).click()
|
||||||
name: 'arc Tangential Arc',
|
|
||||||
exact: true,
|
// Verify the URL and that you can see a list of shortcuts
|
||||||
|
await expect.poll(() => page.url()).toContain('?tab=keybindings')
|
||||||
|
await expect(
|
||||||
|
page.getByRole('heading', { name: 'Enter Sketch Mode' })
|
||||||
|
).toBeAttached()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Test these hotkeys perform actions when
|
test('First escape in tool pops you out of tool, second exits sketch mode', async ({
|
||||||
// focus is on the canvas
|
page,
|
||||||
await page.mouse.move(600, 250)
|
homePage,
|
||||||
await page.mouse.click(600, 250)
|
}) => {
|
||||||
|
// Wait for the app to be ready for use
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
// Start a sketch
|
await homePage.goToModelingScene()
|
||||||
await page.keyboard.press('s')
|
await u.openDebugPanel()
|
||||||
await page.mouse.move(800, 300)
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await page.mouse.click(800, 300)
|
await u.closeDebugPanel()
|
||||||
await page.waitForTimeout(1000)
|
|
||||||
await expect(lineButton).toBeVisible()
|
|
||||||
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
|
||||||
|
|
||||||
// Draw a line
|
const lineButton = page.getByRole('button', {
|
||||||
await page.mouse.move(700, 200, { steps: 5 })
|
name: 'line Line',
|
||||||
await page.mouse.click(700, 200)
|
exact: true,
|
||||||
await page.mouse.move(800, 250, { steps: 5 })
|
})
|
||||||
await page.mouse.click(800, 250)
|
const arcButton = page.getByRole('button', {
|
||||||
// Unequip line tool
|
name: 'arc Tangential Arc',
|
||||||
await page.keyboard.press('Escape')
|
exact: true,
|
||||||
// Make sure we didn't pop out of sketch mode.
|
})
|
||||||
await expect(page.getByRole('button', { name: 'Exit Sketch' })).toBeVisible()
|
|
||||||
await expect(lineButton).not.toHaveAttribute('aria-pressed', 'true')
|
|
||||||
// Equip arc tool
|
|
||||||
await page.keyboard.press('a')
|
|
||||||
await expect(arcButton).toHaveAttribute('aria-pressed', 'true')
|
|
||||||
await page.mouse.move(1000, 100, { steps: 5 })
|
|
||||||
await page.mouse.click(1000, 100)
|
|
||||||
await page.keyboard.press('Escape')
|
|
||||||
await page.keyboard.press('l')
|
|
||||||
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
|
||||||
|
|
||||||
// Do not close the sketch.
|
// Test these hotkeys perform actions when
|
||||||
// On close it will exit sketch mode.
|
// focus is on the canvas
|
||||||
|
await page.mouse.move(600, 250)
|
||||||
|
await page.mouse.click(600, 250)
|
||||||
|
|
||||||
// Unequip line tool
|
// Start a sketch
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('s')
|
||||||
await expect(lineButton).toHaveAttribute('aria-pressed', 'false')
|
await page.mouse.move(800, 300)
|
||||||
await expect(arcButton).toHaveAttribute('aria-pressed', 'false')
|
await page.mouse.click(800, 300)
|
||||||
// Make sure we didn't pop out of sketch mode.
|
await page.waitForTimeout(1000)
|
||||||
await expect(page.getByRole('button', { name: 'Exit Sketch' })).toBeVisible()
|
await expect(lineButton).toBeVisible()
|
||||||
// Exit sketch
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
await page.keyboard.press('Escape')
|
|
||||||
await expect(
|
// Draw a line
|
||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
await page.mouse.move(700, 200, { steps: 5 })
|
||||||
).not.toBeVisible() })
|
await page.mouse.click(700, 200)
|
||||||
|
await page.mouse.move(800, 250, { steps: 5 })
|
||||||
|
await page.mouse.click(800, 250)
|
||||||
|
// Unequip line tool
|
||||||
|
await page.keyboard.press('Escape')
|
||||||
|
// Make sure we didn't pop out of sketch mode.
|
||||||
|
await expect(page.getByRole('button', { name: 'Exit Sketch' })).toBeVisible()
|
||||||
|
await expect(lineButton).not.toHaveAttribute('aria-pressed', 'true')
|
||||||
|
// Equip arc tool
|
||||||
|
await page.keyboard.press('a')
|
||||||
|
await expect(arcButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
await page.mouse.move(1000, 100, { steps: 5 })
|
||||||
|
await page.mouse.click(1000, 100)
|
||||||
|
await page.keyboard.press('Escape')
|
||||||
|
await page.keyboard.press('l')
|
||||||
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
|
// Do not close the sketch.
|
||||||
|
// On close it will exit sketch mode.
|
||||||
|
|
||||||
|
// Unequip line tool
|
||||||
|
await page.keyboard.press('Escape')
|
||||||
|
await expect(lineButton).toHaveAttribute('aria-pressed', 'false')
|
||||||
|
await expect(arcButton).toHaveAttribute('aria-pressed', 'false')
|
||||||
|
// Make sure we didn't pop out of sketch mode.
|
||||||
|
await expect(page.getByRole('button', { name: 'Exit Sketch' })).toBeVisible()
|
||||||
|
// Exit sketch
|
||||||
|
await page.keyboard.press('Escape')
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
|
).not.toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
test.fixme(
|
test.fixme(
|
||||||
'Basic default modeling and sketch hotkeys work',
|
'Basic default modeling and sketch hotkeys work',
|
||||||
@ -412,37 +428,38 @@ test.fixme(
|
|||||||
)
|
)
|
||||||
|
|
||||||
test('Delete key does not navigate back', async ({ page, homePage }) => {
|
test('Delete key does not navigate back', async ({ page, homePage }) => {
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
|
||||||
await homePage.goToModelingScene();
|
|
||||||
|
|
||||||
await page.waitForURL('file:///**', { waitUntil: 'domcontentloaded' })
|
const settingsButton = page.getByRole('link', {
|
||||||
|
name: 'Settings',
|
||||||
|
exact: false,
|
||||||
|
})
|
||||||
|
const settingsCloseButton = page.getByTestId('settings-close-button')
|
||||||
|
|
||||||
const settingsButton = page.getByRole('link', {
|
await settingsButton.click()
|
||||||
name: 'Settings',
|
await expect.poll(() => page.url()).toContain('/settings')
|
||||||
exact: false,
|
|
||||||
|
// Make sure that delete doesn't go back from settings
|
||||||
|
await page.keyboard.press('Delete')
|
||||||
|
await expect.poll(() => page.url()).toContain('/settings')
|
||||||
|
|
||||||
|
// Now close the settings and try delete again,
|
||||||
|
// make sure it doesn't go back to settings
|
||||||
|
await settingsCloseButton.click()
|
||||||
|
await page.keyboard.press('Delete')
|
||||||
|
await expect.poll(() => page.url()).not.toContain('/settings')
|
||||||
})
|
})
|
||||||
const settingsCloseButton = page.getByTestId('settings-close-button')
|
|
||||||
|
|
||||||
await settingsButton.click()
|
test('Sketch on face', async ({ page, homePage }) => {
|
||||||
await expect.poll(() => page.url()).toContain('/settings')
|
test.setTimeout(90_000)
|
||||||
|
const u = await getUtils(page)
|
||||||
// Make sure that delete doesn't go back from settings
|
await page.addInitScript(async () => {
|
||||||
await page.keyboard.press('Delete')
|
localStorage.setItem(
|
||||||
await expect.poll(() => page.url()).toContain('/settings')
|
'persistCode',
|
||||||
|
`sketch001 = startSketchOn('XZ')
|
||||||
// Now close the settings and try delete again,
|
|
||||||
// make sure it doesn't go back to settings
|
|
||||||
await settingsCloseButton.click()
|
|
||||||
await page.keyboard.press('Delete')
|
|
||||||
await expect.poll(() => page.url()).not.toContain('/settings') })
|
|
||||||
|
|
||||||
test('Sketch on face', async ({ page, homePage }) => { test.setTimeout(90_000)
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.addInitScript(async () => {
|
|
||||||
localStorage.setItem(
|
|
||||||
'persistCode',
|
|
||||||
`sketch001 = startSketchOn('XZ')
|
|
||||||
|> startProfileAt([3.29, 7.86], %)
|
|> startProfileAt([3.29, 7.86], %)
|
||||||
|> line([2.48, 2.44], %)
|
|> line([2.48, 2.44], %)
|
||||||
|> line([2.66, 1.17], %)
|
|> line([2.66, 1.17], %)
|
||||||
@ -456,126 +473,127 @@ await page.addInitScript(async () => {
|
|||||||
|> line([-17.67, 0.85], %)
|
|> line([-17.67, 0.85], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
extrude001 = extrude(5 + 7, sketch001)`
|
extrude001 = extrude(5 + 7, sketch001)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
|
// wait for execution done
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).not.toBeDisabled()
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||||
|
await page.waitForTimeout(300)
|
||||||
|
|
||||||
|
let previousCodeContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
|
await u.openAndClearDebugPanel()
|
||||||
|
await u.doAndWaitForCmd(
|
||||||
|
() => page.mouse.click(625, 165),
|
||||||
|
'default_camera_get_settings',
|
||||||
|
true
|
||||||
)
|
)
|
||||||
})
|
await page.waitForTimeout(150)
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
const firstClickPosition = [612, 238]
|
||||||
|
const secondClickPosition = [661, 242]
|
||||||
|
const thirdClickPosition = [609, 267]
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await page.mouse.click(firstClickPosition[0], firstClickPosition[1])
|
||||||
|
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
||||||
|
previousCodeContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
// wait for execution done
|
await page.waitForTimeout(100)
|
||||||
await u.openDebugPanel()
|
await page.mouse.click(secondClickPosition[0], secondClickPosition[1])
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
||||||
await u.closeDebugPanel()
|
previousCodeContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
await expect(
|
await page.waitForTimeout(100)
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
await page.mouse.click(thirdClickPosition[0], thirdClickPosition[1])
|
||||||
).not.toBeDisabled()
|
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
||||||
|
previousCodeContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
await page.waitForTimeout(100)
|
||||||
await page.waitForTimeout(300)
|
await page.mouse.click(firstClickPosition[0], firstClickPosition[1])
|
||||||
|
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
||||||
|
previousCodeContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
let previousCodeContent = await page.locator('.cm-content').innerText()
|
await expect.poll(u.normalisedEditorCode).toContain(
|
||||||
|
u.normalisedCode(`sketch002 = startSketchOn(extrude001, seg01)
|
||||||
await u.openAndClearDebugPanel()
|
|
||||||
await u.doAndWaitForCmd(
|
|
||||||
() => page.mouse.click(625, 165),
|
|
||||||
'default_camera_get_settings',
|
|
||||||
true
|
|
||||||
)
|
|
||||||
await page.waitForTimeout(150)
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
const firstClickPosition = [612, 238]
|
|
||||||
const secondClickPosition = [661, 242]
|
|
||||||
const thirdClickPosition = [609, 267]
|
|
||||||
|
|
||||||
await page.mouse.click(firstClickPosition[0], firstClickPosition[1])
|
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
|
||||||
previousCodeContent = await page.locator('.cm-content').innerText()
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await page.mouse.click(secondClickPosition[0], secondClickPosition[1])
|
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
|
||||||
previousCodeContent = await page.locator('.cm-content').innerText()
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await page.mouse.click(thirdClickPosition[0], thirdClickPosition[1])
|
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
|
||||||
previousCodeContent = await page.locator('.cm-content').innerText()
|
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await page.mouse.click(firstClickPosition[0], firstClickPosition[1])
|
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
|
||||||
previousCodeContent = await page.locator('.cm-content').innerText()
|
|
||||||
|
|
||||||
await expect.poll(u.normalisedEditorCode).toContain(
|
|
||||||
u.normalisedCode(`sketch002 = startSketchOn(extrude001, seg01)
|
|
||||||
|> startProfileAt([-12.94, 6.6], %)
|
|> startProfileAt([-12.94, 6.6], %)
|
||||||
|> line([2.45, -0.2], %)
|
|> line([2.45, -0.2], %)
|
||||||
|> line([-2.6, -1.25], %)
|
|> line([-2.6, -1.25], %)
|
||||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
`)
|
`)
|
||||||
)
|
)
|
||||||
|
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
|
||||||
await u.updateCamPosition([1049, 239, 686])
|
await u.updateCamPosition([1049, 239, 686])
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
await page.getByText('startProfileAt([-12').click()
|
await page.getByText('startProfileAt([-12').click()
|
||||||
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
|
await expect(page.getByRole('button', { name: 'Edit Sketch' })).toBeVisible()
|
||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
await page.waitForTimeout(400)
|
await page.waitForTimeout(400)
|
||||||
await page.waitForTimeout(150)
|
await page.waitForTimeout(150)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 1200 })
|
await page.setBodyDimensions({ width: 1200, height: 1200 })
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
await u.updateCamPosition([452, -152, 1166])
|
await u.updateCamPosition([452, -152, 1166])
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
await page.waitForTimeout(200)
|
await page.waitForTimeout(200)
|
||||||
|
|
||||||
const pointToDragFirst = [787, 565]
|
const pointToDragFirst = [787, 565]
|
||||||
await page.mouse.move(pointToDragFirst[0], pointToDragFirst[1])
|
await page.mouse.move(pointToDragFirst[0], pointToDragFirst[1])
|
||||||
await page.mouse.down()
|
await page.mouse.down()
|
||||||
await page.mouse.move(pointToDragFirst[0] - 20, pointToDragFirst[1], {
|
await page.mouse.move(pointToDragFirst[0] - 20, pointToDragFirst[1], {
|
||||||
steps: 5,
|
steps: 5,
|
||||||
})
|
})
|
||||||
await page.mouse.up()
|
await page.mouse.up()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
await expect(page.locator('.cm-content')).not.toHaveText(previousCodeContent)
|
||||||
previousCodeContent = await page.locator('.cm-content').innerText()
|
previousCodeContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
const result = makeTemplate`sketch002 = startSketchOn(extrude001, seg01)
|
const result = makeTemplate`sketch002 = startSketchOn(extrude001, seg01)
|
||||||
|> startProfileAt([-12.83, 6.7], %)
|
|> startProfileAt([-12.83, 6.7], %)
|
||||||
|> line([${[2.28, 2.35]}, -${0.07}], %)
|
|> line([${[2.28, 2.35]}, -${0.07}], %)
|
||||||
|> line([-3.05, -1.47], %)
|
|> line([-3.05, -1.47], %)
|
||||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||||
|> close(%)`
|
|> close(%)`
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(result.regExp)
|
await expect(page.locator('.cm-content')).toHaveText(result.regExp)
|
||||||
|
|
||||||
// exit sketch
|
// exit sketch
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
|
||||||
await page.getByText('startProfileAt([-12').click()
|
await page.getByText('startProfileAt([-12').click()
|
||||||
|
|
||||||
await expect(page.getByRole('button', { name: 'Extrude' })).not.toBeDisabled()
|
await expect(page.getByRole('button', { name: 'Extrude' })).not.toBeDisabled()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.getByRole('button', { name: 'Extrude' }).click()
|
await page.getByRole('button', { name: 'Extrude' }).click()
|
||||||
|
|
||||||
await expect(page.getByTestId('command-bar')).toBeVisible()
|
await expect(page.getByTestId('command-bar')).toBeVisible()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
await page.getByRole('button', { name: 'arrow right Continue' }).click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await expect(page.getByText('Confirm Extrude')).toBeVisible()
|
await expect(page.getByText('Confirm Extrude')).toBeVisible()
|
||||||
await page.getByRole('button', { name: 'checkmark Submit command' }).click()
|
await page.getByRole('button', { name: 'checkmark Submit command' }).click()
|
||||||
|
|
||||||
const result2 = result.genNext`
|
const result2 = result.genNext`
|
||||||
const sketch002 = extrude(${[5, 5]} + 7, sketch002)`
|
const sketch002 = extrude(${[5, 5]} + 7, sketch002)`
|
||||||
await expect(page.locator('.cm-content')).toHaveText(result2.regExp) })
|
await expect(page.locator('.cm-content')).toHaveText(result2.regExp)
|
||||||
|
})
|
||||||
|
@ -10,7 +10,6 @@ export { expect, Page, BrowserContext, TestInfo } from '@playwright/test'
|
|||||||
// switch between web and electron if needed.
|
// switch between web and electron if needed.
|
||||||
const pwTestFnWithFixtures = playwrightTestFn.extend<Fixtures>(fixtures)
|
const pwTestFnWithFixtures = playwrightTestFn.extend<Fixtures>(fixtures)
|
||||||
|
|
||||||
|
|
||||||
// In JavaScript you cannot replace a function's body only (despite functions
|
// In JavaScript you cannot replace a function's body only (despite functions
|
||||||
// are themselves objects, which you'd expect a body property or something...)
|
// are themselves objects, which you'd expect a body property or something...)
|
||||||
// So we must redefine the function and then re-attach properties.
|
// So we must redefine the function and then re-attach properties.
|
||||||
@ -61,7 +60,7 @@ export function test(desc, objOrFn, fnMaybe) {
|
|||||||
// We need to expose this in order for some tests that require folder
|
// We need to expose this in order for some tests that require folder
|
||||||
// creation. Before they used to do this by their own electronSetup({...})
|
// creation. Before they used to do this by their own electronSetup({...})
|
||||||
// calls.
|
// calls.
|
||||||
tronApp.context.folderSetupFn = function(fn) {
|
tronApp.context.folderSetupFn = function (fn) {
|
||||||
return fn(tronApp.dir).then(() => ({ dir: tronApp.dir }))
|
return fn(tronApp.dir).then(() => ({ dir: tronApp.dir }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ const save_ = async (file: ModelingAppFile, toastId: string) => {
|
|||||||
// Skip file picker, save to the test dir downloads directory
|
// Skip file picker, save to the test dir downloads directory
|
||||||
const downloadDir = window.electron.join(
|
const downloadDir = window.electron.join(
|
||||||
window.electron.process.env.TEST_SETTINGS_FILE_KEY,
|
window.electron.process.env.TEST_SETTINGS_FILE_KEY,
|
||||||
"downloads-during-playwright",
|
'downloads-during-playwright'
|
||||||
)
|
)
|
||||||
await window.electron.mkdir(downloadDir, { recursive: true })
|
await window.electron.mkdir(downloadDir, { recursive: true })
|
||||||
await window.electron.writeFile(
|
await window.electron.writeFile(
|
||||||
|
Reference in New Issue
Block a user