Correct all tsc errors
This commit is contained in:
@ -4,7 +4,7 @@ test.describe('Electron app header tests', () => {
|
||||
test(
|
||||
'Open Command Palette button has correct shortcut',
|
||||
{ tag: '@electron' },
|
||||
async ({ page, browserName }, testInfo) => {
|
||||
async ({ page }, testInfo) => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
// No space before the shortcut since it checks textContent.
|
||||
@ -29,7 +29,7 @@ test.describe('Electron app header tests', () => {
|
||||
test(
|
||||
'User settings has correct shortcut',
|
||||
{ tag: '@electron' },
|
||||
async ({ page, browserName }, testInfo) => {
|
||||
async ({ page }, testInfo) => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
// Open the user sidebar menu.
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { test, expect, Page } from './zoo-test'
|
||||
import { HomePageFixture } from './fixtures/HomePageFixture'
|
||||
import { HomePageFixture } from './fixtures/homePageFixture'
|
||||
import { getUtils } from './test-utils'
|
||||
import { EngineCommand } from 'lang/std/artifactGraph'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
|
@ -125,8 +125,6 @@ test.describe('Code pane and errors', () => {
|
||||
homePage,
|
||||
context,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
// Load the app with the working starter code
|
||||
await context.addInitScript((code) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
@ -168,8 +166,6 @@ test.describe('Code pane and errors', () => {
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
// Load the app with the working starter code
|
||||
await context.addInitScript((code) => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
@ -236,9 +232,9 @@ test.describe('Code pane and errors', () => {
|
||||
test(
|
||||
'Opening multiple panes persists when switching projects',
|
||||
{ tag: '@electron' },
|
||||
async ({ context, browserName, page }, testInfo) => {
|
||||
async ({ context, page }, testInfo) => {
|
||||
// Setup multiple projects.
|
||||
context.folderSetupFn(async (dir) => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
const routerTemplateDir = join(dir, 'router-template-slate')
|
||||
const bracketDir = join(dir, 'bracket')
|
||||
await Promise.all([
|
||||
@ -307,7 +303,7 @@ test(
|
||||
test(
|
||||
'external change of file contents are reflected in editor',
|
||||
{ tag: '@electron' },
|
||||
async ({ context, browserName, page }, testInfo) => {
|
||||
async ({ context, page }, testInfo) => {
|
||||
const PROJECT_DIR_NAME = 'lee-was-here'
|
||||
const { dir: projectsDir } = await context.folderSetupFn(async (dir) => {
|
||||
const aProjectDir = join(dir, PROJECT_DIR_NAME)
|
||||
|
@ -2,7 +2,6 @@ import { test, expect } from './zoo-test'
|
||||
|
||||
import { getUtils } from './test-utils'
|
||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
||||
import { normalizeLineEndings } from 'lib/codeEditor'
|
||||
|
||||
test.describe('Command bar tests', () => {
|
||||
test('Extrude from command bar selects extrude line after', async ({
|
||||
@ -89,7 +88,6 @@ test.describe('Command bar tests', () => {
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
@ -171,7 +169,6 @@ test.describe('Command bar tests', () => {
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
@ -300,7 +297,6 @@ test.describe('Command bar tests', () => {
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
|
@ -45,6 +45,7 @@ test.describe('Copilot ghost text', () => {
|
||||
|
||||
test.skip('copilot disabled in sketch mode no select plane', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
// const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||
|
@ -2,7 +2,6 @@ import { test, expect } from './zoo-test'
|
||||
import path from 'path'
|
||||
import {
|
||||
getUtils,
|
||||
setupElectron,
|
||||
executorInputPath,
|
||||
getPlaywrightDownloadDir,
|
||||
} from './test-utils'
|
||||
@ -12,7 +11,7 @@ test(
|
||||
'export works on the first try',
|
||||
{ tag: '@electron' },
|
||||
async ({ page, context }, testInfo) => {
|
||||
context.folderSetupFn(async (dir) => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
const bracketDir = path.join(dir, 'bracket')
|
||||
await Promise.all([fsp.mkdir(bracketDir, { recursive: true })])
|
||||
await Promise.all([
|
||||
@ -25,7 +24,7 @@ test(
|
||||
path.join(bracketDir, 'main.kcl')
|
||||
),
|
||||
])
|
||||
}),
|
||||
})
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
page.on('console', console.log)
|
||||
|
@ -190,8 +190,6 @@ test.describe('Editor tests', () => {
|
||||
})
|
||||
|
||||
test('fold gutters work', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
const fullCode = `sketch001 = startSketchOn('XY')
|
||||
|> startProfileAt([-10, -10], %)
|
||||
|> line([20, 0], %)
|
||||
@ -642,8 +640,6 @@ test.describe('Editor tests', () => {
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
|
@ -56,11 +56,11 @@ export class EditorFixture {
|
||||
if (!shouldNormalise) {
|
||||
const expectStart = expect.poll(() => this.codeContent.textContent())
|
||||
if (not) {
|
||||
const result = await expectStart.not.toContain(code, { timeout })
|
||||
const result = await expectStart.not.toContain(code)
|
||||
await resetPane()
|
||||
return result
|
||||
}
|
||||
const result = await expectStart.toContain(code, { timeout })
|
||||
const result = await expectStart.toContain(code)
|
||||
await resetPane()
|
||||
return result
|
||||
}
|
||||
@ -150,9 +150,11 @@ export class EditorFixture {
|
||||
scrollToText(text: string) {
|
||||
return this.page.evaluate((scrollToText: string) => {
|
||||
// editorManager is available on the window object.
|
||||
// @ts-ignore
|
||||
let index = editorManager._editorView.docView.view.state.doc
|
||||
.toString()
|
||||
.indexOf(scrollToText)
|
||||
// @ts-ignore
|
||||
editorManager._editorView.dispatch({
|
||||
selection: {
|
||||
anchor: index,
|
||||
|
@ -1,11 +1,11 @@
|
||||
import type {
|
||||
BrowserContext,
|
||||
ElectronApplication,
|
||||
Page,
|
||||
TestInfo,
|
||||
Page,
|
||||
} from '@playwright/test'
|
||||
import { test as base } from '@playwright/test'
|
||||
import { getUtils, setup, setupElectron, tearDown } from '../test-utils'
|
||||
|
||||
import { getUtils, setup, setupElectron } from '../test-utils'
|
||||
import fsp from 'fs/promises'
|
||||
import { join } from 'path'
|
||||
import { CmdBarFixture } from './cmdBarFixture'
|
||||
@ -50,8 +50,6 @@ export class AuthenticatedApp {
|
||||
}
|
||||
|
||||
export interface Fixtures {
|
||||
app: AuthenticatedApp
|
||||
tronApp: AuthenticatedTronApp
|
||||
cmdBar: CmdBarFixture
|
||||
editor: EditorFixture
|
||||
toolbar: ToolbarFixture
|
||||
@ -122,19 +120,19 @@ export class AuthenticatedTronApp {
|
||||
}
|
||||
|
||||
export const fixtures = {
|
||||
cmdBar: async ({ page }, use) => {
|
||||
cmdBar: async ({ page }: { page: Page }, use: any) => {
|
||||
await use(new CmdBarFixture(page))
|
||||
},
|
||||
editor: async ({ page }, use) => {
|
||||
editor: async ({ page }: { page: Page }, use: any) => {
|
||||
await use(new EditorFixture(page))
|
||||
},
|
||||
toolbar: async ({ page }, use) => {
|
||||
toolbar: async ({ page }: { page: Page }, use: any) => {
|
||||
await use(new ToolbarFixture(page))
|
||||
},
|
||||
scene: async ({ page }, use) => {
|
||||
scene: async ({ page }: { page: Page }, use: any) => {
|
||||
await use(new SceneFixture(page))
|
||||
},
|
||||
homePage: async ({ page }, use, testInfo) => {
|
||||
homePage: async ({ page }: { page: Page }, use: any) => {
|
||||
await use(new HomePageFixture(page))
|
||||
},
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ export class HomePageFixture {
|
||||
await projectCard.click()
|
||||
}
|
||||
|
||||
goToModelingScene = async (name?: string = 'testDefault') => {
|
||||
goToModelingScene = async (name: string = 'testDefault') => {
|
||||
// On web this is a no-op. There is no project view.
|
||||
if (process.env.PLATFORM === 'web') return
|
||||
|
||||
|
@ -8,7 +8,6 @@ import {
|
||||
TEST_SETTINGS_KEY,
|
||||
TEST_SETTINGS_ONBOARDING_START,
|
||||
TEST_SETTINGS_ONBOARDING_EXPORT,
|
||||
TEST_SETTINGS_ONBOARDING_PARAMETRIC_MODELING,
|
||||
TEST_SETTINGS_ONBOARDING_USER_MENU,
|
||||
} from './storageStates'
|
||||
import * as TOML from '@iarna/toml'
|
||||
@ -29,8 +28,6 @@ test.describe('Onboarding tests', () => {
|
||||
cleanProjectDir: true,
|
||||
},
|
||||
async ({ context, page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
@ -117,7 +114,6 @@ test.describe('Onboarding tests', () => {
|
||||
localStorage.setItem('persistCode', code)
|
||||
}, initialCode)
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
@ -159,8 +155,6 @@ test.describe('Onboarding tests', () => {
|
||||
},
|
||||
},
|
||||
async ({ context, page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
// Override beforeEach test setup
|
||||
await context.addInitScript(
|
||||
async ({ settingsKey, settings }) => {
|
||||
@ -212,8 +206,6 @@ test.describe('Onboarding tests', () => {
|
||||
cleanProjectDir: true,
|
||||
},
|
||||
async ({ context, page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
const originalCode = 'sigmaAllow = 15000'
|
||||
|
||||
// Override beforeEach test setup
|
||||
@ -332,7 +324,6 @@ test.describe('Onboarding tests', () => {
|
||||
}
|
||||
)
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
@ -407,7 +398,6 @@ test.describe('Onboarding tests', () => {
|
||||
}
|
||||
)
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
|
@ -622,18 +622,12 @@ openSketch = startSketchOn('XY')
|
||||
localStorage.setItem('persistCode', code)
|
||||
}, initialCode)
|
||||
|
||||
|
||||
await homePage.goToModelingScene()
|
||||
await u.waitForPageLoad()
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
const pointOnSketchArea = {
|
||||
x: viewPortSize.width * 0.7,
|
||||
y: viewPortSize.height * 0.7,
|
||||
}
|
||||
|
||||
const pointInsideCircle = {
|
||||
x: viewPortSize.width * 0.55,
|
||||
x: viewPortSize.width * 0.58,
|
||||
y: viewPortSize.height * 0.5,
|
||||
}
|
||||
const pointOnPathAfterSketching = {
|
||||
@ -678,8 +672,14 @@ openSketch = startSketchOn('XY')
|
||||
|
||||
// Drag the sketch line out of the axis view which blocks the click
|
||||
await page.dragAndDrop('#stream', '#stream', {
|
||||
sourcePosition: { x: viewPortSize.width * 0.7, y: viewPortSize.height* 0.5 },
|
||||
targetPosition: { x: viewPortSize.width * 0.7, y: viewPortSize.height* 0.4 },
|
||||
sourcePosition: {
|
||||
x: viewPortSize.width * 0.7,
|
||||
y: viewPortSize.height * 0.5,
|
||||
},
|
||||
targetPosition: {
|
||||
x: viewPortSize.width * 0.7,
|
||||
y: viewPortSize.height * 0.4,
|
||||
},
|
||||
})
|
||||
|
||||
await page.waitForTimeout(500)
|
||||
@ -711,7 +711,6 @@ test(`Offset plane point-and-click`, async ({
|
||||
toolbar,
|
||||
cmdBar,
|
||||
}) => {
|
||||
|
||||
// One dumb hardcoded screen pixel value
|
||||
const testPoint = { x: 700, y: 150 }
|
||||
const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y)
|
||||
|
@ -1574,7 +1574,7 @@ test(
|
||||
.locator('section#projectDirectory input')
|
||||
.inputValue()
|
||||
|
||||
const handleFile = electronApp.evaluate(
|
||||
const handleFile = electronApp?.evaluate(
|
||||
async ({ dialog }, filePaths) => {
|
||||
dialog.showOpenDialog = () =>
|
||||
Promise.resolve({ canceled: false, filePaths })
|
||||
@ -1604,7 +1604,7 @@ test(
|
||||
|
||||
await page.getByTestId('project-directory-settings-link').click()
|
||||
|
||||
const handleFile = electronApp.evaluate(
|
||||
const handleFile = electronApp?.evaluate(
|
||||
async ({ dialog }, filePaths) => {
|
||||
dialog.showOpenDialog = () =>
|
||||
Promise.resolve({ canceled: false, filePaths })
|
||||
|
@ -101,7 +101,6 @@ test.describe('Sketch tests', () => {
|
||||
})
|
||||
test('Can delete most of a sketch and the line tool will still work', async ({
|
||||
page,
|
||||
center,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
@ -142,7 +141,7 @@ test.describe('Sketch tests', () => {
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await expect(async () => {
|
||||
await page.mouse.move(700, 200, { step: 25 })
|
||||
await page.mouse.move(700, 200, { steps: 25 })
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await expect
|
||||
@ -164,7 +163,6 @@ test.describe('Sketch tests', () => {
|
||||
localStorage.setItem('persistCode', ``)
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
await homePage.goToModelingScene()
|
||||
@ -428,8 +426,11 @@ test.describe('Sketch tests', () => {
|
||||
})
|
||||
|
||||
// expect the code to have changed
|
||||
await editor.expectEditor.toContain(`sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [7.26, -2.37], radius = 11.44 }, %)`, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(
|
||||
`sketch001 = startSketchOn('XZ')
|
||||
|> circle({ center = [7.26, -2.37], radius = 11.44 }, %)`,
|
||||
{ shouldNormalise: true }
|
||||
)
|
||||
})
|
||||
test('Can edit a sketch that has been extruded in the same pipe', async ({
|
||||
page,
|
||||
@ -1289,7 +1290,7 @@ test.describe(`Sketching with offset planes`, () => {
|
||||
)
|
||||
})
|
||||
|
||||
homePage.goToModelingScene()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
const [planeClick, planeHover] = scene.makeMouseHelpers(650, 200)
|
||||
|
||||
|
@ -80,7 +80,6 @@ test.describe('Test network and connection issues', () => {
|
||||
|
||||
test('Engine disconnect & reconnect in sketch mode', async ({
|
||||
page,
|
||||
browserName,
|
||||
homePage,
|
||||
}) => {
|
||||
// TODO: Don't skip Mac for these. After `window.tearDown` is working in Safari, these should work on webkit
|
||||
|
@ -1,13 +1,11 @@
|
||||
import {
|
||||
expect,
|
||||
Page,
|
||||
Download,
|
||||
BrowserContext,
|
||||
TestInfo,
|
||||
_electron as electron,
|
||||
Locator,
|
||||
test,
|
||||
} from '@playwright/test'
|
||||
import { test, Page } from './zoo-test'
|
||||
import { EngineCommand } from 'lang/std/artifactGraph'
|
||||
import fsp from 'fs/promises'
|
||||
import fsSync from 'fs'
|
||||
@ -16,7 +14,7 @@ import pixelMatch from 'pixelmatch'
|
||||
import { PNG } from 'pngjs'
|
||||
import { Protocol } from 'playwright-core/types/protocol'
|
||||
import type { Models } from '@kittycad/lib'
|
||||
import { APP_NAME, COOKIE_NAME } from 'lib/constants'
|
||||
import { COOKIE_NAME } from 'lib/constants'
|
||||
import { secrets } from './secrets'
|
||||
import {
|
||||
TEST_SETTINGS_KEY,
|
||||
@ -163,8 +161,10 @@ async function openKclCodePanel(page: Page) {
|
||||
// Code Mirror lazy loads text! Wowza! Let's force-load the text for tests.
|
||||
await page.evaluate(() => {
|
||||
// editorManager is available on the window object.
|
||||
//@ts-ignore this is in an entirely different context that tsc can't see.
|
||||
editorManager._editorView.dispatch({
|
||||
selection: {
|
||||
//@ts-ignore this is in an entirely different context that tsc can't see.
|
||||
anchor: editorManager._editorView.docView.length,
|
||||
},
|
||||
scrollIntoView: true,
|
||||
@ -515,10 +515,12 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
||||
|
||||
async editorTextMatches(code: string) {
|
||||
const editor = page.locator(editorSelector)
|
||||
return expect.poll(async () => {
|
||||
return expect
|
||||
.poll(async () => {
|
||||
const text = await editor.textContent()
|
||||
return toNormalizedCode(text)
|
||||
}).toContain(toNormalizedCode(code))
|
||||
return toNormalizedCode(text ?? '')
|
||||
})
|
||||
.toContain(toNormalizedCode(code))
|
||||
},
|
||||
|
||||
pasteCodeInEditor: async (code: string) => {
|
||||
@ -716,7 +718,7 @@ const moveDownloadedFileTo = async (page: Page, toLocation: string) => {
|
||||
const downloadDir = getPlaywrightDownloadDir(page)
|
||||
|
||||
// Expect there to be at least one file
|
||||
expect
|
||||
await expect
|
||||
.poll(async () => {
|
||||
const files = await fsp.readdir(downloadDir)
|
||||
return files.length
|
||||
@ -848,7 +850,7 @@ export async function tearDown(page: Page, testInfo: TestInfo) {
|
||||
// It's not super reliable but we have no real other choice for now
|
||||
await page.waitForTimeout(3000)
|
||||
|
||||
await testInfo.tronApp.close()
|
||||
await testInfo.tronApp?.close()
|
||||
}
|
||||
|
||||
// settingsOverrides may need to be augmented to take more generic items,
|
||||
|
@ -1069,10 +1069,10 @@ part002 = startSketchOn('XZ')
|
||||
)
|
||||
|
||||
const linebb = await u.getBoundingBox('[data-overlay-index="1"]')
|
||||
await page.mouse.move(linebb.x, linebb.y, { step: 25 })
|
||||
await page.mouse.move(linebb.x, linebb.y, { steps: 25 })
|
||||
await page.mouse.click(linebb.x, linebb.y)
|
||||
|
||||
expect
|
||||
await expect
|
||||
.poll(async () => await u.getGreatestPixDiff(lineAfter, TEST_COLORS.BLUE))
|
||||
.toBeLessThan(3)
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { test, expect } from './zoo-test'
|
||||
import { getUtils, executorInputPath } from './test-utils'
|
||||
import { getUtils } from './test-utils'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { TEST_CODE_GIZMO } from './storageStates'
|
||||
import path from 'node:path'
|
||||
import fsp from 'fs/promises'
|
||||
|
||||
test.describe('Testing Gizmo', () => {
|
||||
const cases = [
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { test, expect } from './zoo-test'
|
||||
import { getUtils } from './test-utils'
|
||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from './storageStates'
|
||||
import * as TOML from '@iarna/toml'
|
||||
|
||||
test.describe('Test toggling perspective', () => {
|
||||
test('via command palette and toggle', async ({ page, homePage }) => {
|
||||
|
@ -11,7 +11,12 @@ test.describe('Testing in-app sample loading', () => {
|
||||
* Note this test implicitly depends on the KCL sample "car-wheel.kcl",
|
||||
* its title, and its units settings. https://github.com/KittyCAD/kcl-samples/blob/main/car-wheel/car-wheel.kcl
|
||||
*/
|
||||
test('Web: should overwrite current code, cannot create new file', async ({ editor, context, page, homePage }) => {
|
||||
test('Web: should overwrite current code, cannot create new file', async ({
|
||||
editor,
|
||||
context,
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await test.step(`Test setup`, async () => {
|
||||
@ -65,7 +70,8 @@ test.describe('Testing in-app sample loading', () => {
|
||||
|
||||
await editor.expectEditor.toContain('// ' + newSample.title)
|
||||
await expect(unitsToast('in')).toBeVisible()
|
||||
}) })
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Note this test implicitly depends on the KCL samples:
|
||||
@ -75,7 +81,7 @@ test.describe('Testing in-app sample loading', () => {
|
||||
test(
|
||||
'Desktop: should create new file by default, optionally overwrite',
|
||||
{ tag: '@electron' },
|
||||
async ({ editor, context, page, browserName: _ }, testInfo) => {
|
||||
async ({ editor, context, page }, testInfo) => {
|
||||
const { dir } = await context.folderSetupFn(async (dir) => {
|
||||
const bracketDir = join(dir, 'bracket')
|
||||
await fsp.mkdir(bracketDir, { recursive: true })
|
||||
|
@ -3,6 +3,7 @@ import { test, expect, Page } from './zoo-test'
|
||||
import { deg, getUtils, wiggleMove } from './test-utils'
|
||||
import { LineInputsType } from 'lang/std/sketchcombos'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { EditorFixture } from './fixtures/editorFixture'
|
||||
|
||||
test.describe('Testing segment overlays', () => {
|
||||
test.describe('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', () => {
|
||||
@ -52,7 +53,9 @@ test.describe('Testing segment overlays', () => {
|
||||
await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator)
|
||||
await page.mouse.move(x, y)
|
||||
|
||||
await editor.expectEditor.toContain(expectBeforeUnconstrained, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(expectBeforeUnconstrained, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
const constrainedLocator = page.locator(
|
||||
`[data-constraint-type="${constraintType}"][data-is-constrained="true"]`
|
||||
)
|
||||
@ -62,7 +65,9 @@ test.describe('Testing segment overlays', () => {
|
||||
await page.getByTestId('constraint-symbol-popover').count()
|
||||
).toBeGreaterThan(0)
|
||||
await constrainedLocator.click()
|
||||
await editor.expectEditor.toContain(expectAfterUnconstrained, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(expectAfterUnconstrained, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
|
||||
await page.mouse.move(0, 0)
|
||||
await page.waitForTimeout(1000)
|
||||
@ -91,6 +96,9 @@ test.describe('Testing segment overlays', () => {
|
||||
.click()
|
||||
await expect(page.locator('.cm-content')).toContainText(expectFinal)
|
||||
await editor.expectEditor.toContain(expectFinal, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(expectFinal, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,7 +146,9 @@ test.describe('Testing segment overlays', () => {
|
||||
await page.mouse.move(x, y)
|
||||
|
||||
await expect(page.getByText('Added variable')).not.toBeVisible()
|
||||
await editor.expectEditor.toContain(expectBeforeUnconstrained, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(expectBeforeUnconstrained, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
const unconstrainedLocator = page.locator(
|
||||
`[data-constraint-type="${constraintType}"][data-is-constrained="false"]`
|
||||
)
|
||||
@ -156,7 +166,9 @@ test.describe('Testing segment overlays', () => {
|
||||
name: 'arrow right Continue',
|
||||
})
|
||||
.click()
|
||||
await editor.expectEditor.toContain(expectAfterUnconstrained, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(expectAfterUnconstrained, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
await expect(page.getByText('Added variable')).not.toBeVisible()
|
||||
|
||||
await page.mouse.move(0, 0)
|
||||
@ -176,7 +188,9 @@ test.describe('Testing segment overlays', () => {
|
||||
await page.getByTestId('constraint-symbol-popover').count()
|
||||
).toBeGreaterThan(0)
|
||||
await constrainedLocator.click()
|
||||
await editor.expectEditor.toContain(expectFinal, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(expectFinal, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
}
|
||||
test.setTimeout(120000)
|
||||
test('for segments [line, angledLine, lineTo, xLineTo]', async ({
|
||||
@ -344,7 +358,11 @@ test.describe('Testing segment overlays', () => {
|
||||
locator: '[data-overlay-toolbar-index="3"]',
|
||||
})
|
||||
})
|
||||
test('for segments [yLineTo, xLine]', async ({ page, editor, homePage }) => {
|
||||
test('for segments [yLineTo, xLine]', async ({
|
||||
page,
|
||||
editor,
|
||||
homePage,
|
||||
}) => {
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
@ -709,7 +727,11 @@ test.describe('Testing segment overlays', () => {
|
||||
locator: '[data-overlay-toolbar-index="11"]',
|
||||
})
|
||||
})
|
||||
test('for segment [tangentialArcTo]', async ({ page, editor, homePage }) => {
|
||||
test('for segment [tangentialArcTo]', async ({
|
||||
page,
|
||||
editor,
|
||||
homePage,
|
||||
}) => {
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
@ -888,12 +910,16 @@ test.describe('Testing segment overlays', () => {
|
||||
await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator)
|
||||
await page.mouse.move(x, y)
|
||||
|
||||
await editor.expectEditor.toContain(codeToBeDeleted, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(codeToBeDeleted, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
|
||||
await page.locator(`[data-stdlib-fn-name="${stdLibFnName}"]`).click()
|
||||
await page.getByText('Delete Segment').click()
|
||||
|
||||
await editor.expectEditor.not.toContain(codeToBeDeleted, { shouldNormalise: true })
|
||||
await editor.expectEditor.not.toContain(codeToBeDeleted, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
}
|
||||
test('all segment types', async ({ page, editor, homePage }) => {
|
||||
await page.addInitScript(async () => {
|
||||
@ -1075,12 +1101,16 @@ test.describe('Testing segment overlays', () => {
|
||||
await page.mouse.move(hoverPos.x, hoverPos.y)
|
||||
|
||||
const codeToBeDeleted = 'lineTo([33, 11.5 + 0], %)'
|
||||
await editor.expectEditor.toContain(codeToBeDeleted, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(codeToBeDeleted, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
|
||||
await page.getByTestId('overlay-menu').click()
|
||||
await page.getByText('Delete Segment').click()
|
||||
|
||||
await editor.expectEditor.not.toContain(codeToBeDeleted, { shouldNormalise: true })
|
||||
await editor.expectEditor.not.toContain(codeToBeDeleted, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
|
||||
segmentToDelete = await getOverlayByIndex(1)
|
||||
ang = await u.getAngle(`[data-overlay-index="${1}"]`)
|
||||
@ -1175,7 +1205,9 @@ test.describe('Testing segment overlays', () => {
|
||||
await page.mouse.move(hoverPos.x + x, hoverPos.y + y)
|
||||
await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 })
|
||||
|
||||
await editor.expectEditor.toContain(lineOfInterest, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(lineOfInterest, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
|
||||
await page.getByTestId('overlay-menu').click()
|
||||
await page.waitForTimeout(100)
|
||||
@ -1186,7 +1218,9 @@ test.describe('Testing segment overlays', () => {
|
||||
await page.mouse.move(hoverPos.x + x, hoverPos.y + y)
|
||||
await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 })
|
||||
|
||||
await editor.expectEditor.toContain(lineOfInterest, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(lineOfInterest, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
|
||||
await page.getByTestId('overlay-menu').click()
|
||||
await page.waitForTimeout(100)
|
||||
@ -1202,12 +1236,18 @@ test.describe('Testing segment overlays', () => {
|
||||
)
|
||||
).toBeTruthy()
|
||||
// eslint-disable-next-line jest/no-conditional-expect
|
||||
await editor.expectEditor.toContain(lineOfInterest, { shouldNormalise: true })
|
||||
await editor.expectEditor.toContain(lineOfInterest, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
} else {
|
||||
// eslint-disable-next-line jest/no-conditional-expect
|
||||
await editor.expectEditor.not.toContain(lineOfInterest, { shouldNormalise: true })
|
||||
await editor.expectEditor.not.toContain(lineOfInterest, {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
// eslint-disable-next-line jest/no-conditional-expect
|
||||
await editor.expectEditor.not.toContain('seg01', { shouldNormalise: true })
|
||||
await editor.expectEditor.not.toContain('seg01', {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { test, expect } from './zoo-test'
|
||||
import * as fsp from 'fs/promises'
|
||||
import { join } from 'path'
|
||||
import {
|
||||
getUtils,
|
||||
executorInputPath,
|
||||
createProject,
|
||||
} from './test-utils'
|
||||
import { getUtils, executorInputPath, createProject } from './test-utils'
|
||||
import { SaveSettingsPayload, SettingsLevel } from 'lib/settings/settingsTypes'
|
||||
import { SETTINGS_FILE_NAME, PROJECT_SETTINGS_FILE_NAME } from 'lib/constants'
|
||||
import {
|
||||
@ -17,14 +13,14 @@ import {
|
||||
import * as TOML from '@iarna/toml'
|
||||
|
||||
test.describe('Testing settings', () => {
|
||||
test('Stored settings are validated and fall back to defaults',
|
||||
test(
|
||||
'Stored settings are validated and fall back to defaults',
|
||||
// Override beforeEach test setup
|
||||
// with corrupted settings
|
||||
{
|
||||
appSettings: TEST_SETTINGS_CORRUPTED
|
||||
appSettings: TEST_SETTINGS_CORRUPTED,
|
||||
},
|
||||
async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
|
||||
async ({ page, homePage }) => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
// Check the settings were reset
|
||||
@ -38,15 +34,20 @@ test.describe('Testing settings', () => {
|
||||
expect(storedSettings.settings?.app?.theme).toBe('dark')
|
||||
|
||||
// Check that the invalid settings were changed to good defaults
|
||||
expect(storedSettings.settings?.modeling?.defaultUnit).toBe("in")
|
||||
expect(storedSettings.settings?.modeling?.mouseControls).toBe("KittyCAD")
|
||||
expect(storedSettings.settings?.app?.projectDirectory).toBe("")
|
||||
expect(storedSettings.settings?.modeling?.defaultUnit).toBe('in')
|
||||
expect(storedSettings.settings?.modeling?.mouseControls).toBe('KittyCAD')
|
||||
expect(storedSettings.settings?.app?.projectDirectory).toBe('')
|
||||
expect(storedSettings.settings?.projects?.defaultProjectName).toBe(
|
||||
"project-$nnn"
|
||||
) })
|
||||
'project-$nnn'
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
// The behavior is actually broken. Parent always takes precedence
|
||||
test.fixme('Project settings can be set and override user settings', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test.fixme(
|
||||
'Project settings can be set and override user settings',
|
||||
async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
await test.step(`Setup`, async () => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
@ -70,11 +71,14 @@ test.describe('Testing settings', () => {
|
||||
/** Test to close https://github.com/KittyCAD/modeling-app/issues/2713 */
|
||||
await test.step(`Confirm that this dialog has a solid background`, async () => {
|
||||
await expect
|
||||
.poll(() => u.getGreatestPixDiff({ x: 600, y: 250 }, [28, 28, 28]), {
|
||||
.poll(
|
||||
() => u.getGreatestPixDiff({ x: 600, y: 250 }, [28, 28, 28]),
|
||||
{
|
||||
timeout: 1000,
|
||||
message:
|
||||
'Checking for solid background, should not see default plane colors',
|
||||
})
|
||||
}
|
||||
)
|
||||
.toBeLessThan(15)
|
||||
})
|
||||
|
||||
@ -107,7 +111,9 @@ test.describe('Testing settings', () => {
|
||||
|
||||
// Roll back to default of "off"
|
||||
await await page
|
||||
.getByText('show debug panelRoll back show debug panelRoll back to match')
|
||||
.getByText(
|
||||
'show debug panelRoll back show debug panelRoll back to match'
|
||||
)
|
||||
.hover()
|
||||
await page
|
||||
.getByRole('button', {
|
||||
@ -120,9 +126,14 @@ test.describe('Testing settings', () => {
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(
|
||||
page.locator('input[name="modeling-showDebugPanel"]')
|
||||
).not.toBeChecked() })
|
||||
).not.toBeChecked()
|
||||
}
|
||||
)
|
||||
|
||||
test('Keybindings display the correct hotkey for Command Palette', async ({ page, homePage }) => {
|
||||
test('Keybindings display the correct hotkey for Command Palette', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
@ -148,9 +159,11 @@ test.describe('Testing settings', () => {
|
||||
// The hotkey is in a kbd element next to the heading.
|
||||
const hotkey = commandPaletteHeading.locator('+ div kbd')
|
||||
const text = process.platform === 'darwin' ? 'Command+K' : 'Control+K'
|
||||
await expect(hotkey).toHaveText(text) })
|
||||
await expect(hotkey).toHaveText(text)
|
||||
})
|
||||
|
||||
test('Project and user settings can be reset', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('Project and user settings can be reset', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
await test.step(`Setup`, async () => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
@ -232,27 +245,28 @@ test.describe('Testing settings', () => {
|
||||
await projectSettingsTab.click()
|
||||
await expect(themeColorSetting).toHaveValue(settingValues.project)
|
||||
})
|
||||
}) })
|
||||
})
|
||||
})
|
||||
|
||||
test.fixme(
|
||||
`Project settings override user settings on desktop`,
|
||||
{ tag: ['@electron', '@skipWin'] },
|
||||
async ({ context, page, browser: _ }, testInfo) => {
|
||||
async ({ context, page }, testInfo) => {
|
||||
test.skip(
|
||||
process.platform === 'win32',
|
||||
'TODO: remove this skip https://github.com/KittyCAD/modeling-app/issues/3557'
|
||||
)
|
||||
const projectName = 'bracket'
|
||||
const {
|
||||
dir: projectDirName,
|
||||
} = await context.folderSetupFn(async (dir) => {
|
||||
const { dir: projectDirName } = await context.folderSetupFn(
|
||||
async (dir) => {
|
||||
const bracketDir = join(dir, projectName)
|
||||
await fsp.mkdir(bracketDir, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
|
||||
join(bracketDir, 'main.kcl')
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
@ -324,7 +338,6 @@ test.describe('Testing settings', () => {
|
||||
await logoLink.click()
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', userThemeColor)
|
||||
})
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
@ -335,7 +348,7 @@ test.describe('Testing settings', () => {
|
||||
// This is what makes no settings file get created
|
||||
cleanProjectDir: false,
|
||||
},
|
||||
async ({ page, browser: _ }, testInfo) => {
|
||||
async ({ page }, testInfo) => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
// Selectors and constants
|
||||
@ -347,7 +360,6 @@ test.describe('Testing settings', () => {
|
||||
// If the app loads without exploding we're in the clear
|
||||
await expect(errorHeading).not.toBeVisible()
|
||||
await expect(projectDirLink).toBeVisible()
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
@ -361,7 +373,7 @@ test.describe('Testing settings', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
async ({ context, page, browser: _ }, testInfo) => {
|
||||
async ({ context, page }, testInfo) => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
// Selectors and constants
|
||||
@ -387,10 +399,12 @@ test.describe('Testing settings', () => {
|
||||
// default to 264.5
|
||||
themeColor: '0',
|
||||
},
|
||||
}
|
||||
},
|
||||
async ({ context, page, browserName }, testInfo) => {
|
||||
const { dir: projectDirName } = await context.folderSetupFn(async () => {})
|
||||
},
|
||||
async ({ context, page }, testInfo) => {
|
||||
const { dir: projectDirName } = await context.folderSetupFn(
|
||||
async () => {}
|
||||
)
|
||||
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
@ -432,8 +446,10 @@ test.describe('Testing settings', () => {
|
||||
test(
|
||||
'project settings reload on external change',
|
||||
{ tag: '@electron' },
|
||||
async ({ context, page, browserName: _ }, testInfo) => {
|
||||
const { dir: projectDirName } = await context.folderSetupFn(async () => {})
|
||||
async ({ context, page }, testInfo) => {
|
||||
const { dir: projectDirName } = await context.folderSetupFn(
|
||||
async () => {}
|
||||
)
|
||||
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
|
||||
@ -466,14 +482,13 @@ test.describe('Testing settings', () => {
|
||||
await changeColorFs('99')
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '99')
|
||||
})
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
`Closing settings modal should go back to the original file being viewed`,
|
||||
{ tag: '@electron' },
|
||||
async ({ context, page, browser: _ }, testInfo) => {
|
||||
async ({ context, page }, testInfo) => {
|
||||
await context.folderSetupFn(async (dir) => {
|
||||
const bracketDir = join(dir, 'project-000')
|
||||
await fsp.mkdir(bracketDir, { recursive: true })
|
||||
@ -534,13 +549,11 @@ test.describe('Testing settings', () => {
|
||||
}
|
||||
)
|
||||
|
||||
test('Changing modeling default unit', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('Changing modeling default unit', async ({ page, homePage }) => {
|
||||
await test.step(`Test setup`, async () => {
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
const toastMessage = page.getByText(
|
||||
`Successfully created "testDefault"`
|
||||
)
|
||||
const toastMessage = page.getByText(`Successfully created "testDefault"`)
|
||||
await expect(toastMessage).not.toBeVisible()
|
||||
await page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
@ -680,9 +693,11 @@ test.describe('Testing settings', () => {
|
||||
await changeUnitOfMeasureInGizmo('mm', 'Millimeters')
|
||||
await changeUnitOfMeasureInGizmo('cm', 'Centimeters')
|
||||
await changeUnitOfMeasureInGizmo('m', 'Meters')
|
||||
}) })
|
||||
})
|
||||
})
|
||||
|
||||
test('Changing theme in sketch mode', async ({ context, page, homePage }) => { const u = await getUtils(page)
|
||||
test('Changing theme in sketch mode', async ({ context, page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
await context.addInitScript(() => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
@ -746,13 +761,16 @@ test.describe('Testing settings', () => {
|
||||
u.getGreatestPixDiff(sketchOriginLocation, lightThemeSegmentColor)
|
||||
)
|
||||
.toBeLessThan(15)
|
||||
}) })
|
||||
})
|
||||
})
|
||||
|
||||
test(`Changing system theme preferences (via media query) should update UI and stream`, {
|
||||
test(
|
||||
`Changing system theme preferences (via media query) should update UI and stream`,
|
||||
{
|
||||
// Override the settings so that the theme is set to `system`
|
||||
appSettings: TEST_SETTINGS_DEFAULT_THEME,
|
||||
}, async ({ page, homePage }) => {
|
||||
|
||||
},
|
||||
async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
// Selectors and constants
|
||||
@ -791,28 +809,30 @@ test.describe('Testing settings', () => {
|
||||
await expect
|
||||
.poll(() => streamBackgroundPixelIsColor(darkBackgroundColor))
|
||||
.toBeLessThan(15)
|
||||
}) })
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
test(`Turning off "Show debug panel" with debug panel open leaves no phantom panel`, {
|
||||
test(
|
||||
`Turning off "Show debug panel" with debug panel open leaves no phantom panel`,
|
||||
{
|
||||
// Override beforeEach test setup
|
||||
// with debug panel open
|
||||
// but "show debug panel" set to false
|
||||
appSettings: {
|
||||
...TEST_SETTINGS,
|
||||
modeling: { ...TEST_SETTINGS.modeling, showDebugPanel: false },
|
||||
}
|
||||
}, async ({ context, page, homePage }) => {
|
||||
|
||||
},
|
||||
},
|
||||
async ({ context, page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await context.addInitScript(
|
||||
async ({ }) => {
|
||||
await context.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistModelingContext',
|
||||
'{"openPanes":["debug"]}'
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
@ -862,5 +882,7 @@ test.describe('Testing settings', () => {
|
||||
await setShowDebugPanelTo('Off')
|
||||
await expect(debugPaneButton).not.toBeVisible()
|
||||
await expect(resizeHandle).not.toBeVisible()
|
||||
}) })
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { test, expect, Page } from './zoo-test'
|
||||
import { getUtils, createProject, } from './test-utils'
|
||||
import { getUtils, createProject } from './test-utils'
|
||||
import { join } from 'path'
|
||||
import fs from 'fs'
|
||||
|
||||
test.describe('Text-to-CAD tests', () => {
|
||||
test('basic lego happy case', async ({ page, homePage }) => {
|
||||
|
||||
const u = await getUtils(page)
|
||||
|
||||
await test.step('Set up', async () => {
|
||||
@ -31,7 +30,6 @@ test.describe('Text-to-CAD tests', () => {
|
||||
const successToastMessage = page.getByText(`Text-to-CAD successful`)
|
||||
await expect(successToastMessage).toBeVisible({ timeout: 15000 })
|
||||
|
||||
|
||||
// Hit accept.
|
||||
const copyToClipboardButton = page.getByRole('button', {
|
||||
name: 'Accept',
|
||||
@ -51,10 +49,13 @@ test.describe('Text-to-CAD tests', () => {
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.closeDebugPanel()
|
||||
|
||||
})
|
||||
|
||||
test('success model, then ignore success toast, user can create new prompt from command bar', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('success model, then ignore success toast, user can create new prompt from command bar', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
@ -91,9 +92,14 @@ test.describe('Text-to-CAD tests', () => {
|
||||
timeout: 15000,
|
||||
})
|
||||
await expect(page.getByText('a 2x4 lego')).toBeVisible()
|
||||
await expect(page.getByText('a 2x6 lego')).toBeVisible() })
|
||||
await expect(page.getByText('a 2x6 lego')).toBeVisible()
|
||||
})
|
||||
|
||||
test('you can reject text-to-cad output and it does nothing', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('you can reject text-to-cad output and it does nothing', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
@ -127,9 +133,14 @@ test.describe('Text-to-CAD tests', () => {
|
||||
await expect(successToastMessage).not.toBeVisible()
|
||||
|
||||
// Expect no code.
|
||||
await expect(page.locator('.cm-content')).toContainText(``) })
|
||||
await expect(page.locator('.cm-content')).toContainText(``)
|
||||
})
|
||||
|
||||
test('sending a bad prompt fails, can dismiss', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('sending a bad prompt fails, can dismiss', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
@ -190,9 +201,14 @@ test.describe('Text-to-CAD tests', () => {
|
||||
await dismissButton.click()
|
||||
|
||||
// The toast should disappear.
|
||||
await expect(failureToastMessage).not.toBeVisible() })
|
||||
await expect(failureToastMessage).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('sending a bad prompt fails, can start over from toast', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('sending a bad prompt fails, can start over from toast', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
@ -275,9 +291,14 @@ test.describe('Text-to-CAD tests', () => {
|
||||
|
||||
await expect(generatingToastMessage).toBeVisible({ timeout: 10000 })
|
||||
|
||||
await expect(successToastMessage).toBeVisible({ timeout: 15000 }) })
|
||||
await expect(successToastMessage).toBeVisible({ timeout: 15000 })
|
||||
})
|
||||
|
||||
test('sending a bad prompt fails, can ignore toast, can start over from command bar', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('sending a bad prompt fails, can ignore toast, can start over from command bar', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
@ -346,9 +367,14 @@ test.describe('Text-to-CAD tests', () => {
|
||||
|
||||
// old failure toast should stick around.
|
||||
await expect(failureToastMessage).toBeVisible()
|
||||
await expect(page.getByText(`Text-to-CAD failed`)).toBeVisible() })
|
||||
await expect(page.getByText(`Text-to-CAD failed`)).toBeVisible()
|
||||
})
|
||||
|
||||
test('ensure you can shift+enter in the prompt box', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('ensure you can shift+enter in the prompt box', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
@ -400,9 +426,14 @@ test.describe('Text-to-CAD tests', () => {
|
||||
const successToastMessage = page.getByText(`Text-to-CAD successful`)
|
||||
await expect(successToastMessage).toBeVisible({ timeout: 15000 })
|
||||
|
||||
await expect(page.getByText(promptWithNewline)).toBeVisible() })
|
||||
await expect(page.getByText(promptWithNewline)).toBeVisible()
|
||||
})
|
||||
|
||||
test('can do many at once and get many prompts back, and interact with many', { tag: ['@skipWin'] }, async ({ page, homePage }) => { // Let this test run longer since we've seen it timeout.
|
||||
test(
|
||||
'can do many at once and get many prompts back, and interact with many',
|
||||
{ tag: ['@skipWin'] },
|
||||
async ({ page, homePage }) => {
|
||||
// Let this test run longer since we've seen it timeout.
|
||||
test.setTimeout(180_000)
|
||||
// skip on windows
|
||||
test.skip(
|
||||
@ -479,10 +510,14 @@ test.describe('Text-to-CAD tests', () => {
|
||||
|
||||
// Expect the code to be pasted.
|
||||
await expect(page.locator('.cm-content')).toContainText(`2x4`)
|
||||
}
|
||||
)
|
||||
|
||||
})
|
||||
|
||||
test('can do many at once with errors, clicking dismiss error does not dismiss all', async ({ page, homePage }) => { const u = await getUtils(page)
|
||||
test('can do many at once with errors, clicking dismiss error does not dismiss all', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
await page.setBodyDimensions({ width: 1000, height: 500 })
|
||||
|
||||
|
@ -3,7 +3,6 @@ import { test, expect } from './zoo-test'
|
||||
import { doExport, getUtils, makeTemplate } from './test-utils'
|
||||
|
||||
test.fixme('Units menu', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
@ -102,15 +101,8 @@ part001 = startSketchOn('-XZ')
|
||||
|
||||
test('Paste should not work unless an input is focused', async ({
|
||||
page,
|
||||
browserName,
|
||||
homePage,
|
||||
}) => {
|
||||
// To run this test locally, uncomment Firefox in playwright.config.ts
|
||||
test.skip(
|
||||
browserName !== 'firefox',
|
||||
"This bug is really Firefox-only, which we don't run in CI."
|
||||
)
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
await page
|
||||
@ -154,7 +146,6 @@ test('Keyboard shortcuts can be viewed through the help menu', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
@ -248,7 +239,7 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
|
||||
|
||||
test.fixme(
|
||||
'Basic default modeling and sketch hotkeys work',
|
||||
async ({ page }) => {
|
||||
async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
// This test can run long if it takes a little too long to load
|
||||
|
@ -1,11 +1,52 @@
|
||||
import { test as playwrightTestFn } from '@playwright/test'
|
||||
import {
|
||||
test as playwrightTestFn,
|
||||
TestInfo as TestInfoPlaywright,
|
||||
BrowserContext as BrowserContextPlaywright,
|
||||
Page as PagePlaywright,
|
||||
TestDetails as TestDetailsPlaywright,
|
||||
PlaywrightTestArgs,
|
||||
PlaywrightTestOptions,
|
||||
PlaywrightWorkerArgs,
|
||||
PlaywrightWorkerOptions,
|
||||
ElectronApplication,
|
||||
} from '@playwright/test'
|
||||
|
||||
import {
|
||||
fixtures,
|
||||
Fixtures,
|
||||
AuthenticatedTronApp,
|
||||
AuthenticatedApp,
|
||||
} from './fixtures/fixtureSetup'
|
||||
export { expect, Page, BrowserContext, TestInfo } from '@playwright/test'
|
||||
|
||||
import { SaveSettingsPayload } from 'lib/settings/settingsTypes'
|
||||
export { expect } from '@playwright/test'
|
||||
|
||||
declare module '@playwright/test' {
|
||||
interface TestInfo {
|
||||
tronApp?: AuthenticatedTronApp
|
||||
}
|
||||
interface BrowserContext {
|
||||
folderSetupFn: (
|
||||
cb: (dir: string) => Promise<void>
|
||||
) => Promise<{ dir: string }>
|
||||
}
|
||||
interface Page {
|
||||
dir: string
|
||||
TEST_SETTINGS_FILE_KEY?: string
|
||||
setBodyDimensions: (dims: {
|
||||
width: number
|
||||
height: number
|
||||
}) => Promise<void>
|
||||
}
|
||||
}
|
||||
|
||||
export type TestInfo = TestInfoPlaywright
|
||||
export type BrowserContext = BrowserContextPlaywright
|
||||
export type Page = PagePlaywright
|
||||
export type TestDetails = TestDetailsPlaywright & {
|
||||
cleanProjectDir?: boolean
|
||||
appSettings?: Partial<SaveSettingsPayload>
|
||||
}
|
||||
|
||||
// Our custom decorated Zoo test object. Makes it easier to add fixtures, and
|
||||
// switch between web and electron if needed.
|
||||
@ -14,7 +55,29 @@ const pwTestFnWithFixtures = playwrightTestFn.extend<Fixtures>(fixtures)
|
||||
// In JavaScript you cannot replace a function's body only (despite functions
|
||||
// are themselves objects, which you'd expect a body property or something...)
|
||||
// So we must redefine the function and then re-attach properties.
|
||||
export function test(desc, objOrFn, fnMaybe) {
|
||||
type PWFunction = (
|
||||
args: PlaywrightTestArgs &
|
||||
Fixtures &
|
||||
PlaywrightWorkerArgs &
|
||||
PlaywrightTestOptions &
|
||||
PlaywrightWorkerOptions & {
|
||||
electronApp?: ElectronApplication
|
||||
},
|
||||
testInfo: TestInfo
|
||||
) => void | Promise<void>
|
||||
|
||||
// The below error is due to the extreme type spaghetti going on. playwright/
|
||||
// types/test.d.ts does not export 2 functions (below is one of them) but tsc
|
||||
// is trying to use a interface name it can't see.
|
||||
// e2e/playwright/zoo-test.ts:64:14 - error TS4023: Exported variable 'test' has
|
||||
// or is using name 'TestFunction' from external module
|
||||
// "/home/lee/Code/Zoo/modeling-app/dirty2/node_modules/playwright/types/test"
|
||||
// but cannot be named.
|
||||
export const test = (
|
||||
desc: string,
|
||||
objOrFn: PWFunction | TestDetails,
|
||||
fnMaybe?: PWFunction
|
||||
) => {
|
||||
const hasTestConf = typeof objOrFn === 'object'
|
||||
const fn = hasTestConf ? fnMaybe : objOrFn
|
||||
|
||||
@ -22,14 +85,14 @@ export function test(desc, objOrFn, fnMaybe) {
|
||||
desc,
|
||||
hasTestConf ? objOrFn : {},
|
||||
async (
|
||||
{ page, context, cmdBar, editor, toolbar, scene, homePage },
|
||||
{ page, context, cmdBar, editor, toolbar, scene, homePage, ...rest },
|
||||
testInfo
|
||||
) => {
|
||||
// To switch to web, use PLATFORM=web environment variable.
|
||||
// Only use this for debugging, since the playwright tracer is busted
|
||||
// for electron.
|
||||
|
||||
let tronApp;
|
||||
let tronApp
|
||||
|
||||
if (process.env.PLATFORM === 'web') {
|
||||
tronApp = new AuthenticatedApp(context, page, testInfo)
|
||||
@ -38,25 +101,37 @@ export function test(desc, objOrFn, fnMaybe) {
|
||||
}
|
||||
|
||||
const fixtures: Fixtures = { cmdBar, editor, toolbar, scene, homePage }
|
||||
if (tronApp instanceof AuthenticatedTronApp) {
|
||||
const options = {
|
||||
fixtures,
|
||||
}
|
||||
if (hasTestConf) {
|
||||
Object.assign(options, {
|
||||
appSettings: objOrFn?.appSettings,
|
||||
cleanProjectDir: objOrFn?.cleanProjectDir,
|
||||
})
|
||||
}
|
||||
await tronApp.initialise(options)
|
||||
} else {
|
||||
await tronApp.initialise('')
|
||||
}
|
||||
|
||||
// We need to patch this because addInitScript will bind too late in our
|
||||
// electron tests, never running. We need to call reload() after each call
|
||||
// to guarantee it runs.
|
||||
const oldContextAddInitScript = tronApp.context.addInitScript
|
||||
tronApp.context.addInitScript = async function (a, b) {
|
||||
// @ts-ignore pretty sure way out of tsc's type checking capabilities.
|
||||
// This code works perfectly fine.
|
||||
await oldContextAddInitScript.apply(this, [a, b])
|
||||
await tronApp.page.reload()
|
||||
}
|
||||
|
||||
// No idea why we mix and match page and context's addInitScript but we do
|
||||
const oldPageAddInitScript = tronApp.page.addInitScript
|
||||
tronApp.page.addInitScript = async function (a, b) {
|
||||
tronApp.page.addInitScript = async function (a: any, b: any) {
|
||||
// @ts-ignore pretty sure way out of tsc's type checking capabilities.
|
||||
// This code works perfectly fine.
|
||||
await oldPageAddInitScript.apply(this, [a, b])
|
||||
await tronApp.page.reload()
|
||||
}
|
||||
@ -75,45 +150,73 @@ export function test(desc, objOrFn, fnMaybe) {
|
||||
return
|
||||
}
|
||||
|
||||
await tronApp.electronApp.evaluateHandle(async ({ app }, dims) => {
|
||||
await tronApp.electronApp?.evaluateHandle(async ({ app }, dims) => {
|
||||
// @ts-ignore sorry jon but see comment in main.ts why this is ignored
|
||||
await app.resizeWindow(dims.width, dims.height)
|
||||
}, dims)
|
||||
|
||||
return tronApp.page.evaluate(async (dims) => {
|
||||
return tronApp.page.evaluate(
|
||||
async (dims: { width: number; height: number }) => {
|
||||
await window.electron.resizeWindow(dims.width, dims.height)
|
||||
window.document.body.style.width = dims.width + 'px'
|
||||
window.document.body.style.height = dims.height + 'px'
|
||||
window.document.documentElement.style.width = dims.width + 'px'
|
||||
window.document.documentElement.style.height = dims.height + 'px'
|
||||
}, dims)
|
||||
},
|
||||
dims
|
||||
)
|
||||
}
|
||||
|
||||
// We need to expose this in order for some tests that require folder
|
||||
// creation. Before they used to do this by their own electronSetup({...})
|
||||
// calls.
|
||||
if (tronApp instanceof AuthenticatedTronApp) {
|
||||
tronApp.context.folderSetupFn = function (fn) {
|
||||
return fn(tronApp.dir).then(() => ({ dir: tronApp.dir }))
|
||||
return fn(tronApp.dir).then(() => ({
|
||||
dir: tronApp.dir,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// tsc aint smart enough to know this'll never be undefined
|
||||
// but I dont blame it, the logic to know is complex
|
||||
if (fn) {
|
||||
await fn(
|
||||
{
|
||||
context: tronApp.context,
|
||||
page: tronApp.page,
|
||||
electronApp: tronApp.electronApp,
|
||||
electronApp:
|
||||
tronApp instanceof AuthenticatedTronApp
|
||||
? tronApp.electronApp
|
||||
: undefined,
|
||||
...fixtures,
|
||||
...rest,
|
||||
},
|
||||
testInfo
|
||||
)
|
||||
}
|
||||
|
||||
testInfo.tronApp = tronApp
|
||||
testInfo.tronApp =
|
||||
tronApp instanceof AuthenticatedTronApp ? tronApp : undefined
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
type ZooTest = typeof test
|
||||
|
||||
test.describe = pwTestFnWithFixtures.describe
|
||||
test.beforeEach = pwTestFnWithFixtures.beforeEach
|
||||
test.afterEach = pwTestFnWithFixtures.afterEach
|
||||
test.step = pwTestFnWithFixtures.step
|
||||
test.skip = pwTestFnWithFixtures.skip
|
||||
test.setTimeout = pwTestFnWithFixtures.setTimeout
|
||||
test.fixme = pwTestFnWithFixtures.fixme
|
||||
test.fixme = pwTestFnWithFixtures.fixme as unknown as ZooTest
|
||||
test.only = pwTestFnWithFixtures.only
|
||||
test.fail = pwTestFnWithFixtures.fail
|
||||
test.slow = pwTestFnWithFixtures.slow
|
||||
test.beforeAll = pwTestFnWithFixtures.beforeAll
|
||||
test.afterAll = pwTestFnWithFixtures.afterAll
|
||||
test.use = pwTestFnWithFixtures.use
|
||||
test.expect = pwTestFnWithFixtures.expect
|
||||
test.extend = pwTestFnWithFixtures.extend
|
||||
test.info = pwTestFnWithFixtures.info
|
||||
|
@ -13,7 +13,7 @@ export default defineConfig({
|
||||
/* Do not retry */
|
||||
retries: 0,
|
||||
/* Different amount of parallelism on CI and local. */
|
||||
workers: 4,
|
||||
workers: 1,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: [
|
||||
['dot'],
|
||||
|
@ -45,7 +45,7 @@ export default class CodeManager {
|
||||
} else if (storedCode === null) {
|
||||
this.code = bracket
|
||||
} else {
|
||||
this.code = storedCode
|
||||
this.code = storedCode || ''
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ export default class CodeManager {
|
||||
}
|
||||
|
||||
localStoragePersistCode(): string {
|
||||
return safeLSGetItem(PERSIST_CODE_KEY)
|
||||
return safeLSGetItem(PERSIST_CODE_KEY) || ''
|
||||
}
|
||||
|
||||
registerCallBacks({ setCode }: { setCode: (arg: string) => void }) {
|
||||
@ -169,7 +169,7 @@ export default class CodeManager {
|
||||
}
|
||||
|
||||
function safeLSGetItem(key: string) {
|
||||
if (typeof window === 'undefined') return null
|
||||
if (typeof window === 'undefined') return
|
||||
return localStorage?.getItem(key)
|
||||
}
|
||||
|
||||
|
@ -134,12 +134,15 @@ app.on('ready', (event, data) => {
|
||||
// There is just not enough code to warrant it and further abstracts everything
|
||||
// which is already quite abstracted
|
||||
|
||||
// @ts-ignore
|
||||
// electron/electron.d.ts has done type = App, making declaration merging not
|
||||
// possible :(
|
||||
app.resizeWindow = async (width: number, height: number) => {
|
||||
return mainWindow?.setSize(width, height)
|
||||
}
|
||||
|
||||
ipcMain.handle('app.resizeWindow', (event, data) => {
|
||||
return mainWindow?.setSize(...data)
|
||||
return mainWindow?.setSize(data[0], data[1])
|
||||
})
|
||||
|
||||
ipcMain.handle('app.getPath', (event, data) => {
|
||||
|
@ -20,12 +20,16 @@ const loginWithDeviceFlow = (): Promise<string> =>
|
||||
ipcRenderer.invoke('loginWithDeviceFlow')
|
||||
const onUpdateDownloaded = (
|
||||
callback: (value: { version: string; releaseNotes: string }) => void
|
||||
) => ipcRenderer.on('update-downloaded', (_event, value) => callback(value))
|
||||
) =>
|
||||
ipcRenderer.on('update-downloaded', (_event: any, value) => callback(value))
|
||||
const onUpdateDownloadStart = (
|
||||
callback: (value: { version: string }) => void
|
||||
) => ipcRenderer.on('update-download-start', (_event, value) => callback(value))
|
||||
) =>
|
||||
ipcRenderer.on('update-download-start', (_event: any, value) =>
|
||||
callback(value)
|
||||
)
|
||||
const onUpdateError = (callback: (value: Error) => void) =>
|
||||
ipcRenderer.on('update-error', (_event, value) => callback(value))
|
||||
ipcRenderer.on('update-error', (_event: any, value) => callback(value))
|
||||
const appRestart = () => ipcRenderer.invoke('app.restart')
|
||||
|
||||
const isMac = os.platform() === 'darwin'
|
||||
|
Reference in New Issue
Block a user