Correct all tsc errors

This commit is contained in:
49lf
2024-12-05 16:37:56 -05:00
parent 449cbb868f
commit b68a2f2d86
29 changed files with 1433 additions and 1254 deletions

View File

@ -4,7 +4,7 @@ test.describe('Electron app header tests', () => {
test( test(
'Open Command Palette button has correct shortcut', 'Open Command Palette button has correct shortcut',
{ tag: '@electron' }, { tag: '@electron' },
async ({ page, browserName }, testInfo) => { async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
// No space before the shortcut since it checks textContent. // No space before the shortcut since it checks textContent.
@ -29,7 +29,7 @@ test.describe('Electron app header tests', () => {
test( test(
'User settings has correct shortcut', 'User settings has correct shortcut',
{ tag: '@electron' }, { tag: '@electron' },
async ({ page, browserName }, testInfo) => { async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
// Open the user sidebar menu. // Open the user sidebar menu.

View File

@ -1,5 +1,5 @@
import { test, expect, Page } from './zoo-test' import { test, expect, Page } from './zoo-test'
import { HomePageFixture } from './fixtures/HomePageFixture' import { HomePageFixture } from './fixtures/homePageFixture'
import { getUtils } from './test-utils' import { getUtils } from './test-utils'
import { EngineCommand } from 'lang/std/artifactGraph' import { EngineCommand } from 'lang/std/artifactGraph'
import { uuidv4 } from 'lib/utils' import { uuidv4 } from 'lib/utils'

View File

@ -125,8 +125,6 @@ test.describe('Code pane and errors', () => {
homePage, homePage,
context, context,
}) => { }) => {
const u = await getUtils(page)
// Load the app with the working starter code // Load the app with the working starter code
await context.addInitScript((code) => { await context.addInitScript((code) => {
localStorage.setItem('persistCode', code) localStorage.setItem('persistCode', code)
@ -168,8 +166,6 @@ test.describe('Code pane and errors', () => {
page, page,
homePage, homePage,
}) => { }) => {
const u = await getUtils(page)
// Load the app with the working starter code // Load the app with the working starter code
await context.addInitScript((code) => { await context.addInitScript((code) => {
localStorage.setItem('persistCode', code) localStorage.setItem('persistCode', code)
@ -236,9 +232,9 @@ test.describe('Code pane and errors', () => {
test( test(
'Opening multiple panes persists when switching projects', 'Opening multiple panes persists when switching projects',
{ tag: '@electron' }, { tag: '@electron' },
async ({ context, browserName, page }, testInfo) => { async ({ context, page }, testInfo) => {
// Setup multiple projects. // Setup multiple projects.
context.folderSetupFn(async (dir) => { await context.folderSetupFn(async (dir) => {
const routerTemplateDir = join(dir, 'router-template-slate') const routerTemplateDir = join(dir, 'router-template-slate')
const bracketDir = join(dir, 'bracket') const bracketDir = join(dir, 'bracket')
await Promise.all([ await Promise.all([
@ -307,7 +303,7 @@ test(
test( test(
'external change of file contents are reflected in editor', 'external change of file contents are reflected in editor',
{ tag: '@electron' }, { tag: '@electron' },
async ({ context, browserName, page }, testInfo) => { async ({ context, page }, testInfo) => {
const PROJECT_DIR_NAME = 'lee-was-here' const PROJECT_DIR_NAME = 'lee-was-here'
const { dir: projectsDir } = await context.folderSetupFn(async (dir) => { const { dir: projectsDir } = await context.folderSetupFn(async (dir) => {
const aProjectDir = join(dir, PROJECT_DIR_NAME) const aProjectDir = join(dir, PROJECT_DIR_NAME)

View File

@ -2,7 +2,6 @@ import { test, expect } from './zoo-test'
import { getUtils } from './test-utils' import { getUtils } from './test-utils'
import { KCL_DEFAULT_LENGTH } from 'lib/constants' import { KCL_DEFAULT_LENGTH } from 'lib/constants'
import { normalizeLineEndings } from 'lib/codeEditor'
test.describe('Command bar tests', () => { test.describe('Command bar tests', () => {
test('Extrude from command bar selects extrude line after', async ({ test('Extrude from command bar selects extrude line after', async ({
@ -89,7 +88,6 @@ test.describe('Command bar tests', () => {
page, page,
homePage, homePage,
}) => { }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -171,7 +169,6 @@ test.describe('Command bar tests', () => {
page, page,
homePage, homePage,
}) => { }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -300,7 +297,6 @@ test.describe('Command bar tests', () => {
page, page,
homePage, homePage,
}) => { }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()

View File

@ -45,6 +45,7 @@ test.describe('Copilot ghost text', () => {
test.skip('copilot disabled in sketch mode no select plane', async ({ test.skip('copilot disabled in sketch mode no select plane', async ({
page, page,
homePage,
}) => { }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio

View File

@ -2,7 +2,6 @@ import { test, expect } from './zoo-test'
import path from 'path' import path from 'path'
import { import {
getUtils, getUtils,
setupElectron,
executorInputPath, executorInputPath,
getPlaywrightDownloadDir, getPlaywrightDownloadDir,
} from './test-utils' } from './test-utils'
@ -12,7 +11,7 @@ test(
'export works on the first try', 'export works on the first try',
{ tag: '@electron' }, { tag: '@electron' },
async ({ page, context }, testInfo) => { async ({ page, context }, testInfo) => {
context.folderSetupFn(async (dir) => { await context.folderSetupFn(async (dir) => {
const bracketDir = path.join(dir, 'bracket') const bracketDir = path.join(dir, 'bracket')
await Promise.all([fsp.mkdir(bracketDir, { recursive: true })]) await Promise.all([fsp.mkdir(bracketDir, { recursive: true })])
await Promise.all([ await Promise.all([
@ -25,7 +24,7 @@ test(
path.join(bracketDir, 'main.kcl') path.join(bracketDir, 'main.kcl')
), ),
]) ])
}), })
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
page.on('console', console.log) page.on('console', console.log)

View File

@ -190,8 +190,6 @@ test.describe('Editor tests', () => {
}) })
test('fold gutters work', async ({ page, homePage }) => { test('fold gutters work', async ({ page, homePage }) => {
const u = await getUtils(page)
const fullCode = `sketch001 = startSketchOn('XY') const fullCode = `sketch001 = startSketchOn('XY')
|> startProfileAt([-10, -10], %) |> startProfileAt([-10, -10], %)
|> line([20, 0], %) |> line([20, 0], %)
@ -642,8 +640,6 @@ test.describe('Editor tests', () => {
page, page,
homePage, homePage,
}) => { }) => {
const u = await getUtils(page)
await context.addInitScript(async () => { await context.addInitScript(async () => {
localStorage.setItem( localStorage.setItem(
'persistCode', 'persistCode',

View File

@ -56,11 +56,11 @@ export class EditorFixture {
if (!shouldNormalise) { if (!shouldNormalise) {
const expectStart = expect.poll(() => this.codeContent.textContent()) const expectStart = expect.poll(() => this.codeContent.textContent())
if (not) { if (not) {
const result = await expectStart.not.toContain(code, { timeout }) const result = await expectStart.not.toContain(code)
await resetPane() await resetPane()
return result return result
} }
const result = await expectStart.toContain(code, { timeout }) const result = await expectStart.toContain(code)
await resetPane() await resetPane()
return result return result
} }
@ -150,9 +150,11 @@ export class EditorFixture {
scrollToText(text: string) { scrollToText(text: string) {
return this.page.evaluate((scrollToText: string) => { return this.page.evaluate((scrollToText: string) => {
// editorManager is available on the window object. // editorManager is available on the window object.
// @ts-ignore
let index = editorManager._editorView.docView.view.state.doc let index = editorManager._editorView.docView.view.state.doc
.toString() .toString()
.indexOf(scrollToText) .indexOf(scrollToText)
// @ts-ignore
editorManager._editorView.dispatch({ editorManager._editorView.dispatch({
selection: { selection: {
anchor: index, anchor: index,

View File

@ -1,11 +1,11 @@
import type { import type {
BrowserContext, BrowserContext,
ElectronApplication, ElectronApplication,
Page,
TestInfo, TestInfo,
Page,
} from '@playwright/test' } 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 fsp from 'fs/promises'
import { join } from 'path' import { join } from 'path'
import { CmdBarFixture } from './cmdBarFixture' import { CmdBarFixture } from './cmdBarFixture'
@ -50,8 +50,6 @@ export class AuthenticatedApp {
} }
export interface Fixtures { export interface Fixtures {
app: AuthenticatedApp
tronApp: AuthenticatedTronApp
cmdBar: CmdBarFixture cmdBar: CmdBarFixture
editor: EditorFixture editor: EditorFixture
toolbar: ToolbarFixture toolbar: ToolbarFixture
@ -122,19 +120,19 @@ export class AuthenticatedTronApp {
} }
export const fixtures = { export const fixtures = {
cmdBar: async ({ page }, use) => { cmdBar: async ({ page }: { page: Page }, use: any) => {
await use(new CmdBarFixture(page)) await use(new CmdBarFixture(page))
}, },
editor: async ({ page }, use) => { editor: async ({ page }: { page: Page }, use: any) => {
await use(new EditorFixture(page)) await use(new EditorFixture(page))
}, },
toolbar: async ({ page }, use) => { toolbar: async ({ page }: { page: Page }, use: any) => {
await use(new ToolbarFixture(page)) await use(new ToolbarFixture(page))
}, },
scene: async ({ page }, use) => { scene: async ({ page }: { page: Page }, use: any) => {
await use(new SceneFixture(page)) await use(new SceneFixture(page))
}, },
homePage: async ({ page }, use, testInfo) => { homePage: async ({ page }: { page: Page }, use: any) => {
await use(new HomePageFixture(page)) await use(new HomePageFixture(page))
}, },
} }

View File

@ -118,7 +118,7 @@ export class HomePageFixture {
await projectCard.click() 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. // On web this is a no-op. There is no project view.
if (process.env.PLATFORM === 'web') return if (process.env.PLATFORM === 'web') return

View File

@ -8,7 +8,6 @@ import {
TEST_SETTINGS_KEY, TEST_SETTINGS_KEY,
TEST_SETTINGS_ONBOARDING_START, TEST_SETTINGS_ONBOARDING_START,
TEST_SETTINGS_ONBOARDING_EXPORT, TEST_SETTINGS_ONBOARDING_EXPORT,
TEST_SETTINGS_ONBOARDING_PARAMETRIC_MODELING,
TEST_SETTINGS_ONBOARDING_USER_MENU, TEST_SETTINGS_ONBOARDING_USER_MENU,
} from './storageStates' } from './storageStates'
import * as TOML from '@iarna/toml' import * as TOML from '@iarna/toml'
@ -29,8 +28,6 @@ test.describe('Onboarding tests', () => {
cleanProjectDir: true, cleanProjectDir: true,
}, },
async ({ context, page, homePage }) => { async ({ context, page, homePage }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -117,7 +114,6 @@ test.describe('Onboarding tests', () => {
localStorage.setItem('persistCode', code) localStorage.setItem('persistCode', code)
}, initialCode) }, initialCode)
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -159,8 +155,6 @@ test.describe('Onboarding tests', () => {
}, },
}, },
async ({ context, page, homePage }) => { async ({ context, page, homePage }) => {
const u = await getUtils(page)
// Override beforeEach test setup // Override beforeEach test setup
await context.addInitScript( await context.addInitScript(
async ({ settingsKey, settings }) => { async ({ settingsKey, settings }) => {
@ -212,8 +206,6 @@ test.describe('Onboarding tests', () => {
cleanProjectDir: true, cleanProjectDir: true,
}, },
async ({ context, page, homePage }) => { async ({ context, page, homePage }) => {
const u = await getUtils(page)
const originalCode = 'sigmaAllow = 15000' const originalCode = 'sigmaAllow = 15000'
// Override beforeEach test setup // 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 page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -407,7 +398,6 @@ test.describe('Onboarding tests', () => {
} }
) )
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()

View File

@ -622,18 +622,12 @@ openSketch = startSketchOn('XY')
localStorage.setItem('persistCode', code) localStorage.setItem('persistCode', code)
}, initialCode) }, initialCode)
await homePage.goToModelingScene() await homePage.goToModelingScene()
await u.waitForPageLoad() await u.waitForPageLoad()
await page.waitForTimeout(1000) await page.waitForTimeout(1000)
const pointOnSketchArea = {
x: viewPortSize.width * 0.7,
y: viewPortSize.height * 0.7,
}
const pointInsideCircle = { const pointInsideCircle = {
x: viewPortSize.width * 0.55, x: viewPortSize.width * 0.58,
y: viewPortSize.height * 0.5, y: viewPortSize.height * 0.5,
} }
const pointOnPathAfterSketching = { const pointOnPathAfterSketching = {
@ -678,8 +672,14 @@ openSketch = startSketchOn('XY')
// Drag the sketch line out of the axis view which blocks the click // Drag the sketch line out of the axis view which blocks the click
await page.dragAndDrop('#stream', '#stream', { await page.dragAndDrop('#stream', '#stream', {
sourcePosition: { x: viewPortSize.width * 0.7, y: viewPortSize.height* 0.5 }, sourcePosition: {
targetPosition: { x: viewPortSize.width * 0.7, y: viewPortSize.height* 0.4 }, 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) await page.waitForTimeout(500)
@ -711,7 +711,6 @@ test(`Offset plane point-and-click`, async ({
toolbar, toolbar,
cmdBar, cmdBar,
}) => { }) => {
// One dumb hardcoded screen pixel value // One dumb hardcoded screen pixel value
const testPoint = { x: 700, y: 150 } const testPoint = { x: 700, y: 150 }
const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y) const [clickOnXzPlane] = scene.makeMouseHelpers(testPoint.x, testPoint.y)

View File

@ -1574,7 +1574,7 @@ test(
.locator('section#projectDirectory input') .locator('section#projectDirectory input')
.inputValue() .inputValue()
const handleFile = electronApp.evaluate( const handleFile = electronApp?.evaluate(
async ({ dialog }, filePaths) => { async ({ dialog }, filePaths) => {
dialog.showOpenDialog = () => dialog.showOpenDialog = () =>
Promise.resolve({ canceled: false, filePaths }) Promise.resolve({ canceled: false, filePaths })
@ -1604,7 +1604,7 @@ test(
await page.getByTestId('project-directory-settings-link').click() await page.getByTestId('project-directory-settings-link').click()
const handleFile = electronApp.evaluate( const handleFile = electronApp?.evaluate(
async ({ dialog }, filePaths) => { async ({ dialog }, filePaths) => {
dialog.showOpenDialog = () => dialog.showOpenDialog = () =>
Promise.resolve({ canceled: false, filePaths }) Promise.resolve({ canceled: false, filePaths })

View File

@ -101,7 +101,6 @@ test.describe('Sketch tests', () => {
}) })
test('Can delete most of a sketch and the line tool will still work', async ({ test('Can delete most of a sketch and the line tool will still work', async ({
page, page,
center,
homePage, homePage,
}) => { }) => {
const u = await getUtils(page) const u = await getUtils(page)
@ -142,7 +141,7 @@ test.describe('Sketch tests', () => {
await page.waitForTimeout(100) await page.waitForTimeout(100)
await expect(async () => { 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 page.mouse.click(700, 200)
await expect await expect
@ -164,7 +163,6 @@ test.describe('Sketch tests', () => {
localStorage.setItem('persistCode', ``) localStorage.setItem('persistCode', ``)
}) })
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -428,8 +426,11 @@ test.describe('Sketch tests', () => {
}) })
// expect the code to have changed // expect the code to have changed
await editor.expectEditor.toContain(`sketch001 = startSketchOn('XZ') await editor.expectEditor.toContain(
|> circle({ center = [7.26, -2.37], radius = 11.44 }, %)`, { shouldNormalise: true }) `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 ({ test('Can edit a sketch that has been extruded in the same pipe', async ({
page, page,
@ -1289,7 +1290,7 @@ test.describe(`Sketching with offset planes`, () => {
) )
}) })
homePage.goToModelingScene() await homePage.goToModelingScene()
const [planeClick, planeHover] = scene.makeMouseHelpers(650, 200) const [planeClick, planeHover] = scene.makeMouseHelpers(650, 200)

View File

@ -80,7 +80,6 @@ test.describe('Test network and connection issues', () => {
test('Engine disconnect & reconnect in sketch mode', async ({ test('Engine disconnect & reconnect in sketch mode', async ({
page, page,
browserName,
homePage, homePage,
}) => { }) => {
// TODO: Don't skip Mac for these. After `window.tearDown` is working in Safari, these should work on webkit // TODO: Don't skip Mac for these. After `window.tearDown` is working in Safari, these should work on webkit

View File

@ -1,13 +1,11 @@
import { import {
expect, expect,
Page,
Download,
BrowserContext, BrowserContext,
TestInfo, TestInfo,
_electron as electron, _electron as electron,
Locator, Locator,
test,
} from '@playwright/test' } from '@playwright/test'
import { test, Page } from './zoo-test'
import { EngineCommand } from 'lang/std/artifactGraph' import { EngineCommand } from 'lang/std/artifactGraph'
import fsp from 'fs/promises' import fsp from 'fs/promises'
import fsSync from 'fs' import fsSync from 'fs'
@ -16,7 +14,7 @@ import pixelMatch from 'pixelmatch'
import { PNG } from 'pngjs' import { PNG } from 'pngjs'
import { Protocol } from 'playwright-core/types/protocol' import { Protocol } from 'playwright-core/types/protocol'
import type { Models } from '@kittycad/lib' 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 { secrets } from './secrets'
import { import {
TEST_SETTINGS_KEY, 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. // Code Mirror lazy loads text! Wowza! Let's force-load the text for tests.
await page.evaluate(() => { await page.evaluate(() => {
// editorManager is available on the window object. // editorManager is available on the window object.
//@ts-ignore this is in an entirely different context that tsc can't see.
editorManager._editorView.dispatch({ editorManager._editorView.dispatch({
selection: { selection: {
//@ts-ignore this is in an entirely different context that tsc can't see.
anchor: editorManager._editorView.docView.length, anchor: editorManager._editorView.docView.length,
}, },
scrollIntoView: true, scrollIntoView: true,
@ -515,10 +515,12 @@ export async function getUtils(page: Page, test_?: typeof test) {
async editorTextMatches(code: string) { async editorTextMatches(code: string) {
const editor = page.locator(editorSelector) const editor = page.locator(editorSelector)
return expect.poll(async () => { return expect
.poll(async () => {
const text = await editor.textContent() const text = await editor.textContent()
return toNormalizedCode(text) return toNormalizedCode(text ?? '')
}).toContain(toNormalizedCode(code)) })
.toContain(toNormalizedCode(code))
}, },
pasteCodeInEditor: async (code: string) => { pasteCodeInEditor: async (code: string) => {
@ -716,7 +718,7 @@ const moveDownloadedFileTo = async (page: Page, toLocation: string) => {
const downloadDir = getPlaywrightDownloadDir(page) const downloadDir = getPlaywrightDownloadDir(page)
// Expect there to be at least one file // Expect there to be at least one file
expect await expect
.poll(async () => { .poll(async () => {
const files = await fsp.readdir(downloadDir) const files = await fsp.readdir(downloadDir)
return files.length 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 // It's not super reliable but we have no real other choice for now
await page.waitForTimeout(3000) await page.waitForTimeout(3000)
await testInfo.tronApp.close() await testInfo.tronApp?.close()
} }
// settingsOverrides may need to be augmented to take more generic items, // settingsOverrides may need to be augmented to take more generic items,

View File

@ -1069,10 +1069,10 @@ part002 = startSketchOn('XZ')
) )
const linebb = await u.getBoundingBox('[data-overlay-index="1"]') 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) await page.mouse.click(linebb.x, linebb.y)
expect await expect
.poll(async () => await u.getGreatestPixDiff(lineAfter, TEST_COLORS.BLUE)) .poll(async () => await u.getGreatestPixDiff(lineAfter, TEST_COLORS.BLUE))
.toBeLessThan(3) .toBeLessThan(3)

View File

@ -1,9 +1,7 @@
import { test, expect } from './zoo-test' import { test, expect } from './zoo-test'
import { getUtils, executorInputPath } from './test-utils' import { getUtils } from './test-utils'
import { uuidv4 } from 'lib/utils' import { uuidv4 } from 'lib/utils'
import { TEST_CODE_GIZMO } from './storageStates' import { TEST_CODE_GIZMO } from './storageStates'
import path from 'node:path'
import fsp from 'fs/promises'
test.describe('Testing Gizmo', () => { test.describe('Testing Gizmo', () => {
const cases = [ const cases = [

View File

@ -1,7 +1,5 @@
import { test, expect } from './zoo-test' import { test, expect } from './zoo-test'
import { getUtils } from './test-utils' 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.describe('Test toggling perspective', () => {
test('via command palette and toggle', async ({ page, homePage }) => { test('via command palette and toggle', async ({ page, homePage }) => {

View File

@ -11,7 +11,12 @@ test.describe('Testing in-app sample loading', () => {
* Note this test implicitly depends on the KCL sample "car-wheel.kcl", * 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 * 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) const u = await getUtils(page)
await test.step(`Test setup`, async () => { await test.step(`Test setup`, async () => {
@ -65,7 +70,8 @@ test.describe('Testing in-app sample loading', () => {
await editor.expectEditor.toContain('// ' + newSample.title) await editor.expectEditor.toContain('// ' + newSample.title)
await expect(unitsToast('in')).toBeVisible() await expect(unitsToast('in')).toBeVisible()
}) }) })
})
/** /**
* Note this test implicitly depends on the KCL samples: * Note this test implicitly depends on the KCL samples:
@ -75,7 +81,7 @@ test.describe('Testing in-app sample loading', () => {
test( test(
'Desktop: should create new file by default, optionally overwrite', 'Desktop: should create new file by default, optionally overwrite',
{ tag: '@electron' }, { tag: '@electron' },
async ({ editor, context, page, browserName: _ }, testInfo) => { async ({ editor, context, page }, testInfo) => {
const { dir } = await context.folderSetupFn(async (dir) => { const { dir } = await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'bracket') const bracketDir = join(dir, 'bracket')
await fsp.mkdir(bracketDir, { recursive: true }) await fsp.mkdir(bracketDir, { recursive: true })

View File

@ -3,6 +3,7 @@ import { test, expect, Page } from './zoo-test'
import { deg, getUtils, wiggleMove } from './test-utils' import { deg, getUtils, wiggleMove } from './test-utils'
import { LineInputsType } from 'lang/std/sketchcombos' import { LineInputsType } from 'lang/std/sketchcombos'
import { uuidv4 } from 'lib/utils' import { uuidv4 } from 'lib/utils'
import { EditorFixture } from './fixtures/editorFixture'
test.describe('Testing segment overlays', () => { 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', () => { 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 wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator)
await page.mouse.move(x, y) await page.mouse.move(x, y)
await editor.expectEditor.toContain(expectBeforeUnconstrained, { shouldNormalise: true }) await editor.expectEditor.toContain(expectBeforeUnconstrained, {
shouldNormalise: true,
})
const constrainedLocator = page.locator( const constrainedLocator = page.locator(
`[data-constraint-type="${constraintType}"][data-is-constrained="true"]` `[data-constraint-type="${constraintType}"][data-is-constrained="true"]`
) )
@ -62,7 +65,9 @@ test.describe('Testing segment overlays', () => {
await page.getByTestId('constraint-symbol-popover').count() await page.getByTestId('constraint-symbol-popover').count()
).toBeGreaterThan(0) ).toBeGreaterThan(0)
await constrainedLocator.click() 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.mouse.move(0, 0)
await page.waitForTimeout(1000) await page.waitForTimeout(1000)
@ -91,6 +96,9 @@ test.describe('Testing segment overlays', () => {
.click() .click()
await expect(page.locator('.cm-content')).toContainText(expectFinal) await expect(page.locator('.cm-content')).toContainText(expectFinal)
await editor.expectEditor.toContain(expectFinal, { shouldNormalise: true }) 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 page.mouse.move(x, y)
await expect(page.getByText('Added variable')).not.toBeVisible() 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( const unconstrainedLocator = page.locator(
`[data-constraint-type="${constraintType}"][data-is-constrained="false"]` `[data-constraint-type="${constraintType}"][data-is-constrained="false"]`
) )
@ -156,7 +166,9 @@ test.describe('Testing segment overlays', () => {
name: 'arrow right Continue', name: 'arrow right Continue',
}) })
.click() .click()
await editor.expectEditor.toContain(expectAfterUnconstrained, { shouldNormalise: true }) await editor.expectEditor.toContain(expectAfterUnconstrained, {
shouldNormalise: true,
})
await expect(page.getByText('Added variable')).not.toBeVisible() await expect(page.getByText('Added variable')).not.toBeVisible()
await page.mouse.move(0, 0) await page.mouse.move(0, 0)
@ -176,7 +188,9 @@ test.describe('Testing segment overlays', () => {
await page.getByTestId('constraint-symbol-popover').count() await page.getByTestId('constraint-symbol-popover').count()
).toBeGreaterThan(0) ).toBeGreaterThan(0)
await constrainedLocator.click() await constrainedLocator.click()
await editor.expectEditor.toContain(expectFinal, { shouldNormalise: true }) await editor.expectEditor.toContain(expectFinal, {
shouldNormalise: true,
})
} }
test.setTimeout(120000) test.setTimeout(120000)
test('for segments [line, angledLine, lineTo, xLineTo]', async ({ test('for segments [line, angledLine, lineTo, xLineTo]', async ({
@ -344,7 +358,11 @@ test.describe('Testing segment overlays', () => {
locator: '[data-overlay-toolbar-index="3"]', 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 () => { await page.addInitScript(async () => {
localStorage.setItem( localStorage.setItem(
'persistCode', 'persistCode',
@ -709,7 +727,11 @@ test.describe('Testing segment overlays', () => {
locator: '[data-overlay-toolbar-index="11"]', 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 () => { await page.addInitScript(async () => {
localStorage.setItem( localStorage.setItem(
'persistCode', 'persistCode',
@ -888,12 +910,16 @@ test.describe('Testing segment overlays', () => {
await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator) await wiggleMove(page, x, y, 20, 30, ang, 10, 5, locator)
await page.mouse.move(x, y) 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.locator(`[data-stdlib-fn-name="${stdLibFnName}"]`).click()
await page.getByText('Delete Segment').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 }) => { test('all segment types', async ({ page, editor, homePage }) => {
await page.addInitScript(async () => { await page.addInitScript(async () => {
@ -1075,12 +1101,16 @@ test.describe('Testing segment overlays', () => {
await page.mouse.move(hoverPos.x, hoverPos.y) await page.mouse.move(hoverPos.x, hoverPos.y)
const codeToBeDeleted = 'lineTo([33, 11.5 + 0], %)' 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.getByTestId('overlay-menu').click()
await page.getByText('Delete Segment').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) segmentToDelete = await getOverlayByIndex(1)
ang = await u.getAngle(`[data-overlay-index="${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 + x, hoverPos.y + y)
await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 }) 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.getByTestId('overlay-menu').click()
await page.waitForTimeout(100) 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 + x, hoverPos.y + y)
await page.mouse.move(hoverPos.x, hoverPos.y, { steps: 5 }) 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.getByTestId('overlay-menu').click()
await page.waitForTimeout(100) await page.waitForTimeout(100)
@ -1202,12 +1236,18 @@ test.describe('Testing segment overlays', () => {
) )
).toBeTruthy() ).toBeTruthy()
// eslint-disable-next-line jest/no-conditional-expect // eslint-disable-next-line jest/no-conditional-expect
await editor.expectEditor.toContain(lineOfInterest, { shouldNormalise: true }) await editor.expectEditor.toContain(lineOfInterest, {
shouldNormalise: true,
})
} else { } else {
// eslint-disable-next-line jest/no-conditional-expect // 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 // eslint-disable-next-line jest/no-conditional-expect
await editor.expectEditor.not.toContain('seg01', { shouldNormalise: true }) await editor.expectEditor.not.toContain('seg01', {
shouldNormalise: true,
})
} }
}) })
} }

View File

@ -1,11 +1,7 @@
import { test, expect } from './zoo-test' import { test, expect } from './zoo-test'
import * as fsp from 'fs/promises' import * as fsp from 'fs/promises'
import { join } from 'path' import { join } from 'path'
import { import { getUtils, executorInputPath, createProject } from './test-utils'
getUtils,
executorInputPath,
createProject,
} from './test-utils'
import { SaveSettingsPayload, SettingsLevel } from 'lib/settings/settingsTypes' import { SaveSettingsPayload, SettingsLevel } from 'lib/settings/settingsTypes'
import { SETTINGS_FILE_NAME, PROJECT_SETTINGS_FILE_NAME } from 'lib/constants' import { SETTINGS_FILE_NAME, PROJECT_SETTINGS_FILE_NAME } from 'lib/constants'
import { import {
@ -17,14 +13,14 @@ import {
import * as TOML from '@iarna/toml' import * as TOML from '@iarna/toml'
test.describe('Testing settings', () => { 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 // Override beforeEach test setup
// with corrupted settings // 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 }) await page.setBodyDimensions({ width: 1200, height: 500 })
// Check the settings were reset // Check the settings were reset
@ -38,15 +34,20 @@ test.describe('Testing settings', () => {
expect(storedSettings.settings?.app?.theme).toBe('dark') expect(storedSettings.settings?.app?.theme).toBe('dark')
// Check that the invalid settings were changed to good defaults // Check that the invalid settings were changed to good defaults
expect(storedSettings.settings?.modeling?.defaultUnit).toBe("in") expect(storedSettings.settings?.modeling?.defaultUnit).toBe('in')
expect(storedSettings.settings?.modeling?.mouseControls).toBe("KittyCAD") expect(storedSettings.settings?.modeling?.mouseControls).toBe('KittyCAD')
expect(storedSettings.settings?.app?.projectDirectory).toBe("") expect(storedSettings.settings?.app?.projectDirectory).toBe('')
expect(storedSettings.settings?.projects?.defaultProjectName).toBe( expect(storedSettings.settings?.projects?.defaultProjectName).toBe(
"project-$nnn" 'project-$nnn'
) }) )
}
)
// The behavior is actually broken. Parent always takes precedence // 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 test.step(`Setup`, async () => {
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -70,11 +71,14 @@ test.describe('Testing settings', () => {
/** Test to close https://github.com/KittyCAD/modeling-app/issues/2713 */ /** Test to close https://github.com/KittyCAD/modeling-app/issues/2713 */
await test.step(`Confirm that this dialog has a solid background`, async () => { await test.step(`Confirm that this dialog has a solid background`, async () => {
await expect await expect
.poll(() => u.getGreatestPixDiff({ x: 600, y: 250 }, [28, 28, 28]), { .poll(
() => u.getGreatestPixDiff({ x: 600, y: 250 }, [28, 28, 28]),
{
timeout: 1000, timeout: 1000,
message: message:
'Checking for solid background, should not see default plane colors', 'Checking for solid background, should not see default plane colors',
}) }
)
.toBeLessThan(15) .toBeLessThan(15)
}) })
@ -107,7 +111,9 @@ test.describe('Testing settings', () => {
// Roll back to default of "off" // Roll back to default of "off"
await await page 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() .hover()
await page await page
.getByRole('button', { .getByRole('button', {
@ -120,9 +126,14 @@ test.describe('Testing settings', () => {
await page.getByRole('radio', { name: 'Project' }).click() await page.getByRole('radio', { name: 'Project' }).click()
await expect( await expect(
page.locator('input[name="modeling-showDebugPanel"]') 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) const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -148,9 +159,11 @@ test.describe('Testing settings', () => {
// The hotkey is in a kbd element next to the heading. // The hotkey is in a kbd element next to the heading.
const hotkey = commandPaletteHeading.locator('+ div kbd') const hotkey = commandPaletteHeading.locator('+ div kbd')
const text = process.platform === 'darwin' ? 'Command+K' : 'Control+K' 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 test.step(`Setup`, async () => {
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -232,27 +245,28 @@ test.describe('Testing settings', () => {
await projectSettingsTab.click() await projectSettingsTab.click()
await expect(themeColorSetting).toHaveValue(settingValues.project) await expect(themeColorSetting).toHaveValue(settingValues.project)
}) })
}) }) })
})
test.fixme( test.fixme(
`Project settings override user settings on desktop`, `Project settings override user settings on desktop`,
{ tag: ['@electron', '@skipWin'] }, { tag: ['@electron', '@skipWin'] },
async ({ context, page, browser: _ }, testInfo) => { async ({ context, page }, testInfo) => {
test.skip( test.skip(
process.platform === 'win32', process.platform === 'win32',
'TODO: remove this skip https://github.com/KittyCAD/modeling-app/issues/3557' 'TODO: remove this skip https://github.com/KittyCAD/modeling-app/issues/3557'
) )
const projectName = 'bracket' const projectName = 'bracket'
const { const { dir: projectDirName } = await context.folderSetupFn(
dir: projectDirName, async (dir) => {
} = await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, projectName) const bracketDir = join(dir, projectName)
await fsp.mkdir(bracketDir, { recursive: true }) await fsp.mkdir(bracketDir, { recursive: true })
await fsp.copyFile( await fsp.copyFile(
executorInputPath('focusrite_scarlett_mounting_braket.kcl'), executorInputPath('focusrite_scarlett_mounting_braket.kcl'),
join(bracketDir, 'main.kcl') join(bracketDir, 'main.kcl')
) )
}) }
)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
@ -324,7 +338,6 @@ test.describe('Testing settings', () => {
await logoLink.click() await logoLink.click()
await expect(logoLink).toHaveCSS('--primary-hue', userThemeColor) await expect(logoLink).toHaveCSS('--primary-hue', userThemeColor)
}) })
} }
) )
@ -335,7 +348,7 @@ test.describe('Testing settings', () => {
// This is what makes no settings file get created // This is what makes no settings file get created
cleanProjectDir: false, cleanProjectDir: false,
}, },
async ({ page, browser: _ }, testInfo) => { async ({ page }, testInfo) => {
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
// Selectors and constants // Selectors and constants
@ -347,7 +360,6 @@ test.describe('Testing settings', () => {
// If the app loads without exploding we're in the clear // If the app loads without exploding we're in the clear
await expect(errorHeading).not.toBeVisible() await expect(errorHeading).not.toBeVisible()
await expect(projectDirLink).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 }) await page.setBodyDimensions({ width: 1200, height: 500 })
// Selectors and constants // Selectors and constants
@ -387,10 +399,12 @@ test.describe('Testing settings', () => {
// default to 264.5 // default to 264.5
themeColor: '0', 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 }) await page.setBodyDimensions({ width: 1200, height: 500 })
@ -432,8 +446,10 @@ test.describe('Testing settings', () => {
test( test(
'project settings reload on external change', 'project settings reload on external change',
{ tag: '@electron' }, { tag: '@electron' },
async ({ context, page, browserName: _ }, testInfo) => { async ({ context, page }, testInfo) => {
const { dir: projectDirName } = await context.folderSetupFn(async () => {}) const { dir: projectDirName } = await context.folderSetupFn(
async () => {}
)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
@ -466,14 +482,13 @@ test.describe('Testing settings', () => {
await changeColorFs('99') await changeColorFs('99')
await expect(logoLink).toHaveCSS('--primary-hue', '99') await expect(logoLink).toHaveCSS('--primary-hue', '99')
}) })
} }
) )
test( test(
`Closing settings modal should go back to the original file being viewed`, `Closing settings modal should go back to the original file being viewed`,
{ tag: '@electron' }, { tag: '@electron' },
async ({ context, page, browser: _ }, testInfo) => { async ({ context, page }, testInfo) => {
await context.folderSetupFn(async (dir) => { await context.folderSetupFn(async (dir) => {
const bracketDir = join(dir, 'project-000') const bracketDir = join(dir, 'project-000')
await fsp.mkdir(bracketDir, { recursive: true }) 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 test.step(`Test setup`, async () => {
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
const toastMessage = page.getByText( const toastMessage = page.getByText(`Successfully created "testDefault"`)
`Successfully created "testDefault"`
)
await expect(toastMessage).not.toBeVisible() await expect(toastMessage).not.toBeVisible()
await page await page
.getByRole('button', { name: 'Start Sketch' }) .getByRole('button', { name: 'Start Sketch' })
@ -680,9 +693,11 @@ test.describe('Testing settings', () => {
await changeUnitOfMeasureInGizmo('mm', 'Millimeters') await changeUnitOfMeasureInGizmo('mm', 'Millimeters')
await changeUnitOfMeasureInGizmo('cm', 'Centimeters') await changeUnitOfMeasureInGizmo('cm', 'Centimeters')
await changeUnitOfMeasureInGizmo('m', 'Meters') 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(() => { await context.addInitScript(() => {
localStorage.setItem( localStorage.setItem(
'persistCode', 'persistCode',
@ -746,13 +761,16 @@ test.describe('Testing settings', () => {
u.getGreatestPixDiff(sketchOriginLocation, lightThemeSegmentColor) u.getGreatestPixDiff(sketchOriginLocation, lightThemeSegmentColor)
) )
.toBeLessThan(15) .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` // Override the settings so that the theme is set to `system`
appSettings: TEST_SETTINGS_DEFAULT_THEME, appSettings: TEST_SETTINGS_DEFAULT_THEME,
}, async ({ page, homePage }) => { },
async ({ page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
// Selectors and constants // Selectors and constants
@ -791,28 +809,30 @@ test.describe('Testing settings', () => {
await expect await expect
.poll(() => streamBackgroundPixelIsColor(darkBackgroundColor)) .poll(() => streamBackgroundPixelIsColor(darkBackgroundColor))
.toBeLessThan(15) .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 // Override beforeEach test setup
// with debug panel open // with debug panel open
// but "show debug panel" set to false // but "show debug panel" set to false
appSettings: { appSettings: {
...TEST_SETTINGS, ...TEST_SETTINGS,
modeling: { ...TEST_SETTINGS.modeling, showDebugPanel: false }, modeling: { ...TEST_SETTINGS.modeling, showDebugPanel: false },
} },
}, async ({ context, page, homePage }) => { },
async ({ context, page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
await context.addInitScript( await context.addInitScript(async () => {
async ({ }) => {
localStorage.setItem( localStorage.setItem(
'persistModelingContext', 'persistModelingContext',
'{"openPanes":["debug"]}' '{"openPanes":["debug"]}'
) )
} })
)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -862,5 +882,7 @@ test.describe('Testing settings', () => {
await setShowDebugPanelTo('Off') await setShowDebugPanelTo('Off')
await expect(debugPaneButton).not.toBeVisible() await expect(debugPaneButton).not.toBeVisible()
await expect(resizeHandle).not.toBeVisible() await expect(resizeHandle).not.toBeVisible()
}) }) })
}
)
}) })

View File

@ -1,11 +1,10 @@
import { test, expect, Page } from './zoo-test' import { test, expect, Page } from './zoo-test'
import { getUtils, createProject, } from './test-utils' import { getUtils, createProject } from './test-utils'
import { join } from 'path' import { join } from 'path'
import fs from 'fs' import fs from 'fs'
test.describe('Text-to-CAD tests', () => { test.describe('Text-to-CAD tests', () => {
test('basic lego happy case', async ({ page, homePage }) => { test('basic lego happy case', async ({ page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
await test.step('Set up', async () => { await test.step('Set up', async () => {
@ -31,7 +30,6 @@ test.describe('Text-to-CAD tests', () => {
const successToastMessage = page.getByText(`Text-to-CAD successful`) const successToastMessage = page.getByText(`Text-to-CAD successful`)
await expect(successToastMessage).toBeVisible({ timeout: 15000 }) await expect(successToastMessage).toBeVisible({ timeout: 15000 })
// Hit accept. // Hit accept.
const copyToClipboardButton = page.getByRole('button', { const copyToClipboardButton = page.getByRole('button', {
name: 'Accept', name: 'Accept',
@ -51,10 +49,13 @@ test.describe('Text-to-CAD tests', () => {
await u.openDebugPanel() await u.openDebugPanel()
await u.expectCmdLog('[data-message-type="execution-done"]') await u.expectCmdLog('[data-message-type="execution-done"]')
await u.closeDebugPanel() await u.closeDebugPanel()
}) })
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 }) await page.setBodyDimensions({ width: 1000, height: 500 })
@ -91,9 +92,14 @@ test.describe('Text-to-CAD tests', () => {
timeout: 15000, timeout: 15000,
}) })
await expect(page.getByText('a 2x4 lego')).toBeVisible() 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 }) await page.setBodyDimensions({ width: 1000, height: 500 })
@ -127,9 +133,14 @@ test.describe('Text-to-CAD tests', () => {
await expect(successToastMessage).not.toBeVisible() await expect(successToastMessage).not.toBeVisible()
// Expect no code. // 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 }) await page.setBodyDimensions({ width: 1000, height: 500 })
@ -190,9 +201,14 @@ test.describe('Text-to-CAD tests', () => {
await dismissButton.click() await dismissButton.click()
// The toast should disappear. // 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 }) 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(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 }) await page.setBodyDimensions({ width: 1000, height: 500 })
@ -346,9 +367,14 @@ test.describe('Text-to-CAD tests', () => {
// old failure toast should stick around. // old failure toast should stick around.
await expect(failureToastMessage).toBeVisible() 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 }) 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`) const successToastMessage = page.getByText(`Text-to-CAD successful`)
await expect(successToastMessage).toBeVisible({ timeout: 15000 }) 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) test.setTimeout(180_000)
// skip on windows // skip on windows
test.skip( test.skip(
@ -479,10 +510,14 @@ test.describe('Text-to-CAD tests', () => {
// Expect the code to be pasted. // Expect the code to be pasted.
await expect(page.locator('.cm-content')).toContainText(`2x4`) 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,
test('can do many at once with errors, clicking dismiss error does not dismiss all', async ({ page, homePage }) => { const u = await getUtils(page) homePage,
}) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1000, height: 500 }) await page.setBodyDimensions({ width: 1000, height: 500 })

View File

@ -3,7 +3,6 @@ import { test, expect } from './zoo-test'
import { doExport, getUtils, makeTemplate } from './test-utils' import { doExport, getUtils, makeTemplate } from './test-utils'
test.fixme('Units menu', async ({ page, homePage }) => { test.fixme('Units menu', async ({ page, homePage }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -102,15 +101,8 @@ part001 = startSketchOn('-XZ')
test('Paste should not work unless an input is focused', async ({ test('Paste should not work unless an input is focused', async ({
page, page,
browserName,
homePage, 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 page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
await page await page
@ -154,7 +146,6 @@ test('Keyboard shortcuts can be viewed through the help menu', async ({
page, page,
homePage, homePage,
}) => { }) => {
const u = await getUtils(page)
await page.setBodyDimensions({ width: 1200, height: 500 }) await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene() await homePage.goToModelingScene()
@ -248,7 +239,7 @@ test('First escape in tool pops you out of tool, second exits sketch mode', asyn
test.fixme( test.fixme(
'Basic default modeling and sketch hotkeys work', 'Basic default modeling and sketch hotkeys work',
async ({ page }) => { async ({ page, homePage }) => {
const u = await getUtils(page) const u = await getUtils(page)
// This test can run long if it takes a little too long to load // This test can run long if it takes a little too long to load

View File

@ -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 { import {
fixtures, fixtures,
Fixtures, Fixtures,
AuthenticatedTronApp, AuthenticatedTronApp,
AuthenticatedApp, AuthenticatedApp,
} from './fixtures/fixtureSetup' } 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 // Our custom decorated Zoo test object. Makes it easier to add fixtures, and
// switch between web and electron if needed. // 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 // In JavaScript you cannot replace a function's body only (despite functions
// are themselves objects, which you'd expect a body property or something...) // are themselves objects, which you'd expect a body property or something...)
// So we must redefine the function and then re-attach properties. // So we must redefine the function and then re-attach properties.
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 hasTestConf = typeof objOrFn === 'object'
const fn = hasTestConf ? fnMaybe : objOrFn const fn = hasTestConf ? fnMaybe : objOrFn
@ -22,14 +85,14 @@ export function test(desc, objOrFn, fnMaybe) {
desc, desc,
hasTestConf ? objOrFn : {}, hasTestConf ? objOrFn : {},
async ( async (
{ page, context, cmdBar, editor, toolbar, scene, homePage }, { page, context, cmdBar, editor, toolbar, scene, homePage, ...rest },
testInfo testInfo
) => { ) => {
// To switch to web, use PLATFORM=web environment variable. // To switch to web, use PLATFORM=web environment variable.
// Only use this for debugging, since the playwright tracer is busted // Only use this for debugging, since the playwright tracer is busted
// for electron. // for electron.
let tronApp; let tronApp
if (process.env.PLATFORM === 'web') { if (process.env.PLATFORM === 'web') {
tronApp = new AuthenticatedApp(context, page, testInfo) tronApp = new AuthenticatedApp(context, page, testInfo)
@ -38,25 +101,37 @@ export function test(desc, objOrFn, fnMaybe) {
} }
const fixtures: Fixtures = { cmdBar, editor, toolbar, scene, homePage } const fixtures: Fixtures = { cmdBar, editor, toolbar, scene, homePage }
if (tronApp instanceof AuthenticatedTronApp) {
const options = { const options = {
fixtures, fixtures,
}
if (hasTestConf) {
Object.assign(options, {
appSettings: objOrFn?.appSettings, appSettings: objOrFn?.appSettings,
cleanProjectDir: objOrFn?.cleanProjectDir, cleanProjectDir: objOrFn?.cleanProjectDir,
})
} }
await tronApp.initialise(options) await tronApp.initialise(options)
} else {
await tronApp.initialise('')
}
// We need to patch this because addInitScript will bind too late in our // 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 // electron tests, never running. We need to call reload() after each call
// to guarantee it runs. // to guarantee it runs.
const oldContextAddInitScript = tronApp.context.addInitScript const oldContextAddInitScript = tronApp.context.addInitScript
tronApp.context.addInitScript = async function (a, b) { 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 oldContextAddInitScript.apply(this, [a, b])
await tronApp.page.reload() await tronApp.page.reload()
} }
// No idea why we mix and match page and context's addInitScript but we do // No idea why we mix and match page and context's addInitScript but we do
const oldPageAddInitScript = tronApp.page.addInitScript 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 oldPageAddInitScript.apply(this, [a, b])
await tronApp.page.reload() await tronApp.page.reload()
} }
@ -75,45 +150,73 @@ export function test(desc, objOrFn, fnMaybe) {
return 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) await app.resizeWindow(dims.width, dims.height)
}, dims) }, 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) await window.electron.resizeWindow(dims.width, dims.height)
window.document.body.style.width = dims.width + 'px' window.document.body.style.width = dims.width + 'px'
window.document.body.style.height = dims.height + 'px' window.document.body.style.height = dims.height + 'px'
window.document.documentElement.style.width = dims.width + 'px' window.document.documentElement.style.width = dims.width + 'px'
window.document.documentElement.style.height = dims.height + 'px' window.document.documentElement.style.height = dims.height + 'px'
}, dims) },
dims
)
} }
// We need to expose this in order for some tests that require folder // We need to expose this in order for some tests that require folder
// creation. Before they used to do this by their own electronSetup({...}) // creation. Before they used to do this by their own electronSetup({...})
// calls. // calls.
if (tronApp instanceof AuthenticatedTronApp) {
tronApp.context.folderSetupFn = function (fn) { tronApp.context.folderSetupFn = function (fn) {
return fn(tronApp.dir).then(() => ({ dir: tronApp.dir })) return fn(tronApp.dir).then(() => ({
dir: tronApp.dir,
}))
}
} }
// 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( await fn(
{ {
context: tronApp.context, context: tronApp.context,
page: tronApp.page, page: tronApp.page,
electronApp: tronApp.electronApp, electronApp:
tronApp instanceof AuthenticatedTronApp
? tronApp.electronApp
: undefined,
...fixtures, ...fixtures,
...rest,
}, },
testInfo testInfo
) )
}
testInfo.tronApp = tronApp testInfo.tronApp =
tronApp instanceof AuthenticatedTronApp ? tronApp : undefined
} }
) )
} }
type ZooTest = typeof test
test.describe = pwTestFnWithFixtures.describe test.describe = pwTestFnWithFixtures.describe
test.beforeEach = pwTestFnWithFixtures.beforeEach test.beforeEach = pwTestFnWithFixtures.beforeEach
test.afterEach = pwTestFnWithFixtures.afterEach test.afterEach = pwTestFnWithFixtures.afterEach
test.step = pwTestFnWithFixtures.step test.step = pwTestFnWithFixtures.step
test.skip = pwTestFnWithFixtures.skip test.skip = pwTestFnWithFixtures.skip
test.setTimeout = pwTestFnWithFixtures.setTimeout 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

View File

@ -13,7 +13,7 @@ export default defineConfig({
/* Do not retry */ /* Do not retry */
retries: 0, retries: 0,
/* Different amount of parallelism on CI and local. */ /* Different amount of parallelism on CI and local. */
workers: 4, workers: 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [ reporter: [
['dot'], ['dot'],

View File

@ -45,7 +45,7 @@ export default class CodeManager {
} else if (storedCode === null) { } else if (storedCode === null) {
this.code = bracket this.code = bracket
} else { } else {
this.code = storedCode this.code = storedCode || ''
} }
} }
@ -58,7 +58,7 @@ export default class CodeManager {
} }
localStoragePersistCode(): string { localStoragePersistCode(): string {
return safeLSGetItem(PERSIST_CODE_KEY) return safeLSGetItem(PERSIST_CODE_KEY) || ''
} }
registerCallBacks({ setCode }: { setCode: (arg: string) => void }) { registerCallBacks({ setCode }: { setCode: (arg: string) => void }) {
@ -169,7 +169,7 @@ export default class CodeManager {
} }
function safeLSGetItem(key: string) { function safeLSGetItem(key: string) {
if (typeof window === 'undefined') return null if (typeof window === 'undefined') return
return localStorage?.getItem(key) return localStorage?.getItem(key)
} }

View File

@ -134,12 +134,15 @@ app.on('ready', (event, data) => {
// There is just not enough code to warrant it and further abstracts everything // There is just not enough code to warrant it and further abstracts everything
// which is already quite abstracted // 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) => { app.resizeWindow = async (width: number, height: number) => {
return mainWindow?.setSize(width, height) return mainWindow?.setSize(width, height)
} }
ipcMain.handle('app.resizeWindow', (event, data) => { ipcMain.handle('app.resizeWindow', (event, data) => {
return mainWindow?.setSize(...data) return mainWindow?.setSize(data[0], data[1])
}) })
ipcMain.handle('app.getPath', (event, data) => { ipcMain.handle('app.getPath', (event, data) => {

View File

@ -20,12 +20,16 @@ const loginWithDeviceFlow = (): Promise<string> =>
ipcRenderer.invoke('loginWithDeviceFlow') ipcRenderer.invoke('loginWithDeviceFlow')
const onUpdateDownloaded = ( const onUpdateDownloaded = (
callback: (value: { version: string; releaseNotes: string }) => void 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 = ( const onUpdateDownloadStart = (
callback: (value: { version: string }) => void 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) => 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 appRestart = () => ipcRenderer.invoke('app.restart')
const isMac = os.platform() === 'darwin' const isMac = os.platform() === 'darwin'