import { Page } from '@playwright/test'; import * as fs from 'fs'; import * as path from 'path'; const USE_LIVE_DATA = Boolean(process.env.API_CONFIG_PATH); const API_CONFIG_PATH = process.env.API_CONFIG_PATH ?? '../dashboards/cujs/config.json'; const RELOADABLE_DASHBOARD_REQUEST_NO = 2; async function loadApiConfig() { const configPath = path.resolve(__dirname, API_CONFIG_PATH); if (configPath.endsWith('.json')) { const configContent = await fs.promises.readFile(configPath, 'utf-8'); return JSON.parse(configContent); } else { const apiConfigModule = await import(configPath); return apiConfigModule.default || apiConfigModule; } } export async function getConfigDashboards() { const config = await loadApiConfig(); return config.dashboards || []; } export async function prepareAPIMocks(page: Page) { const apiConfig = await loadApiConfig(); if (USE_LIVE_DATA) { return apiConfig; } const keys = Object.keys(apiConfig); if (keys.includes('labels')) { // mock the API call to get the labels const labels = ['asserts_env', 'cluster', 'job']; await page.route(apiConfig.labels, async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ status: 'success', data: labels, }), }); }); } if (keys.includes('values')) { // mock the API call to get the values const values = ['value1', 'value2', 'test1', 'test2']; await page.route(apiConfig.values, async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ status: 'success', data: values, }), }); }); } return apiConfig; } interface DashboardRequest { url: string; timestamp: number; response: { metadata: { annotations: string[] } }; } export async function trackDashboardReloadRequests(page: Page): Promise<{ getRequests: () => DashboardRequest[]; waitForExpectedRequests: () => Promise; }> { const dashboardRequests: DashboardRequest[] = []; let resolveWhenComplete: () => void; let expectedRequestCount = 1; //initial request that gives us the meta param const completionPromise = new Promise((resolve) => { resolveWhenComplete = resolve; }); const handler = async (route) => { const response = await route.fetch(); const responseJson = await response.json(); const isFirstRequest = dashboardRequests.length === 0; dashboardRequests.push({ url: route.request().url(), timestamp: Date.now(), response: responseJson, }); // After first request, check if we should expect more if (isFirstRequest) { const hasReloadAnnotation = responseJson?.metadata?.annotations?.['grafana.app/reloadOnParamsChange'] === 'true'; if (hasReloadAnnotation) { expectedRequestCount = RELOADABLE_DASHBOARD_REQUEST_NO; } } // Resolve if we've reached the expected count if (dashboardRequests.length >= expectedRequestCount) { resolveWhenComplete(); } await route.fulfill({ response }); }; await page.route('**/dashboards/**/dto?**', handler); return { getRequests: () => dashboardRequests, waitForExpectedRequests: () => completionPromise, }; } export function checkDashboardReloadBehavior(requests: DashboardRequest[]): boolean { if (requests.length === 0) { return false; } const firstRequest = requests[0]; const hasReloadAnnotation = firstRequest?.response?.metadata?.annotations?.['grafana.app/reloadOnParamsChange'] === 'true'; if (hasReloadAnnotation) { return requests.length === RELOADABLE_DASHBOARD_REQUEST_NO; } else { return requests.length === 1; } }