October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
JavaScript

How to Detect When a Power BI Report Finishes Loading with Puppeteer

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a Power BI report embedded with the JavaScript client, wait for the SDK’s rendered event—not merely Puppeteer’s network-idle state or Power BI’s earlier loaded event. Register the listener before embedding, resolve a readiness signal when rendered fires, and reject or report failures from the SDK’s error event. Then have Puppeteer await that signal with a bounded timeout.

What “finished loading” means in Power BI

Power BI exposes two events that are easy to confuse. Microsoft defines loaded as the point when the report is initialized; it does not mean the visuals have finished drawing. The rendered event indicates that the report is fully rendered using actual data. For a test or screenshot that needs the visible report, use rendered as the completion signal. See Microsoft’s best practices for faster performance in Power BI embedded analytics and phased embedding.

There is no universal number of seconds a report needs. Microsoft notes that loading time depends on report elements, data size, and query or measure complexity. Choose a timeout that fits your report and test environment rather than treating any one duration as a guarantee.

Best option when you control the embed host: bridge the SDK event to Puppeteer

Puppeteer runs against the host page, while an embedded report may run in a cross-origin iframe. Instead of trying to inspect Power BI’s internal DOM from Puppeteer, let the host page listen to the SDK event and publish a stable, application-owned readiness signal. Register both listeners immediately after embedding, before code that waits for the result.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Host-page event bridge

// Run in the host application when creating the report.
const report = powerbi.embed(
  document.querySelector('#report'),
  embedConfig
);

window.__powerBiReady = false;
window.__powerBiError = null;

report.on('error', event => {
  window.__powerBiError = event.detail;
});

report.on('rendered', () => {
  window.__powerBiReady = true;
});

This readiness flag is intentionally owned by your application. The error is retained separately so the test can distinguish an SDK failure from a wait that simply timed out.

Puppeteer test

const page = await browser.newPage();

await page.goto(reportUrl, {
  waitUntil: 'domcontentloaded',
  timeout: 60000,
});

await page.waitForFunction(
  () => window.__powerBiReady === true || window.__powerBiError !== null,
  { timeout: 60000 }
);

const error = await page.evaluate(() => window.__powerBiError);
if (error) {
  throw new Error(`Power BI report failed: ${JSON.stringify(error)}`);
}

// The report's initial rendered event has fired; capture or continue the test.
await page.screenshot({ path: 'report.png', fullPage: true });

The example’s 60-second limits are illustrative bounds, not a claim that reports normally finish in that time. Set navigation and report-readiness timeouts separately if your host page and report have different expected behavior. Puppeteer’s waitForFunction API waits for a page condition to become true and accepts a timeout.

Promise-based readiness

If application code needs to await readiness too, create a Promise before the embedding action and settle it from the SDK events. This avoids a race in which a fast report renders before the listener is attached.

let readyResolve;
let readyReject;

window.powerBiReady = new Promise((resolve, reject) => {
  readyResolve = resolve;
  readyReject = reject;
});

const report = powerbi.embed(embedContainer, embedConfig);

report.on('error', event => {
  readyReject(event.detail);
});

report.on('rendered', () => {
  window.__powerBiReady = true;
  readyResolve();
});

In production code, also initialize window.__powerBiReady to false and window.__powerBiError to null before calling powerbi.embed if Puppeteer will observe those values. If the Promise rejects, catch the rejection in application code or use the error marker pattern above so the page does not produce an unhandled rejection.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Phased embedding: wait for the render phase, not just load

With phased embedding, the host controls initialization and rendering separately. Call powerbi.load, wait for loaded when initialization is complete, perform any required setup, then call report.render. Resolve the Puppeteer readiness signal only from the subsequent rendered event. Microsoft documents that rendered fires when the report finishes rendering in its phased embedding guidance.

const report = powerbi.load(embedContainer, embedConfig);

report.on('error', event => {
  window.__powerBiError = event.detail;
});

report.on('loaded', async () => {
  // Apply any setup that must happen before rendering.
  report.on('rendered', () => {
    window.__powerBiReady = true;
  });

  await report.render();
});

Attach the rendered listener before calling render(). Otherwise, a quick render could complete before the listener is in place. Adapt setup and error handling to the lifecycle of your application rather than relying on internal report elements.

Detecting a later render after filters or navigation

The initial render is not the only time the report can emit rendered. It can fire again after interactions such as applying filters. A readiness flag that remains true after the first render cannot prove that a later action has completed. For interaction tests, create a fresh per-action Promise or reset a generation counter before triggering the action, then wait for the next render event.

