From 0f8e84f810b1e660eb07f279097779963de8d9bb Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Thu, 12 Dec 2024 09:07:56 -0600 Subject: [PATCH] fix: config UI is up to date with IDB --- src/lib/config-db.ts | 133 ++++++++++------- src/lib/generic-db.ts | 28 ++++ src/pages/config.tsx | 36 ++++- test-e2e/config-ui.test.ts | 34 +++++ test-e2e/fixtures/config-test-fixtures.ts | 22 +-- test-e2e/fixtures/locators.ts | 10 +- test-e2e/fixtures/set-sw-config.ts | 149 +++++++++++++++---- test-e2e/fixtures/wait-for-service-worker.ts | 8 +- test-e2e/subdomain-detection.test.ts | 22 +-- 9 files changed, 302 insertions(+), 140 deletions(-) create mode 100644 test-e2e/config-ui.test.ts diff --git a/src/lib/config-db.ts b/src/lib/config-db.ts index 52a035e4..3e9ca05d 100644 --- a/src/lib/config-db.ts +++ b/src/lib/config-db.ts @@ -81,65 +81,86 @@ export async function setConfig (config: ConfigDbWithoutPrivateFields, logger: C } } -export async function getConfig (logger: ComponentLogger): Promise { - const log = logger.forComponent('get-config') - let gateways = defaultGateways - let routers = defaultRouters - let dnsJsonResolvers = defaultDnsJsonResolvers - let enableRecursiveGateways - let enableWss - let enableWebTransport - let enableGatewayProviders - let debug = '' - let _supportsSubdomains = defaultSupportsSubdomains - - try { - await configDb.open() - - gateways = await configDb.get('gateways') +let getConfigPromise: Promise | null = null - routers = await configDb.get('routers') - - dnsJsonResolvers = await configDb.get('dnsJsonResolvers') - - enableRecursiveGateways = await configDb.get('enableRecursiveGateways') ?? defaultEnableRecursiveGateways - enableWss = await configDb.get('enableWss') ?? defaultEnableWss - enableWebTransport = await configDb.get('enableWebTransport') ?? defaultEnableWebTransport - enableGatewayProviders = await configDb.get('enableGatewayProviders') ?? defaultEnableGatewayProviders - - debug = await configDb.get('debug') ?? defaultDebug() - enable(debug) - - _supportsSubdomains ??= await configDb.get('_supportsSubdomains') - } catch (err) { - log('error loading config from db', err) - } finally { - configDb.close() - } - - if (gateways == null || gateways.length === 0) { - gateways = [...defaultGateways] - } - - if (routers == null || routers.length === 0) { - routers = [...defaultRouters] - } - if (dnsJsonResolvers == null || Object.keys(dnsJsonResolvers).length === 0) { - dnsJsonResolvers = { ...defaultDnsJsonResolvers } +export async function getConfig (logger: ComponentLogger): Promise { + if (getConfigPromise != null) { + /** + * If there is already a promise to get the config, return it. + * This is to prevent multiple calls to the db to get the same config, because + * each request will close the DB when done, and then the next request will fail at some point + */ + return getConfigPromise } - // always return the config, even if we failed to load it. - return { - gateways, - routers, - dnsJsonResolvers, - enableRecursiveGateways, - enableWss, - enableWebTransport, - enableGatewayProviders, - debug, - _supportsSubdomains - } + getConfigPromise = (async () => { + const log = logger.forComponent('get-config') + let gateways = defaultGateways + let routers = defaultRouters + let dnsJsonResolvers = defaultDnsJsonResolvers + let enableRecursiveGateways + let enableWss + let enableWebTransport + let enableGatewayProviders + let debug = '' + let _supportsSubdomains = defaultSupportsSubdomains + + let config: ConfigDb + + log('config-debug: getting config for domain %s', globalThis.location.origin) + try { + await configDb.open() + + config = await configDb.getAll() + debug = config.debug ?? defaultDebug() + enable(debug) + + gateways = config.gateways + + routers = config.routers + + dnsJsonResolvers = config.dnsJsonResolvers + enableRecursiveGateways = config.enableRecursiveGateways ?? defaultEnableRecursiveGateways + enableWss = config.enableWss ?? defaultEnableWss + enableWebTransport = config.enableWebTransport ?? defaultEnableWebTransport + enableGatewayProviders = config.enableGatewayProviders ?? defaultEnableGatewayProviders + + _supportsSubdomains ??= config.thing + } catch (err) { + log('error loading config from db', err) + } finally { + configDb.close() + } + + if (gateways == null || gateways.length === 0) { + gateways = [...defaultGateways] + } + + if (routers == null || routers.length === 0) { + routers = [...defaultRouters] + } + if (dnsJsonResolvers == null || Object.keys(dnsJsonResolvers).length === 0) { + dnsJsonResolvers = { ...defaultDnsJsonResolvers } + } + + // always return the config, even if we failed to load it. + return { + gateways, + routers, + dnsJsonResolvers, + enableRecursiveGateways, + enableWss, + enableWebTransport, + enableGatewayProviders, + debug, + _supportsSubdomains + } + })().finally(() => { + getConfigPromise = null + }) + + const result = await getConfigPromise + return result } export async function validateConfig (config: ConfigDbWithoutPrivateFields, logger: ComponentLogger): Promise { diff --git a/src/lib/generic-db.ts b/src/lib/generic-db.ts index 434892dd..1391db99 100644 --- a/src/lib/generic-db.ts +++ b/src/lib/generic-db.ts @@ -59,6 +59,34 @@ export class GenericIDB { }) } + async getAll (): Promise { + if (this.db == null) { + throw new Error('Database not opened') + } + const transaction = this.db.transaction(this.storeName, 'readonly') + const store = transaction.objectStore(this.storeName) + + return new Promise((resolve, reject) => { + // @ts-expect-error - its empty right now... + const result: { [K in keyof T]: T[K] } = {} + const request = store.openCursor() + + request.onerror = () => { + reject(request.error ?? new Error(`Could not get all keys and values from store "${this.storeName}"`)) + } + + request.onsuccess = () => { + const cursor = request.result + if (cursor != null) { + result[cursor.key as keyof T] = cursor.value as T[keyof T] + cursor.continue() + } else { + resolve(result) + } + } + }) + } + close (): void { if (this.db != null) { this.db.close() diff --git a/src/pages/config.tsx b/src/pages/config.tsx index 1cff0a87..05a2dd8a 100644 --- a/src/pages/config.tsx +++ b/src/pages/config.tsx @@ -7,7 +7,7 @@ import Input from '../components/textarea-input.jsx' import { ConfigContext, ConfigProvider } from '../context/config-context.jsx' import { RouteContext } from '../context/router-context.jsx' import { ServiceWorkerProvider } from '../context/service-worker-context.jsx' -import { setConfig as storeConfig } from '../lib/config-db.js' +import { getConfig, setConfig as storeConfig } from '../lib/config-db.js' import { convertDnsResolverInputToObject, convertDnsResolverObjectToInput, convertUrlArrayToInput, convertUrlInputToArray } from '../lib/input-helpers.js' import { isConfigPage } from '../lib/is-config-page.js' import { getUiComponentLogger, uiLogger } from '../lib/logger.js' @@ -82,7 +82,7 @@ export interface ConfigPageProps extends React.HTMLProps { // Config Page can be loaded either as a page or as a component in the landing helper-ui page const ConfigPage: FunctionComponent = () => { const { gotoPage } = useContext(RouteContext) - const { setConfig, resetConfig, gateways, routers, dnsJsonResolvers, debug, enableGatewayProviders, enableRecursiveGateways, enableWss, enableWebTransport, _supportsSubdomains } = useContext(ConfigContext) + const { isLoading, setConfig, resetConfig, gateways, routers, dnsJsonResolvers, debug, enableGatewayProviders, enableRecursiveGateways, enableWss, enableWebTransport, _supportsSubdomains } = useContext(ConfigContext) const [isSaving, setIsSaving] = useState(false) const [error, setError] = useState(null) const [resetKey, setResetKey] = useState(0) @@ -107,11 +107,14 @@ const ConfigPage: FunctionComponent = () => { }, [gateways, routers, dnsJsonResolvers, debug, enableGatewayProviders, enableRecursiveGateways, enableWss, enableWebTransport]) useEffect(() => { + if (isLoading) { + return + } /** * On initial load, we want to send the config to the parent window, so that the reload page can auto-reload if enabled, and the subdomain registered service worker gets the latest config without user interaction. */ void postFromIframeToParentSw() - }, []) + }, [isLoading]) const saveConfig = useCallback(async () => { try { @@ -133,6 +136,13 @@ const ConfigPage: FunctionComponent = () => { setError(err as Error) } finally { setIsSaving(false) + await getConfig(uiComponentLogger).then((config) => { + // eslint-disable-next-line no-console + console.log('config directly from idb: ', config) + }).catch((err) => { + // eslint-disable-next-line no-console + console.error('error getting config directly from idb: ', err) + }) } }, [gateways, routers, dnsJsonResolvers, debug, enableGatewayProviders, enableRecursiveGateways, enableWss, enableWebTransport]) @@ -143,6 +153,16 @@ const ConfigPage: FunctionComponent = () => { setResetKey((prev) => prev + 1) }, []) + console.log('config-page: isLoading', isLoading) + + // if (isLoading) { + // return null + // } + + // eslint-disable-next-line no-console + console.log('config is done loading: ', { gateways, routers, dnsJsonResolvers, debug, enableGatewayProviders, enableRecursiveGateways, enableWss, enableWebTransport }) + // console.log('config directly from idb: ') + return ( <> {isConfigPage(window.location.hash) ?
: null} @@ -150,7 +170,7 @@ const ConfigPage: FunctionComponent = () => {

Configure your IPFS Gateway

= () => { resetKey={resetKey} /> = () => { resetKey={resetKey} /> = () => { = () => { resetKey={resetKey} /> { + test('setting the config via UI actually works', async ({ page, protocol, rootDomain }) => { + await page.goto(`${protocol}//${rootDomain}`) + // await waitForServiceWorker(page) + + // read the config from the page + const config = await getConfigUi({ page }) + + // change the config + const testConfig: typeof config = { + ...config, + gateways: ['https://example.com'], + routers: ['https://example2.com'] + } + + // change the UI & save it + await setConfigViaUi({ page, config: testConfig }) + + // verify that the IndexedDB has the new config + expect(await getConfig({ page })).toMatchObject(testConfig) + + // reload the page, and ensure the config is the same as the one we set + await page.reload() + expect(await getConfigUi({ page })).toMatchObject(testConfig) + expect(await getConfig({ page })).toMatchObject(testConfig) + }) +}) diff --git a/test-e2e/fixtures/config-test-fixtures.ts b/test-e2e/fixtures/config-test-fixtures.ts index 819b8bbb..89747ac3 100644 --- a/test-e2e/fixtures/config-test-fixtures.ts +++ b/test-e2e/fixtures/config-test-fixtures.ts @@ -1,5 +1,5 @@ import { test as base, type Page } from '@playwright/test' -import { setConfig, setSubdomainConfig } from './set-sw-config.js' +import { setConfig } from './set-sw-config.js' import { waitForServiceWorker } from './wait-for-service-worker.js' function isNoServiceWorkerProject (test: T): boolean { @@ -90,26 +90,6 @@ export const testSubdomainRouting = test.extend<{ rootDomain: string, baseURL: s throw new Error('KUBO_GATEWAY not set') } const kuboGateway = process.env.KUBO_GATEWAY - const oldPageGoto = page.goto.bind(page) - page.goto = async (url: Parameters[0], options: Parameters[1]): ReturnType => { - const response = await oldPageGoto(url, options) - if (['.ipfs.', '.ipns.'].some((part) => url.includes(part))) { - await setSubdomainConfig({ - page, - config: { - autoReload: true, - gateways: [kuboGateway], - routers: [kuboGateway], - dnsJsonResolvers: { - '.': 'https://delegated-ipfs.dev/dns-query' - } - } - }) - } else { - // already set on root. - } - return response - } // set config for the initial page await setConfig({ diff --git a/test-e2e/fixtures/locators.ts b/test-e2e/fixtures/locators.ts index f1a55bfd..331e20ec 100644 --- a/test-e2e/fixtures/locators.ts +++ b/test-e2e/fixtures/locators.ts @@ -16,9 +16,14 @@ export const getConfigPage: GetLocator = (page) => page.locator('.e2e-config-pag export const getConfigPageInput: GetLocator = (page) => page.locator('.e2e-config-page-input') export const getConfigPageSaveButton: GetLocator = (page) => page.locator('.e2e-config-page-button#save-config') export const getIframeLocator: GetFrameLocator = (page) => page.frameLocator('iframe') -export const getConfigGatewaysInput: GetLocator = (page) => page.locator('.e2e-config-page-input-gateways') +export const getConfigEnableGatewayProviders: GetLocator = (page) => page.locator('.e2e-config-page-input-enableGatewayProviders') +export const getConfigEnableWss: GetLocator = (page) => page.locator('.e2e-config-page-input-enableWss') +export const getConfigEnableWebTransport: GetLocator = (page) => page.locator('.e2e-config-page-input-enableWebTransport') export const getConfigRoutersInput: GetLocator = (page) => page.locator('.e2e-config-page-input-routers') -export const getConfigAutoReloadInput: GetLocator = (page) => page.locator('.e2e-config-page-input-autoreload') +export const getConfigEnableRecursiveGateways: GetLocator = (page) => page.locator('.e2e-config-page-input-enableRecursiveGateways') +export const getConfigGatewaysInput: GetLocator = (page) => page.locator('.e2e-config-page-input-gateways') +export const getConfigDnsJsonResolvers: GetLocator = (page) => page.locator('.e2e-config-page-input-dnsJsonResolvers') +export const getConfigDebug: GetLocator = (page) => page.locator('.e2e-config-page-input-debug') export const getNoServiceWorkerError: GetLocator = (page) => page.locator('.e2e-no-service-worker-error') @@ -31,5 +36,4 @@ export const getAboutSection: GetLocator = (page) => page.locator('.e2e-about-se export const getConfigButtonIframe: GetLocator = (page) => getIframeLocator(page).locator('.e2e-collapsible-button') export const getConfigGatewaysInputIframe: GetLocator = (page) => getConfigGatewaysInput(getIframeLocator(page)) export const getConfigRoutersInputIframe: GetLocator = (page) => getConfigRoutersInput(getIframeLocator(page)) -export const getConfigAutoReloadInputIframe: GetLocator = (page) => getConfigAutoReloadInput(getIframeLocator(page)) export const getConfigPageSaveButtonIframe: GetLocator = (page) => getConfigPageSaveButton(getIframeLocator(page)) diff --git a/test-e2e/fixtures/set-sw-config.ts b/test-e2e/fixtures/set-sw-config.ts index 8072bd26..0331c83c 100644 --- a/test-e2e/fixtures/set-sw-config.ts +++ b/test-e2e/fixtures/set-sw-config.ts @@ -4,24 +4,50 @@ * * Note that this was only tested and confirmed working for subdomain pages. */ -import { getConfigAutoReloadInputIframe, getConfigButtonIframe, getConfigGatewaysInput, getConfigGatewaysInputIframe, getConfigPage, getConfigPageSaveButton, getConfigPageSaveButtonIframe, getConfigRoutersInput, getConfigRoutersInputIframe } from './locators.js' +import { getConfigDebug, getConfigDnsJsonResolvers, getConfigEnableGatewayProviders, getConfigEnableRecursiveGateways, getConfigEnableWebTransport, getConfigEnableWss, getConfigGatewaysInput, getConfigGatewaysInputIframe, getConfigPage, getConfigPageSaveButton, getConfigPageSaveButtonIframe, getConfigRoutersInput, getConfigRoutersInputIframe } from './locators.js' import { waitForServiceWorker } from './wait-for-service-worker.js' -import type { ConfigDb } from '../../src/lib/config-db.js' +import type { ConfigDb, ConfigDbWithoutPrivateFields } from '../../src/lib/config-db.js' import type { Page } from '@playwright/test' export async function setConfigViaUiSubdomain ({ page, config }: { page: Page, config: Partial }): Promise { await waitForServiceWorker(page) - await getConfigButtonIframe(page).isVisible() - await getConfigButtonIframe(page).click() + await getConfigGatewaysInputIframe(page).locator('input').fill([process.env.KUBO_GATEWAY].join('\n')) + await getConfigRoutersInputIframe(page).locator('input').fill([process.env.KUBO_GATEWAY].join('\n')) - for (const [key] of Object.entries(config)) { - if (key === 'autoReload') { - await getConfigAutoReloadInputIframe(page).click() - } + if (config.enableGatewayProviders != null) { + await getConfigEnableGatewayProviders(page).locator('input').setChecked(config.enableGatewayProviders) + } + + if (config.enableWss != null) { + await getConfigEnableWss(page).locator('input').setChecked(config.enableWss) + } + + if (config.enableWebTransport != null) { + await getConfigEnableWebTransport(page).locator('input').setChecked(config.enableWebTransport) + } + + if (config.routers != null) { + await getConfigRoutersInputIframe(page).locator('input').fill(config.routers.join('\n')) + } + + if (config.enableRecursiveGateways != null) { + await getConfigEnableRecursiveGateways(page).locator('input').setChecked(config.enableRecursiveGateways) + } + + if (config.gateways != null) { + await getConfigGatewaysInputIframe(page).locator('input').fill(config.gateways.join('\n')) + } + + // if (config.dnsJsonResolvers != null) { + // await getConfigDnsJsonResolvers(page).locator('input').fill(config.dnsJsonResolvers.reduce((acc, [key, value]) => { + // acc.push(`${key} ${value}`) + // return acc + // }, []).join('\n')) + // } + if (config.debug != null) { + await getConfigDebug(page).locator('input').fill(config.debug) } - await getConfigGatewaysInputIframe(page).locator('input').fill(JSON.stringify([process.env.KUBO_GATEWAY])) - await getConfigRoutersInputIframe(page).locator('input').fill(JSON.stringify([process.env.KUBO_GATEWAY])) await getConfigPageSaveButtonIframe(page).click() @@ -33,12 +59,85 @@ export async function setConfigViaUi ({ page, config }: { page: Page, config: Pa await getConfigPage(page).isVisible() - await getConfigGatewaysInput(page).locator('input').fill(JSON.stringify([process.env.KUBO_GATEWAY])) - await getConfigRoutersInput(page).locator('input').fill(JSON.stringify([process.env.KUBO_GATEWAY])) + await getConfigGatewaysInput(page).locator('textarea').fill([process.env.KUBO_GATEWAY].join('\n')) + await getConfigRoutersInput(page).locator('textarea').fill([process.env.KUBO_GATEWAY].join('\n')) + + if (config.enableGatewayProviders != null) { + // scroll to the element so it's visible + await getConfigEnableGatewayProviders(page).scrollIntoViewIfNeeded() + await getConfigEnableGatewayProviders(page).locator('input').setChecked(config.enableGatewayProviders) + } + + if (config.enableWss != null) { + await getConfigEnableWss(page).scrollIntoViewIfNeeded() + await getConfigEnableWss(page).locator('input').setChecked(config.enableWss) + } + + if (config.enableWebTransport != null) { + await getConfigEnableWebTransport(page).scrollIntoViewIfNeeded() + await getConfigEnableWebTransport(page).locator('input').setChecked(config.enableWebTransport) + } + + if (config.routers != null) { + await getConfigRoutersInput(page).scrollIntoViewIfNeeded() + await getConfigRoutersInput(page).locator('textarea').fill(config.routers.join('\n')) + } + + if (config.enableRecursiveGateways != null) { + await getConfigEnableRecursiveGateways(page).scrollIntoViewIfNeeded() + await getConfigEnableRecursiveGateways(page).locator('input').setChecked(config.enableRecursiveGateways) + } + + if (config.gateways != null) { + await getConfigGatewaysInput(page).scrollIntoViewIfNeeded() + await getConfigGatewaysInput(page).locator('textarea').fill(config.gateways.join('\n')) + } + + // if (config.dnsJsonResolvers != null) { + // await getConfigDnsJsonResolvers(page).locator('input').fill(config.dnsJsonResolvers.reduce((acc, [key, value]) => { + // acc.push(`${key} ${value}`) + // return acc + // }, []).join('\n')) + // } + + if (config.debug != null) { + await getConfigDebug(page).scrollIntoViewIfNeeded() + await getConfigDebug(page).locator('textarea').fill(config.debug) + } await getConfigPageSaveButton(page).click() +} - await getConfigPage(page).isHidden() +export async function getConfigUi ({ page }: { page: Page }): Promise { + await waitForServiceWorker(page) + + await getConfigPage(page).isVisible() + + const enableGatewayProviders = await getConfigEnableGatewayProviders(page).locator('input').isChecked() + const enableWss = await getConfigEnableWss(page).locator('input').isChecked() + const enableWebTransport = await getConfigEnableWebTransport(page).locator('input').isChecked() + const routers = (await getConfigRoutersInput(page).locator('textarea').inputValue()).split('\n') + const enableRecursiveGateways = await getConfigEnableRecursiveGateways(page).locator('input').isChecked() + const gateways = (await getConfigGatewaysInput(page).locator('textarea').inputValue()).split('\n') + const dnsJsonResolvers = await getConfigDnsJsonResolvers(page).locator('textarea').inputValue().then((value) => { + return value.split('\n').reduce((acc, line) => { + const [key, value] = line.split(' ') + acc[key] = value + return acc + }, {}) + }) + const debug = await getConfigDebug(page).locator('textarea').inputValue() + + return { + enableGatewayProviders, + enableWss, + enableWebTransport, + routers, + enableRecursiveGateways, + gateways, + dnsJsonResolvers, + debug + } } export async function setConfig ({ page, config }: { page: Page, config: Partial }): Promise { @@ -129,15 +228,15 @@ export async function getConfig ({ page }: { page: Page }): Promise { return config } -export async function setSubdomainConfig ({ page, config }: { page: Page, config: Partial }): Promise { - await waitForServiceWorker(page) - - await page.evaluate(async (configInPage) => { - // TODO: we shouldn't need this. We should be able to just post a message to the service worker to reload it's config. - window.postMessage({ source: 'helia-sw-config-iframe', target: 'PARENT', action: 'RELOAD_CONFIG', config: configInPage }, { targetOrigin: window.location.origin }) - }, { - gateways: [process.env.KUBO_GATEWAY], - routers: [process.env.KUBO_GATEWAY], - ...config - }) -} +// export async function setSubdomainConfig ({ page, config }: { page: Page, config: Partial }): Promise { +// await waitForServiceWorker(page) + +// await page.evaluate(async (configInPage) => { +// // TODO: we shouldn't need this. We should be able to just post a message to the service worker to reload it's config. +// window.postMessage({ source: 'helia-sw-config-iframe', target: 'PARENT', action: 'RELOAD_CONFIG', config: configInPage }, { targetOrigin: window.location.origin }) +// }, { +// gateways: [process.env.KUBO_GATEWAY], +// routers: [process.env.KUBO_GATEWAY], +// ...config +// }) +// } diff --git a/test-e2e/fixtures/wait-for-service-worker.ts b/test-e2e/fixtures/wait-for-service-worker.ts index d5dd6b19..79b1631b 100644 --- a/test-e2e/fixtures/wait-for-service-worker.ts +++ b/test-e2e/fixtures/wait-for-service-worker.ts @@ -1,15 +1,11 @@ import type { Page } from '@playwright/test' export async function waitForServiceWorker (page: Page): Promise { - await page.evaluate(async () => { + await page.waitForFunction(async () => { const registration = await window.navigator.serviceWorker.getRegistration() if (registration?.active?.state === 'activated') { - return + return true } - - await new Promise((resolve, reject) => { - window.navigator.serviceWorker.addEventListener('controllerchange', resolve) - }) }) } diff --git a/test-e2e/subdomain-detection.test.ts b/test-e2e/subdomain-detection.test.ts index 808e8682..cd177a86 100644 --- a/test-e2e/subdomain-detection.test.ts +++ b/test-e2e/subdomain-detection.test.ts @@ -1,5 +1,5 @@ import { test, testSubdomainRouting, expect } from './fixtures/config-test-fixtures.js' -import { setConfig, setSubdomainConfig } from './fixtures/set-sw-config.js' +import { setConfig } from './fixtures/set-sw-config.js' import { waitForServiceWorker } from './fixtures/wait-for-service-worker.js' test.describe('subdomain-detection', () => { @@ -18,7 +18,6 @@ test.describe('subdomain-detection', () => { await setConfig({ page, config: { - autoReload: false, gateways, routers, dnsJsonResolvers: { @@ -38,25 +37,6 @@ test.describe('subdomain-detection', () => { await expect(bodyTextLocator).toContainText('hello') }) - - test('enabling autoreload automatically loads the subdomain', async ({ page, rootDomain, protocol }) => { - await page.goto(`${protocol}//bafkqablimvwgy3y.ipfs.${rootDomain}/`, { waitUntil: 'networkidle' }) - await setSubdomainConfig({ - page, - config: { - autoReload: true, - gateways, - routers, - dnsJsonResolvers: { - '.': 'https://delegated-ipfs.dev/dns-query' - } - } - }) - - const bodyTextLocator = page.locator('body') - - await expect(bodyTextLocator).toContainText('hello') - }) }) testSubdomainRouting.describe('subdomain-detection auto fixture', () => {