2024-05-29 18:04:27 -04:00
|
|
|
import { test, expect } from '@playwright/test'
|
2023-11-24 08:59:24 +11:00
|
|
|
import { secrets } from './secrets'
|
2024-05-29 18:04:27 -04:00
|
|
|
import { Paths, doExport, getUtils } from './test-utils'
|
2023-11-29 11:20:23 +11:00
|
|
|
import { Models } from '@kittycad/lib'
|
|
|
|
import fsp from 'fs/promises'
|
2023-12-18 13:17:09 +11:00
|
|
|
import { spawn } from 'child_process'
|
2024-05-29 18:04:27 -04:00
|
|
|
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
2024-03-14 11:50:46 -04:00
|
|
|
import JSZip from 'jszip'
|
|
|
|
import path from 'path'
|
2024-08-16 07:15:42 -04:00
|
|
|
import {
|
|
|
|
IS_PLAYWRIGHT_KEY,
|
|
|
|
TEST_SETTINGS,
|
|
|
|
TEST_SETTINGS_KEY,
|
|
|
|
} from './storageStates'
|
2024-04-02 10:29:34 -04:00
|
|
|
import * as TOML from '@iarna/toml'
|
2023-11-24 08:59:24 +11:00
|
|
|
|
2024-04-02 10:29:34 -04:00
|
|
|
test.beforeEach(async ({ page }) => {
|
2023-11-24 08:59:24 +11:00
|
|
|
// reducedMotion kills animations, which speeds up tests and reduces flakiness
|
|
|
|
await page.emulateMedia({ reducedMotion: 'reduce' })
|
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
// set the default settings
|
|
|
|
await page.addInitScript(
|
2024-08-16 07:15:42 -04:00
|
|
|
async ({ token, settingsKey, settings, IS_PLAYWRIGHT_KEY }) => {
|
2024-04-11 13:37:49 -04:00
|
|
|
localStorage.setItem('TOKEN_PERSIST_KEY', token)
|
|
|
|
localStorage.setItem('persistCode', ``)
|
|
|
|
localStorage.setItem(settingsKey, settings)
|
2024-08-16 07:15:42 -04:00
|
|
|
localStorage.setItem(IS_PLAYWRIGHT_KEY, 'true')
|
2024-04-11 13:37:49 -04:00
|
|
|
},
|
|
|
|
{
|
|
|
|
token: secrets.token,
|
|
|
|
settingsKey: TEST_SETTINGS_KEY,
|
|
|
|
settings: TOML.stringify({ settings: TEST_SETTINGS }),
|
2024-08-16 07:15:42 -04:00
|
|
|
IS_PLAYWRIGHT_KEY: IS_PLAYWRIGHT_KEY,
|
2024-04-11 13:37:49 -04:00
|
|
|
}
|
|
|
|
)
|
2024-04-16 14:29:33 -04:00
|
|
|
|
|
|
|
// 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) => {
|
|
|
|
await route.fulfill({
|
|
|
|
status: 404,
|
|
|
|
contentType: 'text/plain',
|
|
|
|
body: 'Not Found!',
|
|
|
|
})
|
|
|
|
})
|
2024-04-02 10:29:34 -04:00
|
|
|
})
|
|
|
|
|
2024-03-05 11:52:43 +11:00
|
|
|
test.setTimeout(60_000)
|
2023-11-24 08:59:24 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test(
|
|
|
|
'exports of each format should work',
|
2024-10-02 11:58:17 -04:00
|
|
|
{ tag: ['@snapshot', '@skipWin', '@skipMacos'] },
|
2024-08-05 21:30:16 +10:00
|
|
|
async ({ page, context }) => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// skip on macos and windows.
|
|
|
|
test.skip(
|
2024-08-19 15:36:18 -04:00
|
|
|
// eslint-disable-next-line jest/valid-title
|
2024-08-17 14:15:11 -07:00
|
|
|
process.platform === 'darwin' || process.platform === 'win32',
|
|
|
|
'Skip on macos and windows'
|
|
|
|
)
|
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// FYI this test doesn't work with only engine running locally
|
|
|
|
// And you will need to have the KittyCAD CLI installed
|
|
|
|
const u = await getUtils(page)
|
|
|
|
await context.addInitScript(async () => {
|
|
|
|
;(window as any).playwrightSkipFilePicker = true
|
|
|
|
localStorage.setItem(
|
|
|
|
'persistCode',
|
2024-10-02 14:19:40 -05:00
|
|
|
`topAng = 25
|
|
|
|
bottomAng = 35
|
|
|
|
baseLen = 3.5
|
|
|
|
baseHeight = 1
|
|
|
|
totalHeightHalf = 2
|
|
|
|
armThick = 0.5
|
|
|
|
totalLen = 9.5
|
|
|
|
part001 = startSketchOn('-XZ')
|
2024-02-27 09:41:09 +11:00
|
|
|
|> startProfileAt([0, 0], %)
|
|
|
|
|> yLine(baseHeight, %)
|
|
|
|
|> xLine(baseLen, %)
|
|
|
|
|> angledLineToY({
|
|
|
|
angle: topAng,
|
|
|
|
to: totalHeightHalf,
|
2024-07-27 22:56:46 -07:00
|
|
|
}, %, $seg04)
|
2024-08-04 08:29:28 +10:00
|
|
|
|> xLineTo(totalLen, %, $seg03)
|
2024-07-27 22:56:46 -07:00
|
|
|
|> yLine(-armThick, %, $seg01)
|
2024-02-27 09:41:09 +11:00
|
|
|
|> angledLineThatIntersects({
|
|
|
|
angle: HALF_TURN,
|
|
|
|
offset: -armThick,
|
2024-07-27 22:56:46 -07:00
|
|
|
intersectTag: seg04
|
2024-02-27 09:41:09 +11:00
|
|
|
}, %)
|
2024-07-27 22:56:46 -07:00
|
|
|
|> angledLineToY([segAng(seg04, %) + 180, ZERO], %)
|
2024-02-27 09:41:09 +11:00
|
|
|
|> angledLineToY({
|
|
|
|
angle: -bottomAng,
|
|
|
|
to: -totalHeightHalf - armThick,
|
2024-07-27 22:56:46 -07:00
|
|
|
}, %, $seg02)
|
|
|
|
|> xLineTo(segEndX(seg03, %) + 0, %)
|
|
|
|
|> yLine(-segLen(seg01, %), %)
|
2024-02-27 09:41:09 +11:00
|
|
|
|> angledLineThatIntersects({
|
|
|
|
angle: HALF_TURN,
|
|
|
|
offset: -armThick,
|
2024-07-27 22:56:46 -07:00
|
|
|
intersectTag: seg02
|
2024-02-27 09:41:09 +11:00
|
|
|
}, %)
|
2024-07-27 22:56:46 -07:00
|
|
|
|> angledLineToY([segAng(seg02, %) + 180, -baseHeight], %)
|
2024-02-27 09:41:09 +11:00
|
|
|
|> xLineTo(ZERO, %)
|
|
|
|
|> close(%)
|
|
|
|
|> extrude(4, %)`
|
2024-08-05 21:30:16 +10:00
|
|
|
)
|
|
|
|
})
|
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
2024-06-29 18:10:07 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.waitForAuthSkipAppStart()
|
2024-06-29 18:10:07 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.openDebugPanel()
|
|
|
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
|
|
await u.waitForCmdReceive('extrude')
|
|
|
|
await page.waitForTimeout(1000)
|
|
|
|
await u.clearAndCloseDebugPanel()
|
2024-02-27 09:41:09 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
const axisDirectionPair: Models['AxisDirectionPair_type'] = {
|
|
|
|
axis: 'z',
|
|
|
|
direction: 'positive',
|
|
|
|
}
|
|
|
|
const sysType: Models['System_type'] = {
|
|
|
|
forward: axisDirectionPair,
|
|
|
|
up: axisDirectionPair,
|
|
|
|
}
|
2024-02-27 09:41:09 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
const exportLocations: Paths[] = []
|
|
|
|
|
|
|
|
// NOTE it was easiest to leverage existing types and have doExport take Models['OutputFormat_type'] as in input
|
|
|
|
// just note that only `type` and `storage` are used for selecting the drop downs is the app
|
|
|
|
// the rest are only there to make typescript happy
|
2024-09-27 05:55:42 +10:00
|
|
|
|
|
|
|
// TODO - failing because of an exporter issue, ADD BACK IN WHEN ITS FIXED
|
|
|
|
// exportLocations.push(
|
|
|
|
// await doExport(
|
|
|
|
// {
|
|
|
|
// type: 'step',
|
|
|
|
// coords: sysType,
|
|
|
|
// },
|
|
|
|
// page
|
|
|
|
// )
|
|
|
|
// )
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
type: 'ply',
|
|
|
|
coords: sysType,
|
|
|
|
selection: { type: 'default_scene' },
|
|
|
|
storage: 'ascii',
|
|
|
|
units: 'in',
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
type: 'ply',
|
|
|
|
storage: 'binary_little_endian',
|
|
|
|
coords: sysType,
|
|
|
|
selection: { type: 'default_scene' },
|
|
|
|
units: 'in',
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
type: 'ply',
|
|
|
|
storage: 'binary_big_endian',
|
|
|
|
coords: sysType,
|
|
|
|
selection: { type: 'default_scene' },
|
|
|
|
units: 'in',
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
type: 'stl',
|
|
|
|
storage: 'ascii',
|
|
|
|
coords: sysType,
|
|
|
|
units: 'in',
|
|
|
|
selection: { type: 'default_scene' },
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
type: 'stl',
|
|
|
|
storage: 'binary',
|
|
|
|
coords: sysType,
|
|
|
|
units: 'in',
|
|
|
|
selection: { type: 'default_scene' },
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
// obj seems to be a little flaky, times out tests sometimes
|
|
|
|
type: 'obj',
|
|
|
|
coords: sysType,
|
|
|
|
units: 'in',
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
type: 'gltf',
|
|
|
|
storage: 'embedded',
|
|
|
|
presentation: 'pretty',
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
type: 'gltf',
|
|
|
|
storage: 'binary',
|
|
|
|
presentation: 'pretty',
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
exportLocations.push(
|
|
|
|
await doExport(
|
|
|
|
{
|
|
|
|
type: 'gltf',
|
|
|
|
storage: 'standard',
|
|
|
|
presentation: 'pretty',
|
|
|
|
},
|
|
|
|
page
|
|
|
|
)
|
2024-05-29 18:04:27 -04:00
|
|
|
)
|
2024-02-27 09:41:09 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// close page to disconnect websocket since we can only have one open atm
|
|
|
|
await page.close()
|
|
|
|
|
|
|
|
// snapshot exports, good compromise to capture that exports are healthy without getting bogged down in "did the formatting change" changes
|
|
|
|
// context: https://github.com/KittyCAD/modeling-app/issues/1222
|
|
|
|
for (let { modelPath, imagePath, outputType } of exportLocations) {
|
|
|
|
// May change depending on the file being dealt with
|
|
|
|
let cliCommand = `export ZOO_TOKEN=${secrets.snapshottoken} && zoo file snapshot --output-format=png --src-format=${outputType} ${modelPath} ${imagePath}`
|
|
|
|
const fileSize = (await fsp.stat(modelPath)).size
|
|
|
|
console.log(`Size of the file at ${modelPath}: ${fileSize} bytes`)
|
|
|
|
|
|
|
|
const parentPath = path.dirname(modelPath)
|
|
|
|
|
|
|
|
// This is actually a zip file.
|
|
|
|
if (modelPath.includes('gltf-standard.gltf')) {
|
|
|
|
console.log('Extracting files from archive')
|
|
|
|
const readZipFile = fsp.readFile(modelPath)
|
|
|
|
const unzip = (archive: any) =>
|
|
|
|
Object.values(archive.files).map((file: any) => ({
|
|
|
|
name: file.name,
|
|
|
|
promise: file.async('nodebuffer'),
|
|
|
|
}))
|
|
|
|
const writeFiles = (files: any) =>
|
|
|
|
Promise.all(
|
|
|
|
files.map((file: any) =>
|
|
|
|
file.promise.then((data: any) => {
|
|
|
|
console.log(`Writing ${file.name}`)
|
|
|
|
return fsp
|
|
|
|
.writeFile(`${parentPath}/${file.name}`, data)
|
|
|
|
.then(() => file.name)
|
|
|
|
})
|
|
|
|
)
|
2024-03-14 11:50:46 -04:00
|
|
|
)
|
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
const filenames = await readZipFile
|
|
|
|
.then(JSZip.loadAsync)
|
|
|
|
.then(unzip)
|
|
|
|
.then(writeFiles)
|
|
|
|
const gltfFilename = filenames.filter((t: string) =>
|
|
|
|
t.includes('.gltf')
|
|
|
|
)[0]
|
|
|
|
if (!gltfFilename) throw new Error('No output.gltf in this archive')
|
|
|
|
cliCommand = `export ZOO_TOKEN=${secrets.snapshottoken} && zoo file snapshot --output-format=png --src-format=${outputType} ${parentPath}/${gltfFilename} ${imagePath}`
|
|
|
|
}
|
2024-03-14 11:50:46 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
console.log(cliCommand)
|
|
|
|
|
|
|
|
const child = spawn(cliCommand, { shell: true })
|
|
|
|
const result = await new Promise<string>((resolve, reject) => {
|
|
|
|
child.on('error', (code: any, msg: any) => {
|
|
|
|
console.log('error', code, msg)
|
|
|
|
reject('error')
|
|
|
|
})
|
|
|
|
child.on('exit', (code, msg) => {
|
|
|
|
console.log('exit', code, msg)
|
|
|
|
if (code !== 0) {
|
|
|
|
reject(`exit code ${code} for model ${modelPath}`)
|
|
|
|
} else {
|
|
|
|
resolve('success')
|
|
|
|
}
|
|
|
|
})
|
|
|
|
child.stderr.on('data', (data) => console.log(`stderr: ${data}`))
|
|
|
|
child.stdout.on('data', (data) => console.log(`stdout: ${data}`))
|
2024-02-27 09:41:09 +11:00
|
|
|
})
|
2024-08-05 21:30:16 +10:00
|
|
|
expect(result).toBe('success')
|
|
|
|
if (result === 'success') {
|
|
|
|
console.log(`snapshot taken for ${modelPath}`)
|
|
|
|
} else {
|
|
|
|
console.log(`snapshot failed for ${modelPath}`)
|
|
|
|
}
|
2024-02-27 15:19:14 +11:00
|
|
|
}
|
2024-02-27 09:41:09 +11:00
|
|
|
}
|
2024-08-05 21:30:16 +10:00
|
|
|
)
|
2024-02-17 12:19:46 +11:00
|
|
|
|
2024-04-17 20:18:07 -07:00
|
|
|
const extrudeDefaultPlane = async (context: any, page: any, plane: string) => {
|
2024-04-03 13:22:56 +11:00
|
|
|
await context.addInitScript(async () => {
|
|
|
|
localStorage.setItem(
|
|
|
|
'SETTINGS_PERSIST_KEY',
|
|
|
|
JSON.stringify({
|
|
|
|
baseUnit: 'in',
|
|
|
|
cameraControls: 'KittyCAD',
|
|
|
|
defaultDirectory: '',
|
|
|
|
defaultProjectName: 'project-$nnn',
|
|
|
|
onboardingStatus: 'dismissed',
|
|
|
|
showDebugPanel: true,
|
|
|
|
textWrapping: 'On',
|
|
|
|
theme: 'dark',
|
|
|
|
unitSystem: 'imperial',
|
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
2024-04-17 20:18:07 -07:00
|
|
|
|
2024-10-02 14:19:40 -05:00
|
|
|
const code = `part001 = startSketchOn('${plane}')
|
2024-03-02 08:20:50 +11:00
|
|
|
|> startProfileAt([7.00, 4.40], %)
|
|
|
|
|> line([6.60, -0.20], %)
|
|
|
|
|> line([2.80, 5.00], %)
|
|
|
|
|> line([-5.60, 4.40], %)
|
|
|
|
|> line([-5.40, -3.80], %)
|
2024-02-17 12:19:46 +11:00
|
|
|
|> close(%)
|
2024-03-02 08:20:50 +11:00
|
|
|
|> extrude(10.00, %)
|
2024-02-17 12:19:46 +11:00
|
|
|
`
|
2024-04-17 20:18:07 -07:00
|
|
|
await page.addInitScript(async (code: string) => {
|
2024-02-17 12:19:46 +11:00
|
|
|
localStorage.setItem('persistCode', code)
|
2024-04-17 20:18:07 -07:00
|
|
|
})
|
|
|
|
|
2024-05-23 02:20:40 -07:00
|
|
|
const u = await getUtils(page)
|
2024-02-17 12:19:46 +11:00
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
2024-06-29 18:10:07 -07:00
|
|
|
|
2024-02-17 12:19:46 +11:00
|
|
|
await u.waitForAuthSkipAppStart()
|
|
|
|
|
|
|
|
// wait for execution done
|
|
|
|
await u.openDebugPanel()
|
|
|
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
|
|
|
await u.clearAndCloseDebugPanel()
|
2024-04-02 10:29:34 -04:00
|
|
|
await page.waitForTimeout(200)
|
2024-04-17 20:18:07 -07:00
|
|
|
// 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()
|
2024-02-17 12:19:46 +11:00
|
|
|
|
2024-04-17 20:18:07 -07:00
|
|
|
await u.closeKclCodePanel()
|
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
})
|
|
|
|
await u.openKclCodePanel()
|
|
|
|
}
|
2024-04-18 15:16:08 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test.describe(
|
|
|
|
'extrude on default planes should be stable',
|
|
|
|
{ tag: '@snapshot' },
|
|
|
|
() => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test('XY', async ({ page, context }) => {
|
|
|
|
await extrudeDefaultPlane(context, page, 'XY')
|
|
|
|
})
|
2024-04-19 11:56:21 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test('XZ', async ({ page, context }) => {
|
|
|
|
await extrudeDefaultPlane(context, page, 'XZ')
|
|
|
|
})
|
2024-04-19 11:56:21 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test('YZ', async ({ page, context }) => {
|
|
|
|
await extrudeDefaultPlane(context, page, 'YZ')
|
|
|
|
})
|
2024-04-19 11:56:21 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test('-XY', async ({ page, context }) => {
|
|
|
|
await extrudeDefaultPlane(context, page, '-XY')
|
|
|
|
})
|
2024-04-19 11:56:21 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test('-XZ', async ({ page, context }) => {
|
|
|
|
await extrudeDefaultPlane(context, page, '-XZ')
|
|
|
|
})
|
2024-04-19 11:56:21 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test('-YZ', async ({ page, context }) => {
|
|
|
|
await extrudeDefaultPlane(context, page, '-YZ')
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
2024-04-19 11:56:21 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test(
|
|
|
|
'Draft segments should look right',
|
|
|
|
{ tag: '@snapshot' },
|
|
|
|
async ({ page, context }) => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
2024-05-23 02:20:40 -07:00
|
|
|
const u = await getUtils(page)
|
2024-04-11 13:37:49 -04:00
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
|
|
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
|
|
|
await u.waitForAuthSkipAppStart()
|
2024-08-05 21:30:16 +10:00
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
await u.openDebugPanel()
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
await expect(
|
|
|
|
page.getByRole('button', { name: 'Start Sketch' })
|
|
|
|
).not.toBeDisabled()
|
|
|
|
await expect(
|
|
|
|
page.getByRole('button', { name: 'Start Sketch' })
|
|
|
|
).toBeVisible()
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
// click on "Start Sketch" button
|
|
|
|
await u.clearCommandLogs()
|
|
|
|
await u.doAndWaitForImageDiff(
|
|
|
|
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
|
|
|
200
|
|
|
|
)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
// select a plane
|
|
|
|
await page.mouse.click(700, 200)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-10-02 14:19:40 -05:00
|
|
|
let code = `sketch001 = startSketchOn('XZ')`
|
2024-06-18 16:08:41 +10:00
|
|
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.waitForTimeout(700) // TODO detect animation ending, or disable animation
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
const startXPx = 600
|
|
|
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
2024-06-18 16:08:41 +10:00
|
|
|
code += `
|
|
|
|
|> startProfileAt([7.19, -9.7], %)`
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
2024-04-11 13:37:49 -04:00
|
|
|
await page.waitForTimeout(100)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
await u.closeDebugPanel()
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.mouse.move(startXPx + PUR * 20, 500 - PUR * 10)
|
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
2024-10-01 14:14:12 -04:00
|
|
|
mask: [page.getByTestId('model-state-indicator')],
|
2024-08-05 21:30:16 +10:00
|
|
|
})
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
|
|
|
await page.waitForTimeout(100)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-06-18 16:08:41 +10:00
|
|
|
code += `
|
2024-11-13 09:41:27 -05:00
|
|
|
|> xLine(7.25, %)`
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-07-24 23:33:31 -04:00
|
|
|
await page
|
2024-08-16 07:15:42 -04:00
|
|
|
.getByRole('button', { name: 'arc Tangential Arc', exact: true })
|
2024-07-24 23:33:31 -04:00
|
|
|
.click()
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-10-18 04:31:00 -04:00
|
|
|
await page.waitForTimeout(1000)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-11 13:37:49 -04:00
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
2024-10-01 07:56:04 +10:00
|
|
|
mask: [page.getByTestId('model-state-indicator')],
|
2024-04-11 13:37:49 -04:00
|
|
|
})
|
2024-08-05 21:30:16 +10:00
|
|
|
}
|
|
|
|
)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test(
|
|
|
|
'Draft rectangles should look right',
|
|
|
|
{ tag: '@snapshot' },
|
|
|
|
async ({ page, context }) => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
2024-05-23 02:20:40 -07:00
|
|
|
const u = await getUtils(page)
|
2024-04-02 10:29:34 -04:00
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
|
|
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
2024-06-29 18:10:07 -07:00
|
|
|
|
2024-04-02 10:29:34 -04:00
|
|
|
await u.waitForAuthSkipAppStart()
|
|
|
|
await u.openDebugPanel()
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-02 10:29:34 -04:00
|
|
|
await expect(
|
|
|
|
page.getByRole('button', { name: 'Start Sketch' })
|
|
|
|
).not.toBeDisabled()
|
|
|
|
await expect(
|
|
|
|
page.getByRole('button', { name: 'Start Sketch' })
|
|
|
|
).toBeVisible()
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-02 10:29:34 -04:00
|
|
|
// click on "Start Sketch" button
|
|
|
|
await u.clearCommandLogs()
|
|
|
|
await u.doAndWaitForImageDiff(
|
|
|
|
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
|
|
|
200
|
|
|
|
)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-02 10:29:34 -04:00
|
|
|
// select a plane
|
|
|
|
await page.mouse.click(700, 200)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(page.locator('.cm-content')).toHaveText(
|
2024-10-02 14:19:40 -05:00
|
|
|
`sketch001 = startSketchOn('XZ')`
|
2024-08-05 21:30:16 +10:00
|
|
|
)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
|
|
|
await u.closeDebugPanel()
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-04-02 10:29:34 -04:00
|
|
|
const startXPx = 600
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// Equip the rectangle tool
|
|
|
|
await page
|
2024-08-16 07:15:42 -04:00
|
|
|
.getByRole('button', { name: 'rectangle Corner rectangle', exact: true })
|
2024-08-05 21:30:16 +10:00
|
|
|
.click()
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// Draw the rectangle
|
|
|
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 30)
|
|
|
|
await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 10, { steps: 5 })
|
2024-10-18 04:31:00 -04:00
|
|
|
await page.waitForTimeout(800)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// Ensure the draft rectangle looks the same as it usually does
|
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
2024-10-01 07:56:04 +10:00
|
|
|
mask: [page.getByTestId('model-state-indicator')],
|
2024-08-05 21:30:16 +10:00
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
2024-09-23 22:42:51 +10:00
|
|
|
test(
|
|
|
|
'Draft circle should look right',
|
|
|
|
{ tag: '@snapshot' },
|
|
|
|
async ({ page, context }) => {
|
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
// test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
|
|
// click on "Start Sketch" button
|
|
|
|
await u.clearCommandLogs()
|
|
|
|
await u.doAndWaitForImageDiff(
|
|
|
|
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
|
|
|
200
|
|
|
|
)
|
|
|
|
|
|
|
|
// select a plane
|
|
|
|
await page.mouse.click(700, 200)
|
|
|
|
|
|
|
|
await expect(page.locator('.cm-content')).toHaveText(
|
2024-10-02 14:19:40 -05:00
|
|
|
`sketch001 = startSketchOn('XZ')`
|
2024-09-23 22:42:51 +10:00
|
|
|
)
|
|
|
|
|
|
|
|
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
|
|
|
await u.closeDebugPanel()
|
|
|
|
|
|
|
|
const startXPx = 600
|
|
|
|
|
|
|
|
// Equip the rectangle tool
|
|
|
|
// await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
|
|
|
await page.getByTestId('circle-center').click()
|
|
|
|
|
|
|
|
// Draw the rectangle
|
|
|
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
|
|
|
await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 10, { steps: 5 })
|
|
|
|
|
|
|
|
// Ensure the draft rectangle looks the same as it usually does
|
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
2024-10-01 07:56:04 +10:00
|
|
|
mask: [page.getByTestId('model-state-indicator')],
|
2024-09-23 22:42:51 +10:00
|
|
|
})
|
|
|
|
await expect(page.locator('.cm-content')).toHaveText(
|
2024-10-02 14:19:40 -05:00
|
|
|
`sketch001 = startSketchOn('XZ')
|
2024-09-23 22:42:51 +10:00
|
|
|
|> circle({ center: [14.44, -2.44], radius: 1 }, %)`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
)
|
2024-08-05 21:30:16 +10:00
|
|
|
|
|
|
|
test.describe(
|
|
|
|
'Client side scene scale should match engine scale',
|
|
|
|
{ tag: '@snapshot' },
|
|
|
|
() => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test('Inch scale', async ({ page }) => {
|
|
|
|
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()
|
|
|
|
|
|
|
|
// click on "Start Sketch" button
|
|
|
|
await u.clearCommandLogs()
|
|
|
|
await u.doAndWaitForImageDiff(
|
|
|
|
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
|
|
|
200
|
|
|
|
)
|
|
|
|
|
|
|
|
// select a plane
|
|
|
|
await page.mouse.click(700, 200)
|
|
|
|
|
2024-10-02 14:19:40 -05:00
|
|
|
let code = `sketch001 = startSketchOn('XZ')`
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(page.locator('.cm-content')).toHaveText(code)
|
|
|
|
|
|
|
|
await page.waitForTimeout(600) // TODO detect animation ending, or disable animation
|
|
|
|
|
|
|
|
const startXPx = 600
|
|
|
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
|
|
|
code += `
|
|
|
|
|> startProfileAt([7.19, -9.7], %)`
|
|
|
|
await expect(u.codeLocator).toHaveText(code)
|
|
|
|
await page.waitForTimeout(100)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.closeDebugPanel()
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
|
|
|
await page.waitForTimeout(100)
|
2024-03-02 08:20:50 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
code += `
|
2024-11-13 09:41:27 -05:00
|
|
|
|> xLine(7.25, %)`
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(u.codeLocator).toHaveText(code)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page
|
2024-08-16 07:15:42 -04:00
|
|
|
.getByRole('button', { name: 'arc Tangential Arc', exact: true })
|
2024-08-05 21:30:16 +10:00
|
|
|
.click()
|
|
|
|
await page.waitForTimeout(100)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
|
|
|
|
|
|
|
code += `
|
|
|
|
|> tangentialArcTo([21.7, -2.44], %)`
|
|
|
|
await expect(u.codeLocator).toHaveText(code)
|
|
|
|
|
|
|
|
// click tangential arc tool again to unequip it
|
|
|
|
await page
|
2024-08-16 07:15:42 -04:00
|
|
|
.getByRole('button', { name: 'arc Tangential Arc', exact: true })
|
2024-08-05 21:30:16 +10:00
|
|
|
.click()
|
|
|
|
await page.waitForTimeout(100)
|
|
|
|
|
|
|
|
// screen shot should show the sketch
|
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
2024-10-11 23:25:51 +02:00
|
|
|
mask: [page.getByTestId('model-state-indicator')],
|
2024-08-05 21:30:16 +10:00
|
|
|
})
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
|
|
|
// second screen shot should look almost identical, i.e. scale should be the same.
|
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
2024-10-11 23:25:51 +02:00
|
|
|
mask: [page.getByTestId('model-state-indicator')],
|
2024-08-05 21:30:16 +10:00
|
|
|
})
|
2024-04-02 10:29:34 -04:00
|
|
|
})
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test('Millimeter scale', async ({ page }) => {
|
|
|
|
await page.addInitScript(
|
|
|
|
async ({ settingsKey, settings }) => {
|
|
|
|
localStorage.setItem(settingsKey, settings)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
settingsKey: TEST_SETTINGS_KEY,
|
|
|
|
settings: TOML.stringify({
|
|
|
|
settings: {
|
|
|
|
...TEST_SETTINGS,
|
|
|
|
modeling: {
|
|
|
|
...TEST_SETTINGS.modeling,
|
|
|
|
defaultUnit: 'mm',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
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()
|
|
|
|
|
|
|
|
// click on "Start Sketch" button
|
|
|
|
await u.clearCommandLogs()
|
|
|
|
await u.doAndWaitForImageDiff(
|
|
|
|
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
|
|
|
200
|
|
|
|
)
|
|
|
|
|
|
|
|
// select a plane
|
|
|
|
await page.mouse.click(700, 200)
|
|
|
|
|
2024-10-02 14:19:40 -05:00
|
|
|
let code = `sketch001 = startSketchOn('XZ')`
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(u.codeLocator).toHaveText(code)
|
|
|
|
|
|
|
|
await page.waitForTimeout(600) // TODO detect animation ending, or disable animation
|
|
|
|
|
|
|
|
const startXPx = 600
|
|
|
|
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
|
|
|
|
code += `
|
|
|
|
|> startProfileAt([182.59, -246.32], %)`
|
|
|
|
await expect(u.codeLocator).toHaveText(code)
|
|
|
|
await page.waitForTimeout(100)
|
2024-03-01 06:55:49 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.closeDebugPanel()
|
2024-04-02 10:29:34 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
|
|
|
|
await page.waitForTimeout(100)
|
|
|
|
|
|
|
|
code += `
|
2024-11-13 09:41:27 -05:00
|
|
|
|> xLine(184.3, %)`
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(u.codeLocator).toHaveText(code)
|
|
|
|
|
|
|
|
await page
|
2024-08-16 07:15:42 -04:00
|
|
|
.getByRole('button', { name: 'arc Tangential Arc', exact: true })
|
2024-08-05 21:30:16 +10:00
|
|
|
.click()
|
|
|
|
await page.waitForTimeout(100)
|
|
|
|
|
|
|
|
await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20)
|
|
|
|
|
|
|
|
code += `
|
|
|
|
|> tangentialArcTo([551.2, -62.01], %)`
|
|
|
|
await expect(u.codeLocator).toHaveText(code)
|
|
|
|
|
|
|
|
await page
|
2024-08-16 07:15:42 -04:00
|
|
|
.getByRole('button', { name: 'arc Tangential Arc', exact: true })
|
2024-08-05 21:30:16 +10:00
|
|
|
.click()
|
|
|
|
await page.waitForTimeout(100)
|
|
|
|
|
|
|
|
// screen shot should show the sketch
|
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
})
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
|
|
|
// second screen shot should look almost identical, i.e. scale should be the same.
|
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
})
|
2024-04-02 10:29:34 -04:00
|
|
|
})
|
2024-08-05 21:30:16 +10:00
|
|
|
}
|
|
|
|
)
|
2024-03-22 10:23:04 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test(
|
|
|
|
'Sketch on face with none z-up',
|
|
|
|
{ tag: '@snapshot' },
|
|
|
|
async ({ page, context }) => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
const u = await getUtils(page)
|
|
|
|
await context.addInitScript(async (KCL_DEFAULT_LENGTH) => {
|
|
|
|
localStorage.setItem(
|
|
|
|
'persistCode',
|
2024-10-02 14:19:40 -05:00
|
|
|
`part001 = startSketchOn('-XZ')
|
2024-03-22 10:23:04 +11:00
|
|
|
|> startProfileAt([1.4, 2.47], %)
|
2024-08-04 08:29:28 +10:00
|
|
|
|> line([9.31, 10.55], %, $seg01)
|
2024-03-22 10:23:04 +11:00
|
|
|
|> line([11.91, -10.42], %)
|
|
|
|
|> close(%)
|
2024-05-17 10:29:04 -04:00
|
|
|
|> extrude(${KCL_DEFAULT_LENGTH}, %)
|
2024-10-02 14:19:40 -05:00
|
|
|
part002 = startSketchOn(part001, seg01)
|
2024-04-16 12:31:50 -04:00
|
|
|
|> startProfileAt([8, 8], %)
|
2024-03-22 10:23:04 +11:00
|
|
|
|> line([4.68, 3.05], %)
|
2024-08-04 08:29:28 +10:00
|
|
|
|> line([0, -7.79], %)
|
2024-03-22 10:23:04 +11:00
|
|
|
|> close(%)
|
2024-05-17 10:29:04 -04:00
|
|
|
|> extrude(${KCL_DEFAULT_LENGTH}, %)
|
2024-03-22 10:23:04 +11:00
|
|
|
`
|
2024-08-05 21:30:16 +10:00
|
|
|
)
|
|
|
|
}, KCL_DEFAULT_LENGTH)
|
2024-03-22 10:23:04 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
2024-06-29 18:10:07 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.waitForAuthSkipAppStart()
|
2024-04-16 12:31:50 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.openDebugPanel()
|
|
|
|
// wait for execution done
|
|
|
|
await expect(
|
|
|
|
page.locator('[data-message-type="execution-done"]')
|
|
|
|
).toHaveCount(1, { timeout: 10_000 })
|
|
|
|
await u.closeDebugPanel()
|
2024-04-16 12:31:50 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// Wait for the second extrusion to appear
|
|
|
|
// TODO: Find a way to truly know that the objects have finished
|
|
|
|
// rendering, because an execution-done message is not sufficient.
|
|
|
|
await page.waitForTimeout(1000)
|
2024-04-16 12:31:50 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(
|
|
|
|
page.getByRole('button', { name: 'Start Sketch' })
|
|
|
|
).not.toBeDisabled()
|
2024-03-22 10:23:04 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
|
|
|
let previousCodeContent = await page.locator('.cm-content').innerText()
|
2024-03-22 10:23:04 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// click at 641, 135
|
|
|
|
await page.mouse.click(641, 135)
|
|
|
|
await expect(page.locator('.cm-content')).not.toHaveText(
|
|
|
|
previousCodeContent
|
|
|
|
)
|
|
|
|
previousCodeContent = await page.locator('.cm-content').innerText()
|
2024-03-22 10:23:04 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.waitForTimeout(300)
|
2024-03-22 10:23:04 +11:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test(
|
|
|
|
'Zoom to fit on load - solid 2d',
|
|
|
|
{ tag: '@snapshot' },
|
|
|
|
async ({ page, context }) => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
const u = await getUtils(page)
|
|
|
|
await context.addInitScript(async () => {
|
|
|
|
localStorage.setItem(
|
|
|
|
'persistCode',
|
2024-10-02 14:19:40 -05:00
|
|
|
`part001 = startSketchOn('XY')
|
2024-05-23 17:05:54 -07:00
|
|
|
|> startProfileAt([-10, -10], %)
|
|
|
|
|> line([20, 0], %)
|
|
|
|
|> line([0, 20], %)
|
|
|
|
|> line([-20, 0], %)
|
|
|
|
|> close(%)
|
|
|
|
`
|
2024-08-05 21:30:16 +10:00
|
|
|
)
|
|
|
|
}, KCL_DEFAULT_LENGTH)
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
2024-06-29 18:10:07 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.waitForAuthSkipAppStart()
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.openDebugPanel()
|
|
|
|
// wait for execution done
|
|
|
|
await expect(
|
|
|
|
page.locator('[data-message-type="execution-done"]')
|
|
|
|
).toHaveCount(1)
|
|
|
|
await u.closeDebugPanel()
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// Wait for the second extrusion to appear
|
|
|
|
// TODO: Find a way to truly know that the objects have finished
|
|
|
|
// rendering, because an execution-done message is not sufficient.
|
2024-10-18 04:31:00 -04:00
|
|
|
await page.waitForTimeout(2000)
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test(
|
|
|
|
'Zoom to fit on load - solid 3d',
|
|
|
|
{ tag: '@snapshot' },
|
|
|
|
async ({ page, context }) => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
const u = await getUtils(page)
|
|
|
|
await context.addInitScript(async () => {
|
|
|
|
localStorage.setItem(
|
|
|
|
'persistCode',
|
2024-10-02 14:19:40 -05:00
|
|
|
`part001 = startSketchOn('XY')
|
2024-05-23 17:05:54 -07:00
|
|
|
|> startProfileAt([-10, -10], %)
|
|
|
|
|> line([20, 0], %)
|
|
|
|
|> line([0, 20], %)
|
|
|
|
|> line([-20, 0], %)
|
|
|
|
|> close(%)
|
|
|
|
|> extrude(10, %)
|
|
|
|
`
|
2024-08-05 21:30:16 +10:00
|
|
|
)
|
|
|
|
}, KCL_DEFAULT_LENGTH)
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
2024-06-29 18:10:07 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.waitForAuthSkipAppStart()
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await u.openDebugPanel()
|
|
|
|
// wait for execution done
|
|
|
|
await expect(
|
|
|
|
page.locator('[data-message-type="execution-done"]')
|
|
|
|
).toHaveCount(1)
|
|
|
|
await u.closeDebugPanel()
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
// Wait for the second extrusion to appear
|
|
|
|
// TODO: Find a way to truly know that the objects have finished
|
|
|
|
// rendering, because an execution-done message is not sufficient.
|
2024-10-18 04:31:00 -04:00
|
|
|
await page.waitForTimeout(2000)
|
2024-05-23 17:05:54 -07:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
await expect(page).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
2024-07-01 15:31:42 -04:00
|
|
|
|
2024-08-05 21:30:16 +10:00
|
|
|
test.describe('Grid visibility', { tag: '@snapshot' }, () => {
|
2024-08-17 14:15:11 -07:00
|
|
|
// FIXME: Skip on macos its being weird.
|
|
|
|
test.skip(process.platform === 'darwin', 'Skip on macos')
|
|
|
|
|
2024-07-01 15:31:42 -04:00
|
|
|
test('Grid turned off', async ({ page }) => {
|
|
|
|
const u = await getUtils(page)
|
|
|
|
const stream = page.getByTestId('stream')
|
|
|
|
const mask = [
|
|
|
|
page.locator('#app-header'),
|
|
|
|
page.locator('#sidebar-top-ribbon'),
|
|
|
|
page.locator('#sidebar-bottom-ribbon'),
|
|
|
|
]
|
|
|
|
|
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
|
|
|
await page.goto('/')
|
|
|
|
await u.waitForAuthSkipAppStart()
|
|
|
|
|
|
|
|
await u.openDebugPanel()
|
|
|
|
// wait for execution done
|
|
|
|
await expect(
|
|
|
|
page.locator('[data-message-type="execution-done"]')
|
2024-08-04 08:29:28 +10:00
|
|
|
).toHaveCount(1)
|
2024-07-01 15:31:42 -04:00
|
|
|
await u.closeDebugPanel()
|
|
|
|
await u.closeKclCodePanel()
|
|
|
|
// TODO: Find a way to truly know that the objects have finished
|
|
|
|
// rendering, because an execution-done message is not sufficient.
|
|
|
|
await page.waitForTimeout(1000)
|
|
|
|
|
|
|
|
await expect(stream).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
mask,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
test('Grid turned on', async ({ page }) => {
|
|
|
|
await page.addInitScript(
|
|
|
|
async ({ settingsKey, settings }) => {
|
|
|
|
localStorage.setItem(settingsKey, settings)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
settingsKey: TEST_SETTINGS_KEY,
|
|
|
|
settings: TOML.stringify({
|
|
|
|
settings: {
|
|
|
|
...TEST_SETTINGS,
|
|
|
|
modeling: {
|
|
|
|
...TEST_SETTINGS.modeling,
|
|
|
|
showScaleGrid: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
const u = await getUtils(page)
|
|
|
|
const stream = page.getByTestId('stream')
|
|
|
|
const mask = [
|
|
|
|
page.locator('#app-header'),
|
|
|
|
page.locator('#sidebar-top-ribbon'),
|
|
|
|
page.locator('#sidebar-bottom-ribbon'),
|
|
|
|
]
|
|
|
|
|
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
|
|
|
await page.goto('/')
|
|
|
|
await u.waitForAuthSkipAppStart()
|
|
|
|
|
|
|
|
await u.openDebugPanel()
|
|
|
|
// wait for execution done
|
|
|
|
await expect(
|
|
|
|
page.locator('[data-message-type="execution-done"]')
|
2024-08-04 08:29:28 +10:00
|
|
|
).toHaveCount(1)
|
2024-07-01 15:31:42 -04:00
|
|
|
await u.closeDebugPanel()
|
|
|
|
await u.closeKclCodePanel()
|
|
|
|
// TODO: Find a way to truly know that the objects have finished
|
|
|
|
// rendering, because an execution-done message is not sufficient.
|
|
|
|
await page.waitForTimeout(1000)
|
|
|
|
|
|
|
|
await expect(stream).toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
mask,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2024-08-21 15:02:54 +10:00
|
|
|
|
2024-11-04 20:34:22 -06:00
|
|
|
test.fixme('theme persists', async ({ page, context }) => {
|
2024-08-21 15:02:54 +10:00
|
|
|
const u = await getUtils(page)
|
|
|
|
await context.addInitScript(async () => {
|
|
|
|
localStorage.setItem(
|
|
|
|
'persistCode',
|
2024-10-02 14:19:40 -05:00
|
|
|
`part001 = startSketchOn('XY')
|
2024-08-21 15:02:54 +10:00
|
|
|
|> startProfileAt([-10, -10], %)
|
|
|
|
|> line([20, 0], %)
|
|
|
|
|> line([0, 20], %)
|
|
|
|
|> line([-20, 0], %)
|
|
|
|
|> close(%)
|
|
|
|
|> extrude(10, %)
|
|
|
|
`
|
|
|
|
)
|
|
|
|
}, KCL_DEFAULT_LENGTH)
|
|
|
|
|
|
|
|
await page.setViewportSize({ width: 1200, height: 500 })
|
|
|
|
|
|
|
|
await u.waitForAuthSkipAppStart()
|
|
|
|
await page.waitForTimeout(500)
|
|
|
|
|
|
|
|
// await page.getByRole('link', { name: 'Settings Settings (tooltip)' }).click()
|
|
|
|
await expect(page.getByTestId('settings-link')).toBeVisible()
|
|
|
|
await page.getByTestId('settings-link').click()
|
|
|
|
|
|
|
|
// open user settingns
|
|
|
|
await page.getByRole('radio', { name: 'person User' }).click()
|
|
|
|
|
|
|
|
await page.getByTestId('app-theme').selectOption('light')
|
|
|
|
|
|
|
|
await page.getByTestId('settings-close-button').click()
|
|
|
|
|
|
|
|
const networkToggle = page.getByTestId('network-toggle')
|
|
|
|
|
|
|
|
// simulate network down
|
|
|
|
await u.emulateNetworkConditions({
|
|
|
|
offline: true,
|
|
|
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
|
|
|
latency: 0,
|
|
|
|
downloadThroughput: -1,
|
|
|
|
uploadThroughput: -1,
|
|
|
|
})
|
|
|
|
|
|
|
|
// Disconnect and reconnect to check the theme persists through a reload
|
|
|
|
|
|
|
|
// Expect the network to be down
|
|
|
|
await expect(networkToggle).toContainText('Offline')
|
|
|
|
|
|
|
|
// simulate network up
|
|
|
|
await u.emulateNetworkConditions({
|
|
|
|
offline: false,
|
|
|
|
// values of 0 remove any active throttling. crbug.com/456324#c9
|
|
|
|
latency: 0,
|
|
|
|
downloadThroughput: -1,
|
|
|
|
uploadThroughput: -1,
|
|
|
|
})
|
|
|
|
|
|
|
|
await expect(networkToggle).toContainText('Connected')
|
|
|
|
|
|
|
|
await expect(page.getByText('building scene')).not.toBeVisible()
|
|
|
|
|
|
|
|
await expect(page, 'expect screenshot to have light theme').toHaveScreenshot({
|
|
|
|
maxDiffPixels: 100,
|
|
|
|
})
|
|
|
|
})
|