Skip to content

Commit 6a876f4

Browse files
authored
WaitingForPanels: Change waiting logic (#496)
* WaitingForPanels: Change waiting logic * add timeout * Fixes
1 parent 670616d commit 6a876f4

File tree

1 file changed

+57
-37
lines changed

1 file changed

+57
-37
lines changed

src/browser/browser.ts

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -321,46 +321,14 @@ export class Browser {
321321
}
322322

323323
const isPDF = options.encoding === 'pdf';
324+
324325
try {
325-
await this.withTimingMetrics(() => {
326+
await this.withTimingMetrics(async () => {
326327
if (this.config.verboseLogging) {
327328
this.log.debug('Waiting for dashboard/panel to load', 'timeout', `${options.timeout}s`);
328329
}
329330

330-
return page.waitForFunction(
331-
(isFullPage) => {
332-
/**
333-
* panelsRendered value is updated every time that a panel renders. It could happen multiple times in a same panel because scrolling. For full page screenshots
334-
* we can reach panelsRendered >= panelCount condition even if we have panels that are still loading data and their panelsRenderer value is 0, generating
335-
* a screenshot with loading panels. It's why the condition for full pages is different from a single panel.
336-
*/
337-
if (isFullPage) {
338-
/**
339-
* data-panelId is the total number of the panels in the dashboard. Rows included.
340-
* panel-content only exists in non-row panels when the data is loaded.
341-
* dashboard-row exists only in rows.
342-
*/
343-
const panelCount = document.querySelectorAll('[data-panelId]').length;
344-
const panelsRendered = document.querySelectorAll("[class$='panel-content']");
345-
let panelsRenderedCount = 0;
346-
panelsRendered.forEach((value: Element) => {
347-
if (value.childElementCount > 0) {
348-
panelsRenderedCount++;
349-
}
350-
});
351-
352-
const totalPanelsRendered = panelsRenderedCount + document.querySelectorAll('.dashboard-row').length;
353-
return totalPanelsRendered >= panelCount;
354-
}
355-
356-
const panelCount = document.querySelectorAll('.panel-solo').length || document.querySelectorAll("[class$='panel-container']").length;
357-
return (window as any).panelsRendered >= panelCount || panelCount === 0;
358-
},
359-
{
360-
timeout: options.timeout * 1000,
361-
},
362-
options.fullPageImage || isPDF
363-
);
331+
await waitForQueriesAndVisualizations(page, options);
364332
}, 'panelsRendered');
365333
} catch (err) {
366334
this.log.error('Error while waiting for the panels to load', 'url', options.url, 'err', err.stack);
@@ -395,8 +363,8 @@ export class Browser {
395363
left: 0,
396364
},
397365
path: options.filePath,
398-
scale: 1/scale,
399-
})
366+
scale: 1 / scale,
367+
});
400368
}
401369

402370
return page.screenshot({ path: options.filePath, fullPage: options.fullPageImage, captureBeyondViewport: options.fullPageImage || false });
@@ -588,3 +556,55 @@ export class Browser {
588556
}, zoomLevel);
589557
}
590558
}
559+
560+
declare global {
561+
interface Window {
562+
__grafanaSceneContext: object;
563+
__grafanaRunningQueryCount?: number;
564+
}
565+
}
566+
567+
async function waitForQueriesAndVisualizations(page: puppeteer.Page, options: ImageRenderOptions) {
568+
await page.waitForFunction(
569+
(isFullPage) => {
570+
if (window.__grafanaSceneContext) {
571+
return window.__grafanaRunningQueryCount === 0;
572+
}
573+
574+
/**
575+
* panelsRendered value is updated every time that a panel renders. It could happen multiple times in a same panel because scrolling. For full page screenshots
576+
* we can reach panelsRendered >= panelCount condition even if we have panels that are still loading data and their panelsRenderer value is 0, generating
577+
* a screenshot with loading panels. It's why the condition for full pages is different from a single panel.
578+
*/
579+
if (isFullPage) {
580+
/**
581+
* data-panelId is the total number of the panels in the dashboard. Rows included.
582+
* panel-content only exists in non-row panels when the data is loaded.
583+
* dashboard-row exists only in rows.
584+
*/
585+
const panelCount = document.querySelectorAll('[data-panelId]').length;
586+
const panelsRendered = document.querySelectorAll("[class$='panel-content']");
587+
let panelsRenderedCount = 0;
588+
panelsRendered.forEach((value: Element) => {
589+
if (value.childElementCount > 0) {
590+
panelsRenderedCount++;
591+
}
592+
});
593+
594+
const totalPanelsRendered = panelsRenderedCount + document.querySelectorAll('.dashboard-row').length;
595+
return totalPanelsRendered >= panelCount;
596+
}
597+
598+
const panelCount = document.querySelectorAll('.panel-solo').length || document.querySelectorAll("[class$='panel-container']").length;
599+
return (window as any).panelsRendered >= panelCount || panelCount === 0;
600+
},
601+
{
602+
timeout: options.timeout * 1000,
603+
polling: 'mutation',
604+
},
605+
options.fullPageImage
606+
);
607+
608+
// Give some more time for rendering to complete
609+
await new Promise((resolve) => setTimeout(resolve, 50));
610+
}

0 commit comments

Comments
 (0)