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'),
},