import type { SvelteComponent } from 'svelte'; import { Page } from 'playwright'; import { state } from './state'; import { RenderOptions, render as renderCommon } from './render'; import { Importer, bootstrap as bootstrapCommon } from './bootstrap'; interface RenderReturn { /** The Playwright page object of the rendered component. */ page: Page; /** Pause current test. */ pause: () => Promise; } type Renderable = typeof SvelteComponent; let renderFn: (element: Renderable) => Promise; const assertAndRender = (element: Renderable) => { if (!renderFn) { throw new Error( 'App is not bootstrapped, did you forget to call `bootstrap({ /* ... */ })`?' ); } return renderFn(element); }; const id = (any: any) => any; export async function render( elementToRender: Renderable | ((app: Renderable) => Renderable) = id, options: RenderOptions = {} ): Promise { if ( typeof elementToRender === 'function' && !elementToRender?.prototype?.constructor?.name && !elementToRender?.prototype?.constructor?.toString().startsWith('class') ) { const rendered = (elementToRender as any)( state.browserState?.renderElement.value ?? ({} as any) ); elementToRender = rendered; } return renderCommon( { __isRenderable: true, thing: elementToRender }, options, async (e) => assertAndRender(e.thing) ); } type BootstrapArgs = Importer & { element: typeof SvelteComponent; render: (e: Renderable) => Promise; }; export const bootstrap = async ( args: BootstrapArgs ): Promise => { renderFn = args.render; state.browserState = { retryAttempt: 0, renderElement: { __type: 'renderElement', value: args.element }, }; return bootstrapCommon({ ...args, defaultRender: () => assertAndRender(args.element), }); };