## Summary Adds the first batch of keyboard shortcuts for the Database → Schema Visualizer page, following the registry pattern established for the SQL editor and table editor. Fixes [FE-3115](https://linear.app/supabase/issue/FE-3115). ## Shortcuts | Shortcut | Action | | --- | --- | | `Mod+Shift+C` | Copy schema as SQL | | `Mod+Shift+M` | Copy schema as Markdown | | `D` then `P` | Download schema as PNG | | `D` then `S` | Download schema as SVG | | `O` then `A` | Open the auto-layout confirmation dialog | | `O` then `S` | Open the schema selector | All six entries appear in the Cmd+K command menu under "Shortcuts" and in the global shortcuts sheet (`Mod+/`) under a new "Schema Visualizer" group while the page is mounted. None are surfaced in Account → Preferences yet (`showInSettings: false`), matching how the SQL/table editor batches shipped. The schema selector and auto-layout button are wrapped in the unified `Shortcut` component so the keybind is shown on hover (Linear-style). The dropdown items for copy/download don't get hover hints since tooltips on dropdown items don't make sense — they're discoverable via Cmd+K instead. ## Toasts Each user-visible action now confirms via a sonner toast: - `Successfully copied as SQL` — fires on Copy as SQL (button or `Mod+Shift+C`). - `Successfully copied as Markdown` — fires on Copy as Markdown (dropdown or `Mod+Shift+M`). - `Successfully downloaded as PNG` / `Successfully downloaded as SVG` — already present in `useExportSchemaToImage`; fires on click or `D → P` / `D → S`. - `Failed to download current view: …` — error toast on download failure (also pre-existing). ## Notes - `Mod+Shift+C` and `Mod+Shift+M` collide with the SQL editor's `results.copy-csv` / `results.copy-markdown` shortcuts. They coexist cleanly because `useShortcut` only fires while the hook is mounted, and the two pages live on different routes. Both labels appear in the global shortcuts sheet honestly scoped per surface. - `SchemaSelector` was promoted to a `forwardRef` component that spreads extra props onto its outer `<div>`. This was needed for `<TooltipTrigger asChild>` to attach event handlers and the ref properly — previously they were silently dropped and the hover tooltip didn't render. - `SchemaSelector` and the auto-layout `AlertDialog` accept controlled `open` props now so the shortcuts can drive them and the tooltip can be suppressed while the popover/dialog is open (`Shortcut` gained a `tooltipOpen` passthrough for this). - Auto-layout still pops the existing confirmation dialog rather than running directly — destructive enough to keep the guardrail. ## Test plan - [x] On the Schema Visualizer page, each of the six shortcuts fires the corresponding action. - [x] Hover the schema selector and the Auto layout button — tooltip shows the action label and keybind badge. - [x] Open the schema selector popover (click or `O → S`) — hover tooltip is suppressed while open. - [x] Open the auto-layout confirm dialog (click or `O → A`) — hover tooltip is suppressed while open. - [x] Cmd+K shows all six entries under "Shortcuts" while on the page; navigating away unregisters them. - [x] `Mod+/` shortcuts sheet has a "Schema Visualizer" group listing all six. - [x] Copy as SQL / Markdown each fire a confirmation toast; PNG / SVG downloads each fire a confirmation toast. - [x] On the SQL editor results page, `Mod+Shift+M` / `Mod+Shift+C` still copy results (no regression from the duplicate keybinds). - [x] The download dropdown items still work via click; PNG/SVG downloads succeed. - [x] All other consumers of `SchemaSelector` (~15 callsites) render unchanged after the `forwardRef` promotion. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Keyboard shortcuts for schema visualizer: copy as SQL/Markdown, download PNG/SVG, auto-layout, and focus selector * Success toasts when copying content to clipboard * **Improvements** * Schema selector and auto-layout dialog can be opened/closed via keyboard and programmatically * Shortcut tooltips can be suppressed when related overlays/dialogs are open * Schema Visualizer added to the shortcuts reference sheet * **Tests** * E2E tests dismiss transient toasts to avoid UI interference <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Supabase Studio E2E Tests
Set up
Prerequisites
For Self-Hosted Tests
- Nothing is required, running with IS_PLATFORM=false should run the tests locally with a self hosted docker container
For Platform Tests
- Create a platform account - You can authenticate using either:
- Email and password
- GitHub OAuth (requires TOTP 2FA)
- Create an organization on the platform, this can be done if run locally through
mise fullstack - Generate a Personal Access Token (PAT) for API access
- Configure the environment variables below (see Authentication section for details on email vs GitHub auth)
Configure Environment
Choose the appropriate example file based on your testing scenario:
For self-hosted tests:
cp .env.local.self-hosted.example .env.local
For platform tests with email authentication:
cp .env.local.email.example .env.local
For platform tests with GitHub authentication:
cp .env.local.github.example .env.local
Edit .env.local and set the appropriate values based on your test environment (see Environment Variables section below).
Install the playwright browser
⚠️ This should be done in the e2e/studio directory
cd e2e/studio
pnpm exec playwright install
Environment Variables
Configure your tests by setting the following environment variables in .env.local. We have examples of what required on self hosted and platform:
Core Configuration
STUDIO_URL: The URL where Studio is running (default:http://localhost:8082)API_URL: The Supabase API endpoint (default:https://localhost:8080)IS_PLATFORM: Set totruefor platform tests,falsefor self-hosted (default:false)- When
true: Tests run serially (1 worker) due to API rate limits - When
false: Tests run in parallel (5 workers)
- When
Authentication (Required for Platform Tests)
⚠️ Before running platform tests, you must create an account and organization on the platform you're testing.
Authentication is automatically enabled when either email/password OR GitHub credentials are configured.
Email Authentication
EMAIL: Your platform account emailPASSWORD: Your platform account passwordPROJECT_REF: Project reference (optional, will be auto-created if not provided)
When both EMAIL and PASSWORD are set, the tests will authenticate using email/password. HCaptcha is mocked during test setup. Note this only works on local and staging environments
GitHub Authentication
GITHUB_USER: Your GitHub usernameGITHUB_PASS: Your GitHub passwordGITHUB_TOTP: Your GitHub TOTP secret for 2FA (required, as GitHub enforces 2FA)
When GITHUB_USER, GITHUB_PASS, and GITHUB_TOTP are all set, the tests will authenticate using GitHub OAuth with TOTP-based 2FA. The authentication flow handles:
- Clicking "Sign In with GitHub" button
- Filling GitHub credentials
- Generating and submitting TOTP codes
- Handling GitHub authorization prompts
- Automatic retry on failure (up to 3 attempts)
Getting your GitHub TOTP secret:
When setting up 2FA on GitHub, you'll see a QR code. Click "enter this text code instead" to reveal the secret key. This is the value to use for GITHUB_TOTP.
Platform-Specific Variables (Required when IS_PLATFORM=true)
ORG_SLUG: Organization slug (default:default)SUPA_REGION: Supabase region (default:us-east-1)SUPA_PAT: Personal Access Token for API authentication (default:test)BRANCH_NAME: Name for the test branch/project (default:e2e-test-local)
Optional Variables
OPENAI_API_KEY: Required for the AI Assistant test (assistant.spec.ts). Without this variable, the assistant test will be skipped.VERCEL_AUTOMATION_BYPASS_SELFHOSTED_STUDIO: Bypass token for Vercel protection (default:false)
Setup Commands Based on Configuration
The test setup automatically runs different commands based on your environment:
- Platform + Localhost (
IS_PLATFORM=trueandSTUDIO_URL=localhost): Runspnpm run e2e:setup:platform - Platform + Remote (
IS_PLATFORM=trueand remoteSTUDIO_URL): No web server setup - Self-hosted (
IS_PLATFORM=false): Runspnpm run e2e:setup:selfhosted
Running the tests
Check the package.json for the available commands and environments.
pnpm run e2e
With Playwright UI:
pnpm run e2e -- --ui
Tips for development
- Read Playwright Best Practices
- Use
pnpm run e2e -- --uito get the playwright UI. - Add the tests in
examples/examples.tsto Cursor as context. - Add messages to expect statements to make them easier to debug.
Example:
await expect(page.getByRole('heading', { name: 'Logs & Analytics' }), {
message: 'Logs heading should be visible',
}).toBeVisible()
- Use the test utility instead of playwrights test.
import { test } from '../utils/test'
- Use the PWDEBUG environment variable to debug the tests.
PWDEBUG=1 pnpm run e2e -- --ui
What should I test?
- Can the feature be navigated to?
- Does the feature load correctly?
- Can you do the actions (filtering, sorting, opening dialogs, etc)?
API Mocks
Read here: https://playwright.dev/docs/mock#mock-api-requests
Example:
await page.route(`*/**/logs.all*`, async (route) => {
await route.fulfill({ body: JSON.stringify(mockAPILogs) })
})