* Move all tests over to electron * Pass the correct param to playwright-electron.sh * Add shebang to script and add macos-14-large as a target * Get sketch-tests.spec.ts passing in electron * Try out 4 workers * Got testing-segment-overlays passing * Pass testing-selections.spec.ts * Go back to fix up sketch-tests test * Pass various.spec.ts, by far the hardest one * Pass can-sketch-on-all-planes... with ease * Pass command bar tests * fmt * Completely fix code mirror text navigating for tests * Pass debug pane tests * Pass desktop export tests * Pass editor tests * Pass file tree tests * Pass onboarding tests * Corrected a fixme in file-tree.spec! * Painfully fix hardcoded coordinates in point-click.spec * Pass machine.spec tests * Pass projects, fought hard with filechooser * Pass regresion-tests.spec tests * Pass network and connection tests * Pass camera-movement.spec tests * Extreme time eaten by gizmo test fixes. All passing now. * Merge main (tests changed x_x) and pass all constraints.spec tests (pain) * Pass another painful spec suite: testing-settings * Pass perspective-toggle, interesting note * Pass samples loading tests * Pass app header tests * Pass text-to-cad tests * Pass segment-overlays (minor ache) and ability to switch to web if needed :) * Fix a ton of syntax changes and deflake 2 more tests (pain) * Correct all tsc errors * Remove to-electron script * Add an f-ton of shit because playwright doesnt want S P R E A D * Try CI again * Stop snapshots of exports (already test in e2e) * Fix flake in double click editor * Hopefully help CI flake * Fixmes, fixmes everywhere * One more fixme to settings * Skip another code pane flake * Port jess's projects.spec tests * fixup * Reuse electron window; difficult task * Rebased and refixed * Remove duplicate cases * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores) * Reduce the workers to something CI can handle * Lower it further, we need to think about the others * Update package.json Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com> * Update package.json Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com> * Fix the last tests and tsc errors * Timeout to 120 and windows-2022-16core * Fix windows runner detection, enable concurrency temporarily * Hopefully this time fix windows runner detection * Comment out Vector, add back removed camera test code * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large) * A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large) * Fix camera tests again * Massively deflake a whole class of tests * A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large) * A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large) * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores) * Try new CI and fix small onboarding test * Derp * No github tuning * Try mac * Add back all the OS * Lord, hallow be thy name * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores) * One last try with window-16-cores * Trigger CI * Try AWS Windows runner * Passing on windows locally with a few skips * Skip more win tests, add back all three oses * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-16-cores) * Add two more fixmes * 2 more fixmes * skip segment overlays on win32 * Another fixme * Trigger CI * Trigger CI * Quick clean up * Move all tests over to electron * Pass the correct param to playwright-electron.sh * Add shebang to script and add macos-14-large as a target * Get sketch-tests.spec.ts passing in electron * Try out 4 workers * Got testing-segment-overlays passing * Pass testing-selections.spec.ts * Go back to fix up sketch-tests test * Pass various.spec.ts, by far the hardest one * Pass can-sketch-on-all-planes... with ease * Pass command bar tests * fmt * Completely fix code mirror text navigating for tests * Pass debug pane tests * Pass desktop export tests * Pass editor tests * Pass file tree tests * Pass onboarding tests * Corrected a fixme in file-tree.spec! * Painfully fix hardcoded coordinates in point-click.spec * Pass machine.spec tests * Pass projects, fought hard with filechooser * Pass regresion-tests.spec tests * Pass network and connection tests * Pass camera-movement.spec tests * Extreme time eaten by gizmo test fixes. All passing now. * Merge main (tests changed x_x) and pass all constraints.spec tests (pain) * Pass another painful spec suite: testing-settings * Pass perspective-toggle, interesting note * Pass samples loading tests * Pass app header tests * Pass text-to-cad tests * Pass segment-overlays (minor ache) and ability to switch to web if needed :) * Fix a ton of syntax changes and deflake 2 more tests (pain) * Correct all tsc errors * Remove to-electron script * Add an f-ton of shit because playwright doesnt want S P R E A D * Try CI again * Stop snapshots of exports (already test in e2e) * Fix flake in double click editor * Hopefully help CI flake * Fixmes, fixmes everywhere * One more fixme to settings * Skip another code pane flake * Port jess's projects.spec tests * fixup * Reuse electron window; difficult task * Rebased and refixed * Remove duplicate cases * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores) * Reduce the workers to something CI can handle * Lower it further, we need to think about the others * Update package.json Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com> * Update package.json Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com> * Fix the last tests and tsc errors * Timeout to 120 and windows-2022-16core * Fix windows runner detection, enable concurrency temporarily * Hopefully this time fix windows runner detection * Comment out Vector, add back removed camera test code * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large) * A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large) * Fix camera tests again * Massively deflake a whole class of tests * A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large) * A snapshot a day keeps the bugs away! 📷🐛 (OS: macos-14-large) * Try new CI and fix small onboarding test * Derp * No github tuning * Try mac * Add back all the OS * Lord, hallow be thy name * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest-8-cores) * Try AWS Windows runner * Passing on windows locally with a few skips * Trigger CI * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * fmt, tsc, lint * Enable two fixmes again * Fix lint, codespell, fmt * Fix lint * Don't run e2e on draft, add back concurrency, clean up * One last windows skip --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com> Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
		
			
				
	
	
		
			335 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			335 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
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'
 | 
						|
 | 
						|
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.
 | 
						|
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.
 | 
						|
