import { getDocument } from 'pptr-testing-library'; import { ElementHandle, Page } from 'puppeteer'; export const url = (path = '') => `http://localhost:9000${path}`; export const prop = async <GReturn>( $element: ElementHandle | Promise<ElementHandle>, property: string, ): Promise<GReturn> => { try { const handle = await $element; const propertyHandle = await handle.getProperty(property); return propertyHandle.jsonValue() as any; } catch (e) { console.error(property, $element.toString()); throw e; } }; export const props = async <GReturn>( $elements: ElementHandle[] | Promise<ElementHandle[]>, property: string, ): Promise<GReturn[]> => { const handles = await $elements; return Promise.all(handles.map((handle) => prop<GReturn>(handle, property))); }; export interface TagAssertionBuilder { selector: string; prop: string; result: string[] | string; indexes?: number[]; } export const assertTags = async ( assertions: TagAssertionBuilder[], $document: ElementHandle, ) => { for (const assertion of assertions) { const { prop: p, result, selector, indexes } = assertion; if (Array.isArray(result)) { await props($document.$$(selector), p).then(async (content) => { if (Array.isArray(indexes)) { expect(indexes.length).toBe(result.length); // Ensure the indexes match; indexes.forEach((ii, index) => { expect(content[ii]).toBe(result[index]); }); } else { expect(content).toHaveLength(result.length); expect(content).toEqual(result); } }); } else { await expect(prop($document.$(selector), p)).resolves.toBe(result); } } }; const { EXAMPLE_COMMAND = 'serve' } = process.env; export const clientOnly = EXAMPLE_COMMAND !== 'serve'; const defaultIterator = [ ['SSR', true], ['Client', false], ] as const; const clientIterator = [['Client', false]] as const; export const testIterator = clientOnly ? clientIterator : defaultIterator; declare global { namespace NodeJS { interface ProcessEnv { EXAMPLE_COMMAND?: 'serve' | 'develop'; } } } interface LaunchParams { path?: string; disableJavascript?: boolean; } export const launch = async ({ path = '/', disableJavascript = false, }: LaunchParams = {}): Promise<ElementHandle> => { if (disableJavascript) { await page.setJavaScriptEnabled(false); } await page.goto( url(path), disableJavascript ? {} : { waitUntil: 'domcontentloaded' }, ); if (clientOnly) { await page.waitFor(500); // gatsby develop takes a moment to warm up on first load } return getDocument(page as Page); };