Get sketch-tests.spec.ts passing in electron
This commit is contained in:
@ -20,11 +20,11 @@ export class AuthenticatedApp {
|
||||
public readonly page: Page
|
||||
public readonly context: BrowserContext
|
||||
public readonly testInfo: TestInfo
|
||||
public readonly viewPortSize = { width: 1000, height: 500 }
|
||||
public readonly viewPortSize = { width: 1200, height: 500 }
|
||||
|
||||
constructor(context: BrowserContext, page: Page, testInfo: TestInfo) {
|
||||
this.page = page
|
||||
this.context = context
|
||||
this.page = page
|
||||
this.testInfo = testInfo
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ export class AuthenticatedApp {
|
||||
}
|
||||
}
|
||||
|
||||
interface Fixtures {
|
||||
export interface Fixtures {
|
||||
app: AuthenticatedApp
|
||||
tronApp: AuthenticatedTronApp
|
||||
cmdBar: CmdBarFixture
|
||||
@ -61,9 +61,10 @@ interface Fixtures {
|
||||
export class AuthenticatedTronApp {
|
||||
public readonly _page: Page
|
||||
public page: Page
|
||||
public readonly context: BrowserContext
|
||||
public context: BrowserContext
|
||||
public readonly testInfo: TestInfo
|
||||
public electronApp?: ElectronApplication
|
||||
public readonly viewPortSize = { width: 1200, height: 500 }
|
||||
|
||||
constructor(context: BrowserContext, page: Page, testInfo: TestInfo) {
|
||||
this._page = page
|
||||
@ -79,15 +80,20 @@ export class AuthenticatedTronApp {
|
||||
appSettings?: Partial<SaveSettingsPayload>
|
||||
} = { fixtures: {} }
|
||||
) {
|
||||
const { electronApp, page } = await setupElectron({
|
||||
const { electronApp, page, context } = await setupElectron({
|
||||
testInfo: this.testInfo,
|
||||
folderSetupFn: arg.folderSetupFn,
|
||||
cleanProjectDir: arg.cleanProjectDir,
|
||||
appSettings: arg.appSettings,
|
||||
})
|
||||
this.page = page
|
||||
this.context = context
|
||||
this.electronApp = electronApp
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
// Setup localStorage, addCookies, reload
|
||||
await setup(this.context, this.page, this.testInfo)
|
||||
|
||||
await page.setViewportSize(this.viewPortSize)
|
||||
|
||||
for (const key of unsafeTypedKeys(arg.fixtures)) {
|
||||
const fixture = arg.fixtures[key]
|
||||
@ -110,13 +116,7 @@ export class AuthenticatedTronApp {
|
||||
})
|
||||
}
|
||||
|
||||
export const test = base.extend<Fixtures>({
|
||||
app: async ({ page, context }, use, testInfo) => {
|
||||
await use(new AuthenticatedApp(context, page, testInfo))
|
||||
},
|
||||
tronApp: async ({ page, context }, use, testInfo) => {
|
||||
await use(new AuthenticatedTronApp(context, page, testInfo))
|
||||
},
|
||||
export const fixtures = {
|
||||
cmdBar: async ({ page }, use) => {
|
||||
await use(new CmdBarFixture(page))
|
||||
},
|
||||
@ -129,13 +129,7 @@ export const test = base.extend<Fixtures>({
|
||||
scene: async ({ page }, use) => {
|
||||
await use(new SceneFixture(page))
|
||||
},
|
||||
homePage: async ({ page }, use) => {
|
||||
homePage: async ({ page }, use, testInfo) => {
|
||||
await use(new HomePageFixture(page))
|
||||
},
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
|
||||
export { expect } from '@playwright/test'
|
||||
}
|
||||
|
@ -14,10 +14,14 @@ interface HomePageState {
|
||||
export class HomePageFixture {
|
||||
public page: Page
|
||||
|
||||
projectSection!: Locator
|
||||
projectCard!: Locator
|
||||
projectCardTitle!: Locator
|
||||
projectCardFile!: Locator
|
||||
projectCardFolder!: Locator
|
||||
projectButtonNew!: Locator
|
||||
projectButtonContinue!: Locator
|
||||
projectTextName!: Locator
|
||||
sortByDateBtn!: Locator
|
||||
sortByNameBtn!: Locator
|
||||
|
||||
@ -28,11 +32,17 @@ export class HomePageFixture {
|
||||
reConstruct = (page: Page) => {
|
||||
this.page = page
|
||||
|
||||
this.projectSection = this.page.getByTestId('home-section')
|
||||
|
||||
this.projectCard = this.page.getByTestId('project-link')
|
||||
this.projectCardTitle = this.page.getByTestId('project-title')
|
||||
this.projectCardFile = this.page.getByTestId('project-file-count')
|
||||
this.projectCardFolder = this.page.getByTestId('project-folder-count')
|
||||
|
||||
this.projectButtonNew = this.page.getByTestId('home-new-file')
|
||||
this.projectTextName = this.page.getByTestId('cmd-bar-arg-value')
|
||||
this.projectButtonContinue = this.page.getByRole('button', { name: 'Continue' })
|
||||
|
||||
this.sortByDateBtn = this.page.getByTestId('home-sort-by-modified')
|
||||
this.sortByNameBtn = this.page.getByTestId('home-sort-by-name')
|
||||
}
|
||||
@ -91,10 +101,22 @@ export class HomePageFixture {
|
||||
.toEqual(expectedState)
|
||||
}
|
||||
|
||||
createAndGoToProject = async (projectTitle: string) => {
|
||||
await expect(this.projectSection).not.toHaveText('Loading your Projects...')
|
||||
await this.projectButtonNew.click()
|
||||
await this.projectTextName.click()
|
||||
await this.projectTextName.fill(projectTitle)
|
||||
await this.projectButtonContinue.click()
|
||||
}
|
||||
|
||||
openProject = async (projectTitle: string) => {
|
||||
const projectCard = this.projectCard.locator(
|
||||
this.page.getByText(projectTitle)
|
||||
)
|
||||
await projectCard.click()
|
||||
}
|
||||
|
||||
goToModelingScene = async (name?: string = "testDefault") => {
|
||||
await this.createAndGoToProject(name)
|
||||
}
|
||||
}
|
||||
|
12
e2e/playwright/null.spec.ts
Normal file
12
e2e/playwright/null.spec.ts
Normal file
@ -0,0 +1,12 @@
|
||||
// These tests are meant to simply test starting and stopping the electron
|
||||
// application, check it can make it to the project pane, and nothing more.
|
||||
// It also tests our test wrappers are working.
|
||||
// Additionally this serves as a nice minimal example.
|
||||
|
||||
import { test as testZoo, expect } from './fixtures/fixtureSetup'
|
||||
|
||||
testZoo.describe('Open the application', () => {
|
||||
testZoo('see the project view', async ({ tronApp: { page, context } }) => {
|
||||
await expect(page.getByTestId('home-section')).toBeVisible()
|
||||
})
|
||||
})
|
@ -1,5 +1,7 @@
|
||||
import { test, expect, Page } from '@playwright/test'
|
||||
import { test as test2, expect as expect2 } from './fixtures/fixtureSetup'
|
||||
import { test, expect, Page } from './zoo-test'
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import { HomePageFixture } from './fixtures/homePageFixture'
|
||||
|
||||
import {
|
||||
getMovementUtils,
|
||||
@ -10,10 +12,6 @@ import {
|
||||
} from './test-utils'
|
||||
import { uuidv4, roundOff } from 'lib/utils'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
})
|
||||
|
||||
test.afterEach(async ({ page }, testInfo) => {
|
||||
await tearDown(page, testInfo)
|
||||
})
|
||||
@ -22,6 +20,7 @@ test.describe('Sketch tests', () => {
|
||||
test('multi-sketch file shows multiple Edit Sketch buttons', async ({
|
||||
page,
|
||||
context,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
const selectionsSnippets = {
|
||||
@ -81,7 +80,7 @@ test.describe('Sketch tests', () => {
|
||||
)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
@ -108,6 +107,8 @@ 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)
|
||||
await page.addInitScript(async () => {
|
||||
@ -120,12 +121,9 @@ test.describe('Sketch tests', () => {
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await expect(async () => {
|
||||
await page.mouse.click(700, 200)
|
||||
await page.getByText('tangentialArcTo([24.95, -5.38], %)').click()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Edit Sketch' })
|
||||
@ -151,6 +149,7 @@ test.describe('Sketch tests', () => {
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
await expect(async () => {
|
||||
await page.mouse.move(700, 200, { step: 25 })
|
||||
await page.mouse.click(700, 200)
|
||||
|
||||
await expect.poll(u.normalisedEditorCode, { timeout: 1000 })
|
||||
@ -161,7 +160,7 @@ test.describe('Sketch tests', () => {
|
||||
`)
|
||||
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
||||
})
|
||||
test('Can exit selection of face', async ({ page }) => {
|
||||
test('Can exit selection of face', async ({ page, homePage }) => {
|
||||
// Load the app with the code panes
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem('persistCode', ``)
|
||||
@ -170,7 +169,7 @@ test.describe('Sketch tests', () => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||
await expect(
|
||||
@ -187,6 +186,7 @@ test.describe('Sketch tests', () => {
|
||||
test.describe('Can edit segments by dragging their handles', () => {
|
||||
const doEditSegmentsByDraggingHandle = async (
|
||||
page: Page,
|
||||
homePage: HomePageFixture,
|
||||
openPanes: string[]
|
||||
) => {
|
||||
// Load the app with the code panes
|
||||
@ -202,9 +202,8 @@ test.describe('Sketch tests', () => {
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
@ -318,7 +317,7 @@ test.describe('Sketch tests', () => {
|
||||
|> line([1.97, 2.06], %)
|
||||
|> close(%)`)
|
||||
}
|
||||
test('code pane open at start-handles', async ({ page }) => {
|
||||
test('code pane open at start-handles', async ({ page, homePage }) => {
|
||||
// Load the app with the code panes
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
@ -331,10 +330,10 @@ test.describe('Sketch tests', () => {
|
||||
})
|
||||
)
|
||||
})
|
||||
await doEditSegmentsByDraggingHandle(page, ['code'])
|
||||
await doEditSegmentsByDraggingHandle(page, homePage, ['code'])
|
||||
})
|
||||
|
||||
test('code pane closed at start-handles', async ({ page }) => {
|
||||
test('code pane closed at start-handles', async ({ page, homePage }) => {
|
||||
// Load the app with the code panes
|
||||
await page.addInitScript(async (persistModelingContext) => {
|
||||
localStorage.setItem(
|
||||
@ -342,12 +341,13 @@ test.describe('Sketch tests', () => {
|
||||
JSON.stringify({ openPanes: [] })
|
||||
)
|
||||
}, PERSIST_MODELING_CONTEXT)
|
||||
await doEditSegmentsByDraggingHandle(page, [])
|
||||
await doEditSegmentsByDraggingHandle(page, homePage, [])
|
||||
})
|
||||
})
|
||||
|
||||
test('Can edit a circle center and radius by dragging its handles', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
@ -358,9 +358,8 @@ test.describe('Sketch tests', () => {
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
@ -434,6 +433,7 @@ test.describe('Sketch tests', () => {
|
||||
})
|
||||
test('Can edit a sketch that has been extruded in the same pipe', async ({
|
||||
page,
|
||||
homePage
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
@ -448,9 +448,8 @@ test.describe('Sketch tests', () => {
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
@ -504,11 +503,11 @@ test.describe('Sketch tests', () => {
|
||||
await page.waitForTimeout(100)
|
||||
|
||||
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
|
||||
await page.waitForTimeout(100)
|
||||
await page.dragAndDrop('#stream', '#stream', {
|
||||
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
|
||||
targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX },
|
||||
sourcePosition: { x: lineEnd.x - 15, y: lineEnd.y },
|
||||
targetPosition: { x: lineEnd.x, y: lineEnd.y + 15 },
|
||||
})
|
||||
await page.waitForTimeout(100)
|
||||
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||
prevContent = await page.locator('.cm-content').innerText()
|
||||
|
||||
@ -517,8 +516,8 @@ test.describe('Sketch tests', () => {
|
||||
await page.dragAndDrop('#stream', '#stream', {
|
||||
sourcePosition: { x: tangentEnd.x + 10, y: tangentEnd.y - 5 },
|
||||
targetPosition: {
|
||||
x: tangentEnd.x + dragPX,
|
||||
y: tangentEnd.y + dragPX,
|
||||
x: tangentEnd.x,
|
||||
y: tangentEnd.y - 15,
|
||||
},
|
||||
})
|
||||
await page.waitForTimeout(100)
|
||||
@ -528,8 +527,8 @@ test.describe('Sketch tests', () => {
|
||||
await expect(page.locator('.cm-content'))
|
||||
.toHaveText(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([7.12, -12.68], %)
|
||||
|> line([15.39, -2.78], %)
|
||||
|> tangentialArcTo([27.6, -3.05], %)
|
||||
|> line([12.68, -1.09], %)
|
||||
|> tangentialArcTo([24.89, 0.68], %)
|
||||
|> close(%)
|
||||
|> extrude(5, %)
|
||||
`)
|
||||
@ -537,6 +536,7 @@ test.describe('Sketch tests', () => {
|
||||
|
||||
test('Can edit a sketch that has been revolved in the same pipe', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
@ -551,9 +551,8 @@ test.describe('Sketch tests', () => {
|
||||
)
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
@ -636,12 +635,13 @@ test.describe('Sketch tests', () => {
|
||||
|> close(%)
|
||||
|> revolve({ axis = "X" }, %)`)
|
||||
})
|
||||
test('Can add multiple sketches', async ({ page }) => {
|
||||
test('Can add multiple sketches', async ({ page, homePage }) => {
|
||||
const u = await getUtils(page)
|
||||
|
||||
const viewportSize = { width: 1200, height: 500 }
|
||||
await page.setViewportSize(viewportSize)
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
await u.openDebugPanel()
|
||||
|
||||
const center = { x: viewportSize.width / 2, y: viewportSize.height / 2 }
|
||||
@ -738,7 +738,6 @@ test.describe('Sketch tests', () => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await u.openDebugPanel()
|
||||
|
||||
const code = `sketch001 = startSketchOn('-XZ')
|
||||
@ -820,16 +819,19 @@ test.describe('Sketch tests', () => {
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.removeCurrentCode()
|
||||
}
|
||||
test('[0, 100, 100]', async ({ page }) => {
|
||||
test('[0, 100, 100]', async ({ page, homePage }) => {
|
||||
await homePage.goToModelingScene()
|
||||
await doSnapAtDifferentScales(page, [0, 100, 100], 0.01)
|
||||
})
|
||||
|
||||
test('[0, 10000, 10000]', async ({ page }) => {
|
||||
test('[0, 10000, 10000]', async ({ page, homePage }) => {
|
||||
await homePage.goToModelingScene()
|
||||
await doSnapAtDifferentScales(page, [0, 10000, 10000])
|
||||
})
|
||||
})
|
||||
test('exiting a close extrude, has the extrude button enabled ready to go', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
// this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
|
||||
await page.addInitScript(async () => {
|
||||
@ -849,7 +851,7 @@ test.describe('Sketch tests', () => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// wait for execution done
|
||||
await u.openDebugPanel()
|
||||
@ -885,7 +887,7 @@ test.describe('Sketch tests', () => {
|
||||
timeout: 10_000,
|
||||
})
|
||||
})
|
||||
test("Existing sketch with bad code delete user's code", async ({ page }) => {
|
||||
test("Existing sketch with bad code delete user's code", async ({ page, homePage }) => {
|
||||
// this was a regression https://github.com/KittyCAD/modeling-app/issues/2832
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
@ -905,7 +907,7 @@ extrude001 = extrude(5, sketch001)
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
@ -1049,12 +1051,8 @@ sketch002 = startSketchOn(extrude001, 'END')
|
||||
|
||||
test('empty-scene default-planes act as expected', async ({
|
||||
page,
|
||||
browserName,
|
||||
homePage,
|
||||
}) => {
|
||||
test.skip(
|
||||
browserName === 'webkit',
|
||||
'Skip on Safari until `window.tearDown` is working there'
|
||||
)
|
||||
/**
|
||||
* Tests the following things
|
||||
* 1) The the planes are there on load because the scene is empty
|
||||
@ -1067,9 +1065,7 @@ sketch002 = startSketchOn(extrude001, 'END')
|
||||
*/
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
@ -1117,7 +1113,7 @@ sketch002 = startSketchOn(extrude001, 'END')
|
||||
|
||||
// click start Sketch
|
||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||
await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y, { steps: 5 })
|
||||
await page.mouse.move(XYPlanePoint.x, XYPlanePoint.y, { steps: 50 })
|
||||
const hoveredColor: [number, number, number] = [93, 93, 127]
|
||||
// now that we're expecting the user to select a plan, it does respond to hover
|
||||
await expect
|
||||
@ -1144,8 +1140,6 @@ sketch002 = startSketchOn(extrude001, 'END')
|
||||
`
|
||||
)
|
||||
})
|
||||
await page.reload()
|
||||
await u.waitForAuthSkipAppStart()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
@ -1159,12 +1153,8 @@ sketch002 = startSketchOn(extrude001, 'END')
|
||||
|
||||
test('Can attempt to sketch on revolved face', async ({
|
||||
page,
|
||||
browserName,
|
||||
homePage,
|
||||
}) => {
|
||||
test.skip(
|
||||
browserName === 'webkit',
|
||||
'Skip on Safari until `window.tearDown` is working there'
|
||||
)
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
@ -1191,7 +1181,7 @@ sketch002 = startSketchOn(extrude001, 'END')
|
||||
)
|
||||
})
|
||||
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
@ -1223,6 +1213,7 @@ sketch002 = startSketchOn(extrude001, 'END')
|
||||
|
||||
test('Can sketch on face when user defined function was used in the sketch', async ({
|
||||
page,
|
||||
homePage,
|
||||
}) => {
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
@ -1279,7 +1270,7 @@ const rail = startSketchOn('XZ')
|
||||
|
||||
const center = { x: 600, y: 250 }
|
||||
const rectangleSize = 20
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
// Start a sketch
|
||||
await page.getByRole('button', { name: 'Start Sketch' }).click()
|
||||
@ -1318,27 +1309,26 @@ const rail = startSketchOn('XZ')
|
||||
})
|
||||
})
|
||||
|
||||
test2.describe('Sketch mode should be toleratant to syntax errors', () => {
|
||||
test2(
|
||||
test.describe('Sketch mode should be toleratant to syntax errors', () => {
|
||||
test(
|
||||
'adding a syntax error, recovers after fixing',
|
||||
{ tag: ['@skipWin'] },
|
||||
async ({ app, scene, editor, toolbar }) => {
|
||||
test.skip(
|
||||
process.platform === 'win32',
|
||||
'a codemirror error appears in this test only on windows, that causes the test to fail only because of our "no new error" logic, but it can not be replicated locally'
|
||||
)
|
||||
const file = await app.getInputFile('e2e-can-sketch-on-chamfer.kcl')
|
||||
await app.initialise(file)
|
||||
async ({ page, homePage, context, scene, editor, toolbar }) => {
|
||||
const file = await fs.readFile(path.resolve(__dirname, '../../', './src/wasm-lib/tests/executor/inputs/e2e-can-sketch-on-chamfer.kcl'), 'utf-8')
|
||||
await context.addInitScript((file) => {
|
||||
localStorage.setItem('persistCode', file)
|
||||
}, file)
|
||||
await homePage.goToModelingScene()
|
||||
|
||||
const [objClick] = scene.makeMouseHelpers(600, 250)
|
||||
const arrowHeadLocation = { x: 604, y: 129 } as const
|
||||
const arrowHeadLocation = { x: 706, y: 129 } as const
|
||||
const arrowHeadWhite: [number, number, number] = [255, 255, 255]
|
||||
const backgroundGray: [number, number, number] = [28, 28, 28]
|
||||
const verifyArrowHeadColor = async (c: [number, number, number]) =>
|
||||
scene.expectPixelColor(c, arrowHeadLocation, 15)
|
||||
|
||||
await test.step('check chamfer selection changes cursor positon', async () => {
|
||||
await expect2(async () => {
|
||||
await expect(async () => {
|
||||
// sometimes initial click doesn't register
|
||||
await objClick()
|
||||
await editor.expectActiveLinesToBe([
|
||||
@ -1374,7 +1364,7 @@ test2.describe('Sketch mode should be toleratant to syntax errors', () => {
|
||||
// this checks sketch segments have been drawn
|
||||
await verifyArrowHeadColor(arrowHeadWhite)
|
||||
})
|
||||
await app.page.waitForTimeout(100)
|
||||
await page.waitForTimeout(100)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -798,6 +798,8 @@ export async function tearDown(page: Page, testInfo: TestInfo) {
|
||||
// It seems it's best to give the browser about 3s to close things
|
||||
// It's not super reliable but we have no real other choice for now
|
||||
await page.waitForTimeout(3000)
|
||||
|
||||
await testInfo.tronApp.close()
|
||||
}
|
||||
|
||||
// settingsOverrides may need to be augmented to take more generic items,
|
||||
@ -887,8 +889,10 @@ export async function setupElectron({
|
||||
? { executablePath: process.env.ELECTRON_OVERRIDE_DIST_PATH + 'electron' }
|
||||
: {}),
|
||||
})
|
||||
|
||||
const context = electronApp.context()
|
||||
const page = await electronApp.firstWindow()
|
||||
|
||||
context.on('console', console.log)
|
||||
page.on('console', console.log)
|
||||
|
||||
@ -924,7 +928,7 @@ export async function setupElectron({
|
||||
|
||||
await setup(context, page)
|
||||
|
||||
return { electronApp, page, dir: projectDirName }
|
||||
return { electronApp, page, context, dir: projectDirName }
|
||||
}
|
||||
|
||||
function failOnConsoleErrors(page: Page, testInfo?: TestInfo) {
|
||||
|
54
e2e/playwright/zoo-test.ts
Normal file
54
e2e/playwright/zoo-test.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { test as playwrightTestFn } from '@playwright/test'
|
||||
import { fixtures, Fixtures, AuthenticatedTronApp } from './fixtures/fixtureSetup'
|
||||
export { expect, Page, BrowserContext, TestInfo } from '@playwright/test'
|
||||
|
||||
// Our custom decorated Zoo test object. Makes it easier to add fixtures, and
|
||||
// switch between web and electron if needed.
|
||||
const pwTestFnWithFixtures = playwrightTestFn.extend<Fixtures>(fixtures)
|
||||
|
||||
export function test(desc, objOrFn, fnMaybe) {
|
||||
const hasTestConf = typeof objOrFn === 'object'
|
||||
const fn = hasTestConf ? fnMaybe : objOrFn
|
||||
|
||||
return pwTestFnWithFixtures(desc, hasTestConf ? objOrFn : {}, async ({ page, context, cmdBar, editor, toolbar, scene, homePage }, testInfo) => {
|
||||
// To switch to web, change this to AuthenticatedApp from fixtureSetup.ts
|
||||
const tronApp = new AuthenticatedTronApp(
|
||||
context,
|
||||
page,
|
||||
testInfo
|
||||
)
|
||||
|
||||
const fixtures: Fixtures = { cmdBar, editor, toolbar, scene, homePage }
|
||||
await tronApp.initialise({ fixtures })
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
await oldPageAddInitScript.apply(this, [a, b])
|
||||
await tronApp.page.reload()
|
||||
}
|
||||
|
||||
await fn({
|
||||
context: tronApp.context,
|
||||
page: tronApp.page,
|
||||
...fixtures
|
||||
}, testInfo)
|
||||
|
||||
testInfo.tronApp = tronApp
|
||||
})
|
||||
}
|
||||
|
||||
test.describe = pwTestFnWithFixtures.describe
|
||||
test.beforeEach = pwTestFnWithFixtures.beforeEach
|
||||
test.afterEach = pwTestFnWithFixtures.afterEach
|
||||
test.step = pwTestFnWithFixtures.step
|
||||
test.skip = pwTestFnWithFixtures.skip
|
@ -103,7 +103,9 @@
|
||||
"generate:machine-api": "npx openapi-typescript ./openapi/machine-api.json -o src/lib/machine-api.d.ts",
|
||||
"tron:start": "electron-forge start",
|
||||
"tron:package": "electron-forge package",
|
||||
"tron:test": "NODE_ENV=development yarn playwright test --config=playwright.electron.config.ts --grep=@electron",
|
||||
"tron:make": "electron-forge make",
|
||||
"tron:publish": "electron-forge publish",
|
||||
"tron:test": "NODE_ENV=development yarn playwright test --config=playwright.electron.config.ts --grep-invert='@snapshot'",
|
||||
"tronb:vite": "vite build -c vite.main.config.ts && vite build -c vite.preload.config.ts && vite build -c vite.renderer.config.ts",
|
||||
"tronb:package": "electron-builder --config electron-builder.yml",
|
||||
"test-setup": "yarn install && yarn build:wasm",
|
||||
|
@ -57,6 +57,10 @@ export default class CodeManager {
|
||||
return this._code
|
||||
}
|
||||
|
||||
localStoragePersistCode(): string {
|
||||
return safeLSGetItem(PERSIST_CODE_KEY)
|
||||
}
|
||||
|
||||
registerCallBacks({ setCode }: { setCode: (arg: string) => void }) {
|
||||
this.#updateState = setCode
|
||||
}
|
||||
|
@ -87,12 +87,13 @@ export const fileLoader: LoaderFunction = async (
|
||||
)
|
||||
const isBrowserProject = params.id === decodeURIComponent(BROWSER_PATH)
|
||||
|
||||
let code = ''
|
||||
|
||||
if (!isBrowserProject && projectPathData) {
|
||||
const { projectName, projectPath, currentFileName, currentFilePath } =
|
||||
projectPathData
|
||||
|
||||
const urlObj = new URL(routerData.request.url)
|
||||
let code = ''
|
||||
|
||||
if (!urlObj.pathname.endsWith('/settings')) {
|
||||
const fallbackFile = isDesktop()
|
||||
@ -122,6 +123,10 @@ export const fileLoader: LoaderFunction = async (
|
||||
})
|
||||
code = normalizeLineEndings(code)
|
||||
|
||||
// If persistCode in localStorage is present, it'll persist that code
|
||||
// through *anything*. INTENDED FOR TESTS.
|
||||
code = codeManager.localStoragePersistCode() || code
|
||||
|
||||
// Update both the state and the editor's code.
|
||||
// We explicitly do not write to the file here since we are loading from
|
||||
// the file system and not the editor.
|
||||
@ -149,12 +154,6 @@ export const fileLoader: LoaderFunction = async (
|
||||
? await getProjectInfo(projectPath)
|
||||
: null
|
||||
|
||||
console.log('maybeProjectInfo', {
|
||||
maybeProjectInfo,
|
||||
defaultProjectData,
|
||||
projectPathData,
|
||||
})
|
||||
|
||||
const projectData: IndexLoaderData = {
|
||||
code,
|
||||
project: maybeProjectInfo ?? defaultProjectData,
|
||||
@ -171,7 +170,7 @@ export const fileLoader: LoaderFunction = async (
|
||||
}
|
||||
|
||||
return {
|
||||
code: '',
|
||||
code,
|
||||
project: {
|
||||
name: BROWSER_PROJECT_NAME,
|
||||
path: '/' + BROWSER_PROJECT_NAME,
|
||||
|
Reference in New Issue
Block a user