type PWFunction = (
 | 
						|
  args: PlaywrightTestArgs &
 | 
						|
    Fixtures &
 | 
						|
    PlaywrightWorkerArgs &
 | 
						|
    PlaywrightTestOptions &
 | 
						|
    PlaywrightWorkerOptions & {
 | 
						|
      electronApp?: ElectronApplication
 | 
						|
    },
 | 
						|
  testInfo: TestInfo
 | 
						|
) => void | Promise<void>
 | 
						|
 | 
						|
let firstUrl = ''
 | 
						|
 | 
						|
// 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
 | 
						|
 | 
						|
  return pwTestFnWithFixtures(
 | 
						|
    desc,
 | 
						|
    hasTestConf ? objOrFn : {},
 | 
						|
    async (
 | 
						|
      {
 | 
						|
        page,
 | 
						|
        context,
 | 
						|
        cmdBar,
 | 
						|
        editor,
 | 
						|
        toolbar,
 | 
						|
        scene,
 | 
						|
        homePage,
 | 
						|
        request,
 | 
						|
        playwright,
 | 
						|
        browser,
 | 
						|
        acceptDownloads,
 | 
						|
        bypassCSP,
 | 
						|
        colorScheme,
 | 
						|
        clientCertificates,
 | 
						|
        deviceScaleFactor,
 | 
						|
        extraHTTPHeaders,
 | 
						|
        geolocation,
 | 
						|
        hasTouch,
 | 
						|
        httpCredentials,
 | 
						|
        ignoreHTTPSErrors,
 | 
						|
        isMobile,
 | 
						|
        javaScriptEnabled,
 | 
						|
        locale,
 | 
						|
        offline,
 | 
						|
        permissions,
 | 
						|
        proxy,
 | 
						|
        storageState,
 | 
						|
        timezoneId,
 | 
						|
        userAgent,
 | 
						|
        viewport,
 | 
						|
        baseURL,
 | 
						|
        contextOptions,
 | 
						|
        actionTimeout,
 | 
						|
        navigationTimeout,
 | 
						|
        serviceWorkers,
 | 
						|
        testIdAttribute,
 | 
						|
        browserName,
 | 
						|
        defaultBrowserType,
 | 
						|
        headless,
 | 
						|
        channel,
 | 
						|
        launchOptions,
 | 
						|
        connectOptions,
 | 
						|
        screenshot,
 | 
						|
        trace,
 | 
						|
        video,
 | 
						|
      },
 | 
						|
      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
 | 
						|
 | 
						|
      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 }
 | 
						|
      if (tronApp instanceof AuthenticatedTronApp) {
 | 
						|
        const options = {
 | 
						|
          fixtures,
 | 
						|
        }
 | 
						|
        if (hasTestConf) {
 | 
						|
          Object.assign(options, {
 | 
						|
            appSettings: objOrFn?.appSettings,
 | 
						|
            cleanProjectDir: objOrFn?.cleanProjectDir,
 | 
						|
          })
 | 
						|
        }
 | 
						|
        await tronApp.initialise(options)
 | 
						|
      } else {
 | 
						|
        await tronApp.initialise('')
 | 
						|
      }
 | 
						|
 | 
						|
      // We need to patch this because addInitScript will bind too late in our
 | 
						|
      // electron tests, never running. We need to call reload() after each call
 | 
						|
      // to guarantee it runs.
 | 
						|
      const oldContextAddInitScript = tronApp.context.addInitScript
 | 
						|
      tronApp.context.addInitScript = async function (a, b) {
 | 
						|
        // @ts-ignore pretty sure way out of tsc's type checking capabilities.
 | 
						|
        // This code works perfectly fine.
 | 
						|
        await oldContextAddInitScript.apply(this, [a, b])
 | 
						|
        await tronApp.page.reload()
 | 
						|
      }
 | 
						|
 | 
						|
      // No idea why we mix and match page and context's addInitScript but we do
 | 
						|
      const oldPageAddInitScript = tronApp.page.addInitScript
 | 
						|
      tronApp.page.addInitScript = async function (a: 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()
 | 
						|
      }
 | 
						|
 | 
						|
      // Create a consistent way to resize the page across electron and web.
 | 
						|
      // (lee) I had to do everything in the book to make electron change its
 | 
						|
      // damn window size. I succeeded in making it consistently and reliably
 | 
						|
      // do it after a whole afternoon.
 | 
						|
      tronApp.page.setBodyDimensions = async function (dims: {
 | 
						|
        width: number
 | 
						|
        height: number
 | 
						|
      }) {
 | 
						|
        await tronApp.page.setViewportSize(dims)
 | 
						|
 | 
						|
        if (!(tronApp instanceof AuthenticatedTronApp)) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        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: { 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
 | 
						|
        )
 | 
						|
      }
 | 
						|
 | 
						|
      await tronApp.page.setBodyDimensions(tronApp.viewPortSize)
 | 
						|
 | 
						|
      // We need to expose this in order for some tests that require folder
 | 
						|
      // creation. Before they used to do this by their own electronSetup({...})
 | 
						|
      // calls.
 | 
						|
      if (tronApp instanceof AuthenticatedTronApp) {
 | 
						|
        tronApp.context.folderSetupFn = async function (fn) {
 | 
						|
          return fn(tronApp.dir)
 | 
						|
            .then(() => tronApp.page.reload())
 | 
						|
            .then(() => ({
 | 
						|
              dir: tronApp.dir,
 | 
						|
            }))
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (!firstUrl) {
 | 
						|
        await tronApp.page.getByText('Your Projects').count()
 | 
						|
        firstUrl = tronApp.page.url()
 | 
						|
      }
 | 
						|
 | 
						|
      // Due to the app controlling its own window context we need to inject new
 | 
						|
      // options and context here.
 | 
						|
      // NOTE TO LEE: Seems to destroy page context when calling an electron loadURL.
 | 
						|
      // await tronApp.electronApp.evaluate(({ app }) => {
 | 
						|
      //   return app.reuseWindowForTest();
 | 
						|
      // });
 | 
						|
 | 
						|
      await tronApp.electronApp?.evaluate(({ app }, projectDirName) => {
 | 
						|
        // @ts-ignore can't declaration merge see main.ts
 | 
						|
        app.testProperty['TEST_SETTINGS_FILE_KEY'] = projectDirName
 | 
						|
      }, tronApp.dir)
 | 
						|
 | 
						|
      // Always start at the root view
 | 
						|
      await tronApp.page.goto(firstUrl)
 | 
						|
 | 
						|
      // Force a hard reload, destroying the stream and other state
 | 
						|
      await tronApp.page.reload()
 | 
						|
 | 
						|
      // 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,
 | 
						|
            request,
 | 
						|
            playwright,
 | 
						|
            browser,
 | 
						|
            acceptDownloads,
 | 
						|
            bypassCSP,
 | 
						|
            colorScheme,
 | 
						|
            clientCertificates,
 | 
						|
            deviceScaleFactor,
 | 
						|
            extraHTTPHeaders,
 | 
						|
            geolocation,
 | 
						|
            hasTouch,
 | 
						|
            httpCredentials,
 | 
						|
            ignoreHTTPSErrors,
 | 
						|
            isMobile,
 | 
						|
            javaScriptEnabled,
 | 
						|
            locale,
 | 
						|
            offline,
 | 
						|
            permissions,
 | 
						|
            proxy,
 | 
						|
            storageState,
 | 
						|
            timezoneId,
 | 
						|
            userAgent,
 | 
						|
            viewport,
 | 
						|
            baseURL,
 | 
						|
            contextOptions,
 | 
						|
            actionTimeout,
 | 
						|
            navigationTimeout,
 | 
						|
            serviceWorkers,
 | 
						|
            testIdAttribute,
 | 
						|
            browserName,
 | 
						|
            defaultBrowserType,
 | 
						|
            headless,
 | 
						|
            channel,
 | 
						|
            launchOptions,
 | 
						|
            connectOptions,
 | 
						|
            screenshot,
 | 
						|
            trace,
 | 
						|
            video,
 | 
						|
          },
 | 
						|
          testInfo
 | 
						|
        )
 | 
						|
      }
 | 
						|
 | 
						|
      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 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
 |