This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 2f82236b297 feat(docs): expand docs:screenshots generator with 
manifest and tutorial captures (#39444)
2f82236b297 is described below

commit 2f82236b29752bb7aa0508b7c1c4a37d1f00da11
Author: Evan Rusackas <[email protected]>
AuthorDate: Fri May 8 10:02:19 2026 -0700

    feat(docs): expand docs:screenshots generator with manifest and tutorial 
captures (#39444)
    
    Co-authored-by: Claude <[email protected]>
    Co-authored-by: Claude Sonnet 4.6 <[email protected]>
    Co-authored-by: Superset Dev <[email protected]>
---
 docs/static/img/screenshots/dashboard.jpg          |  Bin 136723 -> 134621 
bytes
 docs/static/img/screenshots/explore.jpg            |  Bin 106386 -> 118936 
bytes
 docs/static/img/screenshots/gallery.jpg            |  Bin 121316 -> 121175 
bytes
 docs/static/img/screenshots/sql_lab.jpg            |  Bin 101650 -> 98906 bytes
 docs/static/img/tutorial/create_pivot.png          |  Bin 80625 -> 245987 bytes
 .../img/tutorial/publish_button_dashboard.png      |  Bin 85940 -> 39607 bytes
 .../img/tutorial/tutorial_08_sources_tables.png    |  Bin 52421 -> 134075 bytes
 docs/static/img/tutorial/tutorial_chart_resize.png |  Bin 86804 -> 12623 bytes
 docs/static/img/tutorial/tutorial_edit_button.png  |  Bin 14099 -> 2176 bytes
 .../img/tutorial/tutorial_first_dashboard.png      |  Bin 99255 -> 37504 bytes
 docs/static/img/tutorial/tutorial_save_slice.png   |  Bin 144443 -> 21738 bytes
 .../generators/docs/docs-screenshots.spec.ts       |  509 ++++++-
 .../generators/docs/screenshot-manifest.yaml       | 1393 ++++++++++++++++++++
 .../playwright/generators/playwright.config.ts     |    1 +
 14 files changed, 1837 insertions(+), 66 deletions(-)

diff --git a/docs/static/img/screenshots/dashboard.jpg 
b/docs/static/img/screenshots/dashboard.jpg
index 9062d7a479d..2bea533aa7a 100644
Binary files a/docs/static/img/screenshots/dashboard.jpg and 
b/docs/static/img/screenshots/dashboard.jpg differ
diff --git a/docs/static/img/screenshots/explore.jpg 
b/docs/static/img/screenshots/explore.jpg
index 8ac41b65796..916f119bcd4 100644
Binary files a/docs/static/img/screenshots/explore.jpg and 
b/docs/static/img/screenshots/explore.jpg differ
diff --git a/docs/static/img/screenshots/gallery.jpg 
b/docs/static/img/screenshots/gallery.jpg
index 2312bd37982..e20749639dd 100644
Binary files a/docs/static/img/screenshots/gallery.jpg and 
b/docs/static/img/screenshots/gallery.jpg differ
diff --git a/docs/static/img/screenshots/sql_lab.jpg 
b/docs/static/img/screenshots/sql_lab.jpg
index d8f5a964adb..a3134bd8c98 100644
Binary files a/docs/static/img/screenshots/sql_lab.jpg and 
b/docs/static/img/screenshots/sql_lab.jpg differ
diff --git a/docs/static/img/tutorial/create_pivot.png 
b/docs/static/img/tutorial/create_pivot.png
index 2a24ee25153..52abb7fc048 100644
Binary files a/docs/static/img/tutorial/create_pivot.png and 
b/docs/static/img/tutorial/create_pivot.png differ
diff --git a/docs/static/img/tutorial/publish_button_dashboard.png 
b/docs/static/img/tutorial/publish_button_dashboard.png
index c20a097dfdc..9c4f29e4055 100644
Binary files a/docs/static/img/tutorial/publish_button_dashboard.png and 
b/docs/static/img/tutorial/publish_button_dashboard.png differ
diff --git a/docs/static/img/tutorial/tutorial_08_sources_tables.png 
b/docs/static/img/tutorial/tutorial_08_sources_tables.png
index 67252a706e9..dee2e47caa1 100644
Binary files a/docs/static/img/tutorial/tutorial_08_sources_tables.png and 
b/docs/static/img/tutorial/tutorial_08_sources_tables.png differ
diff --git a/docs/static/img/tutorial/tutorial_chart_resize.png 
b/docs/static/img/tutorial/tutorial_chart_resize.png
index 50983127aec..c40b90da3c2 100644
Binary files a/docs/static/img/tutorial/tutorial_chart_resize.png and 
b/docs/static/img/tutorial/tutorial_chart_resize.png differ
diff --git a/docs/static/img/tutorial/tutorial_edit_button.png 
b/docs/static/img/tutorial/tutorial_edit_button.png
index 9028fa5743f..6ae85634f8f 100644
Binary files a/docs/static/img/tutorial/tutorial_edit_button.png and 
b/docs/static/img/tutorial/tutorial_edit_button.png differ
diff --git a/docs/static/img/tutorial/tutorial_first_dashboard.png 
b/docs/static/img/tutorial/tutorial_first_dashboard.png
index f0382290766..ce925328f24 100644
Binary files a/docs/static/img/tutorial/tutorial_first_dashboard.png and 
b/docs/static/img/tutorial/tutorial_first_dashboard.png differ
diff --git a/docs/static/img/tutorial/tutorial_save_slice.png 
b/docs/static/img/tutorial/tutorial_save_slice.png
index 89e26773838..91ba6f9685d 100644
Binary files a/docs/static/img/tutorial/tutorial_save_slice.png and 
b/docs/static/img/tutorial/tutorial_save_slice.png differ
diff --git 
a/superset-frontend/playwright/generators/docs/docs-screenshots.spec.ts 
b/superset-frontend/playwright/generators/docs/docs-screenshots.spec.ts
index 5e3814b849e..d7bc20c45fe 100644
--- a/superset-frontend/playwright/generators/docs/docs-screenshots.spec.ts
+++ b/superset-frontend/playwright/generators/docs/docs-screenshots.spec.ts
@@ -25,76 +25,134 @@
  *
  * Run locally:
  *   cd superset-frontend
- *   npm run docs:screenshots
+ *   PLAYWRIGHT_BASE_URL=http://localhost:8088 PLAYWRIGHT_ADMIN_PASSWORD=admin 
npm run docs:screenshots
  *
  * Or directly:
  *   npx playwright test --config=playwright/generators/playwright.config.ts 
docs/
  *
- * Screenshots are saved to docs/static/img/screenshots/.
+ * Screenshots are saved under docs/static/img/.
+ * As new screenshots are scripted, entries are removed from 
screenshot-manifest.yaml
+ * and the output path moves from that manifest into the test below.
  */
 
 import path from 'path';
+import { Page } from '@playwright/test';
 import { test, expect } from '@playwright/test';
 import { URL } from '../../utils/urls';
+import { apiDelete, apiGet } from '../../helpers/api/requests';
 
-const SCREENSHOTS_DIR = path.resolve(
-  __dirname,
-  '../../../../docs/static/img/screenshots',
-);
+const DOCS_STATIC = path.resolve(__dirname, '../../../../docs/static/img');
+const SCREENSHOTS_DIR = path.join(DOCS_STATIC, 'screenshots');
+const TUTORIAL_DIR = path.join(DOCS_STATIC, 'tutorial');
 
-test('chart gallery screenshot', async ({ page }) => {
-  await page.goto(URL.CHART_ADD);
-
-  // Wait for chart creation page to load
-  await expect(page.getByText('Choose chart type')).toBeVisible({
-    timeout: 15000,
-  });
-  await page.getByRole('tab', { name: 'All charts' }).click();
-
-  // Wait for viz gallery to render chart type thumbnails
-  const vizGallery = page.locator('.viz-gallery');
-  await expect(vizGallery).toBeVisible();
-  await expect(
-    vizGallery.locator('[data-test="viztype-selector-container"]').first(),
-  ).toBeVisible();
-
-  await vizGallery.screenshot({
-    path: path.join(SCREENSHOTS_DIR, 'gallery.jpg'),
-    type: 'jpeg',
-  });
-});
+/**
+ * Waits for animations and async renders to settle before taking a screenshot.
+ * ECharts entry animations, image lazy-loading, and other async UI updates
+ * require a short pause that can't be expressed as a deterministic wait 
condition.
+ */
+async function settle(page: Page, ms = 1000): Promise<void> {
+  await page.waitForTimeout(ms);
+}
 
-test('dashboard screenshot', async ({ page }) => {
-  // Navigate to Sales Dashboard via the dashboard list (slug is null)
+/**
+ * Navigates to the Sales Dashboard (from example data) and waits for charts
+ * to finish rendering. Used by several tutorial screenshots that show the
+ * dashboard in view or edit mode.
+ */
+async function openSalesDashboard(page: Page): Promise<void> {
   await page.goto(URL.DASHBOARD_LIST);
   const searchInput = page.getByPlaceholder('Type a value');
   await expect(searchInput).toBeVisible({ timeout: 15000 });
   await searchInput.fill('Sales Dashboard');
   await searchInput.press('Enter');
 
-  // Click the Sales Dashboard link
   const dashboardLink = page.getByRole('link', { name: /sales dashboard/i });
   await expect(dashboardLink).toBeVisible({ timeout: 10000 });
   await dashboardLink.click();
 
-  // Wait for dashboard to fully render
   const dashboardWrapper = page.locator(
     '[data-test="dashboard-content-wrapper"]',
   );
   await expect(dashboardWrapper).toBeVisible({ timeout: 30000 });
-
-  // Wait for chart holders to appear, then wait for all loading spinners to 
clear
   await expect(
     page.locator('.dashboard-component-chart-holder').first(),
   ).toBeVisible({ timeout: 15000 });
   await expect(
     dashboardWrapper.locator('[data-test="loading-indicator"]'),
   ).toHaveCount(0, { timeout: 30000 });
-
-  // Wait for at least one chart to finish rendering (ECharts renders to 
canvas)
   await expect(
     page.locator('.dashboard-component-chart-holder canvas').first(),
   ).toBeVisible({ timeout: 15000 });
+}
+
+/**
+ * Delete all dashboards matching the given exact title, along with the
+ * charts attached to them. Used by the save-flow test to clean up after
+ * itself and to recover from prior failed runs (idempotent pre-cleanup).
+ *
+ * Only safe because the title is unique to the test ("Superset Duper
+ * Sales Dashboard"); don't reuse this against titles that could match
+ * example-data dashboards.
+ */
+async function deleteDashboardByTitle(
+  page: Page,
+  title: string,
+): Promise<void> {
+  const filter = `(filters:!((col:dashboard_title,opr:eq,value:'${title}')))`;
+  const resp = await apiGet(page, 'api/v1/dashboard/', {
+    params: { q: filter },
+    failOnStatusCode: false,
+  });
+  if (!resp.ok()) return;
+  const body = await resp.json();
+  const dashboards: { id: number }[] = body.result || [];
+
+  for (const dash of dashboards) {
+    const chartsResp = await apiGet(
+      page,
+      `api/v1/dashboard/${dash.id}/charts`,
+      { failOnStatusCode: false },
+    );
+    const chartIds: number[] = chartsResp.ok()
+      ? ((await chartsResp.json()).result || [])
+          .map((c: { id?: number }) => c.id)
+          .filter((id: unknown): id is number => typeof id === 'number')
+      : [];
+
+    await apiDelete(page, `api/v1/dashboard/${dash.id}`, {
+      failOnStatusCode: false,
+    });
+    for (const id of chartIds) {
+      await apiDelete(page, `api/v1/chart/${id}`, { failOnStatusCode: false });
+    }
+  }
+}
+
+test('chart gallery screenshot', async ({ page }) => {
+  await page.goto(URL.CHART_ADD);
+
+  // Wait for chart creation page to load
+  await expect(page.getByText('Choose chart type')).toBeVisible({
+    timeout: 15000,
+  });
+  await page.getByRole('tab', { name: 'All charts' }).click();
+
+  // Wait for viz gallery to render chart type thumbnails
+  const vizGallery = page.locator('.viz-gallery');
+  await expect(vizGallery).toBeVisible();
+  await expect(
+    vizGallery.locator('[data-test="viztype-selector-container"]').first(),
+  ).toBeVisible();
+
+  await settle(page);
+  await vizGallery.screenshot({
+    path: path.join(SCREENSHOTS_DIR, 'gallery.jpg'),
+    type: 'jpeg',
+  });
+});
+
+test('dashboard screenshot', async ({ page }) => {
+  await openSalesDashboard(page);
 
   // Open the filter bar (collapsed by default)
   const expandButton = page.locator('[data-test="filter-bar__expand-button"]');
@@ -109,6 +167,8 @@ test('dashboard screenshot', async ({ page }) => {
     ).toBeVisible({ timeout: 5000 });
   }
 
+  // Allow ECharts entry animations to finish before capturing
+  await settle(page);
   await page.screenshot({
     path: path.join(SCREENSHOTS_DIR, 'dashboard.jpg'),
     type: 'jpeg',
@@ -143,6 +203,7 @@ test('chart editor screenshot', async ({ page }) => {
     timeout: 15000,
   });
 
+  await settle(page);
   await page.screenshot({
     path: path.join(SCREENSHOTS_DIR, 'explore.jpg'),
     type: 'jpeg',
@@ -151,7 +212,7 @@ test('chart editor screenshot', async ({ page }) => {
 });
 
 test('SQL Lab screenshot', async ({ page }) => {
-  // SQL Lab has many interactive steps (schema, table, query, results) — 
allow extra time
+  // SQL Lab has many interactive steps — allow extra time
   test.setTimeout(90000);
   await page.goto(URL.SQLLAB);
 
@@ -168,34 +229,7 @@ test('SQL Lab screenshot', async ({ page }) => {
   }
   await expect(aceEditor).toBeVisible({ timeout: 15000 });
 
-  // Select the "public" schema so we can pick a table from the left panel
-  const schemaSelect = page.locator('#select-schema');
-  await expect(schemaSelect).toBeEnabled({ timeout: 10000 });
-  await schemaSelect.click({ force: true });
-  await schemaSelect.fill('public');
-  await page.getByRole('option', { name: 'public' }).click();
-
-  // Wait for table list to load after schema change, then select birth_names
-  const tableSelectWrapper = page
-    .locator('.ant-select')
-    .filter({ has: page.locator('#select-table') });
-  await expect(tableSelectWrapper).toBeVisible({ timeout: 10000 });
-  await tableSelectWrapper.click();
-  await page.keyboard.type('birth_names');
-  // Wait for the filtered option to appear in the DOM, then select it
-  const tableOption = page
-    .locator('.ant-select-dropdown [role="option"]')
-    .filter({ hasText: 'birth_names' });
-  await expect(tableOption).toBeAttached({ timeout: 10000 });
-  await page.keyboard.press('Enter');
-
-  // Wait for table schema to load and show columns in the left panel
-  await expect(page.locator('[data-test="col-name"]').first()).toBeVisible({
-    timeout: 15000,
-  });
-
-  // Close the table dropdown by clicking elsewhere, then switch to the query 
tab
-  await page.locator('[data-test="sql-editor-tabs"]').first().click();
+  // Click the active query tab to ensure focus is on the editor pane
   await page.getByText('Untitled Query').first().click();
 
   // Write a multi-line SELECT with explicit columns to fill the editor
@@ -205,8 +239,8 @@ test('SQL Lab screenshot', async ({ page }) => {
     'SELECT\n  ds,\n  name,\n  gender,\n  state,\n  num\nFROM 
birth_names\nLIMIT 100',
   );
 
-  // Run the query
-  const runButton = page.getByText('Run', { exact: true });
+  // Run the query — use the stable data-test attribute on the action button
+  const runButton = page.locator('[data-test="run-query-action"]');
   await expect(runButton).toBeVisible();
   await runButton.click();
 
@@ -222,9 +256,352 @@ test('SQL Lab screenshot', async ({ page }) => {
   await page.mouse.move(0, 0);
   await expect(page.getByRole('tooltip')).toHaveCount(0, { timeout: 2000 });
 
+  await settle(page);
   await page.screenshot({
     path: path.join(SCREENSHOTS_DIR, 'sql_lab.jpg'),
     type: 'jpeg',
     fullPage: true,
   });
 });
+
+// ---------------------------------------------------------------------------
+// Tutorial screenshots
+// ---------------------------------------------------------------------------
+
+test('datasets list screenshot', async ({ page }) => {
+  await page.goto(URL.DATASET_LIST);
+
+  const table = page.locator('[data-test="listview-table"]');
+  await expect(table).toBeVisible({ timeout: 15000 });
+  // Wait for at least one visible data row (skip ant-table-measure-row which 
is always hidden)
+  await expect(
+    table.locator('tbody tr:not(.ant-table-measure-row)').first(),
+  ).toBeVisible({ timeout: 10000 });
+
+  // Viewport screenshot (not fullPage) captures the SubMenu — showing the
+  // "Datasets" nav item, Bulk Select button, and + Dataset button — plus the
+  // top of the table. This is more informative than screenshotting the table 
alone.
+  await settle(page);
+  await page.screenshot({
+    path: path.join(TUTORIAL_DIR, 'tutorial_08_sources_tables.png'),
+    type: 'png',
+  });
+});
+
+test('chart type picker screenshot', async ({ page }) => {
+  await page.goto(URL.CHART_ADD);
+
+  // Wait for the dataset step to appear (step title is first match; 
placeholder is second)
+  await expect(page.getByText('Choose a dataset').first()).toBeVisible({
+    timeout: 15000,
+  });
+
+  // Open the dataset selector and choose birth_names
+  await page.getByTestId('Dataset').click();
+  await page.keyboard.type('birth_names');
+  // The dataset select uses a hidden ARIA listbox — the visible popup is a 
portal.
+  // Wait for the first option to appear in the DOM, then select it via 
keyboard.
+  await expect(
+    page.locator('[role="listbox"] [role="option"]').first(),
+  ).toBeAttached({ timeout: 10000 });
+  await page.keyboard.press('ArrowDown');
+  await page.keyboard.press('Enter');
+
+  // Open the chart gallery and wait for thumbnails to render
+  await expect(page.getByText('Choose chart type')).toBeVisible({
+    timeout: 10000,
+  });
+  await page.getByRole('tab', { name: 'All charts' }).click();
+  const vizGallery = page.locator('.viz-gallery');
+  await expect(vizGallery).toBeVisible();
+  await expect(
+    vizGallery.locator('[data-test="viztype-selector-container"]').first(),
+  ).toBeVisible();
+
+  // Select the Pivot Table chart type
+  await vizGallery
+    .locator('[data-test="viztype-selector-container"]')
+    .filter({ hasText: 'Pivot Table' })
+    .first()
+    .click();
+
+  // Allow thumbnails to finish loading and selection state to render
+  await settle(page);
+
+  // Viewport screenshot shows the dataset step (birth_names selected) and
+  // the chart type gallery (Pivot Table highlighted)
+  await page.screenshot({
+    path: path.join(TUTORIAL_DIR, 'create_pivot.png'),
+    type: 'png',
+  });
+});
+
+test('publish button dashboard screenshot', async ({ page }) => {
+  // Toggle Sales Dashboard to Draft, hover the label so the tooltip renders,
+  // then capture the header area plus enough room below for the tooltip.
+  // Always restores the dashboard to Published at the end.
+  await openSalesDashboard(page);
+
+  const publishedLabel = page.getByText('Published', { exact: true }).first();
+  await expect(publishedLabel).toBeVisible({ timeout: 10000 });
+  await publishedLabel.click();
+
+  const draftLabel = page.getByText('Draft', { exact: true }).first();
+  await expect(draftLabel).toBeVisible({ timeout: 10000 });
+
+  try {
+    await draftLabel.hover();
+    await expect(page.getByRole('tooltip')).toBeVisible({ timeout: 5000 });
+    await settle(page, 500);
+
+    const headerBox = await page
+      .locator('[data-test="dashboard-header-container"]')
+      .boundingBox();
+    if (!headerBox) {
+      throw new Error('Could not locate dashboard header container');
+    }
+    await page.screenshot({
+      path: path.join(TUTORIAL_DIR, 'publish_button_dashboard.png'),
+      type: 'png',
+      clip: {
+        x: headerBox.x,
+        y: headerBox.y,
+        width: headerBox.width,
+        height: headerBox.height + 140,
+      },
+    });
+  } finally {
+    // Restore: click Draft to re-publish so other runs start from a clean 
state
+    await page.mouse.move(0, 0);
+    await draftLabel.click();
+    await expect(
+      page.getByText('Published', { exact: true }).first(),
+    ).toBeVisible({ timeout: 10000 });
+  }
+});
+
+test('edit button screenshot', async ({ page }) => {
+  // Capture the right-side action buttons (Edit dashboard + "..." menu)
+  // rather than the edit button in isolation.
+  await openSalesDashboard(page);
+  await settle(page);
+
+  const rightPanel = page.locator('.right-button-panel');
+  await expect(rightPanel).toBeVisible({ timeout: 5000 });
+  await rightPanel.screenshot({
+    path: path.join(TUTORIAL_DIR, 'tutorial_edit_button.png'),
+    type: 'png',
+  });
+});
+
+test('chart resize screenshot', async ({ page }) => {
+  // Enter edit mode, start a resize drag on the right-edge handle, then
+  // screenshot the chart mid-drag. While `DashboardGrid` is in the resizing
+  // state it renders vertical `grid-column-guide` overlays across the grid
+  // and the chart gets a blue `--resizing` outline — that's the state the
+  // original tutorial screenshot was capturing.
+  await openSalesDashboard(page);
+
+  const editButton = page.locator('[data-test="edit-dashboard-button"]');
+  await expect(editButton).toBeVisible();
+  await editButton.click();
+
+  await expect(
+    page.locator('[data-test="dashboard-builder-sidepane"]'),
+  ).toBeVisible({ timeout: 10000 });
+
+  const chart = page.locator('.dashboard-component-chart-holder').first();
+  await expect(chart).toBeVisible();
+  const chartBox = await chart.boundingBox();
+  if (!chartBox) {
+    throw new Error('Could not locate chart bounding box');
+  }
+
+  // Hover over the chart so the on-hover action buttons (drag/trash/settings)
+  // and resize handles become visible.
+  await page.mouse.move(
+    chartBox.x + chartBox.width / 2,
+    chartBox.y + chartBox.height / 2,
+  );
+  await settle(page, 200);
+
+  // The right-edge handle is a `<span>` added by re-resizable with our
+  // custom class. Locating it by class is more reliable than computing
+  // coordinates from the chart-holder (which isn't the full resizable box).
+  const rightHandle = page
+    .locator('.resizable-container-handle--right')
+    .first();
+  await expect(rightHandle).toBeVisible();
+  const handleBox = await rightHandle.boundingBox();
+  if (!handleBox) {
+    throw new Error('Could not locate right-edge resize handle');
+  }
+  const handleX = handleBox.x + handleBox.width / 2;
+  const handleY = handleBox.y + handleBox.height / 2;
+
+  await page.mouse.move(handleX, handleY);
+  await page.mouse.down();
+  // Move far enough to snap at least one grid column, which puts
+  // DashboardGrid into isResizing=true so the column guides render.
+  await page.mouse.move(handleX + 80, handleY, { steps: 10 });
+  await settle(page, 500);
+
+  // Clip to the chart area plus a left gutter for the hover action rail
+  // and right padding that reaches past the dragged handle position.
+  const leftGutter = 32;
+  const rightPadding = 100;
+  const topPadding = 16;
+  const bottomPadding = 24;
+  await page.screenshot({
+    path: path.join(TUTORIAL_DIR, 'tutorial_chart_resize.png'),
+    type: 'png',
+    clip: {
+      x: Math.max(0, chartBox.x - leftGutter),
+      y: Math.max(0, chartBox.y - topPadding),
+      width: chartBox.width + leftGutter + rightPadding,
+      height: chartBox.height + topPadding + bottomPadding,
+    },
+  });
+
+  // Release back at the start to avoid persisting a size change. Edit-mode
+  // changes aren't saved (we never click the dashboard Save button).
+  await page.mouse.move(handleX, handleY, { steps: 6 });
+  await page.mouse.up();
+});
+
+test('save flow and first dashboard screenshots', async ({ page }) => {
+  // Captures two linked tutorial screenshots in a single flow so the second
+  // faithfully shows the dashboard the user just created:
+  //   1. tutorial_save_slice.png — Save modal with the "Add to dashboard"
+  //      dropdown surfacing a creatable option for a new dashboard.
+  //   2. tutorial_first_dashboard.png — the freshly-created dashboard with
+  //      the single saved chart (matches the tutorial narrative).
+  //
+  // Creates and then deletes a "Superset Duper Sales Dashboard" dashboard
+  // plus the duplicate chart it owns. Pre-cleans in case a prior run failed.
+  const NEW_DASHBOARD_NAME = 'Superset Duper Sales Dashboard';
+  await deleteDashboardByTitle(page, NEW_DASHBOARD_NAME);
+
+  // 1100px is wide enough to show the full "Superset Duper Sales Dashboard"
+  // title alongside the header actions without truncation.
+  await page.setViewportSize({ width: 1100, height: 800 });
+  await page.goto(URL.CHART_LIST);
+
+  const searchInput = page.getByPlaceholder('Type a value');
+  await expect(searchInput).toBeVisible({ timeout: 15000 });
+  await searchInput.fill('Scatter Plot');
+  await searchInput.press('Enter');
+
+  const chartLink = page.getByRole('link', { name: /scatter plot/i });
+  await expect(chartLink).toBeVisible({ timeout: 10000 });
+  await chartLink.click();
+
+  await page.waitForURL('**/explore/**', { timeout: 15000 });
+  const sliceContainer = page.locator('[data-test="slice-container"]');
+  await expect(sliceContainer).toBeVisible({ timeout: 15000 });
+  await expect(
+    sliceContainer.locator('[data-test="loading-indicator"]'),
+  ).toHaveCount(0, { timeout: 15000 });
+
+  const saveButton = page.locator('[data-test="query-save-button"]');
+  await expect(saveButton).toBeVisible({ timeout: 10000 });
+  await saveButton.click();
+
+  const modal = page.locator('.ant-modal-content').filter({
+    has: page.locator('[data-test="save-modal-body"]'),
+  });
+  await expect(modal).toBeVisible({ timeout: 10000 });
+
+  // Open the "Add to dashboard" select and type a new dashboard name so
+  // the dropdown surfaces the creatable option.
+  const dashboardSelect = page.getByRole('combobox', {
+    name: /select a dashboard/i,
+  });
+  await dashboardSelect.click();
+  await page.keyboard.type(NEW_DASHBOARD_NAME);
+
+  // Ant Design portals the visible dropdown with the class
+  // `.ant-select-item-option` on each option (distinct from the hidden
+  // ARIA listbox options rendered inside the combobox itself).
+  const createOption = page
+    .locator('.ant-select-item-option')
+    .filter({ hasText: NEW_DASHBOARD_NAME });
+  await expect(createOption).toBeVisible({ timeout: 10000 });
+  await settle(page);
+
+  try {
+    // Screenshot 1: save modal + portaled dropdown.
+    const modalBox = await modal.boundingBox();
+    const optionBox = await createOption.boundingBox();
+    if (!modalBox || !optionBox) {
+      throw new Error('Could not locate save modal or create-option');
+    }
+    const padding = 16;
+    const top = Math.max(0, modalBox.y - padding);
+    const bottom = optionBox.y + optionBox.height + padding;
+    await page.screenshot({
+      path: path.join(TUTORIAL_DIR, 'tutorial_save_slice.png'),
+      type: 'png',
+      clip: {
+        x: Math.max(0, modalBox.x - padding),
+        y: top,
+        width: modalBox.width + padding * 2,
+        height: bottom - top,
+      },
+    });
+
+    // Pick the creatable option, then click "Save & go to dashboard" so the
+    // backend creates the dashboard + slice and redirects us to the new one.
+    await createOption.click();
+    const saveAndGotoBtn = page.locator('#btn_modal_save_goto_dash');
+    await expect(saveAndGotoBtn).toBeEnabled({ timeout: 5000 });
+    await saveAndGotoBtn.click();
+
+    await page.waitForURL(/\/dashboard\/[^/]+\/?/, { timeout: 30000 });
+    await expect(
+      page.locator('[data-test="dashboard-content-wrapper"]'),
+    ).toBeVisible({ timeout: 30000 });
+    await expect(
+      page.locator('.dashboard-component-chart-holder').first(),
+    ).toBeVisible({ timeout: 30000 });
+    await expect(
+      page.locator('.dashboard-component-chart-holder canvas').first(),
+    ).toBeVisible({ timeout: 15000 });
+
+    // Dismiss the "Chart [X] has been saved" toast so it doesn't appear in
+    // the screenshot. The close button is inside the toast container.
+    const toast = page.locator('[data-test="toast-container"]').first();
+    if (await toast.isVisible().catch(() => false)) {
+      await toast.locator('.toast__close').click();
+      await expect(toast).toBeHidden({ timeout: 5000 });
+    }
+    await settle(page);
+
+    // Screenshot 2: the newly-created single-chart dashboard (title + chart).
+    const headerBox = await page
+      .locator('[data-test="dashboard-header-wrapper"]')
+      .boundingBox();
+    const chartBox = await page
+      .locator('.dashboard-component-chart-holder')
+      .first()
+      .boundingBox();
+    if (!headerBox || !chartBox) {
+      throw new Error('Could not locate dashboard header or chart');
+    }
+    // Trim right edge to just past the chart so the screenshot isn't padded
+    // with empty grid space.
+    const rightPadding = 16;
+    await page.screenshot({
+      path: path.join(TUTORIAL_DIR, 'tutorial_first_dashboard.png'),
+      type: 'png',
+      clip: {
+        x: 0,
+        y: headerBox.y,
+        width: Math.min(1100, chartBox.x + chartBox.width + rightPadding),
+        height: chartBox.y + chartBox.height - headerBox.y + 16,
+      },
+    });
+  } finally {
+    await deleteDashboardByTitle(page, NEW_DASHBOARD_NAME);
+  }
+});
diff --git 
a/superset-frontend/playwright/generators/docs/screenshot-manifest.yaml 
b/superset-frontend/playwright/generators/docs/screenshot-manifest.yaml
new file mode 100644
index 00000000000..1d10dd53034
--- /dev/null
+++ b/superset-frontend/playwright/generators/docs/screenshot-manifest.yaml
@@ -0,0 +1,1393 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Superset Documentation Image Manifest
+#
+# This file is the source of truth for images used in the Superset docs.
+# It is consumed by the docs:screenshots npm script to auto-capture UI 
screenshots.
+#
+# To enable screenshot generation for an entry, fill in:
+#   app_path  - Superset app URL path to navigate to (e.g. chart/add)
+#              relative, no leading slash; resolved against PLAYWRIGHT_BASE_URL
+#   selector  - CSS selector for the element to capture
+#              (null = full-page screenshot)
+#
+# type values: screenshot | tutorial | site-asset | database-logo | badge | 
external | community
+# database-logo, badge, external, community: inventory only, no generation.
+
+images:
+  # --- tutorial (37) ---
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_01_add_database_connection.png";
+    output_path: 
docs/static/img/tutorial/tutorial_01_add_database_connection.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_02_select_database.png";
+    output_path: docs/static/img/tutorial/tutorial_02_select_database.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: .ant-modal-content
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_03a_database_connection_string_link.png";
+    output_path: 
docs/static/img/tutorial/tutorial_03a_database_connection_string_link.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: .ant-modal-content
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_03b_connection_string_details.png";
+    output_path: 
docs/static/img/tutorial/tutorial_03b_connection_string_details.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: .ant-modal-content
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_09_add_new_table.png";
+    output_path: docs/static/img/tutorial/tutorial_09_add_new_table.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: .ant-modal-content
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_calculated_column.png";
+    output_path: docs/static/img/tutorial/tutorial_calculated_column.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_column_properties.png";
+    output_path: docs/static/img/tutorial/tutorial_column_properties.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_dashboard_access.png";
+    output_path: docs/static/img/tutorial/tutorial_dashboard_access.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: .ant-modal-content
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_explore_run.jpg";
+    output_path: docs/static/img/tutorial/tutorial_explore_run.jpg
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_explore_settings.jpg";
+    output_path: docs/static/img/tutorial/tutorial_explore_settings.jpg
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_launch_explore.png";
+    output_path: docs/static/img/tutorial/tutorial_launch_explore.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/creating-your-first-dashboard";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_sql_metric.png";
+    output_path: docs/static/img/tutorial/tutorial_sql_metric.png
+    alt: ""
+    source_file: docs/using-superset/creating-your-first-dashboard.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/advanced_analytics_base.png";
+    output_path: docs/static/img/tutorial/advanced_analytics_base.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/allow-file-uploads.png";
+    output_path: docs/static/img/tutorial/allow-file-uploads.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: .ant-modal-content
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/annotation.png";
+    output_path: docs/static/img/tutorial/annotation.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/annotation_settings.png";
+    output_path: docs/static/img/tutorial/annotation_settings.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/average_aggregate_for_cost.png";
+    output_path: docs/static/img/tutorial/average_aggregate_for_cost.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/blue_bar_insert_component.png";
+    output_path: docs/static/img/tutorial/blue_bar_insert_component.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/csv_to_database_configuration.png";
+    output_path: docs/static/img/tutorial/csv_to_database_configuration.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/edit-record.png";
+    output_path: docs/static/img/tutorial/edit-record.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/edit_annotation.png";
+    output_path: docs/static/img/tutorial/edit_annotation.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: .ant-modal-content
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/markdown.png";
+    output_path: docs/static/img/tutorial/markdown.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/no_filter_on_time_filter.png";
+    output_path: docs/static/img/tutorial/no_filter_on_time_filter.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/parse_dates_column.png";
+    output_path: docs/static/img/tutorial/parse_dates_column.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/publish_dashboard.png";
+    output_path: docs/static/img/tutorial/publish_dashboard.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"dashboard-header-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/resample.png";
+    output_path: docs/static/img/tutorial/resample.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/resize_tutorial_table_on_dashboard.png";
+    output_path: 
docs/static/img/tutorial/resize_tutorial_table_on_dashboard.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"dashboard-content-wrapper\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/rolling_mean.png";
+    output_path: docs/static/img/tutorial/rolling_mean.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/save_tutorial_table.png";
+    output_path: docs/static/img/tutorial/save_tutorial_table.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: .ant-modal-content
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/select_dates_pivot_table.png";
+    output_path: docs/static/img/tutorial/select_dates_pivot_table.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/sum_cost_column.png";
+    output_path: docs/static/img/tutorial/sum_cost_column.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/time_comparison_absolute_difference.png";
+    output_path: 
docs/static/img/tutorial/time_comparison_absolute_difference.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/time_comparison_two_series.png";
+    output_path: docs/static/img/tutorial/time_comparison_two_series.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_line_chart.png";
+    output_path: docs/static/img/tutorial/tutorial_line_chart.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: 
"https://superset.apache.org/img/tutorial/tutorial_pivot_table.png";
+    output_path: docs/static/img/tutorial/tutorial_pivot_table.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/tutorial_table.png";
+    output_path: docs/static/img/tutorial/tutorial_table.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: "[data-test=\"slice-container\"]"
+  - type: tutorial
+    page_url: 
"https://superset.apache.org/user-docs/using-superset/exploring-data";
+    image_url: "https://superset.apache.org/img/tutorial/upload_a_csv.png";
+    output_path: docs/static/img/tutorial/upload_a_csv.png
+    alt: ""
+    source_file: docs/using-superset/exploring-data.mdx
+    app_path: null
+    selector: null
+  # --- site-asset (19) ---
+  - type: site-asset
+    page_url: 
"https://superset.apache.org/admin-docs/installation/docker-compose";
+    image_url: "https://superset.apache.org/img/docker-compose.webp";
+    output_path: docs/static/img/docker-compose.webp
+    alt: ""
+    source_file: admin_docs/installation/docker-compose.mdx
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/admin-docs/installation/kubernetes";
+    image_url: "https://superset.apache.org/img/k8s.png";
+    output_path: docs/static/img/k8s.png
+    alt: ""
+    source_file: admin_docs/installation/kubernetes.mdx
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/admin-docs/installation/pypi";
+    image_url: "https://superset.apache.org/img/pypi.png";
+    output_path: docs/static/img/pypi.png
+    alt: ""
+    source_file: admin_docs/installation/pypi.mdx
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/components";
+    image_url: "https://superset.apache.org/img/atomic-design.png";
+    output_path: docs/static/img/atomic-design.png
+    alt: Atoms = Foundations, Molecules = Components, Organisms = Patterns, 
Templates = Templates, Pages / Screens = Features
+    source_file: developer_docs/components/index.mdx
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: "https://superset.apache.org/img/extensions/api-explorer.png";
+    output_path: docs/static/img/extensions/api-explorer.png
+    alt: Extensions API Explorer
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: "https://superset.apache.org/img/extensions/editor-snippets.png";
+    output_path: docs/static/img/extensions/editor-snippets.png
+    alt: Editor Snippets
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: "https://superset.apache.org/img/extensions/editors-bundle.png";
+    output_path: docs/static/img/extensions/editors-bundle.png
+    alt: Editors Bundle
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: "https://superset.apache.org/img/extensions/gsheets-export.png";
+    output_path: docs/static/img/extensions/gsheets-export.png
+    alt: SQL Lab Export to Google Sheets
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: "https://superset.apache.org/img/extensions/parquet-export.png";
+    output_path: docs/static/img/extensions/parquet-export.png
+    alt: SQL Lab Export to Parquet
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: 
"https://superset.apache.org/img/extensions/query-comparison.png";
+    output_path: docs/static/img/extensions/query-comparison.png
+    alt: Query Comparison
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: "https://superset.apache.org/img/extensions/query-estimator.png";
+    output_path: docs/static/img/extensions/query-estimator.png
+    alt: Query Estimator
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: "https://superset.apache.org/img/extensions/result-stats.png";
+    output_path: docs/static/img/extensions/result-stats.png
+    alt: Result Stats
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: 
"https://superset.apache.org/img/extensions/sql-flow-visualizer.png";
+    output_path: docs/static/img/extensions/sql-flow-visualizer.png
+    alt: SQL Flow Visualizer
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/developer-docs/extensions/registry";
+    image_url: "https://superset.apache.org/img/extensions/your-screenshot.png";
+    output_path: docs/static/img/extensions/your-screenshot.png
+    alt: Your Extension
+    source_file: developer_docs/extensions/registry.md
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/src/pages";
+    image_url: "https://superset.apache.org/img/check-icon.svg";
+    output_path: docs/static/img/check-icon.svg
+    alt: check-icon
+    source_file: src/pages/index.tsx
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/src/pages";
+    image_url: "https://superset.apache.org/img/hero-screenshot.jpg";
+    output_path: docs/static/img/hero-screenshot.jpg
+    alt: hero-screenshot
+    source_file: src/pages/index.tsx
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/src/pages";
+    image_url: "https://superset.apache.org/img/superset-mark-dark.svg";
+    output_path: docs/static/img/superset-mark-dark.svg
+    alt: Superset mark
+    source_file: src/pages/index.tsx
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/src/pages/community";
+    image_url: "https://superset.apache.org/img/calendar-icon.svg";
+    output_path: docs/static/img/calendar-icon.svg
+    alt: calendar-icon
+    source_file: src/pages/community.tsx
+    app_path: null
+    selector: null
+  - type: site-asset
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/superset-logo-horiz-apache.svg";
+    output_path: docs/static/img/superset-logo-horiz-apache.svg
+    alt: Superset logo (light)
+    source_file: docs/index.mdx
+    app_path: null
+    selector: null
+  # --- community (1) ---
+  - type: community
+    page_url: "https://superset.apache.org/src/pages";
+    image_url: "https://superset.apache.org/img/community/line.png";
+    output_path: docs/static/img/community/line.png
+    alt: line
+    source_file: src/pages/index.tsx
+    selector: null
+  # --- external (6) ---
+  - type: external
+    page_url: 
"https://superset.apache.org/developer-docs/contributing/submitting-pr";
+    image_url: link-to-after-screenshot
+    alt: After
+    source_file: developer_docs/contributing/submitting-pr.md
+    selector: null
+  - type: external
+    page_url: 
"https://superset.apache.org/developer-docs/contributing/submitting-pr";
+    image_url: link-to-before-screenshot
+    alt: Before
+    source_file: developer_docs/contributing/submitting-pr.md
+    selector: null
+  - type: external
+    page_url: 
"https://superset.apache.org/developer-docs/extensions/architecture";
+    image_url: 
"https://github.com/user-attachments/assets/cc2a41df-55a4-48c8-b056-35f7a1e567c6";
+    alt: Extension System Architecture
+    source_file: developer_docs/extensions/architecture.md
+    selector: null
+  - type: external
+    page_url: 
"https://superset.apache.org/developer-docs/extensions/architecture";
+    image_url: 
"https://github.com/user-attachments/assets/e5e4d2ae-e8b5-4d17-a2a1-3667c65f25ca";
+    alt: Module Federation Flow
+    source_file: developer_docs/extensions/architecture.md
+    selector: null
+  - type: external
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: 
"https://github.com/apache/superset/actions/workflows/superset-python-unittest.yml/badge.svg";
+    alt: Build Status
+    source_file: docs/index.mdx
+    selector: null
+  - type: external
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: 
"https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=39464018&image_size=auto&color_scheme=light";
+    alt: Performance Stats of apache/superset - Last 28 days
+    source_file: docs/index.mdx
+    selector: null
+  # --- database-logo (122) ---
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/amazon-athena.jpg
+    alt: Amazon Athena
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/apache-drill.png
+    alt: Apache Drill
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/apache-hive.svg
+    alt: Apache Hive
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/apache-impala.png
+    alt: Apache Impala
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/apache-kylin.png
+    alt: Apache Kylin
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/apache-pinot.svg
+    alt: Apache Pinot
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/apache-solr.png
+    alt: Apache Solr
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/apache-spark.png
+    alt: Apache Spark SQL
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/ascend.webp
+    alt: Ascend
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/aws.png
+    alt: Amazon DynamoDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/azure.svg
+    alt: Azure Synapse
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/clickhouse.png
+    alt: ClickHouse
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/cloudflare.png
+    alt: Cloudflare D1
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/cockroachdb.png
+    alt: CockroachDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/couchbase.svg
+    alt: Couchbase
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/cratedb.svg
+    alt: CrateDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/databend.png
+    alt: Databend
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/databricks.png
+    alt: Databricks
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/denodo.png
+    alt: Denodo
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/doris.png
+    alt: Apache Doris
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/dremio.png
+    alt: Dremio
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/druid.png
+    alt: Apache Druid
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/duckdb.png
+    alt: DuckDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/elasticsearch.png
+    alt: Elasticsearch
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/exasol.png
+    alt: Exasol
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/firebird.png
+    alt: Firebird
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/firebolt.png
+    alt: Firebolt
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/google-big-query.svg
+    alt: Google BigQuery
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/google-sheets.svg
+    alt: Google Sheets
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/greenplum.png
+    alt: Greenplum
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/hologres.png
+    alt: Hologres
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/ibm-db2.svg
+    alt: IBM Db2
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/kusto.png
+    alt: Azure Data Explorer
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/mariadb.png
+    alt: MariaDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/monet-db.png
+    alt: MonetDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/mongodb.png
+    alt: MongoDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/motherduck.png
+    alt: MotherDuck
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/msql.png
+    alt: Microsoft SQL Server
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/mysql.png
+    alt: Aurora MySQL (Data API)
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/netezza.png
+    alt: IBM Netezza Performance Server
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/oceanbase.svg
+    alt: OceanBase
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/oraclelogo.png
+    alt: Oracle
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/postgresql.svg
+    alt: Aurora PostgreSQL (Data API)
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/presto-og.png
+    alt: Presto
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/redshift.png
+    alt: Amazon Redshift
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/risingwave.svg
+    alt: RisingWave
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/sap-hana.png
+    alt: SAP HANA
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/shillelagh.png
+    alt: Shillelagh
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/singlestore.png
+    alt: SingleStore
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/snowflake.svg
+    alt: Snowflake
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/sqlite.png
+    alt: SQLite
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/starrocks.png
+    alt: StarRocks
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/superset.svg
+    alt: Superset meta database
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/sybase.png
+    alt: SAP Sybase
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/tdengine.png
+    alt: TDengine
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/teradata.png
+    alt: Teradata
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/timescale.png
+    alt: TimescaleDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/trino.png
+    alt: Trino
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/vertica.png
+    alt: Vertica
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/ydb.svg
+    alt: YDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: docs/static/img/databases/yugabyte.png
+    alt: YugabyteDB
+    source_file: docs/intro.md
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/amazon-athena.jpg";
+    output_path: docs/static/img/databases/amazon-athena.jpg
+    alt: Amazon Athena
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/apache-drill.png";
+    output_path: docs/static/img/databases/apache-drill.png
+    alt: Apache Drill
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/apache-hive.svg";
+    output_path: docs/static/img/databases/apache-hive.svg
+    alt: Apache Hive
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/apache-impala.png";
+    output_path: docs/static/img/databases/apache-impala.png
+    alt: Apache Impala
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/apache-kylin.png";
+    output_path: docs/static/img/databases/apache-kylin.png
+    alt: Apache Kylin
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/apache-pinot.svg";
+    output_path: docs/static/img/databases/apache-pinot.svg
+    alt: Apache Pinot
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/apache-solr.png";
+    output_path: docs/static/img/databases/apache-solr.png
+    alt: Apache Solr
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/apache-spark.png";
+    output_path: docs/static/img/databases/apache-spark.png
+    alt: Apache Spark SQL
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/ascend.webp";
+    output_path: docs/static/img/databases/ascend.webp
+    alt: Ascend
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/aws.png";
+    output_path: docs/static/img/databases/aws.png
+    alt: Amazon DynamoDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/azure.svg";
+    output_path: docs/static/img/databases/azure.svg
+    alt: Azure Synapse
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/clickhouse.png";
+    output_path: docs/static/img/databases/clickhouse.png
+    alt: ClickHouse
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/cloudflare.png";
+    output_path: docs/static/img/databases/cloudflare.png
+    alt: Cloudflare D1
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/cockroachdb.png";
+    output_path: docs/static/img/databases/cockroachdb.png
+    alt: CockroachDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/couchbase.svg";
+    output_path: docs/static/img/databases/couchbase.svg
+    alt: Couchbase
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/cratedb.svg";
+    output_path: docs/static/img/databases/cratedb.svg
+    alt: CrateDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/databend.png";
+    output_path: docs/static/img/databases/databend.png
+    alt: Databend
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/databricks.png";
+    output_path: docs/static/img/databases/databricks.png
+    alt: Databricks
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/denodo.png";
+    output_path: docs/static/img/databases/denodo.png
+    alt: Denodo
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/doris.png";
+    output_path: docs/static/img/databases/doris.png
+    alt: Apache Doris
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/dremio.png";
+    output_path: docs/static/img/databases/dremio.png
+    alt: Dremio
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/druid.png";
+    output_path: docs/static/img/databases/druid.png
+    alt: Apache Druid
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/duckdb.png";
+    output_path: docs/static/img/databases/duckdb.png
+    alt: DuckDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/elasticsearch.png";
+    output_path: docs/static/img/databases/elasticsearch.png
+    alt: Elasticsearch
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/exasol.png";
+    output_path: docs/static/img/databases/exasol.png
+    alt: Exasol
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/firebird.png";
+    output_path: docs/static/img/databases/firebird.png
+    alt: Firebird
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/firebolt.png";
+    output_path: docs/static/img/databases/firebolt.png
+    alt: Firebolt
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/google-big-query.svg";
+    output_path: docs/static/img/databases/google-big-query.svg
+    alt: Google BigQuery
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/google-sheets.svg";
+    output_path: docs/static/img/databases/google-sheets.svg
+    alt: Google Sheets
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/greenplum.png";
+    output_path: docs/static/img/databases/greenplum.png
+    alt: Greenplum
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/hologres.png";
+    output_path: docs/static/img/databases/hologres.png
+    alt: Hologres
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/ibm-db2.svg";
+    output_path: docs/static/img/databases/ibm-db2.svg
+    alt: IBM Db2
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/kusto.png";
+    output_path: docs/static/img/databases/kusto.png
+    alt: Azure Data Explorer
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/mariadb.png";
+    output_path: docs/static/img/databases/mariadb.png
+    alt: MariaDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/monet-db.png";
+    output_path: docs/static/img/databases/monet-db.png
+    alt: MonetDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/mongodb.png";
+    output_path: docs/static/img/databases/mongodb.png
+    alt: MongoDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/motherduck.png";
+    output_path: docs/static/img/databases/motherduck.png
+    alt: MotherDuck
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/msql.png";
+    output_path: docs/static/img/databases/msql.png
+    alt: Microsoft SQL Server
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/mysql.png";
+    output_path: docs/static/img/databases/mysql.png
+    alt: Aurora MySQL (Data API)
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/netezza.png";
+    output_path: docs/static/img/databases/netezza.png
+    alt: IBM Netezza Performance Server
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/oceanbase.svg";
+    output_path: docs/static/img/databases/oceanbase.svg
+    alt: OceanBase
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/oraclelogo.png";
+    output_path: docs/static/img/databases/oraclelogo.png
+    alt: Oracle
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/postgresql.svg";
+    output_path: docs/static/img/databases/postgresql.svg
+    alt: Aurora PostgreSQL (Data API)
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/presto-og.png";
+    output_path: docs/static/img/databases/presto-og.png
+    alt: Presto
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/redshift.png";
+    output_path: docs/static/img/databases/redshift.png
+    alt: Amazon Redshift
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/risingwave.svg";
+    output_path: docs/static/img/databases/risingwave.svg
+    alt: RisingWave
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/sap-hana.png";
+    output_path: docs/static/img/databases/sap-hana.png
+    alt: SAP HANA
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/shillelagh.png";
+    output_path: docs/static/img/databases/shillelagh.png
+    alt: Shillelagh
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/singlestore.png";
+    output_path: docs/static/img/databases/singlestore.png
+    alt: SingleStore
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/snowflake.svg";
+    output_path: docs/static/img/databases/snowflake.svg
+    alt: Snowflake
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/sqlite.png";
+    output_path: docs/static/img/databases/sqlite.png
+    alt: SQLite
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/starrocks.png";
+    output_path: docs/static/img/databases/starrocks.png
+    alt: StarRocks
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/superset.svg";
+    output_path: docs/static/img/databases/superset.svg
+    alt: Superset meta database
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/sybase.png";
+    output_path: docs/static/img/databases/sybase.png
+    alt: SAP Sybase
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/tdengine.png";
+    output_path: docs/static/img/databases/tdengine.png
+    alt: TDengine
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/teradata.png";
+    output_path: docs/static/img/databases/teradata.png
+    alt: Teradata
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/timescale.png";
+    output_path: docs/static/img/databases/timescale.png
+    alt: TimescaleDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/trino.png";
+    output_path: docs/static/img/databases/trino.png
+    alt: Trino
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/vertica.png";
+    output_path: docs/static/img/databases/vertica.png
+    alt: Vertica
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/ydb.svg";
+    output_path: docs/static/img/databases/ydb.svg
+    alt: YDB
+    source_file: docs/index.mdx
+    selector: null
+  - type: database-logo
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://superset.apache.org/img/databases/yugabyte.png";
+    output_path: docs/static/img/databases/yugabyte.png
+    alt: YugabyteDB
+    source_file: docs/index.mdx
+    selector: null
+  # --- badge (12) ---
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://badge.fury.io/py/apache_superset.svg";
+    alt: PyPI version
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://img.shields.io/badge/License-Apache%202.0-blue.svg";
+    alt: License
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://img.shields.io/badge/docs-apache.org-blue.svg";
+    alt: Documentation
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://img.shields.io/badge/slack-join-orange.svg";
+    alt: Get on Slack
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://img.shields.io/github/contributors/apache/superset";
+    alt: Contributors
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://img.shields.io/github/issues-pr/apache/superset";
+    alt: Open PRs
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://img.shields.io/github/issues/apache/superset";
+    alt: Open Issues
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: "https://img.shields.io/github/last-commit/apache/superset";
+    alt: Last Commit
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: 
"https://img.shields.io/github/stars/apache/superset?style=social";
+    alt: GitHub Stars
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: 
"https://img.shields.io/github/v/release/apache/superset?sort=semver";
+    alt: Latest Release on Github
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: 
"https://img.shields.io/pypi/pyversions/apache_superset.svg?maxAge=2592000";
+    alt: PyPI
+    source_file: docs/index.mdx
+    selector: null
+  - type: badge
+    page_url: "https://superset.apache.org/user-docs";
+    image_url: 
"https://static.scarf.sh/a.png?x-pxid=bc1c90cd-bc04-4e11-8c7b-289fb2839492";
+    alt: ""
+    source_file: docs/index.mdx
+    selector: null
diff --git a/superset-frontend/playwright/generators/playwright.config.ts 
b/superset-frontend/playwright/generators/playwright.config.ts
index 54b8b4be702..0ebc082a860 100644
--- a/superset-frontend/playwright/generators/playwright.config.ts
+++ b/superset-frontend/playwright/generators/playwright.config.ts
@@ -64,6 +64,7 @@ export default defineConfig({
       name: 'docs-generators',
       use: {
         browserName: 'chromium',
+        baseURL, // explicit here so globalSetup can read it from 
config.projects[0].use.baseURL
         testIdAttribute: 'data-test',
         storageState: path.resolve(__dirname, '../.auth/user.json'),
       },

Reply via email to