import { test as base } from "@playwright/test" import { CodeServer, CodeServerPage } from "./models/CodeServer" /** * Wraps `test.describe` to create and manage an instance of code-server. If you * don't use this you will need to create your own code-server instance and pass * it to `test.use`. * * If `includeCredentials` is `true` page requests will be authenticated. */ export const describe = ( name: string, codeServerArgs: string[], codeServerEnv: NodeJS.ProcessEnv, fn: (codeServer: CodeServer) => void, ) => { test.describe(name, () => { // This will spawn on demand so nothing is necessary on before. const codeServer = new CodeServer(name, codeServerArgs, codeServerEnv, undefined) // Kill code-server after the suite has ended. This may happen even without // doing it explicitly but it seems prudent to be sure. test.afterAll(async () => { await codeServer.close() }) test.use({ // Makes `codeServer` and `authenticated` available to the extend call // below. codeServer, // NOTE@jsjoeio some tests use --cert which uses a self-signed certificate // without this option, those tests will fail. ignoreHTTPSErrors: true, }) fn(codeServer) }) } interface TestFixtures { codeServer: CodeServer codeServerPage: CodeServerPage } /** * Create a test that spawns code-server if necessary and ensures the page is * ready. */ export const test = base.extend({ codeServer: undefined, // No default; should be provided through `test.use`. codeServerPage: async ({ codeServer, page }, use) => { // It's possible code-server might prevent navigation because of unsaved // changes (seems to happen based on timing even if no changes have been // made too). In these cases just accept. page.on("dialog", (d) => d.accept()) const codeServerPage = new CodeServerPage(codeServer, page) await codeServerPage.navigate() await use(codeServerPage) }, }) /** Shorthand for test.expect. */ export const expect = test.expect