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(
'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.

View File

@ -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'

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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,8 +24,8 @@ test(
path.join(bracketDir, 'main.kcl')
),
])
}),
await page.setBodyDimensions({ width: 1200, height: 500 })
})
await page.setBodyDimensions({ width: 1200, height: 500 })
page.on('console', console.log)

View File

@ -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',

View File

@ -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,

View File

@ -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))
},
}

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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 })

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 ({
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)

View File

@ -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

View File

@ -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 () => {
const text = await editor.textContent()
return toNormalizedCode(text)
}).toContain(toNormalizedCode(code))
return expect
.poll(async () => {
const text = await editor.textContent()
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,

View File

@ -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)

View File

@ -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 = [

View File

@ -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 }) => {

View File

@ -11,62 +11,68 @@ 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 () => {
await context.addInitScript((code) => {
window.localStorage.setItem('persistCode', code)
}, bracket)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
})
// Locators and constants
const newSample = {
file: 'car-wheel' + FILE_EXT,
title: 'Car Wheel',
}
const commandBarButton = page.getByRole('button', { name: 'Commands' })
const samplesCommandOption = page.getByRole('option', {
name: 'Open Sample',
})
const commandSampleOption = page.getByRole('option', {
name: newSample.title,
exact: true,
})
const commandMethodArgButton = page.getByRole('button', {
name: 'Method',
})
const commandMethodOption = (name: 'Overwrite' | 'Create new file') =>
page.getByRole('option', {
name,
await test.step(`Test setup`, async () => {
await context.addInitScript((code) => {
window.localStorage.setItem('persistCode', code)
}, bracket)
await page.setBodyDimensions({ width: 1200, height: 500 })
await homePage.goToModelingScene()
})
const warningText = page.getByText('Overwrite current file and units?')
const confirmButton = page.getByRole('button', { name: 'Submit command' })
const unitsToast = (unit: UnitLength_type) =>
page.getByText(`Set default unit to "${unit}" for this project`)
await test.step(`Precondition: check the initial code`, async () => {
await u.openKclCodePanel()
await editor.scrollToText(bracket.split('\n')[0])
await editor.expectEditor.toContain(bracket.split('\n')[0])
// Locators and constants
const newSample = {
file: 'car-wheel' + FILE_EXT,
title: 'Car Wheel',
}
const commandBarButton = page.getByRole('button', { name: 'Commands' })
const samplesCommandOption = page.getByRole('option', {
name: 'Open Sample',
})
const commandSampleOption = page.getByRole('option', {
name: newSample.title,
exact: true,
})
const commandMethodArgButton = page.getByRole('button', {
name: 'Method',
})
const commandMethodOption = (name: 'Overwrite' | 'Create new file') =>
page.getByRole('option', {
name,
})
const warningText = page.getByText('Overwrite current file and units?')
const confirmButton = page.getByRole('button', { name: 'Submit command' })
const unitsToast = (unit: UnitLength_type) =>
page.getByText(`Set default unit to "${unit}" for this project`)
await test.step(`Precondition: check the initial code`, async () => {
await u.openKclCodePanel()
await editor.scrollToText(bracket.split('\n')[0])
await editor.expectEditor.toContain(bracket.split('\n')[0])
})
await test.step(`Load a KCL sample with the command palette`, async () => {
await commandBarButton.click()
await samplesCommandOption.click()
await commandSampleOption.click()
await commandMethodArgButton.click()
await expect(commandMethodOption('Create new file')).not.toBeVisible()
await commandMethodOption('Overwrite').click()
await expect(warningText).toBeVisible()
await confirmButton.click()
await editor.expectEditor.toContain('// ' + newSample.title)
await expect(unitsToast('in')).toBeVisible()
})
})
await test.step(`Load a KCL sample with the command palette`, async () => {
await commandBarButton.click()
await samplesCommandOption.click()
await commandSampleOption.click()
await commandMethodArgButton.click()
await expect(commandMethodOption('Create new file')).not.toBeVisible()
await commandMethodOption('Overwrite').click()
await expect(warningText).toBeVisible()
await confirmButton.click()
await editor.expectEditor.toContain('// ' + newSample.title)
await expect(unitsToast('in')).toBeVisible()
}) })
/**
* Note this test implicitly depends on the KCL samples:
* "car-wheel.kcl": https://github.com/KittyCAD/kcl-samples/blob/main/car-wheel/car-wheel.kcl
@ -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 })

View File

@ -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,
})
}
})
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

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 {
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,41 +85,53 @@ 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') {
if (process.env.PLATFORM === 'web') {
tronApp = new AuthenticatedApp(context, page, testInfo)
} else {
tronApp = new AuthenticatedTronApp(context, page, testInfo)
}
const fixtures: Fixtures = { cmdBar, editor, toolbar, scene, homePage }
const options = {
fixtures,
appSettings: objOrFn?.appSettings,
cleanProjectDir: objOrFn?.cleanProjectDir,
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('')
}
await tronApp.initialise(options)
// 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) => {
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)
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
)
}
// 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.
tronApp.context.folderSetupFn = function (fn) {
return fn(tronApp.dir).then(() => ({ dir: tronApp.dir }))
if (tronApp instanceof AuthenticatedTronApp) {
tronApp.context.folderSetupFn = function (fn) {
return fn(tronApp.dir).then(() => ({
dir: tronApp.dir,
}))
}
}
await fn(
{
context: tronApp.context,
page: tronApp.page,
electronApp: tronApp.electronApp,
...fixtures,
},
testInfo
)
// 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 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

View File

@ -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'],

View File

@ -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)
}

View File

@ -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) => {

View File

@ -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'