function waitForNextRender(report, timeoutMs = 60000) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      report.off('rendered', onRendered);
      report.off('error', onError);
      reject(new Error(`No rendered event within ${timeoutMs} ms`));
    }, timeoutMs);

    function cleanup() {
      clearTimeout(timer);
      report.off('rendered', onRendered);
      report.off('error', onError);
    }

    function onRendered() {
      cleanup();
      resolve();
    }

    function onError(event) {
      cleanup();
      reject(new Error(JSON.stringify(event.detail)));
    }

    report.on('rendered', onRendered);
    report.on('error', onError);
  });
}

const nextRender = waitForNextRender(report);
await report.setFilters(filters);
await nextRender;

Register the per-action wait before invoking the action that should cause a render. Confirm that the action actually triggers the report update you intend to test; a filter operation that does not change the report may not produce the event your test expects.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When you cannot change the host page

If the page does not expose an SDK event or a readiness marker, Puppeteer cannot reliably infer full visual completion from the outer document alone. Use fallback checks in descending order of reliability, and label the result as a heuristic when it is based on visual or network activity.

  1. Wait for an application-owned signal. Prefer a stable container attribute or marker maintained by the host. For example: await page.waitForSelector('#report[data-report-ready="true"]', { timeout: 60000 });
  2. Use a visible loading indicator only as a heuristic. If the application has a loading logo or progress element, wait for it to become hidden. Its disappearance may indicate that a UI transition completed, but it is not as authoritative as the SDK’s rendered event.
  3. Use network idle only as a stabilization aid. After the application signal or heuristic, optionally wait for network activity to settle. Puppeteer’s waitForNetworkIdle API waits for network idleness and always waits at least the configured idle time. It does not establish that Power BI visuals are complete.

A simple marker bridge, when you can make a small host-page change, looks like this:

// Host page
const report = powerbi.embed(document.querySelector('#report'), config);
report.on('error', event => {
  window.__powerBiError = event.detail;
});
report.on('rendered', () => {
  document.querySelector('#report').setAttribute('data-report-ready', 'true');
});

// Puppeteer test
await page.goto(reportUrl, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('#report[data-report-ready="true"]', {
  timeout: 60000,
});
const error = await page.evaluate(() => window.__powerBiError || null);
if (error) throw new Error(JSON.stringify(error));

Why common Puppeteer waits give false confidence

networkidle0 on navigation

page.goto(url, {waitUntil: 'networkidle0'}) observes the page’s network activity; it does not certify that an embedded, cross-origin Power BI report has finished drawing its visuals. Work in an iframe, cached data, or later requests can make network idleness diverge from visual readiness. Use navigation completion to know the host document is available, then wait for the report-specific signal.

The loaded event

loaded marks initialization, not the completion of visual rendering. It is useful in phased embedding when you need to configure the report before calling render(); it is not the right final signal for a screenshot that must contain rendered visuals.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fixed sleeps

A fixed delay is wasteful on a fast run and unreliable on a slow or data-heavy one. Replace setTimeout-style waiting with an event or marker and a finite timeout. A timeout should fail with useful diagnostics, not silently proceed to capture an incomplete report.

Power BI internal DOM selectors

Selectors aimed at undocumented internal markup couple the test to implementation details that can change. Prefer the SDK event or a marker your application owns and can keep stable through UI redesigns.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Timeout diagnostics and failure handling

When the readiness wait expires, collect evidence that distinguishes a delayed report from a navigation, embed, or test failure. Include the SDK error detail whenever available.

  • Record the page URL and whether navigation completed.
  • Capture a screenshot of the current state and the browser console messages.
  • Record iframe URLs and failed network requests; this can reveal a failed embed or blocked resource without requiring Puppeteer to inspect a cross-origin frame’s internals.
  • Check whether the application-owned marker was initialized and whether the host registered the event listeners before embedding.
  • Report the configured timeout and the report or interaction being tested.

Use separate, finite bounds for navigation and report readiness. Reports vary with their contents and data path, so tune the readiness limit from your own environment and test cases; do not infer a universal completion time from a single run.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your goal is a screenshot file rather than testing Power BI’s SDK lifecycle, ScreenshotNeo can return a screenshot or PDF from one GET request. It is a website screenshot API and MCP server from Yorker Media. For example, the cURL call below captures a public page; replace the target URL with the page you need. See the ScreenshotNeo documentation for request options and response details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month without a card; paid plans start at $5 for 3,000 shots. It does not replace an SDK-event test when you need to assert that Power BI itself rendered successfully.

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

Frequently Asked Questions

Can Puppeteer listen directly for Power BI’s rendered event?

Not by itself when the event is emitted by client code inside a cross-origin embedded report. Have the host application bridge the SDK event to a marker or Promise that Puppeteer can observe.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does rendered fire only once?

No. It can fire again after filters or other interactions, so use a new wait tied to each action you are testing.

What should I capture when the wait times out?

Capture the current screenshot, console messages, iframe URLs, failed requests, and any Power BI error detail exposed by the host.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.