Compare commits
6 Commits
kcl-52
...
lf94/speci
Author | SHA1 | Date | |
---|---|---|---|
b5bcb8a5ff | |||
5e72da5770 | |||
00be11f6d6 | |||
4fd53d527f | |||
0f75d945b1 | |||
9cc956ddff |
3
.github/workflows/build-apps.yml
vendored
@ -134,6 +134,7 @@ jobs:
|
||||
# Windows is picky sometimes and fails on fetch. Step takes about ~30s
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 2
|
||||
max_attempts: 3
|
||||
command: yarn install
|
||||
@ -185,6 +186,7 @@ jobs:
|
||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: yarn tronb:package:prod
|
||||
@ -246,6 +248,7 @@ jobs:
|
||||
# TODO: Fix electron-notarize flakes. The logs above should help gather more data on failures
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: yarn tronb:package:prod
|
||||
|
6
.github/workflows/e2e-tests.yml
vendored
@ -51,6 +51,7 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'yarn'
|
||||
- name: Install dependencies
|
||||
id: deps-install
|
||||
shell: bash
|
||||
run: yarn
|
||||
- name: Cache Playwright Browsers
|
||||
@ -133,7 +134,7 @@ jobs:
|
||||
# TODO: break this in its own job, for now it's not slowing down the overall execution as ubuntu is the quickest,
|
||||
# but we could do better. This forces a large 1/1 shard of all 20 snapshot tests that runs in about 3 minutes.
|
||||
run: |
|
||||
PLATFORM=web yarn playwright test --config=playwright.config.ts --retries="3" --update-snapshots --grep=@snapshot --trace=on --shard=1/1
|
||||
yarn test:snapshots
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: development
|
||||
@ -193,9 +194,10 @@ jobs:
|
||||
path: test-results/
|
||||
- name: Run playwright/electron flow (with retries)
|
||||
id: retry
|
||||
if: ${{ !cancelled() && (success() || failure()) }}
|
||||
if: ${{ !cancelled() && steps.deps-install.outcome == 'success' }}
|
||||
uses: nick-fields/retry@v3.0.2
|
||||
with:
|
||||
shell: bash
|
||||
command: .github/ci-cd-scripts/playwright-electron.sh ${{matrix.shardIndex}} ${{matrix.shardTotal}} ${{matrix.os}}
|
||||
timeout_minutes: 30
|
||||
max_attempts: 25
|
||||
|
@ -1,12 +1,14 @@
|
||||
import type { Page, Locator } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
import { expect } from '../zoo-test'
|
||||
import { isArray, uuidv4 } from 'lib/utils'
|
||||
import { CmdBarFixture } from './cmdBarFixture'
|
||||
import {
|
||||
closeDebugPanel,
|
||||
doAndWaitForImageDiff,
|
||||
getPixelRGBs,
|
||||
openAndClearDebugPanel,
|
||||
sendCustomCmd,
|
||||
getUtils,
|
||||
} from '../test-utils'
|
||||
|
||||
type MouseParams = {
|
||||
@ -40,9 +42,13 @@ export class SceneFixture {
|
||||
public page: Page
|
||||
public streamWrapper!: Locator
|
||||
public loadingIndicator!: Locator
|
||||
public networkToggleConnected!: Locator
|
||||
public startEditSketchBtn!: Locator
|
||||
|
||||
get exeIndicator() {
|
||||
return this.page.getByTestId('model-state-indicator-execution-done')
|
||||
return this.page
|
||||
.getByTestId('model-state-indicator-execution-done')
|
||||
.or(this.page.getByTestId('model-state-indicator-receive-reliable'))
|
||||
}
|
||||
|
||||
constructor(page: Page) {
|
||||
@ -70,7 +76,11 @@ export class SceneFixture {
|
||||
this.page = page
|
||||
|
||||
this.streamWrapper = page.getByTestId('stream')
|
||||
this.networkToggleConnected = page.getByTestId('network-toggle-ok')
|
||||
this.loadingIndicator = this.streamWrapper.getByTestId('loading')
|
||||
this.startEditSketchBtn = page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.or(page.getByRole('button', { name: 'Edit Sketch' }))
|
||||
}
|
||||
|
||||
makeMouseHelpers = (
|
||||
@ -229,6 +239,27 @@ export class SceneFixture {
|
||||
await expect(this.exeIndicator).toBeVisible({ timeout: 30000 })
|
||||
}
|
||||
|
||||
connectionEstablished = async () => {
|
||||
const timeout = 30000
|
||||
await expect(this.networkToggleConnected).toBeVisible({ timeout })
|
||||
}
|
||||
|
||||
settled = async (cmdBar: CmdBarFixture) => {
|
||||
const u = await getUtils(this.page)
|
||||
|
||||
await cmdBar.openCmdBar()
|
||||
await cmdBar.chooseCommand('Settings · app · show debug panel')
|
||||
await cmdBar.selectOption({ name: 'on' }).click()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
|
||||
await this.waitForExecutionDone()
|
||||
await expect(this.startEditSketchBtn).not.toBeDisabled()
|
||||
await expect(this.startEditSketchBtn).toBeVisible()
|
||||
}
|
||||
|
||||
expectPixelColor = async (
|
||||
colour: [number, number, number] | [number, number, number][],
|
||||
coords: { x: number; y: number },
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { test, expect } from './zoo-test'
|
||||
import { secrets } from './secrets'
|
||||
import { Paths, doExport, getUtils } from './test-utils'
|
||||
import { Models } from '@kittycad/lib'
|
||||
@ -13,27 +13,10 @@ import {
|
||||
TEST_SETTINGS_KEY,
|
||||
} from './storageStates'
|
||||
import * as TOML from '@iarna/toml'
|
||||
import { SceneFixture } from './fixtures/sceneFixture'
|
||||
import { CmdBarFixture } from './fixtures/cmdBarFixture'
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// reducedMotion kills animations, which speeds up tests and reduces flakiness
|
||||
await page.emulateMedia({ reducedMotion: 'reduce' })
|
||||
|
||||
// set the default settings
|
||||
await page.addInitScript(
|
||||
async ({ token, settingsKey, settings, IS_PLAYWRIGHT_KEY }) => {
|
||||
localStorage.setItem('TOKEN_PERSIST_KEY', token)
|
||||
localStorage.setItem('persistCode', ``)
|
||||
localStorage.setItem(settingsKey, settings)
|
||||
localStorage.setItem(IS_PLAYWRIGHT_KEY, 'true')
|
||||
},
|
||||
{
|
||||
token: secrets.token,
|
||||
settingsKey: TEST_SETTINGS_KEY,
|
||||
settings: TOML.stringify({ settings: TEST_SETTINGS }),
|
||||
IS_PLAYWRIGHT_KEY: IS_PLAYWRIGHT_KEY,
|
||||
}
|
||||
)
|
||||
|
||||
test.beforeEach(async ({ page, context }) => {
|
||||
// Make the user avatar image always 404
|
||||
// so we see the fallback menu icon for all snapshot tests
|
||||
await page.route('https://lh3.googleusercontent.com/**', async (route) => {
|
||||
@ -45,6 +28,14 @@ test.beforeEach(async ({ page }) => {
|
||||
})
|
||||
})
|
||||
|
||||
// Help engine-manager: tear shit down.
|
||||
test.afterEach(async ({ page }) => {
|
||||
await page.evaluate(() => {
|
||||
// @ts-expect-error
|
||||
window.tearDown()
|
||||
})
|
||||
})
|
||||
|
||||
test.setTimeout(60_000)
|
||||
|
||||
// We test this end to end already - getting this to work on web just to take
|
||||
@ -54,7 +45,7 @@ test.setTimeout(60_000)
|
||||
test.skip(
|
||||
'exports of each format should work',
|
||||
{ tag: ['@snapshot', '@skipWin', '@skipMacos'] },
|
||||
async ({ page, context }) => {
|
||||
async ({ page, context, scene, cmdBar }) => {
|
||||
// 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)
|
||||
@ -106,11 +97,8 @@ part001 = startSketchOn('-XZ')
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.waitForCmdReceive('extrude')
|
||||
await page.waitForTimeout(1000)
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
const axisDirectionPair: Models['AxisDirectionPair_type'] = {
|
||||
axis: 'z',
|
||||
@ -313,8 +301,25 @@ part001 = startSketchOn('-XZ')
|
||||
}
|
||||
)
|
||||
|
||||
const extrudeDefaultPlane = async (context: any, page: any, plane: string) => {
|
||||
await context.addInitScript(async () => {
|
||||
const extrudeDefaultPlane = async (
|
||||
context: any,
|
||||
page: any,
|
||||
cmdBar: CmdBarFixture,
|
||||
scene: SceneFixture,
|
||||
plane: string
|
||||
) => {
|
||||
const code = `part001 = startSketchOn('${plane}')
|
||||
|> startProfileAt([7.00, 4.40], %)
|
||||
|> line(end = [6.60, -0.20])
|
||||
|> line(end = [2.80, 5.00])
|
||||
|> line(end = [-5.60, 4.40])
|
||||
|> line(end = [-5.40, -3.80])
|
||||
|> close()
|
||||
|> extrude(length = 10.00)
|
||||
`
|
||||
|
||||
// This probably does absolutely nothing based on my trip through here.
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'SETTINGS_PERSIST_KEY',
|
||||
JSON.stringify({
|
||||
@ -331,41 +336,17 @@ const extrudeDefaultPlane = async (context: any, page: any, plane: string) => {
|
||||
)
|
||||
})
|
||||
|
||||
const code = `part001 = startSketchOn('${plane}')
|
||||
|> startProfileAt([7.00, 4.40], %)
|
||||
|> line(end = [6.60, -0.20])
|
||||
|> line(end = [2.80, 5.00])
|
||||
|> line(end = [-5.60, 4.40])
|
||||
|> line(end = [-5.40, -3.80])
|
||||
|> close()
|
||||
|> extrude(length = 10.00)
|
||||
`
|
||||
await page.addInitScript(async (code: string) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
})
|
||||
}, code)
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await page.waitForTimeout(200)
|
||||
// clear code
|
||||
await u.removeCurrentCode()
|
||||
await u.openAndClearDebugPanel()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.locator('.cm-content').fill(code),
|
||||
200
|
||||
)
|
||||
// wait for execution done
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
|
||||
await u.closeKclCodePanel()
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
mask: [page.getByTestId('model-state-indicator')],
|
||||
@ -380,28 +361,28 @@ test.describe(
|
||||
// FIXME: Skip on macos its being weird.
|
||||
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
test('XY', async ({ page, context }) => {
|
||||
await extrudeDefaultPlane(context, page, 'XY')
|
||||
test('XY', async ({ page, context, cmdBar, scene }) => {
|
||||
await extrudeDefaultPlane(context, page, cmdBar, scene, 'XY')
|
||||
})
|
||||
|
||||
test('XZ', async ({ page, context }) => {
|
||||
await extrudeDefaultPlane(context, page, 'XZ')
|
||||
test('XZ', async ({ page, context, cmdBar, scene }) => {
|
||||
await extrudeDefaultPlane(context, page, cmdBar, scene, 'XZ')
|
||||
})
|
||||
|
||||
test('YZ', async ({ page, context }) => {
|
||||
await extrudeDefaultPlane(context, page, 'YZ')
|
||||
test('YZ', async ({ page, context, cmdBar, scene }) => {
|
||||
await extrudeDefaultPlane(context, page, cmdBar, scene, 'YZ')
|
||||
})
|
||||
|
||||
test('-XY', async ({ page, context }) => {
|
||||
await extrudeDefaultPlane(context, page, '-XY')
|
||||
test('-XY', async ({ page, context, cmdBar, scene }) => {
|
||||
await extrudeDefaultPlane(context, page, cmdBar, scene, '-XY')
|
||||
})
|
||||
|
||||
test('-XZ', async ({ page, context }) => {
|
||||
await extrudeDefaultPlane(context, page, '-XZ')
|
||||
test('-XZ', async ({ page, context, cmdBar, scene }) => {
|
||||
await extrudeDefaultPlane(context, page, cmdBar, scene, '-XZ')
|
||||
})
|
||||
|
||||
test('-YZ', async ({ page, context }) => {
|
||||
await extrudeDefaultPlane(context, page, '-YZ')
|
||||
test('-YZ', async ({ page, context, cmdBar, scene }) => {
|
||||
await extrudeDefaultPlane(context, page, cmdBar, scene, '-YZ')
|
||||
})
|
||||
}
|
||||
)
|
||||
@ -409,7 +390,7 @@ test.describe(
|
||||
test(
|
||||
'Draft segments should look right',
|
||||
{ tag: '@snapshot' },
|
||||
async ({ page, context }) => {
|
||||
async ({ page, context, scene, cmdBar }) => {
|
||||
// FIXME: Skip on macos its being weird.
|
||||
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
@ -418,17 +399,9 @@ test(
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).toBeVisible()
|
||||
await scene.connectionEstablished()
|
||||
|
||||
// click on "Start Sketch" button
|
||||
await u.clearCommandLogs()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||
200
|
||||
@ -448,8 +421,9 @@ test(
|
||||
await expect(page.locator('.cm-content')).toHaveText(code)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await u.closeDebugPanel()
|
||||
await page.mouse.move(startXPx + PUR * 20, 500 - PUR * 10)
|
||||
|
||||
await page.waitForTimeout(500)
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
mask: [page.getByTestId('model-state-indicator')],
|
||||
@ -458,7 +432,7 @@ test(
|
||||
const lineEndClick = () =>
|
||||
page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||
await lineEndClick()
|
||||
await page.waitForTimeout(100)
|
||||
await page.waitForTimeout(500)
|
||||
|
||||
code += `
|
||||
|> xLine(7.25, %)`
|
||||
@ -469,18 +443,16 @@ test(
|
||||
.click()
|
||||
|
||||
// click on the end of the profile to continue it
|
||||
await page.waitForTimeout(300)
|
||||
await page.waitForTimeout(500)
|
||||
await lineEndClick()
|
||||
await page.waitForTimeout(100)
|
||||
await page.waitForTimeout(500)
|
||||
|
||||
// click to continue profile
|
||||
await page.mouse.move(813, 392, { steps: 10 })
|
||||
await page.waitForTimeout(100)
|
||||
await page.waitForTimeout(500)
|
||||
|
||||
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
|
||||
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
mask: [page.getByTestId('model-state-indicator')],
|
||||
@ -491,7 +463,7 @@ test(
|
||||
test(
|
||||
'Draft rectangles should look right',
|
||||
{ tag: '@snapshot' },
|
||||
async ({ page, context }) => {
|
||||
async ({ page, context, cmdBar, scene }) => {
|
||||
// FIXME: Skip on macos its being weird.
|
||||
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
@ -500,17 +472,10 @@ test(
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await u.openDebugPanel()
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).toBeVisible()
|
||||
await scene.connectionEstablished()
|
||||
|
||||
// click on "Start Sketch" button
|
||||
await u.clearCommandLogs()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||
200
|
||||
@ -523,8 +488,8 @@ test(
|
||||
`sketch001 = startSketchOn('XZ')`
|
||||
)
|
||||
|
||||
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
||||
await u.closeDebugPanel()
|
||||
// Wait for camera animation
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
const startXPx = 600
|
||||
|
||||
@ -548,7 +513,7 @@ test(
|
||||
test(
|
||||
'Draft circle should look right',
|
||||
{ tag: '@snapshot' },
|
||||
async ({ page, context }) => {
|
||||
async ({ page, context, cmdBar, scene }) => {
|
||||
// FIXME: Skip on macos its being weird.
|
||||
// test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
@ -557,17 +522,9 @@ test(
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await u.openDebugPanel()
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).toBeVisible()
|
||||
await scene.connectionEstablished()
|
||||
|
||||
// click on "Start Sketch" button
|
||||
await u.clearCommandLogs()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||
200
|
||||
@ -580,8 +537,8 @@ test(
|
||||
`sketch001 = startSketchOn('XZ')`
|
||||
)
|
||||
|
||||
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
||||
await u.closeDebugPanel()
|
||||
// Wait for camera animation
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
const startXPx = 600
|
||||
|
||||
@ -611,23 +568,15 @@ test.describe(
|
||||
// FIXME: Skip on macos its being weird.
|
||||
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
test('Inch scale', async ({ page }) => {
|
||||
test('Inch scale', async ({ page, cmdBar, scene }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await u.openDebugPanel()
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).toBeVisible()
|
||||
await scene.connectionEstablished()
|
||||
|
||||
// click on "Start Sketch" button
|
||||
await u.clearCommandLogs()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||
200
|
||||
@ -639,7 +588,8 @@ test.describe(
|
||||
let code = `sketch001 = startSketchOn('XZ')`
|
||||
await expect(page.locator('.cm-content')).toHaveText(code)
|
||||
|
||||
await page.waitForTimeout(600) // TODO detect animation ending, or disable animation
|
||||
// Wait for camera animation
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
@ -647,8 +597,6 @@ test.describe(
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await u.closeDebugPanel()
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
@ -683,17 +631,12 @@ test.describe(
|
||||
mask: [page.getByTestId('model-state-indicator')],
|
||||
})
|
||||
|
||||
// exit sketch
|
||||
await u.openAndClearDebugPanel()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.getByRole('button', { name: 'Exit Sketch' }).click(),
|
||||
200
|
||||
)
|
||||
|
||||
// wait for execution done
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await page.waitForTimeout(300)
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||
await expect(page).toHaveScreenshot({
|
||||
@ -702,8 +645,8 @@ test.describe(
|
||||
})
|
||||
})
|
||||
|
||||
test('Millimeter scale', async ({ page }) => {
|
||||
await page.addInitScript(
|
||||
test('Millimeter scale', async ({ page, context, cmdBar, scene }) => {
|
||||
await context.addInitScript(
|
||||
async ({ settingsKey, settings }) => {
|
||||
localStorage.setItem(settingsKey, settings)
|
||||
},
|
||||
@ -725,17 +668,10 @@ test.describe(
|
||||
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await u.openDebugPanel()
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).toBeVisible()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// click on "Start Sketch" button
|
||||
await u.clearCommandLogs()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||
200
|
||||
@ -747,7 +683,8 @@ test.describe(
|
||||
let code = `sketch001 = startSketchOn('XZ')`
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
|
||||
await page.waitForTimeout(600) // TODO detect animation ending, or disable animation
|
||||
// Wait for camera animation
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
const startXPx = 600
|
||||
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
||||
@ -755,8 +692,6 @@ test.describe(
|
||||
await expect(u.codeLocator).toHaveText(code)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await u.closeDebugPanel()
|
||||
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
@ -790,16 +725,12 @@ test.describe(
|
||||
})
|
||||
|
||||
// exit sketch
|
||||
await u.openAndClearDebugPanel()
|
||||
await u.doAndWaitForImageDiff(
|
||||
() => page.getByRole('button', { name: 'Exit Sketch' }).click(),
|
||||
200
|
||||
)
|
||||
|
||||
// wait for execution done
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await page.waitForTimeout(300)
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// second screen shot should look almost identical, i.e. scale should be the same.
|
||||
await expect(page).toHaveScreenshot({
|
||||
@ -812,7 +743,7 @@ test.describe(
|
||||
test(
|
||||
'Sketch on face with none z-up',
|
||||
{ tag: '@snapshot' },
|
||||
async ({ page, context }) => {
|
||||
async ({ page, context, cmdBar, scene }) => {
|
||||
// FIXME: Skip on macos its being weird.
|
||||
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
@ -840,12 +771,8 @@ part002 = startSketchOn(part001, seg01)
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(1, { timeout: 10_000 })
|
||||
await u.closeDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
@ -877,7 +804,7 @@ part002 = startSketchOn(part001, seg01)
|
||||
test(
|
||||
'Zoom to fit on load - solid 2d',
|
||||
{ tag: '@snapshot' },
|
||||
async ({ page, context }) => {
|
||||
async ({ page, context, cmdBar, scene }) => {
|
||||
// FIXME: Skip on macos its being weird.
|
||||
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
@ -899,12 +826,8 @@ test(
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(1)
|
||||
await u.closeDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
@ -920,7 +843,7 @@ test(
|
||||
test(
|
||||
'Zoom to fit on load - solid 3d',
|
||||
{ tag: '@snapshot' },
|
||||
async ({ page, context }) => {
|
||||
async ({ page, context, cmdBar, scene }) => {
|
||||
// FIXME: Skip on macos its being weird.
|
||||
test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
@ -943,12 +866,8 @@ test(
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(1)
|
||||
await u.closeDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
@ -965,7 +884,11 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
||||
// FIXME: Skip on macos its being weird.
|
||||
// test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||
|
||||
test('Grid turned off to on via command bar', async ({ page }) => {
|
||||
test('Grid turned off to on via command bar', async ({
|
||||
page,
|
||||
cmdBar,
|
||||
scene,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
const stream = page.getByTestId('stream')
|
||||
const mask = [
|
||||
@ -978,12 +901,9 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(1)
|
||||
await u.closeDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await u.closeKclCodePanel()
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
@ -1033,7 +953,7 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('Grid turned off', async ({ page }) => {
|
||||
test('Grid turned off', async ({ page, cmdBar, scene }) => {
|
||||
const u = await getUtils(page)
|
||||
const stream = page.getByTestId('stream')
|
||||
const mask = [
|
||||
@ -1046,12 +966,9 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(1)
|
||||
await u.closeDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await u.closeKclCodePanel()
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
@ -1063,8 +980,8 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('Grid turned on', async ({ page }) => {
|
||||
await page.addInitScript(
|
||||
test('Grid turned on', async ({ page, context, cmdBar, scene }) => {
|
||||
await context.addInitScript(
|
||||
async ({ settingsKey, settings }) => {
|
||||
localStorage.setItem(settingsKey, settings)
|
||||
},
|
||||
@ -1094,12 +1011,9 @@ test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
// wait for execution done
|
||||
await expect(
|
||||
page.locator('[data-message-type="execution-done"]')
|
||||
).toHaveCount(1)
|
||||
await u.closeDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await u.closeKclCodePanel()
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
@ -1179,7 +1093,7 @@ test.fixme('theme persists', async ({ page, context }) => {
|
||||
})
|
||||
|
||||
test.describe('code color goober', { tag: '@snapshot' }, () => {
|
||||
test('code color goober', async ({ page, context }) => {
|
||||
test('code color goober', async ({ page, context, scene, cmdBar }) => {
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
@ -1213,19 +1127,22 @@ sweepSketch = startSketchOn('XY')
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 1000 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await expect(page, 'expect small color widget').toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
})
|
||||
})
|
||||
|
||||
test('code color goober opening window', async ({ page, context }) => {
|
||||
test('code color goober opening window', async ({
|
||||
page,
|
||||
context,
|
||||
scene,
|
||||
cmdBar,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
@ -1259,12 +1176,10 @@ sweepSketch = startSketchOn('XY')
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 1000 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.clearAndCloseDebugPanel()
|
||||
await scene.connectionEstablished()
|
||||
await scene.settled(cmdBar)
|
||||
|
||||
await expect(page.locator('.cm-css-color-picker-wrapper')).toBeVisible()
|
||||
|
||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 68 KiB |
@ -118,6 +118,7 @@
|
||||
"tronb:package:prod": "yarn tronb:vite:prod && electron-builder --config electron-builder.yml --publish always",
|
||||
"test-setup": "yarn install && yarn build:wasm",
|
||||
"test": "vitest --mode development",
|
||||
"test:snapshots": "PLATFORM=web NODE_ENV=development yarn playwright test --config=playwright.config.ts --update-snapshots --grep=@snapshot --trace=on --shard=1/1",
|
||||
"test:unit": "vitest run --mode development --exclude **/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'",
|
||||
|
@ -19,21 +19,25 @@ export interface ActionIconProps extends React.PropsWithChildren {
|
||||
bgClassName?: string
|
||||
iconClassName?: string
|
||||
size?: keyof typeof iconSizes
|
||||
'data-testid'?: string
|
||||
}
|
||||
|
||||
export const ActionIcon = ({
|
||||
icon = faCircleExclamation,
|
||||
className,
|
||||
bgClassName,
|
||||
iconClassName,
|
||||
size = 'md',
|
||||
children,
|
||||
}: ActionIconProps) => {
|
||||
export const ActionIcon = (props: ActionIconProps) => {
|
||||
const {
|
||||
icon = faCircleExclamation,
|
||||
className,
|
||||
bgClassName,
|
||||
iconClassName,
|
||||
size = 'md',
|
||||
children,
|
||||
} = props
|
||||
|
||||
const computedIconClassName = `h-auto text-inherit dark:text-current group-disabled:text-chalkboard-60 group-disabled:text-chalkboard-60 ${iconClassName}`
|
||||
const computedBgClassName = `bg-chalkboard-20 dark:bg-chalkboard-80 group-disabled:bg-chalkboard-30 dark:group-disabled:bg-chalkboard-80 ${bgClassName}`
|
||||
|
||||
return (
|
||||
<div
|
||||
data-testid={props['data-testid']}
|
||||
className={
|
||||
`w-fit self-stretch inline-grid place-content-center ${className} ` +
|
||||
computedBgClassName
|
||||
|
@ -99,6 +99,9 @@ export const NetworkHealthIndicator = () => {
|
||||
>
|
||||
<ActionIcon
|
||||
icon={overallConnectionStateIcon[overallState]}
|
||||
data-testid={`network-toggle-${
|
||||
overallState == NetworkHealthState.Ok ? 'ok' : 'other'
|
||||
}`}
|
||||
className="p-1"
|
||||
iconClassName={overallConnectionStateColor[overallState].icon}
|
||||
bgClassName={
|
||||
|