Opt-in tests that cover Windows-specific capabilities (#6489)
* Opt-in tests that cover Windows-specific capabilities * Remove unnecessary quotes
This commit is contained in:
@ -155,7 +155,7 @@ async function doBasicSketch(
|
|||||||
|> xLine(length = -segLen(seg01))`)
|
|> xLine(length = -segLen(seg01))`)
|
||||||
}
|
}
|
||||||
|
|
||||||
test.describe('Basic sketch', { tag: ['@skipWin'] }, () => {
|
test.describe('Basic sketch', () => {
|
||||||
test('code pane open at start', async ({ page, homePage }) => {
|
test('code pane open at start', async ({ page, homePage }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
await doBasicSketch(page, homePage, ['code'])
|
await doBasicSketch(page, homePage, ['code'])
|
||||||
|
@ -8,130 +8,126 @@ import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
|
|||||||
import { getUtils } from '@e2e/playwright/test-utils'
|
import { getUtils } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe(
|
test.describe('Can create sketches on all planes and their back sides', () => {
|
||||||
'Can create sketches on all planes and their back sides',
|
const sketchOnPlaneAndBackSideTest = async (
|
||||||
{ tag: ['@skipWin'] },
|
page: Page,
|
||||||
() => {
|
homePage: HomePageFixture,
|
||||||
const sketchOnPlaneAndBackSideTest = async (
|
scene: SceneFixture,
|
||||||
page: Page,
|
toolbar: ToolbarFixture,
|
||||||
homePage: HomePageFixture,
|
plane: string,
|
||||||
scene: SceneFixture,
|
clickCoords: { x: number; y: number }
|
||||||
toolbar: ToolbarFixture,
|
) => {
|
||||||
plane: string,
|
const u = await getUtils(page)
|
||||||
clickCoords: { x: number; y: number }
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
) => {
|
|
||||||
const u = await getUtils(page)
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
const XYPlanRed: [number, number, number] = [98, 50, 51]
|
const XYPlanRed: [number, number, number] = [98, 50, 51]
|
||||||
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
await scene.expectPixelColor(XYPlanRed, { x: 700, y: 300 }, 15)
|
||||||
|
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
|
|
||||||
const coord =
|
const coord =
|
||||||
plane === '-XY' || plane === '-YZ' || plane === 'XZ' ? -100 : 100
|
plane === '-XY' || plane === '-YZ' || plane === 'XZ' ? -100 : 100
|
||||||
const camCommand: EngineCommand = {
|
const camCommand: EngineCommand = {
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
cmd: {
|
cmd: {
|
||||||
type: 'default_camera_look_at',
|
type: 'default_camera_look_at',
|
||||||
center: { x: 0, y: 0, z: 0 },
|
center: { x: 0, y: 0, z: 0 },
|
||||||
vantage: { x: coord, y: coord, z: coord },
|
vantage: { x: coord, y: coord, z: coord },
|
||||||
up: { x: 0, y: 0, z: 1 },
|
up: { x: 0, y: 0, z: 1 },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const updateCamCommand: EngineCommand = {
|
const updateCamCommand: EngineCommand = {
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
cmd: {
|
cmd: {
|
||||||
type: 'default_camera_get_settings',
|
type: 'default_camera_get_settings',
|
||||||
},
|
},
|
||||||
}
|
|
||||||
|
|
||||||
const code = `@settings(defaultLengthUnit = in)sketch001 = startSketchOn(${plane})profile001 = startProfileAt([0.91, -1.22], sketch001)`
|
|
||||||
|
|
||||||
await u.openDebugPanel()
|
|
||||||
|
|
||||||
await u.clearCommandLogs()
|
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
|
||||||
|
|
||||||
await u.sendCustomCmd(camCommand)
|
|
||||||
await page.waitForTimeout(100)
|
|
||||||
await u.sendCustomCmd(updateCamCommand)
|
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
|
|
||||||
await page.mouse.click(clickCoords.x, clickCoords.y)
|
|
||||||
await page.waitForTimeout(600) // wait for animation
|
|
||||||
|
|
||||||
await toolbar.waitUntilSketchingReady()
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.getByRole('button', { name: 'line Line', exact: true })
|
|
||||||
).toBeVisible()
|
|
||||||
|
|
||||||
await u.closeDebugPanel()
|
|
||||||
await page.mouse.click(707, 393)
|
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(code)
|
|
||||||
|
|
||||||
await page
|
|
||||||
.getByRole('button', { name: 'line Line', exact: true })
|
|
||||||
.first()
|
|
||||||
.click()
|
|
||||||
await u.openAndClearDebugPanel()
|
|
||||||
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
||||||
|
|
||||||
await u.clearCommandLogs()
|
|
||||||
await u.removeCurrentCode()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const planeConfigs = [
|
const code = `@settings(defaultLengthUnit = in)sketch001 = startSketchOn(${plane})profile001 = startProfileAt([0.91, -1.22], sketch001)`
|
||||||
{
|
|
||||||
plane: 'XY',
|
|
||||||
coords: { x: 600, y: 388 },
|
|
||||||
description: 'red plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: 'YZ',
|
|
||||||
coords: { x: 700, y: 250 },
|
|
||||||
description: 'green plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: 'XZ',
|
|
||||||
coords: { x: 684, y: 427 },
|
|
||||||
description: 'blue plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: '-XY',
|
|
||||||
coords: { x: 600, y: 118 },
|
|
||||||
description: 'back of red plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: '-YZ',
|
|
||||||
coords: { x: 700, y: 219 },
|
|
||||||
description: 'back of green plane',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
plane: '-XZ',
|
|
||||||
coords: { x: 700, y: 80 },
|
|
||||||
description: 'back of blue plane',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
for (const config of planeConfigs) {
|
await u.openDebugPanel()
|
||||||
test(config.plane, async ({ page, homePage, scene, toolbar }) => {
|
|
||||||
await sketchOnPlaneAndBackSideTest(
|
await u.clearCommandLogs()
|
||||||
page,
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||||
homePage,
|
|
||||||
scene,
|
await u.sendCustomCmd(camCommand)
|
||||||
toolbar,
|
await page.waitForTimeout(100)
|
||||||
config.plane,
|
await u.sendCustomCmd(updateCamCommand)
|
||||||
config.coords
|
|
||||||
)
|
await u.closeDebugPanel()
|
||||||
})
|
|
||||||
}
|
await page.mouse.click(clickCoords.x, clickCoords.y)
|
||||||
|
await page.waitForTimeout(600) // wait for animation
|
||||||
|
|
||||||
|
await toolbar.waitUntilSketchingReady()
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'line Line', exact: true })
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
await page.mouse.click(707, 393)
|
||||||
|
|
||||||
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByRole('button', { name: 'line Line', exact: true })
|
||||||
|
.first()
|
||||||
|
.click()
|
||||||
|
await u.openAndClearDebugPanel()
|
||||||
|
await page.getByRole('button', { name: 'Exit Sketch' }).click()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
|
||||||
|
await u.clearCommandLogs()
|
||||||
|
await u.removeCurrentCode()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
const planeConfigs = [
|
||||||
|
{
|
||||||
|
plane: 'XY',
|
||||||
|
coords: { x: 600, y: 388 },
|
||||||
|
description: 'red plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: 'YZ',
|
||||||
|
coords: { x: 700, y: 250 },
|
||||||
|
description: 'green plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: 'XZ',
|
||||||
|
coords: { x: 684, y: 427 },
|
||||||
|
description: 'blue plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: '-XY',
|
||||||
|
coords: { x: 600, y: 118 },
|
||||||
|
description: 'back of red plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: '-YZ',
|
||||||
|
coords: { x: 700, y: 219 },
|
||||||
|
description: 'back of green plane',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plane: '-XZ',
|
||||||
|
coords: { x: 700, y: 80 },
|
||||||
|
description: 'back of blue plane',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const config of planeConfigs) {
|
||||||
|
test(config.plane, async ({ page, homePage, scene, toolbar }) => {
|
||||||
|
await sketchOnPlaneAndBackSideTest(
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
scene,
|
||||||
|
toolbar,
|
||||||
|
config.plane,
|
||||||
|
config.coords
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
|
test.describe('Code pane and errors', () => {
|
||||||
test('Typing KCL errors induces a badge on the code pane button', async ({
|
test('Typing KCL errors induces a badge on the code pane button', async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
|
test.describe('Command bar tests', () => {
|
||||||
test('Extrude from command bar selects extrude line after', async ({
|
test('Extrude from command bar selects extrude line after', async ({
|
||||||
page,
|
page,
|
||||||
homePage,
|
homePage,
|
||||||
@ -179,57 +179,57 @@ test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
|
|||||||
await expect(commandLevelArgButton).toHaveText('level: project')
|
await expect(commandLevelArgButton).toHaveText('level: project')
|
||||||
})
|
})
|
||||||
|
|
||||||
test(
|
test('Command bar keybinding works from code editor and can change a setting', async ({
|
||||||
'Command bar keybinding works from code editor and can change a setting',
|
page,
|
||||||
{ tag: ['@skipWin'] },
|
homePage,
|
||||||
async ({ page, homePage }) => {
|
}) => {
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
// FIXME: No KCL code, unable to wait for engine execution
|
// FIXME: No KCL code, unable to wait for engine execution
|
||||||
await page.waitForTimeout(10000)
|
await page.waitForTimeout(10000)
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled()
|
).not.toBeDisabled()
|
||||||
|
|
||||||
// Put the cursor in the code editor
|
// Put the cursor in the code editor
|
||||||
await page.locator('.cm-content').click()
|
await page.locator('.cm-content').click()
|
||||||
|
|
||||||
// Now try the same, but with the keyboard shortcut, check focus
|
// Now try the same, but with the keyboard shortcut, check focus
|
||||||
await page.keyboard.press('ControlOrMeta+K')
|
await page.keyboard.press('ControlOrMeta+K')
|
||||||
|
|
||||||
let cmdSearchBar = page.getByPlaceholder('Search commands')
|
let cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||||
await expect(cmdSearchBar).toBeVisible()
|
await expect(cmdSearchBar).toBeVisible()
|
||||||
await expect(cmdSearchBar).toBeFocused()
|
await expect(cmdSearchBar).toBeFocused()
|
||||||
|
|
||||||
// Try typing in the command bar
|
// Try typing in the command bar
|
||||||
await cmdSearchBar.fill('theme')
|
await cmdSearchBar.fill('theme')
|
||||||
const themeOption = page.getByRole('option', {
|
const themeOption = page.getByRole('option', {
|
||||||
name: 'Settings · app · theme',
|
name: 'Settings · app · theme',
|
||||||
})
|
})
|
||||||
await expect(themeOption).toBeVisible()
|
await expect(themeOption).toBeVisible()
|
||||||
await themeOption.click()
|
await themeOption.click()
|
||||||
const themeInput = page.getByPlaceholder('dark')
|
const themeInput = page.getByPlaceholder('dark')
|
||||||
await expect(themeInput).toBeVisible()
|
await expect(themeInput).toBeVisible()
|
||||||
await expect(themeInput).toBeFocused()
|
await expect(themeInput).toBeFocused()
|
||||||
// Select dark theme
|
// Select dark theme
|
||||||
await page.keyboard.press('ArrowDown')
|
await page.keyboard.press('ArrowDown')
|
||||||
await page.keyboard.press('ArrowDown')
|
await page.keyboard.press('ArrowDown')
|
||||||
await page.keyboard.press('ArrowDown')
|
await page.keyboard.press('ArrowDown')
|
||||||
await expect(
|
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
|
||||||
page.getByRole('option', { name: 'system' })
|
'data-headlessui-state',
|
||||||
).toHaveAttribute('data-headlessui-state', 'active')
|
'active'
|
||||||
await page.keyboard.press('Enter')
|
)
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
|
||||||
// Check the toast appeared
|
// Check the toast appeared
|
||||||
await expect(
|
await expect(
|
||||||
page.getByText(`Set theme to "system" as a user default`)
|
page.getByText(`Set theme to "system" as a user default`)
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
// Check that the theme changed
|
// Check that the theme changed
|
||||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
test('Can extrude from the command bar', async ({
|
test('Can extrude from the command bar', async ({
|
||||||
page,
|
page,
|
||||||
|
@ -10,7 +10,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
|
|||||||
|
|
||||||
test(
|
test(
|
||||||
'export works on the first try',
|
'export works on the first try',
|
||||||
{ tag: ['@electron', '@macOS', '@skipLocalEngine'] },
|
{ tag: ['@electron', '@macos', '@windows', '@skipLocalEngine'] },
|
||||||
async ({ page, context, scene, tronApp, cmdBar }, testInfo) => {
|
async ({ page, context, scene, tronApp, cmdBar }, testInfo) => {
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
fail()
|
fail()
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
|
test.describe('Editor tests', () => {
|
||||||
test('can comment out code with ctrl+/', async ({ page, homePage }) => {
|
test('can comment out code with ctrl+/', async ({ page, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
@ -989,162 +989,162 @@ sketch001 = startSketchOn(XZ)
|
|||||||
|> close()`)
|
|> close()`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test(
|
test('Can undo a sketch modification with ctrl+z', async ({
|
||||||
'Can undo a sketch modification with ctrl+z',
|
page,
|
||||||
{ tag: ['@skipWin'] },
|
homePage,
|
||||||
async ({ page, homePage, editor }) => {
|
editor,
|
||||||
const u = await getUtils(page)
|
}) => {
|
||||||
await page.addInitScript(async () => {
|
const u = await getUtils(page)
|
||||||
localStorage.setItem(
|
await page.addInitScript(async () => {
|
||||||
'persistCode',
|
localStorage.setItem(
|
||||||
`@settings(defaultLengthUnit=in)
|
'persistCode',
|
||||||
|
`@settings(defaultLengthUnit=in)
|
||||||
sketch001 = startSketchOn(XZ)
|
sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([4.61, -10.01], %)
|
|> startProfileAt([4.61, -10.01], %)
|
||||||
|> line(end = [12.73, -0.09])
|
|> line(end = [12.73, -0.09])
|
||||||
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5)`
|
|> extrude(length = 5)`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled()
|
).not.toBeDisabled()
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
await u.sendCustomCmd({
|
await u.sendCustomCmd({
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
cmd: {
|
cmd: {
|
||||||
type: 'default_camera_look_at',
|
type: 'default_camera_look_at',
|
||||||
vantage: { x: 0, y: -1250, z: 580 },
|
vantage: { x: 0, y: -1250, z: 580 },
|
||||||
center: { x: 0, y: 0, z: 0 },
|
center: { x: 0, y: 0, z: 0 },
|
||||||
up: { x: 0, y: 0, z: 1 },
|
up: { x: 0, y: 0, z: 1 },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await u.sendCustomCmd({
|
await u.sendCustomCmd({
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
cmd: {
|
cmd: {
|
||||||
type: 'default_camera_get_settings',
|
type: 'default_camera_get_settings',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
const startPX = [1200 / 2, 500 / 2]
|
const startPX = [1200 / 2, 500 / 2]
|
||||||
|
|
||||||
const dragPX = 40
|
const dragPX = 40
|
||||||
|
|
||||||
await page.getByText('startProfileAt([4.61, -10.01], %)').click()
|
await page.getByText('startProfileAt([4.61, -10.01], %)').click()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Edit Sketch' })
|
page.getByRole('button', { name: 'Edit Sketch' })
|
||||||
).toBeVisible()
|
).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)
|
||||||
let prevContent = await page.locator('.cm-content').innerText()
|
let prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
|
||||||
|
|
||||||
// drag startProfileAt handle
|
// drag startProfileAt handle
|
||||||
await page.dragAndDrop('#stream', '#stream', {
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
sourcePosition: { x: startPX[0] + 68, y: startPX[1] + 147 },
|
sourcePosition: { x: startPX[0] + 68, y: startPX[1] + 147 },
|
||||||
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] + dragPX },
|
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] + dragPX },
|
||||||
})
|
})
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||||
prevContent = await page.locator('.cm-content').innerText()
|
prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
// drag line handle
|
// drag line handle
|
||||||
// we wait so it saves the code
|
// we wait so it saves the code
|
||||||
await page.waitForTimeout(800)
|
await page.waitForTimeout(800)
|
||||||
|
|
||||||
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
|
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.dragAndDrop('#stream', '#stream', {
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
|
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
|
||||||
targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX },
|
targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX },
|
||||||
})
|
})
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||||
prevContent = await page.locator('.cm-content').innerText()
|
prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
// we wait so it saves the code
|
// we wait so it saves the code
|
||||||
await page.waitForTimeout(800)
|
await page.waitForTimeout(800)
|
||||||
|
|
||||||
// drag tangentialArc handle
|
// drag tangentialArc handle
|
||||||
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
|
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
|
||||||
await page.dragAndDrop('#stream', '#stream', {
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
sourcePosition: { x: tangentEnd.x + 10, y: tangentEnd.y - 5 },
|
sourcePosition: { x: tangentEnd.x + 10, y: tangentEnd.y - 5 },
|
||||||
targetPosition: {
|
targetPosition: {
|
||||||
x: tangentEnd.x + dragPX,
|
x: tangentEnd.x + dragPX,
|
||||||
y: tangentEnd.y + dragPX,
|
y: tangentEnd.y + dragPX,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||||
|
|
||||||
// expect the code to have changed
|
// expect the code to have changed
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([2.71, -2.71], %)
|
|> startProfileAt([2.71, -2.71], %)
|
||||||
|> line(end = [15.4, -2.78])
|
|> line(end = [15.4, -2.78])
|
||||||
|> tangentialArc(endAbsolute = [27.6, -3.05])
|
|> tangentialArc(endAbsolute = [27.6, -3.05])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5)`,
|
|> extrude(length = 5)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hit undo
|
// Hit undo
|
||||||
await page.keyboard.down('Control')
|
await page.keyboard.down('Control')
|
||||||
await page.keyboard.press('KeyZ')
|
await page.keyboard.press('KeyZ')
|
||||||
await page.keyboard.up('Control')
|
await page.keyboard.up('Control')
|
||||||
|
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([2.71, -2.71], %)
|
|> startProfileAt([2.71, -2.71], %)
|
||||||
|> line(end = [15.4, -2.78])
|
|> line(end = [15.4, -2.78])
|
||||||
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5)`,
|
|> extrude(length = 5)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hit undo again.
|
// Hit undo again.
|
||||||
await page.keyboard.down('Control')
|
await page.keyboard.down('Control')
|
||||||
await page.keyboard.press('KeyZ')
|
await page.keyboard.press('KeyZ')
|
||||||
await page.keyboard.up('Control')
|
await page.keyboard.up('Control')
|
||||||
|
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([2.71, -2.71], %)
|
|> startProfileAt([2.71, -2.71], %)
|
||||||
|> line(end = [12.73, -0.09])
|
|> line(end = [12.73, -0.09])
|
||||||
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5)`,
|
|> extrude(length = 5)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hit undo again.
|
// Hit undo again.
|
||||||
await page.keyboard.down('Control')
|
await page.keyboard.down('Control')
|
||||||
await page.keyboard.press('KeyZ')
|
await page.keyboard.press('KeyZ')
|
||||||
await page.keyboard.up('Control')
|
await page.keyboard.up('Control')
|
||||||
|
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await editor.expectEditor.toContain(
|
await editor.expectEditor.toContain(
|
||||||
`sketch001 = startSketchOn(XZ)
|
`sketch001 = startSketchOn(XZ)
|
||||||
|> startProfileAt([4.61, -10.01], %)
|
|> startProfileAt([4.61, -10.01], %)
|
||||||
|> line(end = [12.73, -0.09])
|
|> line(end = [12.73, -0.09])
|
||||||
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
|> tangentialArc(endAbsolute = [24.95, -0.38])
|
||||||
|> close()
|
|> close()
|
||||||
|> extrude(length = 5)`,
|
|> extrude(length = 5)`,
|
||||||
{ shouldNormalise: true }
|
{ shouldNormalise: true }
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
test(
|
test(
|
||||||
`Can import a local OBJ file`,
|
`Can import a local OBJ file`,
|
||||||
|
@ -41,7 +41,7 @@ class MyAPIReporter implements Reporter {
|
|||||||
annotations: test.annotations.map((a) => a.type), // e.g. 'fail' or 'fixme'
|
annotations: test.annotations.map((a) => a.type), // e.g. 'fail' or 'fixme'
|
||||||
id: test.id, // computed file/test/project ID used for reruns
|
id: test.id, // computed file/test/project ID used for reruns
|
||||||
retry: result.retry,
|
retry: result.retry,
|
||||||
tags: test.tags, // e.g. '@snapshot' or '@skipWin'
|
tags: test.tags, // e.g. '@snapshot' or '@skipLocalEngine'
|
||||||
// Extra environment variables
|
// Extra environment variables
|
||||||
CI_COMMIT_SHA: process.env.CI_COMMIT_SHA || null,
|
CI_COMMIT_SHA: process.env.CI_COMMIT_SHA || null,
|
||||||
CI_PR_NUMBER: process.env.CI_PR_NUMBER || null,
|
CI_PR_NUMBER: process.env.CI_PR_NUMBER || null,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
|
|||||||
|
|
||||||
test(
|
test(
|
||||||
'projects reload if a new one is created, deleted, or renamed externally',
|
'projects reload if a new one is created, deleted, or renamed externally',
|
||||||
{ tag: ['@electron', '@macOS'] },
|
{ tag: ['@electron', '@macos', '@windows'] },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page }, testInfo) => {
|
||||||
let externalCreatedProjectName = 'external-created-project'
|
let externalCreatedProjectName = 'external-created-project'
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ sketch003 = startSketchOn(XY)
|
|||||||
extrude003 = extrude(sketch003, length = 20)
|
extrude003 = extrude(sketch003, length = 20)
|
||||||
`
|
`
|
||||||
|
|
||||||
test.describe('Prompt-to-edit tests', { tag: '@skipWin' }, () => {
|
test.describe('Prompt-to-edit tests', () => {
|
||||||
test.describe('Check the happy path, for basic changing color', () => {
|
test.describe('Check the happy path, for basic changing color', () => {
|
||||||
const cases = [
|
const cases = [
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Regression tests', { tag: ['@skipWin'] }, () => {
|
test.describe('Regression tests', () => {
|
||||||
// bugs we found that don't fit neatly into other categories
|
// bugs we found that don't fit neatly into other categories
|
||||||
test('bad model has inline error #3251', async ({
|
test('bad model has inline error #3251', async ({
|
||||||
context,
|
context,
|
||||||
@ -239,17 +239,18 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
await expect(zooLogo).not.toHaveAttribute('href')
|
await expect(zooLogo).not.toHaveAttribute('href')
|
||||||
})
|
})
|
||||||
|
|
||||||
test(
|
test('Position _ Is Out Of Range... regression test', async ({
|
||||||
'Position _ Is Out Of Range... regression test',
|
context,
|
||||||
{ tag: ['@skipWin'] },
|
page,
|
||||||
async ({ context, page, homePage }) => {
|
homePage,
|
||||||
const u = await getUtils(page)
|
}) => {
|
||||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
const u = await getUtils(page)
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
await context.addInitScript(async () => {
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
localStorage.setItem(
|
await context.addInitScript(async () => {
|
||||||
'persistCode',
|
localStorage.setItem(
|
||||||
`exampleSketch = startSketchOn("XZ")
|
'persistCode',
|
||||||
|
`exampleSketch = startSketchOn("XZ")
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine(angle = 50, length = 45 )
|
|> angledLine(angle = 50, length = 45 )
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
@ -258,55 +259,55 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
|
|
||||||
example = extrude(exampleSketch, length = 5)
|
example = extrude(exampleSketch, length = 5)
|
||||||
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
|
shell(exampleSketch, faces = ['end'], thickness = 0.25)`
|
||||||
)
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
|
await homePage.goToModelingScene()
|
||||||
|
await u.waitForPageLoad()
|
||||||
|
|
||||||
|
// error in guter
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
||||||
|
timeout: 1_000,
|
||||||
})
|
})
|
||||||
|
await page.waitForTimeout(200)
|
||||||
|
// expect it still to be there (sometimes it just clears for a bit?)
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
||||||
|
timeout: 1_000,
|
||||||
|
})
|
||||||
|
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
||||||
|
|
||||||
await expect(async () => {
|
// error text on hover
|
||||||
await homePage.goToModelingScene()
|
await page.hover('.cm-lint-marker-error')
|
||||||
await u.waitForPageLoad()
|
await expect(page.getByText('Unexpected token: |').first()).toBeVisible()
|
||||||
|
|
||||||
// error in guter
|
// Okay execution finished, let's start editing text below the error.
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
await u.codeLocator.click()
|
||||||
timeout: 1_000,
|
// Go to the end of the editor
|
||||||
})
|
// This bug happens when there is a diagnostic in the editor and you try to
|
||||||
await page.waitForTimeout(200)
|
// edit text below it.
|
||||||
// expect it still to be there (sometimes it just clears for a bit?)
|
// Or delete a huge chunk of text and then try to edit below it.
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible({
|
await page.keyboard.press('End')
|
||||||
timeout: 1_000,
|
await page.keyboard.down('Shift')
|
||||||
})
|
await page.keyboard.press('ArrowUp')
|
||||||
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('ArrowUp')
|
||||||
|
await page.keyboard.press('End')
|
||||||
|
await page.keyboard.up('Shift')
|
||||||
|
await page.keyboard.press('Backspace')
|
||||||
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
|
|
||||||
// error text on hover
|
await page.keyboard.press('Enter')
|
||||||
await page.hover('.cm-lint-marker-error')
|
await page.keyboard.press('Enter')
|
||||||
await expect(page.getByText('Unexpected token: |').first()).toBeVisible()
|
await page.keyboard.type('thing: "blah"', { delay: 100 })
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
await page.keyboard.press('ArrowLeft')
|
||||||
|
|
||||||
// Okay execution finished, let's start editing text below the error.
|
await expect(
|
||||||
await u.codeLocator.click()
|
page.locator('.cm-content')
|
||||||
// Go to the end of the editor
|
).toContainText(`exampleSketch = startSketchOn("XZ")
|
||||||
// This bug happens when there is a diagnostic in the editor and you try to
|
|
||||||
// edit text below it.
|
|
||||||
// Or delete a huge chunk of text and then try to edit below it.
|
|
||||||
await page.keyboard.press('End')
|
|
||||||
await page.keyboard.down('Shift')
|
|
||||||
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('End')
|
|
||||||
await page.keyboard.up('Shift')
|
|
||||||
await page.keyboard.press('Backspace')
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
await page.keyboard.type('thing: "blah"', { delay: 100 })
|
|
||||||
await page.keyboard.press('Enter')
|
|
||||||
await page.keyboard.press('ArrowLeft')
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.locator('.cm-content')
|
|
||||||
).toContainText(`exampleSketch = startSketchOn("XZ")
|
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> angledLine(angle = 50, length = 45 )
|
|> angledLine(angle = 50, length = 45 )
|
||||||
|> yLine(endAbsolute = 0)
|
|> yLine(endAbsolute = 0)
|
||||||
@ -314,9 +315,8 @@ extrude001 = extrude(sketch001, length = 50)
|
|||||||
|
|
||||||
thing: "blah"`)
|
thing: "blah"`)
|
||||||
|
|
||||||
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'window resize updates should reconfigure the stream',
|
'window resize updates should reconfigure the stream',
|
||||||
@ -486,82 +486,81 @@ extrude002 = extrude(profile002, length = 150)
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
// We updated this test such that you can have multiple exports going at once.
|
// We updated this test such that you can have multiple exports going at once.
|
||||||
test(
|
test('ensure you CAN export while an export is already going', async ({
|
||||||
'ensure you CAN export while an export is already going',
|
page,
|
||||||
{ tag: ['@skipLinux', '@skipWin'] },
|
homePage,
|
||||||
async ({ page, homePage }) => {
|
}) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await test.step('Set up the code and durations', async () => {
|
await test.step('Set up the code and durations', async () => {
|
||||||
await page.addInitScript(
|
await page.addInitScript(
|
||||||
async ({ code }) => {
|
async ({ code }) => {
|
||||||
localStorage.setItem('persistCode', code)
|
localStorage.setItem('persistCode', code)
|
||||||
;(window as any).playwrightSkipFilePicker = true
|
;(window as any).playwrightSkipFilePicker = true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
code: bracket,
|
code: bracket,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
await u.waitForPageLoad()
|
||||||
|
|
||||||
// wait for execution done
|
// wait for execution done
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
// expect zero errors in guter
|
// expect zero errors in guter
|
||||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
const errorToastMessage = page.getByText(`Error while exporting`)
|
const errorToastMessage = page.getByText(`Error while exporting`)
|
||||||
const exportingToastMessage = page.getByText(`Exporting...`)
|
const exportingToastMessage = page.getByText(`Exporting...`)
|
||||||
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
const engineErrorToastMessage = page.getByText(`Nothing to export`)
|
||||||
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
const alreadyExportingToastMessage = page.getByText(`Already exporting`)
|
||||||
const successToastMessage = page.getByText(`Exported successfully`)
|
const successToastMessage = page.getByText(`Exported successfully`)
|
||||||
|
|
||||||
await test.step('second export', async () => {
|
await test.step('second export', async () => {
|
||||||
await clickExportButton(page)
|
await clickExportButton(page)
|
||||||
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
await expect(exportingToastMessage).toBeVisible()
|
||||||
|
|
||||||
await clickExportButton(page)
|
await clickExportButton(page)
|
||||||
|
|
||||||
await test.step('The first export still succeeds', async () => {
|
await test.step('The first export still succeeds', async () => {
|
||||||
await Promise.all([
|
|
||||||
expect(exportingToastMessage).not.toBeVisible({ timeout: 15_000 }),
|
|
||||||
expect(errorToastMessage).not.toBeVisible(),
|
|
||||||
expect(engineErrorToastMessage).not.toBeVisible(),
|
|
||||||
expect(successToastMessage).toBeVisible({ timeout: 15_000 }),
|
|
||||||
expect(alreadyExportingToastMessage).not.toBeVisible({
|
|
||||||
timeout: 15_000,
|
|
||||||
}),
|
|
||||||
])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
await test.step('Successful, unblocked export', async () => {
|
|
||||||
// Try exporting again.
|
|
||||||
await clickExportButton(page)
|
|
||||||
|
|
||||||
// Find the toast.
|
|
||||||
// Look out for the toast message
|
|
||||||
await expect(exportingToastMessage).toBeVisible()
|
|
||||||
|
|
||||||
// Expect it to succeed.
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
expect(exportingToastMessage).not.toBeVisible(),
|
expect(exportingToastMessage).not.toBeVisible({ timeout: 15_000 }),
|
||||||
expect(errorToastMessage).not.toBeVisible(),
|
expect(errorToastMessage).not.toBeVisible(),
|
||||||
expect(engineErrorToastMessage).not.toBeVisible(),
|
expect(engineErrorToastMessage).not.toBeVisible(),
|
||||||
expect(alreadyExportingToastMessage).not.toBeVisible(),
|
expect(successToastMessage).toBeVisible({ timeout: 15_000 }),
|
||||||
|
expect(alreadyExportingToastMessage).not.toBeVisible({
|
||||||
|
timeout: 15_000,
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
|
|
||||||
await expect(successToastMessage).toHaveCount(2)
|
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
await test.step('Successful, unblocked export', async () => {
|
||||||
|
// Try exporting again.
|
||||||
|
await clickExportButton(page)
|
||||||
|
|
||||||
|
// Find the toast.
|
||||||
|
// Look out for the toast message
|
||||||
|
await expect(exportingToastMessage).toBeVisible()
|
||||||
|
|
||||||
|
// Expect it to succeed.
|
||||||
|
await Promise.all([
|
||||||
|
expect(exportingToastMessage).not.toBeVisible(),
|
||||||
|
expect(errorToastMessage).not.toBeVisible(),
|
||||||
|
expect(engineErrorToastMessage).not.toBeVisible(),
|
||||||
|
expect(alreadyExportingToastMessage).not.toBeVisible(),
|
||||||
|
])
|
||||||
|
|
||||||
|
await expect(successToastMessage).toHaveCount(2)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test(
|
test(
|
||||||
`Network health indicator only appears in modeling view`,
|
`Network health indicator only appears in modeling view`,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -47,7 +47,7 @@ test.setTimeout(60_000)
|
|||||||
// up with another PR if we want this back.
|
// up with another PR if we want this back.
|
||||||
test(
|
test(
|
||||||
'exports of each format should work',
|
'exports of each format should work',
|
||||||
{ tag: ['@snapshot', '@skipWin', '@skipMacos'] },
|
{ tag: ['@snapshot'] },
|
||||||
async ({ page, context, scene, cmdBar, tronApp }) => {
|
async ({ page, context, scene, cmdBar, tronApp }) => {
|
||||||
if (!tronApp) {
|
if (!tronApp) {
|
||||||
fail()
|
fail()
|
||||||
|
@ -8,230 +8,235 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Test network and connection issues', {
|
test.describe(
|
||||||
tag: ['@macOS'],
|
'Test network and connection issues',
|
||||||
}, () => {
|
{
|
||||||
test(
|
tag: ['@macos', '@windows'],
|
||||||
'simulate network down and network little widget',
|
},
|
||||||
{ tag: '@skipLocalEngine' },
|
() => {
|
||||||
async ({ page, homePage }) => {
|
test(
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
'simulate network down and network little widget',
|
||||||
const u = await getUtils(page)
|
{ tag: '@skipLocalEngine' },
|
||||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
async ({ page, homePage }) => {
|
||||||
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
|
|
||||||
const networkToggle = page.getByTestId('network-toggle')
|
const networkToggle = page.getByTestId('network-toggle')
|
||||||
|
|
||||||
// This is how we wait until the stream is online
|
// This is how we wait until the stream is online
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled({ timeout: 15000 })
|
).not.toBeDisabled({ timeout: 15000 })
|
||||||
|
|
||||||
const networkWidget = page.locator('[data-testid="network-toggle"]')
|
const networkWidget = page.locator('[data-testid="network-toggle"]')
|
||||||
await expect(networkWidget).toBeVisible()
|
await expect(networkWidget).toBeVisible()
|
||||||
await networkWidget.hover()
|
await networkWidget.hover()
|
||||||
|
|
||||||
const networkPopover = page.locator('[data-testid="network-popover"]')
|
const networkPopover = page.locator('[data-testid="network-popover"]')
|
||||||
await expect(networkPopover).not.toBeVisible()
|
await expect(networkPopover).not.toBeVisible()
|
||||||
|
|
||||||
// (First check) Expect the network to be up
|
// (First check) Expect the network to be up
|
||||||
await expect(networkToggle).toContainText('Connected')
|
await expect(networkToggle).toContainText('Connected')
|
||||||
|
|
||||||
// Click the network widget
|
// Click the network widget
|
||||||
await networkWidget.click()
|
await networkWidget.click()
|
||||||
|
|
||||||
// Check the modal opened.
|
// Check the modal opened.
|
||||||
await expect(networkPopover).toBeVisible()
|
await expect(networkPopover).toBeVisible()
|
||||||
|
|
||||||
// Click off the modal.
|
// Click off the modal.
|
||||||
await page.mouse.click(100, 100)
|
await page.mouse.click(100, 100)
|
||||||
await expect(networkPopover).not.toBeVisible()
|
await expect(networkPopover).not.toBeVisible()
|
||||||
|
|
||||||
// Turn off the network
|
// Turn off the network
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
offline: true,
|
offline: true,
|
||||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||||
latency: 0,
|
latency: 0,
|
||||||
downloadThroughput: -1,
|
downloadThroughput: -1,
|
||||||
uploadThroughput: -1,
|
uploadThroughput: -1,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Expect the network to be down
|
// Expect the network to be down
|
||||||
await expect(networkToggle).toContainText('Problem')
|
await expect(networkToggle).toContainText('Problem')
|
||||||
|
|
||||||
// Click the network widget
|
// Click the network widget
|
||||||
await networkWidget.click()
|
await networkWidget.click()
|
||||||
|
|
||||||
// Check the modal opened.
|
// Check the modal opened.
|
||||||
await expect(networkPopover).toBeVisible()
|
await expect(networkPopover).toBeVisible()
|
||||||
|
|
||||||
// Click off the modal.
|
// Click off the modal.
|
||||||
await page.mouse.click(0, 0)
|
await page.mouse.click(0, 0)
|
||||||
await expect(networkPopover).not.toBeVisible()
|
await expect(networkPopover).not.toBeVisible()
|
||||||
|
|
||||||
// Turn back on the network
|
// Turn back on the network
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
offline: false,
|
offline: false,
|
||||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||||
latency: 0,
|
latency: 0,
|
||||||
downloadThroughput: -1,
|
downloadThroughput: -1,
|
||||||
uploadThroughput: -1,
|
uploadThroughput: -1,
|
||||||
})
|
})
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled({ timeout: 15000 })
|
).not.toBeDisabled({ timeout: 15000 })
|
||||||
|
|
||||||
// (Second check) expect the network to be up
|
// (Second check) expect the network to be up
|
||||||
await expect(networkToggle).toContainText('Connected')
|
await expect(networkToggle).toContainText('Connected')
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'Engine disconnect & reconnect in sketch mode',
|
'Engine disconnect & reconnect in sketch mode',
|
||||||
{ tag: '@skipLocalEngine' },
|
{ tag: '@skipLocalEngine' },
|
||||||
async ({ page, homePage, toolbar, scene, cmdBar }) => {
|
async ({ page, homePage, toolbar, scene, cmdBar }) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
const networkToggle = page.getByTestId('network-toggle')
|
const networkToggle = page.getByTestId('network-toggle')
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
await u.waitForPageLoad()
|
||||||
|
|
||||||
await u.openDebugPanel()
|
await u.openDebugPanel()
|
||||||
// click on "Start Sketch" button
|
// click on "Start Sketch" button
|
||||||
await u.clearCommandLogs()
|
await u.clearCommandLogs()
|
||||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
// select a plane
|
// select a plane
|
||||||
await page.mouse.click(700, 200)
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`sketch001 = startSketchOn(XZ)`
|
`sketch001 = startSketchOn(XZ)`
|
||||||
)
|
)
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
||||||
|
|
||||||
const startXPx = 600
|
const startXPx = 600
|
||||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||||
await expect(page.locator('.cm-content')).toHaveText(
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001)`
|
`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001)`
|
||||||
)
|
)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
page.locator('.cm-content')
|
page.locator('.cm-content')
|
||||||
).toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|
).toHaveText(`sketch001 = startSketchOn(XZ)profile001 = startProfileAt(${commonPoints.startAt}, sketch001)
|
||||||
|> xLine(length = ${commonPoints.num1})`)
|
|> xLine(length = ${commonPoints.num1})`)
|
||||||
|
|
||||||
// Expect the network to be up
|
// Expect the network to be up
|
||||||
await expect(networkToggle).toContainText('Connected')
|
await expect(networkToggle).toContainText('Connected')
|
||||||
|
|
||||||
// simulate network down
|
// simulate network down
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
offline: true,
|
offline: true,
|
||||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||||
latency: 0,
|
latency: 0,
|
||||||
downloadThroughput: -1,
|
downloadThroughput: -1,
|
||||||
uploadThroughput: -1,
|
uploadThroughput: -1,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Expect the network to be down
|
// Expect the network to be down
|
||||||
await expect(networkToggle).toContainText('Problem')
|
await expect(networkToggle).toContainText('Problem')
|
||||||
|
|
||||||
// Ensure we are not in sketch mode
|
// Ensure we are not in sketch mode
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
).not.toBeVisible()
|
).not.toBeVisible()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
|
||||||
// simulate network up
|
// simulate network up
|
||||||
await u.emulateNetworkConditions({
|
await u.emulateNetworkConditions({
|
||||||
offline: false,
|
offline: false,
|
||||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||||
latency: 0,
|
latency: 0,
|
||||||
downloadThroughput: -1,
|
downloadThroughput: -1,
|
||||||
uploadThroughput: -1,
|
uploadThroughput: -1,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Wait for the app to be ready for use
|
// Wait for the app to be ready for use
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Start Sketch' })
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
).not.toBeDisabled({ timeout: 15000 })
|
).not.toBeDisabled({ timeout: 15000 })
|
||||||
|
|
||||||
// Expect the network to be up
|
// Expect the network to be up
|
||||||
await expect(networkToggle).toContainText('Connected')
|
await expect(networkToggle).toContainText('Connected')
|
||||||
await scene.settled(cmdBar)
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
// Click off the code pane.
|
// Click off the code pane.
|
||||||
await page.mouse.click(100, 100)
|
await page.mouse.click(100, 100)
|
||||||
|
|
||||||
// select a line
|
// select a line
|
||||||
await page
|
await page
|
||||||
.getByText(`startProfileAt(${commonPoints.startAt}, sketch001)`)
|
.getByText(`startProfileAt(${commonPoints.startAt}, sketch001)`)
|
||||||
.click()
|
.click()
|
||||||
|
|
||||||
// enter sketch again
|
// enter sketch again
|
||||||
await toolbar.editSketch()
|
await toolbar.editSketch()
|
||||||
|
|
||||||
// Click the line tool
|
// Click the line tool
|
||||||
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
await page
|
||||||
|
.getByRole('button', { name: 'line Line', exact: true })
|
||||||
|
.click()
|
||||||
|
|
||||||
await page.waitForTimeout(150)
|
await page.waitForTimeout(150)
|
||||||
|
|
||||||
const camCommand: EngineCommand = {
|
const camCommand: EngineCommand = {
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
cmd: {
|
cmd: {
|
||||||
type: 'default_camera_look_at',
|
type: 'default_camera_look_at',
|
||||||
center: { x: 109, y: 0, z: -152 },
|
center: { x: 109, y: 0, z: -152 },
|
||||||
vantage: { x: 115, y: -505, z: -152 },
|
vantage: { x: 115, y: -505, z: -152 },
|
||||||
up: { x: 0, y: 0, z: 1 },
|
up: { x: 0, y: 0, z: 1 },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const updateCamCommand: EngineCommand = {
|
const updateCamCommand: EngineCommand = {
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd_id: uuidv4(),
|
cmd_id: uuidv4(),
|
||||||
cmd: {
|
cmd: {
|
||||||
type: 'default_camera_get_settings',
|
type: 'default_camera_get_settings',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
await toolbar.openPane('debug')
|
await toolbar.openPane('debug')
|
||||||
await u.sendCustomCmd(camCommand)
|
await u.sendCustomCmd(camCommand)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await u.sendCustomCmd(updateCamCommand)
|
await u.sendCustomCmd(updateCamCommand)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
// click to continue profile
|
// click to continue profile
|
||||||
await page.mouse.click(1007, 400)
|
await page.mouse.click(1007, 400)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
// Ensure we can continue sketching
|
// Ensure we can continue sketching
|
||||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||||
await expect
|
await expect
|
||||||
.poll(u.normalisedEditorCode)
|
.poll(u.normalisedEditorCode)
|
||||||
.toBe(`sketch001 = startSketchOn(XZ)
|
.toBe(`sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfileAt([12.34, -12.34], sketch001)
|
profile001 = startProfileAt([12.34, -12.34], sketch001)
|
||||||
|> xLine(length = 12.34)
|
|> xLine(length = 12.34)
|
||||||
|> line(end = [-12.34, 12.34])
|
|> line(end = [-12.34, 12.34])
|
||||||
|
|
||||||
`)
|
`)
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
await page.mouse.click(startXPx, 500 - PUR * 20)
|
await page.mouse.click(startXPx, 500 - PUR * 20)
|
||||||
|
|
||||||
await expect
|
await expect
|
||||||
.poll(u.normalisedEditorCode)
|
.poll(u.normalisedEditorCode)
|
||||||
.toBe(`sketch001 = startSketchOn(XZ)
|
.toBe(`sketch001 = startSketchOn(XZ)
|
||||||
profile001 = startProfileAt([12.34, -12.34], sketch001)
|
profile001 = startProfileAt([12.34, -12.34], sketch001)
|
||||||
|> xLine(length = 12.34)
|
|> xLine(length = 12.34)
|
||||||
|> line(end = [-12.34, 12.34])
|
|> line(end = [-12.34, 12.34])
|
||||||
@ -239,21 +244,22 @@ profile001 = startProfileAt([12.34, -12.34], sketch001)
|
|||||||
|
|
||||||
`)
|
`)
|
||||||
|
|
||||||
// Unequip line tool
|
// Unequip line tool
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
// Make sure we didn't pop out of sketch mode.
|
// Make sure we didn't pop out of sketch mode.
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'line Line', exact: true })
|
page.getByRole('button', { name: 'line Line', exact: true })
|
||||||
).not.toHaveAttribute('aria-pressed', 'true')
|
).not.toHaveAttribute('aria-pressed', 'true')
|
||||||
|
|
||||||
// Exit sketch
|
// Exit sketch
|
||||||
await page.keyboard.press('Escape')
|
await page.keyboard.press('Escape')
|
||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Exit Sketch' })
|
page.getByRole('button', { name: 'Exit Sketch' })
|
||||||
).not.toBeVisible()
|
).not.toBeVisible()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
@ -4,7 +4,7 @@ import { uuidv4 } from '@src/lib/utils'
|
|||||||
import { getUtils, orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
|
import { getUtils, orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Testing Camera Movement', { tag: ['@skipWin'] }, () => {
|
test.describe('Testing Camera Movement', () => {
|
||||||
test('Can move camera reliably', async ({
|
test('Can move camera reliably', async ({
|
||||||
page,
|
page,
|
||||||
context,
|
context,
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
|
test.describe('Testing constraints', () => {
|
||||||
test('Can constrain line length', async ({ page, homePage }) => {
|
test('Can constrain line length', async ({ page, homePage }) => {
|
||||||
await page.addInitScript(async () => {
|
await page.addInitScript(async () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
|
@ -4,7 +4,7 @@ import { TEST_CODE_GIZMO } from '@e2e/playwright/storageStates'
|
|||||||
import { getUtils } from '@e2e/playwright/test-utils'
|
import { getUtils } from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Testing Gizmo', { tag: ['@skipWin'] }, () => {
|
test.describe('Testing Gizmo', () => {
|
||||||
const cases = [
|
const cases = [
|
||||||
{
|
{
|
||||||
testDescription: 'top view',
|
testDescription: 'top view',
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
|
test.describe('Testing segment overlays', () => {
|
||||||
test('Hover over a segment should show its overlay, hovering over the input overlays should show its popover, clicking the input overlay should constrain/unconstrain it:\nfor the following segments', () => {
|
test('Hover over a segment should show its overlay, hovering over the input overlays should show its popover, clicking the input overlay should constrain/unconstrain it:\nfor the following segments', () => {
|
||||||
// TODO: fix this test on mac after the electron migration
|
// TODO: fix this test on mac after the electron migration
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
|
test.describe('Testing selections', () => {
|
||||||
test.setTimeout(90_000)
|
test.setTimeout(90_000)
|
||||||
test('Selections work on fresh and edited sketch', async ({
|
test('Selections work on fresh and edited sketch', async ({
|
||||||
page,
|
page,
|
||||||
|
@ -29,7 +29,7 @@ import { expect, test } from '@e2e/playwright/zoo-test'
|
|||||||
test.describe(
|
test.describe(
|
||||||
'Testing settings',
|
'Testing settings',
|
||||||
{
|
{
|
||||||
tag: ['@macOS'],
|
tag: ['@macos', '@windows'],
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
test('Stored settings are validated and fall back to defaults', async ({
|
test('Stored settings are validated and fall back to defaults', async ({
|
||||||
@ -281,7 +281,7 @@ test.describe(
|
|||||||
|
|
||||||
test(
|
test(
|
||||||
`Project settings override user settings on desktop`,
|
`Project settings override user settings on desktop`,
|
||||||
{ tag: ['@electron', '@skipWin'] },
|
{ tag: ['@electron'] },
|
||||||
async ({ context, page }, testInfo) => {
|
async ({ context, page }, testInfo) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
const projectName = 'bracket'
|
const projectName = 'bracket'
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from '@e2e/playwright/test-utils'
|
} from '@e2e/playwright/test-utils'
|
||||||
import { expect, test } from '@e2e/playwright/zoo-test'
|
import { expect, test } from '@e2e/playwright/zoo-test'
|
||||||
|
|
||||||
test.describe('Text-to-CAD tests', { tag: ['@skipWin'] }, () => {
|
test.describe('Text-to-CAD tests', () => {
|
||||||
test('basic lego happy case', async ({ page, homePage }) => {
|
test('basic lego happy case', async ({ page, homePage }) => {
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
|
||||||
@ -436,93 +436,92 @@ test.describe('Text-to-CAD tests', { tag: ['@skipWin'] }, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// This will be fine once greg makes prompt at top of file deterministic
|
// This will be fine once greg makes prompt at top of file deterministic
|
||||||
test(
|
test('can do many at once and get many prompts back, and interact with many', async ({
|
||||||
'can do many at once and get many prompts back, and interact with many',
|
page,
|
||||||
{ tag: ['@skipWin'] },
|
homePage,
|
||||||
async ({ page, homePage }) => {
|
}) => {
|
||||||
test.fixme(orRunWhenFullSuiteEnabled())
|
test.fixme(orRunWhenFullSuiteEnabled())
|
||||||
// Let this test run longer since we've seen it timeout.
|
// Let this test run longer since we've seen it timeout.
|
||||||
test.setTimeout(180_000)
|
test.setTimeout(180_000)
|
||||||
|
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
|
|
||||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||||
|
|
||||||
await homePage.goToModelingScene()
|
await homePage.goToModelingScene()
|
||||||
await u.waitForPageLoad()
|
await u.waitForPageLoad()
|
||||||
|
|
||||||
await sendPromptFromCommandBar(page, 'a 2x4 lego')
|
await sendPromptFromCommandBar(page, 'a 2x4 lego')
|
||||||
|
|
||||||
await sendPromptFromCommandBar(page, 'a 2x8 lego')
|
await sendPromptFromCommandBar(page, 'a 2x8 lego')
|
||||||
|
|
||||||
await sendPromptFromCommandBar(page, 'a 2x10 lego')
|
await sendPromptFromCommandBar(page, 'a 2x10 lego')
|
||||||
|
|
||||||
// Find the toast.
|
// Find the toast.
|
||||||
// Look out for the toast message
|
// Look out for the toast message
|
||||||
const submittingToastMessage = page.getByText(
|
const submittingToastMessage = page.getByText(
|
||||||
`Submitting to Text-to-CAD API...`
|
`Submitting to Text-to-CAD API...`
|
||||||
)
|
)
|
||||||
await expect(submittingToastMessage.first()).toBeVisible()
|
await expect(submittingToastMessage.first()).toBeVisible()
|
||||||
|
|
||||||
const generatingToastMessage = page.getByText(
|
const generatingToastMessage = page.getByText(
|
||||||
`Generating parametric model...`
|
`Generating parametric model...`
|
||||||
)
|
)
|
||||||
await expect(generatingToastMessage.first()).toBeVisible({
|
await expect(generatingToastMessage.first()).toBeVisible({
|
||||||
timeout: 10_000,
|
timeout: 10_000,
|
||||||
})
|
})
|
||||||
|
|
||||||
const successToastMessage = page.getByText(`Text-to-CAD successful`)
|
const successToastMessage = page.getByText(`Text-to-CAD successful`)
|
||||||
// We should have three success toasts.
|
// We should have three success toasts.
|
||||||
await expect(successToastMessage).toHaveCount(3, { timeout: 25_000 })
|
await expect(successToastMessage).toHaveCount(3, { timeout: 25_000 })
|
||||||
|
|
||||||
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
||||||
await expect(page.getByText(`a 2x8 lego`)).toBeVisible()
|
await expect(page.getByText(`a 2x8 lego`)).toBeVisible()
|
||||||
await expect(page.getByText(`a 2x10 lego`)).toBeVisible()
|
await expect(page.getByText(`a 2x10 lego`)).toBeVisible()
|
||||||
|
|
||||||
// Ensure if you reject one, the others stay.
|
// Ensure if you reject one, the others stay.
|
||||||
const rejectButton = page.getByRole('button', { name: 'Reject' })
|
const rejectButton = page.getByRole('button', { name: 'Reject' })
|
||||||
await expect(rejectButton.first()).toBeVisible()
|
await expect(rejectButton.first()).toBeVisible()
|
||||||
// Click the reject button on the first toast.
|
// Click the reject button on the first toast.
|
||||||
await rejectButton.first().click()
|
await rejectButton.first().click()
|
||||||
|
|
||||||
// The first toast should disappear, but not the others.
|
// The first toast should disappear, but not the others.
|
||||||
await expect(page.getByText(`a 2x10 lego`)).not.toBeVisible()
|
await expect(page.getByText(`a 2x10 lego`)).not.toBeVisible()
|
||||||
await expect(page.getByText(`a 2x8 lego`)).toBeVisible()
|
await expect(page.getByText(`a 2x8 lego`)).toBeVisible()
|
||||||
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
||||||
|
|
||||||
// Ensure you can copy the code for one of the models remaining.
|
// Ensure you can copy the code for one of the models remaining.
|
||||||
const copyToClipboardButton = page.getByRole('button', {
|
const copyToClipboardButton = page.getByRole('button', {
|
||||||
name: 'Accept',
|
name: 'Accept',
|
||||||
})
|
})
|
||||||
await expect(copyToClipboardButton.first()).toBeVisible()
|
await expect(copyToClipboardButton.first()).toBeVisible()
|
||||||
// Click the button.
|
// Click the button.
|
||||||
await copyToClipboardButton.first().click()
|
await copyToClipboardButton.first().click()
|
||||||
|
|
||||||
// Do NOT do AI tests like this: "Expect the code to be pasted."
|
// Do NOT do AI tests like this: "Expect the code to be pasted."
|
||||||
// Reason: AI tests are NONDETERMINISTIC. Thus we need to be as most
|
// Reason: AI tests are NONDETERMINISTIC. Thus we need to be as most
|
||||||
// general as we can for the assertion.
|
// general as we can for the assertion.
|
||||||
// We can use Kolmogorov complexity as a measurement of the
|
// We can use Kolmogorov complexity as a measurement of the
|
||||||
// "probably most minimal version of this program" to have a lower
|
// "probably most minimal version of this program" to have a lower
|
||||||
// bound to work with. It is completely by feel because there are
|
// bound to work with. It is completely by feel because there are
|
||||||
// no proofs that any program is its smallest self.
|
// no proofs that any program is its smallest self.
|
||||||
const code2x8 = await page.locator('.cm-content').innerText()
|
const code2x8 = await page.locator('.cm-content').innerText()
|
||||||
await expect(code2x8.length).toBeGreaterThan(249)
|
await expect(code2x8.length).toBeGreaterThan(249)
|
||||||
|
|
||||||
// Ensure the final toast remains.
|
// Ensure the final toast remains.
|
||||||
await expect(page.getByText(`a 2x10 lego`)).not.toBeVisible()
|
await expect(page.getByText(`a 2x10 lego`)).not.toBeVisible()
|
||||||
await expect(page.getByText(`Prompt: "a 2x8 lego`)).not.toBeVisible()
|
await expect(page.getByText(`Prompt: "a 2x8 lego`)).not.toBeVisible()
|
||||||
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
||||||
|
|
||||||
// Ensure you can copy the code for the final model.
|
// Ensure you can copy the code for the final model.
|
||||||
await expect(copyToClipboardButton).toBeVisible()
|
await expect(copyToClipboardButton).toBeVisible()
|
||||||
// Click the button.
|
// Click the button.
|
||||||
await copyToClipboardButton.click()
|
await copyToClipboardButton.click()
|
||||||
|
|
||||||
// Expect the code to be pasted.
|
// Expect the code to be pasted.
|
||||||
const code2x4 = await page.locator('.cm-content').innerText()
|
const code2x4 = await page.locator('.cm-content').innerText()
|
||||||
await expect(code2x4.length).toBeGreaterThan(249)
|
await expect(code2x4.length).toBeGreaterThan(249)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
|
|
||||||
test('can do many at once with errors, clicking dismiss error does not dismiss all', async ({
|
test('can do many at once with errors, clicking dismiss error does not dismiss all', async ({
|
||||||
page,
|
page,
|
||||||
|
20
package.json
20
package.json
@ -126,7 +126,7 @@
|
|||||||
"generate:machine-api": "npx openapi-typescript ./openapi/machine-api.json -o src/lib/machine-api.d.ts",
|
"generate:machine-api": "npx openapi-typescript ./openapi/machine-api.json -o src/lib/machine-api.d.ts",
|
||||||
"generate:samples-manifest": "cd public/kcl-samples && node generate-manifest.js",
|
"generate:samples-manifest": "cd public/kcl-samples && node generate-manifest.js",
|
||||||
"tron:start": "electron-forge start",
|
"tron:start": "electron-forge start",
|
||||||
"chrome:test": "PLATFORM=web NODE_ENV=development playwright test --config=playwright.config.ts --project='Google Chrome' --grep-invert='@snapshot'",
|
"chrome:test": "PLATFORM=web NODE_ENV=development playwright test --config=playwright.config.ts --project='Google Chrome' --grep-invert=@snapshot",
|
||||||
"tronb:vite:dev": "vite build -c vite.main.config.ts -m development && vite build -c vite.preload.config.ts -m development && vite build -c vite.renderer.config.ts -m development",
|
"tronb:vite:dev": "vite build -c vite.main.config.ts -m development && vite build -c vite.preload.config.ts -m development && vite build -c vite.renderer.config.ts -m development",
|
||||||
"tronb:vite:prod": "vite build -c vite.main.config.ts && vite build -c vite.preload.config.ts && vite build -c vite.renderer.config.ts",
|
"tronb:vite:prod": "vite build -c vite.main.config.ts && vite build -c vite.preload.config.ts && vite build -c vite.renderer.config.ts",
|
||||||
"tronb:package:dev": "npm run tronb:vite:dev && electron-builder --config electron-builder.yml",
|
"tronb:package:dev": "npm run tronb:vite:dev && electron-builder --config electron-builder.yml",
|
||||||
@ -136,15 +136,15 @@
|
|||||||
"test:snapshots": "PLATFORM=web NODE_ENV=development playwright test --config=playwright.config.ts --grep=@snapshot --trace=on --shard=1/1",
|
"test:snapshots": "PLATFORM=web NODE_ENV=development playwright test --config=playwright.config.ts --grep=@snapshot --trace=on --shard=1/1",
|
||||||
"test:unit": "vitest run --mode development --exclude **/kclSamples.test.ts",
|
"test:unit": "vitest run --mode development --exclude **/kclSamples.test.ts",
|
||||||
"test:unit:kcl-samples": "vitest run --mode development ./src/lang/kclSamples.test.ts",
|
"test:unit:kcl-samples": "vitest run --mode development ./src/lang/kclSamples.test.ts",
|
||||||
"test:playwright:electron": "playwright test --config=playwright.electron.config.ts --grep-invert='@snapshot'",
|
"test:playwright:electron": "playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot",
|
||||||
"test:playwright:electron:windows": "playwright test --config=playwright.electron.config.ts --grep-invert=\"@skipWin|@snapshot\" --quiet",
|
"test:playwright:electron:windows": "playwright test --config=playwright.electron.config.ts --grep=@windows --quiet",
|
||||||
"test:playwright:electron:macos": "playwright test --config=playwright.electron.config.ts --grep='@macOS' --quiet",
|
"test:playwright:electron:macos": "playwright test --config=playwright.electron.config.ts --grep=@macos --quiet",
|
||||||
"test:playwright:electron:ubuntu": "playwright test --config=playwright.electron.config.ts --grep-invert='@skipLinux|@snapshot' --quiet",
|
"test:playwright:electron:ubuntu": "playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot --quiet",
|
||||||
"test:playwright:electron:local": "npm run tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert='@snapshot'",
|
"test:playwright:electron:local": "npm run tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot",
|
||||||
"test:playwright:electron:windows:local": "npm run tronb:vite:dev && set NODE_ENV='development' && playwright test --config=playwright.electron.config.ts --grep-invert=\"@skipWin|@snapshot\"",
|
"test:playwright:electron:windows:local": "npm run tronb:vite:dev && set NODE_ENV='development' && playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot",
|
||||||
"test:playwright:electron:macos:local": "npm run tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert='@skipMacos|@snapshot'",
|
"test:playwright:electron:macos:local": "npm run tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot",
|
||||||
"test:playwright:electron:ubuntu:local": "npm run tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert='@skipLinux|@snapshot'",
|
"test:playwright:electron:ubuntu:local": "npm run tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot",
|
||||||
"test:playwright:electron:ubuntu:engine:local": "npm run tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert='@skipLinux|@snapshot|@skipLocalEngine'",
|
"test:playwright:electron:ubuntu:engine:local": "npm run tronb:vite:dev && NODE_ENV=development playwright test --config=playwright.electron.config.ts --grep-invert=@snapshot|@skipLocalEngine",
|
||||||
"test:unit:local": "npm run simpleserver:bg && npm run test:unit; kill-port 3000",
|
"test:unit:local": "npm run simpleserver:bg && npm run test:unit; kill-port 3000",
|
||||||
"test:unit:kcl-samples:local": "npm run simpleserver:bg && npm run test:unit:kcl-samples; kill-port 3000"
|
"test:unit:kcl-samples:local": "npm run simpleserver:bg && npm run test:unit:kcl-samples; kill-port 3000"
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user