diff --git a/.github/workflows/studio-e2e-tests.yml b/.github/workflows/studio-e2e-tests.yml
index 54bbb01d07..1a57cd0b0d 100644
--- a/.github/workflows/studio-e2e-tests.yml
+++ b/.github/workflows/studio-e2e-tests.yml
@@ -5,14 +5,14 @@ on:
paths:
- 'packages/pg-meta/**/*'
- 'apps/studio/**'
- - 'tests/studio-tests/**'
+ - 'e2e/studio/**'
- 'pnpm-lock.yaml'
pull_request:
branches: [master]
paths:
- 'packages/pg-meta/**/*'
- 'apps/studio/**'
- - 'tests/studio-tests/**'
+ - 'e2e/studio/**'
- 'pnpm-lock.yaml'
# Cancel old builds on new commit for same workflow + branch/PR
@@ -27,6 +27,18 @@ jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
+ # Make the job non-blocking
+ continue-on-error: true
+
+ env:
+ EMAIL: ${{ secrets.CI_EMAIL }}
+ PASSWORD: ${{ secrets.CI_PASSWORD }}
+ PROJECT_REF: ${{ secrets.CI_PROJECT_REF }}
+ NEXT_PUBLIC_IS_PLATFORM: true
+ NEXT_PUBLIC_API_URL: https://api.supabase.green
+ VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
+ VERCEL_PROJECT_ID: ${{ secrets.VERCEL_STUDIO_HOSTED_PROJECT_ID }}
+ NEXT_PUBLIC_HCAPTCHA_SITE_KEY: 10000000-ffff-ffff-ffff-000000000001
steps:
- uses: actions/checkout@v4
@@ -39,20 +51,41 @@ jobs:
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- - uses: supabase/setup-cli@v1
- with:
- version: latest
+
- name: Install dependencies
run: pnpm i
+
+ - name: Install Vercel CLI
+ run: pnpm add --global vercel@latest
+
+ - name: Pull Vercel Environment Information (Preview)
+ run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
+
+ - name: Build Project Artifacts for Vercel
+ run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
+
+ - name: Deploy Project to Vercel and Get URL
+ id: deploy_vercel
+ run: |
+ DEPLOY_URL=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
+ echo "Vercel Preview URL: $DEPLOY_URL"
+ echo "DEPLOY_URL=$DEPLOY_URL" >> $GITHUB_OUTPUT
+
- name: Install Playwright Browsers
- run: pnpm -C tests/studio-tests exec playwright install --with-deps
+ run: pnpm -C e2e/studio exec playwright install --with-deps
+
- name: Run Playwright tests
- run: pnpm test:e2e:studio-local
- # mark the action as succeeded even if the tests failed. This is temporarily until we make the tests more stable.
- # continue-on-error: true
+ id: playwright
+ env:
+ AUTHENTICATION: true
+ STUDIO_URL: ${{ steps.deploy_vercel.outputs.DEPLOY_URL }}/dashboard
+ run: pnpm e2e
+
- uses: actions/upload-artifact@v4
if: always()
with:
- name: playwright-report
- path: tests/studio-tests/playwright-report/
+ name: playwright-artifacts
+ path: |
+ e2e/studio/playwright-report/
+ e2e/studio/test-results/
retention-days: 7
diff --git a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/RunButton.tsx b/apps/studio/components/interfaces/SQLEditor/UtilityPanel/RunButton.tsx
index 03faf85ac5..627e73768a 100644
--- a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/RunButton.tsx
+++ b/apps/studio/components/interfaces/SQLEditor/UtilityPanel/RunButton.tsx
@@ -29,6 +29,7 @@ export const SqlRunButton = ({
disabled={isDisabled}
type="primary"
size="tiny"
+ data-testid="sql-run-button"
iconRight={
isExecuting ? (
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogSelectionRenderers/DefaultPreviewSelectionRenderer.tsx b/apps/studio/components/interfaces/Settings/Logs/LogSelectionRenderers/DefaultPreviewSelectionRenderer.tsx
index cfcd76b665..5da4f516be 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogSelectionRenderers/DefaultPreviewSelectionRenderer.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogSelectionRenderers/DefaultPreviewSelectionRenderer.tsx
@@ -184,12 +184,7 @@ const DefaultPreviewSelectionRenderer = ({ log }: { log: PreviewLogData }) => {
)}
{log?.status && }
{log?.timestamp && (
-
+
)}
{Object.entries(rest).map(([key, value]) => {
return
diff --git a/apps/studio/components/layouts/LogsLayout/LogsLayout.tsx b/apps/studio/components/layouts/LogsLayout/LogsLayout.tsx
index 5c9c0d7ece..7296bb61f6 100644
--- a/apps/studio/components/layouts/LogsLayout/LogsLayout.tsx
+++ b/apps/studio/components/layouts/LogsLayout/LogsLayout.tsx
@@ -23,13 +23,15 @@ const LogsLayout = ({ title, children }: PropsWithChildren) =>
const router = useRouter()
const [_, setLastLogsPage] = useLocalStorageQuery(
LOCAL_STORAGE_KEYS.LAST_VISITED_LOGS_PAGE,
- router.pathname.split('/logs/')[1]
+ router.pathname.split('/logs/')[1] || ''
)
useEffect(() => {
if (router.pathname.includes('/logs/')) {
const path = router.pathname.split('/logs/')[1]
- setLastLogsPage(path)
+ if (path) {
+ setLastLogsPage(path)
+ }
}
}, [router, setLastLogsPage])
diff --git a/apps/studio/tests/README.md b/apps/studio/tests/README.md
index 28ea24fa06..605f7cab87 100644
--- a/apps/studio/tests/README.md
+++ b/apps/studio/tests/README.md
@@ -60,6 +60,7 @@ test('mock is working', async () => {
To render a component that uses Nuqs with some predefined query parameters, you can use `customRender` with the `nuqs` prop.
```ts
+
customRender(, {
nuqs: {
searchParams: {
diff --git a/e2e/studio/.env.local.example b/e2e/studio/.env.local.example
new file mode 100644
index 0000000000..256a6101fb
--- /dev/null
+++ b/e2e/studio/.env.local.example
@@ -0,0 +1,14 @@
+
+# 1. Copy and paste this file and rename it to .env.local
+
+# 2. Set the STUDIO_URL and API_URL you want the e2e tests to run against
+
+STUDIO_URL=https://supabase.com/dashboard
+API_URL=https://api.supabase.com
+AUTHENTICATION=true
+
+# 3. *Optional* If the environment requires auth, set AUTHENTICATION to true, auth credentials, and PROJECT_REF
+
+EMAIL=
+PASSWORD=
+PROJECT_REF=
diff --git a/tests/studio-tests/.gitignore b/e2e/studio/.gitignore
similarity index 100%
rename from tests/studio-tests/.gitignore
rename to e2e/studio/.gitignore
diff --git a/e2e/studio/README.md b/e2e/studio/README.md
new file mode 100644
index 0000000000..21e66a97f7
--- /dev/null
+++ b/e2e/studio/README.md
@@ -0,0 +1,143 @@
+# Supabase Studio E2E Tests
+
+## Set up
+
+```bash
+cp .env.local.example .env.local
+```
+
+Edit the `.env.local` file with your credentials and environment.
+
+### Install the playwright browser
+
+```bash
+pnpm exec playwright install
+```
+
+## Environments
+
+### Staging
+
+```bash
+STUDIO_URL=https://supabase.green/dashboard
+API_URL=https://api.supabase.green
+AUTHENTICATION=true
+EMAIL=your@email.com
+PASSWORD=yourpassword
+PROJECT_REF=yourprojectref
+```
+
+### CLI (NO AUTH)
+
+You'll need to run the CLI locally.
+
+```bash
+STUDIO_URL=http://localhost:54323
+API_URL=http://localhost:54323/api
+AUTHENTICATION=false
+```
+
+### CLI Development (NO AUTH)
+
+You'll need to run Studio in development mode with `IS_PLATFORM=false`
+
+```bash
+STUDIO_URL=http://localhost:8082/
+API_URL=http://localhost:8082/api
+AUTHENTICATION=false
+```
+
+### Hosted Development
+
+You'll need to run Studio in development mode with `IS_PLATFORM=true`
+
+```bash
+STUDIO_URL=http://localhost:8082/
+API_URL=http://localhost:8080/api
+AUTHENTICATION=true
+EMAIL=your@email.com
+PASSWORD=yourpassword
+PROJECT_REF=yourprojectref
+```
+
+---
+
+## Running the tests
+
+Check the `package.json` for the available commands and environments.
+
+#### Example:
+
+```bash
+pnpm run e2e
+```
+
+With Playwright UI:
+
+```bash
+pnpm run e2e -- --ui
+```
+
+---
+
+## Tips for development
+
+- Read [Playwright Best Practices](https://playwright.dev/docs/best-practices)
+- Use `pnpm run e2e -- --ui` to get the playwright UI.
+- Add the tests in `examples/examples.ts` to Cursor as context.
+- Add messages to expect statements to make them easier to debug.
+
+Example:
+
+```ts
+await expect(page.getByRole('heading', { name: 'Logs & Analytics' }), {
+ message: 'Logs heading should be visible',
+}).toBeVisible()
+```
+
+- Use the test utility instead of playwrights test.
+
+```ts
+import { test } from '../utils/test'
+```
+
+- Use the PWDEBUG environment variable to debug the tests.
+
+```bash
+PWDEBUG=1 pnpm run e2e -- --ui
+```
+
+---
+
+## Organization
+
+Name the folders based on the feature you are testing.
+
+```bash
+e2e/studio/logs/
+e2e/studio/sql-editor/
+e2e/studio/storage/
+e2e/studio/auth/
+```
+
+---
+
+## 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:
+
+```ts
+await page.route(`*/**/logs.all*`, async (route) => {
+ await route.fulfill({ body: JSON.stringify(mockAPILogs) })
+})
+```
diff --git a/e2e/studio/env.config.ts b/e2e/studio/env.config.ts
new file mode 100644
index 0000000000..4629685171
--- /dev/null
+++ b/e2e/studio/env.config.ts
@@ -0,0 +1,12 @@
+import path from 'path'
+
+export const env = {
+ STUDIO_URL: process.env.STUDIO_URL,
+ API_URL: process.env.API_URL || 'https://api.supabase.green',
+ AUTHENTICATION: process.env.AUTHENTICATION,
+ EMAIL: process.env.EMAIL,
+ PASSWORD: process.env.PASSWORD,
+ PROJECT_REF: process.env.PROJECT_REF || 'default',
+}
+
+export const STORAGE_STATE_PATH = path.join(__dirname, './playwright/.auth/user.json')
diff --git a/e2e/studio/examples/examples.ts b/e2e/studio/examples/examples.ts
new file mode 100644
index 0000000000..f9cd5f6ee0
--- /dev/null
+++ b/e2e/studio/examples/examples.ts
@@ -0,0 +1,79 @@
+import { expect } from '@playwright/test'
+import { isEnv } from '../env.config'
+import { test } from '../utils/test'
+
+/**
+ * * Example tests for Studio.
+ * Tips:
+ * - Use the test utility instead of playwrights test.
+ * import { test } from '../utils/test'
+ * - Use the isEnv utility to check the environment.
+ * import { isEnv } from '../env.config'
+ * - Make tests easy to debug by adding enough expect() statements.
+ */
+
+/**
+ * * Test that is skipped in self-hosted environment
+ */
+test('Loads the page 1', async ({ page }) => {
+ if (isEnv('selfhosted')) return
+
+ await page.goto('https://www.supabase.com')
+ await expect(
+ page.getByRole('heading', { name: 'Build in a weekend Scale to millions' })
+ ).toBeVisible()
+})
+
+/**
+ * * Test that only runs in staging and production environments
+ */
+test('Loads the page 2', async ({ page }) => {
+ if (!isEnv(['staging', 'production'])) return
+
+ await page.goto('https://www.supabase.com')
+ await expect(
+ page.getByRole('heading', { name: 'Build in a weekend Scale to millions' })
+ ).toBeVisible()
+})
+
+/**
+ * * Test that navigates to a project by ref
+ * Make sure to set up the project in the `.env.local` file.
+ */
+test('Navigates to a project by ref', async ({ page, ref }) => {
+ await page.goto(`${process.env.BASE_URL}/project/${ref}`)
+ await expect(page.getByRole('heading', { name: 'Project Home' })).toBeVisible()
+})
+
+/**
+ * * Test that mocks some API calls
+ */
+
+const mockRes = {
+ data: [
+ {
+ id: 1,
+ name: 'John Doe',
+ email: 'john.doe@example.com',
+ },
+ {
+ id: 2,
+ name: 'Jane Doe',
+ email: 'jane.doe@example.com',
+ },
+ ],
+}
+
+test.beforeEach(async ({ context }) => {
+ context.route('*/**/users*', async (route, request) => {
+ await route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify(mockRes),
+ })
+ })
+})
+
+test('Mocks some API calls', async ({ page }) => {
+ // ... Run some code that depends on that API call
+})
diff --git a/e2e/studio/features/_global.setup.ts b/e2e/studio/features/_global.setup.ts
new file mode 100644
index 0000000000..187e72fb8f
--- /dev/null
+++ b/e2e/studio/features/_global.setup.ts
@@ -0,0 +1,155 @@
+import { expect, test as setup } from '@playwright/test'
+import dotenv from 'dotenv'
+import path from 'path'
+import { env, STORAGE_STATE_PATH } from '../env.config'
+
+/**
+ * Run any setup tasks for the tests.
+ * Catch errors and show useful messages.
+ */
+
+dotenv.config({
+ path: path.resolve(__dirname, '..', '.env.local'),
+ override: true,
+})
+
+const IS_PLATFORM = process.env.IS_PLATFORM
+
+const envHasAuth = env.AUTHENTICATION
+
+setup('Global Setup', async ({ page }) => {
+ console.log(`\n ๐งช Setting up test environment.
+ - Studio URL: ${env.STUDIO_URL}
+ - API URL: ${env.API_URL}
+ - Auth: ${envHasAuth ? 'enabled' : 'disabled'}
+ - Is Platform: ${IS_PLATFORM}
+ `)
+
+ /**
+ * Studio Check
+ */
+
+ const studioUrl = env.STUDIO_URL
+ const apiUrl = env.API_URL
+
+ await page.goto(studioUrl).catch((err) => {
+ console.error(
+ `\n ๐จ Setup Error
+Studio is not available at: ${studioUrl}
+
+Please ensure:
+ 1. Studio is running in the expected URL
+ 2. You have proper network access
+`
+ )
+ throw err
+ })
+
+ console.log(`\n โ
Studio is running at ${studioUrl}`)
+
+ /**
+ * API Check
+ */
+
+ await fetch(apiUrl).catch((err) => {
+ console.error(`\n ๐จ Setup Error
+API is not available at: ${apiUrl}
+
+Please ensure:
+ 1. API is running in the expected URL
+ 2. You have proper network access
+
+To start API locally, run:
+ npm run dev:api`)
+ throw new Error('API is not available')
+ })
+
+ console.log(`\n โ
API is running at ${apiUrl}`)
+
+ /**
+ * Only run authentication if the environment requires it
+ */
+ if (!env.AUTHENTICATION) {
+ console.log(`\n ๐ Skipping authentication for ${env.STUDIO_URL}`)
+ return
+ } else {
+ if (!env.EMAIL || !env.PASSWORD || !env.PROJECT_REF) {
+ console.error(`Missing environment variables. Check README.md for more information.`)
+ throw new Error('Missing environment variables')
+ }
+ }
+
+ const signInUrl = `${studioUrl}/sign-in`
+ console.log(`\n ๐ Navigating to sign in page: ${signInUrl}`)
+
+ await page.goto(signInUrl, { waitUntil: 'networkidle' })
+ await page.waitForLoadState('domcontentloaded')
+ await page.waitForLoadState('networkidle')
+
+ // Check if we're still on the sign-in page
+ const currentUrl = page.url()
+ console.log(`\n ๐ Current URL: ${currentUrl}`)
+
+ if (!currentUrl.includes('/sign-in')) {
+ console.log('\n โ ๏ธ Redirected away from sign-in page. Checking if already authenticated...')
+
+ // Check if we're already on the projects page
+ if (currentUrl.includes('/projects')) {
+ console.log('\n โ
Already authenticated, proceeding with tests')
+ await page.context().storageState({ path: STORAGE_STATE_PATH })
+ return
+ }
+
+ // If we're redirected somewhere else, try to navigate back to sign-in
+ console.log('\n ๐ Attempting to navigate back to sign-in page')
+ await page.goto(signInUrl, { waitUntil: 'networkidle' })
+ await page.waitForLoadState('domcontentloaded')
+ await page.waitForLoadState('networkidle')
+
+ // Check URL again after second attempt
+ const secondAttemptUrl = page.url()
+ if (!secondAttemptUrl.includes('/sign-in')) {
+ throw new Error(`Failed to reach sign-in page. Current URL: ${secondAttemptUrl}`)
+ }
+ }
+
+ const auth = {
+ email: env.EMAIL,
+ password: env.PASSWORD,
+ projectRef: env.PROJECT_REF,
+ }
+
+ expect(auth).toBeDefined()
+ expect(auth.email).toBeDefined()
+ expect(auth.password).toBeDefined()
+ expect(auth.projectRef).toBeDefined()
+
+ // Wait for form elements with increased timeout
+ const emailInput = page.getByLabel('Email')
+ const passwordInput = page.getByLabel('Password')
+ const signInButton = page.getByRole('button', { name: 'Sign In' })
+
+ // if found click opt out on telemetry
+ const optOutButton = page.getByRole('button', { name: 'Opt out' })
+ if ((await optOutButton.count()) > 0) {
+ await optOutButton.click()
+ }
+
+ // Debug element states
+ console.log('\n ๐ Checking form elements:')
+ console.log(`Email input exists: ${(await emailInput.count()) > 0}`)
+ console.log(`Password input exists: ${(await passwordInput.count()) > 0}`)
+ console.log(`Sign in button exists: ${(await signInButton.count()) > 0}`)
+
+ await emailInput.waitFor({ state: 'visible', timeout: 15000 })
+ await passwordInput.waitFor({ state: 'visible', timeout: 15000 })
+ await signInButton.waitFor({ state: 'visible', timeout: 15000 })
+
+ await emailInput.fill(auth.email ?? '')
+ await passwordInput.fill(auth.password ?? '')
+ await signInButton.click()
+
+ await page.waitForURL('**/organizations')
+
+ await page.context().storageState({ path: STORAGE_STATE_PATH })
+})
diff --git a/e2e/studio/features/home.spec.ts b/e2e/studio/features/home.spec.ts
new file mode 100644
index 0000000000..38a0adbbed
--- /dev/null
+++ b/e2e/studio/features/home.spec.ts
@@ -0,0 +1,12 @@
+import { expect } from '@playwright/test'
+import { test } from '../utils/test'
+import { toUrl } from '../utils/to-url'
+
+test.describe('Project', async () => {
+ test('Can navigate to project home page', async ({ page, ref }) => {
+ console.log(page.url())
+ await page.goto(toUrl(`/project/${ref}`))
+
+ await expect(page.getByRole('button', { name: 'Project Status' })).toBeVisible()
+ })
+})
diff --git a/e2e/studio/features/logs.spec.ts b/e2e/studio/features/logs.spec.ts
new file mode 100644
index 0000000000..87cc79c188
--- /dev/null
+++ b/e2e/studio/features/logs.spec.ts
@@ -0,0 +1,90 @@
+import { expect } from '@playwright/test'
+import { test } from '../utils/test'
+import { toUrl } from '../utils/to-url'
+const LOGS_PAGES = [
+ { label: 'API Gateway', route: 'edge-logs' },
+ { label: 'Postgres', route: 'postgres-logs' },
+]
+
+const mockAPILogs = {
+ error: null,
+ result: [
+ {
+ id: 'uuid-1',
+ timestamp: 1713200000000, // 15 Apr 18:53:20"
+ event_message: 'Random event message: uuid-1',
+ count: 123,
+ ok_count: 123,
+ error_count: 0,
+ warning_count: 20,
+ metadata: {
+ foo: 'bar',
+ request: {
+ url: 'https://example.com',
+ },
+ response: {
+ status: 200,
+ },
+ },
+ },
+ ],
+}
+
+test.beforeEach(async ({ context }) => {
+ context.route(/.*logs\.all.*/, async (route) => {
+ await route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify(mockAPILogs),
+ })
+ })
+})
+
+test.describe('Logs', () => {
+ for (const logPage of LOGS_PAGES) {
+ test(`${logPage.label} logs page`, async ({ page, ref }) => {
+ /**
+ * Navigates to Logs
+ */
+ await page.goto(toUrl(`/project/${ref}/logs/${logPage.route}`))
+
+ await expect(page.getByRole('heading', { name: 'Logs & Analytics' }), {
+ message: 'Logs & Analytics heading should be visible',
+ }).toBeVisible()
+
+ /**
+ * Shows the logs table
+ */
+
+ const logsTable = page.getByRole('table')
+
+ await expect(logsTable, {
+ message: 'Logs table should be visible',
+ }).toBeVisible({ timeout: 20000 })
+
+ /**
+ * Shows the logs data without errors
+ */
+ await expect(page.getByText(mockAPILogs.result[0].event_message), {
+ message: 'Logs data should be visible',
+ }).toBeVisible()
+
+ /**
+ * Can select and view log details
+ */
+ const gridcells = page.getByText('Random event message')
+ await gridcells.click()
+
+ const tabPanel = page.getByTestId('log-selection')
+ await expect(tabPanel).toBeVisible()
+
+ // Assert known fixed values instead of extracting text
+ await expect(tabPanel, {
+ message: 'Log selection should be visible',
+ }).toContainText('Random event message: uuid-1')
+ await expect(tabPanel.getByTestId('log-selection-id'), {
+ message: 'Log selection ID should be visible',
+ }).toContainText('uuid-1')
+ })
+ }
+})
diff --git a/e2e/studio/features/sql-editor.spec.ts b/e2e/studio/features/sql-editor.spec.ts
new file mode 100644
index 0000000000..efb523b418
--- /dev/null
+++ b/e2e/studio/features/sql-editor.spec.ts
@@ -0,0 +1,36 @@
+import { expect } from '@playwright/test'
+import { test } from '../utils/test'
+import { toUrl } from '../utils/to-url'
+import { env } from '../env.config'
+
+test.describe('SQL Editor', () => {
+ test('should check if SQL editor can run simple commands', async ({ page }) => {
+ await page.goto(toUrl(`/project/${env.PROJECT_REF}/sql`))
+
+ const editor = page.getByRole('code').nth(0)
+
+ // write some sql in the editor
+ // This has to be done since the editor is not editable (input, textarea, etc.)
+ await editor.click()
+ await editor.click()
+ await page.keyboard.press('ControlOrMeta+KeyA')
+ await page.keyboard.type(`select 'hello world';`)
+
+ await page.getByRole('button', { name: /^Run( CTRL)?$/, exact: false }).click()
+
+ // Should say "Running..."
+ await expect(page.getByText('Running...')).toBeVisible()
+
+ // Wait until Running... is not visible
+ await expect(page.getByText('Running...')).not.toBeVisible()
+
+ // clear the editor
+ await editor.click()
+ await page.keyboard.press('ControlOrMeta+KeyA')
+ await page.keyboard.press('Backspace')
+
+ // verify the result
+ const result = page.getByRole('gridcell', { name: 'hello world' })
+ await expect(result).toBeVisible()
+ })
+})
diff --git a/e2e/studio/features/table-editor.spec.ts b/e2e/studio/features/table-editor.spec.ts
new file mode 100644
index 0000000000..c23238a665
--- /dev/null
+++ b/e2e/studio/features/table-editor.spec.ts
@@ -0,0 +1,210 @@
+import { expect, Page } from '@playwright/test'
+import { test } from '../utils/test'
+import { toUrl } from '../utils/to-url'
+
+// Helper to generate a random table name
+const getRandomTableName = () => `pw-test-${Math.floor(Math.random() * 10000)}`
+
+const getSelectors = (tableName: string) => ({
+ tableButton: (page) => page.getByRole('button', { name: `View ${tableName}` }),
+ newTableBtn: (page) => page.getByRole('button', { name: 'New table', exact: true }),
+ tableNameInput: (page) => page.getByTestId('table-name-input'),
+ createdAtExtraOptions: (page) => page.getByTestId('created_at-extra-options'),
+ addColumnBtn: (page) => page.getByRole('button', { name: 'Add column' }),
+ columnNameInput: (page) => page.getByRole('textbox', { name: 'column_name' }),
+ chooseColumnType: (page) => page.locator('button').filter({ hasText: 'Choose a column type...' }),
+ signedIntOption: (page) => page.getByText('Signed two-byte integer'),
+ defaultValueField: (page) => page.getByTestId('defaultValueColumn-default-value'),
+ saveBtn: (page) => page.getByRole('button', { name: 'Save' }),
+ definitionTab: (page) => page.getByText('definition', { exact: true }),
+ viewLines: (page) => page.locator('div.view-lines'),
+ insertRowBtn: (page) => page.getByTestId('table-editor-insert-new-row'),
+ insertModal: (page) => page.getByText('Insert a new row into'),
+ defaultValueInput: (page) => page.getByTestId('defaultValueColumn-input'),
+ actionBarSaveRow: (page) => page.getByTestId('action-bar-save-row'),
+ grid: (page) => page.getByRole('grid'),
+ row: (page) => page.getByRole('row'),
+ sortBtn: (page) => page.getByRole('button', { name: 'Sort', exact: true }),
+ pickSortColumnBtn: (page) => page.getByTestId('table-editor-pick-column-to-sort-button'),
+ sortColumnOption: (page) =>
+ page.getByLabel('Pick a column to sort by').getByText('defaultValueColumn'),
+ applySortingBtn: (page) => page.getByRole('button', { name: 'Apply sorting' }),
+ sortedByRuleBtn: (page) => page.getByRole('button', { name: 'Sorted by 1 rule' }),
+ filterBtn: (page) => page.getByRole('button', { name: 'Filter', exact: true }),
+ addFilterBtn: (page) => page.getByRole('button', { name: 'Add filter' }),
+ columnPickerBtn: (page) => page.getByRole('button', { name: 'id' }),
+ filterColumnOption: (page) => page.getByLabel('id').getByText('defaultValueColumn'),
+ filterInput: (page) => page.getByPlaceholder('Enter a value'),
+ applyFilterBtn: (page) => page.getByRole('button', { name: 'Apply filter' }),
+ viewTableLabel: (page) => page.getByLabel(`View ${tableName}`, { exact: true }),
+ deleteTableBtn: (page) => page.getByText('Delete table'),
+ confirmDeleteBtn: (page) => page.getByRole('button', { name: 'Delete' }),
+ rlsCheckbox: (page) => page.getByLabel('Enable Row Level Security ('),
+ rlsConfirmBtn: (page) => page.getByRole('button', { name: 'Confirm' }),
+ deleteTableToast: (page) => page.getByText('Successfully deleted table "'),
+})
+
+test.describe('Table Editor', () => {
+ let page: Page
+ let tableName: string
+
+ test.beforeAll(async ({ browser, ref }) => {
+ test.setTimeout(60000)
+
+ /**
+ * Create a new table for the tests
+ */
+ page = await browser.newPage()
+
+ await page.goto(toUrl(`/project/${ref}/editor`))
+
+ tableName = getRandomTableName()
+ const s = getSelectors(tableName)
+
+ await s.newTableBtn(page).click()
+ await s.tableNameInput(page).fill(tableName)
+
+ await s.createdAtExtraOptions(page).click()
+ await page.getByText('Is Nullable').click()
+ await s.createdAtExtraOptions(page).click({ force: true })
+
+ await s.addColumnBtn(page).click()
+ await s.columnNameInput(page).fill('defaultValueColumn')
+ await s.chooseColumnType(page).click()
+ await s.signedIntOption(page).click()
+ await s.defaultValueField(page).click()
+ await s.defaultValueField(page).fill('2')
+
+ await s.saveBtn(page).click()
+
+ // wait till we see the success toast
+ // Text: Table tableName is good to go!
+
+ await expect(
+ page.getByText(`Table ${tableName} is good to go!`),
+ 'Success toast should be visible after table creation'
+ ).toBeVisible({
+ timeout: 50000,
+ })
+
+ await expect(
+ page.getByRole('button', { name: `View ${tableName}` }),
+ 'Table should be visible after creation'
+ ).toBeVisible()
+ })
+
+ test.afterAll(async () => {
+ test.setTimeout(60000)
+ /**
+ * Delete the table after the tests are done
+ */
+ const s = getSelectors(tableName)
+
+ const exists = (await s.tableButton(page).count()) > 0
+ if (!exists) return
+
+ await s.viewTableLabel(page).click()
+ await s.viewTableLabel(page).getByRole('button').nth(1).click()
+ await s.deleteTableBtn(page).click()
+ await s.confirmDeleteBtn(page).click()
+ await expect(
+ s.deleteTableToast(page),
+ 'Delete confirmation toast should be visible'
+ ).toBeVisible()
+ })
+
+ test('should perform all table operations sequentially', async ({ ref }) => {
+ const s = getSelectors(tableName)
+ test.setTimeout(60000)
+
+ // 1. View table definition
+ await page.evaluate(() => document.querySelector('.ReactQueryDevtools')?.remove())
+ await s.definitionTab(page).click()
+ await expect(
+ s.viewLines(page),
+ 'Table definition should contain the correct SQL'
+ ).toContainText(
+ `CREATE TABLE public.${tableName} ( id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL, created_at timestamp with time zone NULL DEFAULT now(), "defaultValueColumn" smallint NULL DEFAULT '2'::smallint, CONSTRAINT ${tableName}_pkey PRIMARY KEY (id)) TABLESPACE pg_default;`
+ )
+
+ // 2. Insert test data
+ await page.getByRole('button', { name: `View ${tableName}` }).click()
+ await s.insertRowBtn(page).click()
+ await s.insertModal(page).click()
+ await s.defaultValueInput(page).fill('100')
+ await s.actionBarSaveRow(page).click()
+
+ await page.getByRole('button', { name: `View ${tableName}` }).click()
+ await s.insertRowBtn(page).click()
+ await s.insertModal(page).click()
+ await s.defaultValueInput(page).fill('4')
+ await s.actionBarSaveRow(page).click()
+
+ // Wait for the grid to be visible and data to be loaded
+ await expect(s.grid(page), 'Grid should be visible after inserting data').toBeVisible()
+
+ // 3. Sort rows
+ await s.sortBtn(page).click()
+ await s.pickSortColumnBtn(page).click()
+ await s.sortColumnOption(page).click()
+ await s.applySortingBtn(page).click()
+ await page.keyboard.down('Escape')
+
+ // Wait for sorting to complete
+ await page.waitForResponse((response) => response.url().includes(`pg-meta/${ref}/query`))
+
+ // give it a second to rerender
+ await page.waitForTimeout(1000)
+
+ const defaultValueCells = page.getByRole('gridcell')
+
+ const thirdGridCell = defaultValueCells.nth(3)
+ const thirdGridCellText = await thirdGridCell.textContent()
+ expect(thirdGridCellText, 'Third grid cell should contain the value "4"').toEqual('4')
+
+ // 4. Filter rows
+ await s.filterBtn(page).click()
+ await s.addFilterBtn(page).click()
+ await s.columnPickerBtn(page).click()
+ await s.filterColumnOption(page).click()
+ await s.filterInput(page).fill('4')
+ await s.applyFilterBtn(page).click()
+ await page.keyboard.down('Escape')
+
+ await expect(
+ s.grid(page).getByRole('gridcell', { name: '4', exact: true }),
+ 'Filtered value "4" should be visible'
+ ).toBeVisible()
+ await expect(
+ s.grid(page).getByText('100'),
+ 'Filtered value "100" should not be visible'
+ ).not.toBeVisible()
+
+ // 5. Check auth schema
+ await page.getByTestId('schema-selector').click()
+ await page.getByRole('option', { name: 'auth' }).click()
+
+ // Wait for the tables list to be visible
+ await expect(
+ page.getByTestId('tables-list'),
+ 'Tables list should be visible in auth schema'
+ ).toBeVisible()
+
+ // search for users
+ await page.getByRole('textbox', { name: 'Search tables...' }).fill('users')
+
+ // Try to find the users table directly
+ const usersTable = page.getByRole('button', { name: 'View users' })
+ await expect(usersTable, 'Users table should be visible in auth schema').toBeVisible()
+
+ // go back to public schema
+ await page.getByTestId('schema-selector').click()
+ await page.getByRole('option', { name: 'public', exact: true }).click()
+
+ // wait for the tables list to be visible
+ await expect(
+ page.getByTestId('tables-list'),
+ 'Tables list should be visible in public schema'
+ ).toBeVisible()
+ })
+})
diff --git a/e2e/studio/package.json b/e2e/studio/package.json
new file mode 100644
index 0000000000..41d49dfa76
--- /dev/null
+++ b/e2e/studio/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "e2e-studio",
+ "version": "1.0.0",
+ "main": "index.js",
+ "scripts": {
+ "e2e": "playwright test"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "description": "",
+ "dependencies": {
+ "dotenv": "^16.5.0",
+ "@playwright/test": "^1.52.0"
+ }
+}
diff --git a/e2e/studio/playwright.config.ts b/e2e/studio/playwright.config.ts
new file mode 100644
index 0000000000..ce5f2dbee8
--- /dev/null
+++ b/e2e/studio/playwright.config.ts
@@ -0,0 +1,45 @@
+import { defineConfig } from '@playwright/test'
+import { env, STORAGE_STATE_PATH } from './env.config'
+import dotenv from 'dotenv'
+import path from 'path'
+
+dotenv.config({ path: path.resolve(__dirname, '.env.local') })
+
+const IS_CI = !!process.env.CI
+
+export default defineConfig({
+ timeout: 60 * 1000,
+ testDir: './features',
+ testMatch: /.*\.spec\.ts/,
+ forbidOnly: IS_CI,
+ retries: 3,
+ use: {
+ baseURL: env.STUDIO_URL,
+ screenshot: 'off',
+ video: 'retain-on-failure',
+ headless: IS_CI,
+ trace: 'retain-on-failure',
+ },
+ projects: [
+ {
+ name: 'setup',
+ testMatch: /.*\.setup\.ts/,
+ },
+ {
+ name: 'Features',
+ testDir: './features',
+ testMatch: /.*\.spec\.ts/,
+ dependencies: ['setup'],
+ use: {
+ browserName: 'chromium',
+ screenshot: 'off',
+ storageState: STORAGE_STATE_PATH,
+ },
+ },
+ ],
+ reporter: [
+ ['list'],
+ ['html', { open: 'never' }],
+ ['json', { outputFile: 'test-results/test-results.json' }],
+ ],
+})
diff --git a/e2e/studio/tsconfig.json b/e2e/studio/tsconfig.json
new file mode 100644
index 0000000000..fa766b8295
--- /dev/null
+++ b/e2e/studio/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "compilerOptions": {
+ "jsx": "react",
+ "skipLibCheck": true,
+ "esModuleInterop": true
+ }
+}
diff --git a/e2e/studio/utils/dismiss-toast.ts b/e2e/studio/utils/dismiss-toast.ts
new file mode 100644
index 0000000000..ed61980dc5
--- /dev/null
+++ b/e2e/studio/utils/dismiss-toast.ts
@@ -0,0 +1,11 @@
+import { Page } from '@playwright/test'
+
+export const dismissToast = async (page: Page) => {
+ await page
+ .locator('li.toast')
+ .getByRole('button', { name: 'Opt out' })
+ .waitFor({ state: 'visible' })
+ await page.locator('li.toast').getByRole('button', { name: 'Opt out' }).click()
+}
+
+export const toKebabCase = (str: string) => str.replace(/([A-Z])/g, '-$1').toLowerCase()
diff --git a/e2e/studio/utils/test.ts b/e2e/studio/utils/test.ts
new file mode 100644
index 0000000000..2d96f75db9
--- /dev/null
+++ b/e2e/studio/utils/test.ts
@@ -0,0 +1,21 @@
+import { test as base } from '@playwright/test'
+import dotenv from 'dotenv'
+import path from 'path'
+import { env } from '../env.config'
+
+dotenv.config({
+ path: path.resolve(__dirname, '../.env.local'),
+ override: true,
+})
+
+export interface TestOptions {
+ env: string
+ ref: string
+ apiUrl: string
+}
+
+export const test = base.extend({
+ env: env.STUDIO_URL,
+ ref: env.PROJECT_REF,
+ apiUrl: env.API_URL,
+})
diff --git a/e2e/studio/utils/to-url.ts b/e2e/studio/utils/to-url.ts
new file mode 100644
index 0000000000..af0bb8b988
--- /dev/null
+++ b/e2e/studio/utils/to-url.ts
@@ -0,0 +1,5 @@
+import { env } from '../env.config'
+
+export function toUrl(path: `/${string}`) {
+ return `${env.STUDIO_URL}${path}`
+}
diff --git a/package.json b/package.json
index 3e8afe69ae..69af2e1c8e 100644
--- a/package.json
+++ b/package.json
@@ -29,8 +29,17 @@
"test:ui-patterns": "turbo run test --filter=ui-patterns",
"test:studio": "turbo run test --filter=studio",
"test:studio:watch": "turbo run test --filter=studio -- watch",
- "test:e2e:studio-local": "pnpm --prefix tests/studio-tests run test:local",
- "test:e2e:studio-staging": "pnpm --prefix tests/studio-tests run test:staging",
+
+ "e2e": "pnpm --prefix e2e/studio run e2e",
+ "e2e:dev-hosted": "pnpm --prefix e2e/studio run e2e:dev-hosted",
+ "e2e:dev-selfhosted": "pnpm --prefix e2e/studio run e2e:dev-selfhosted",
+ "e2e:selfhosted": "pnpm --prefix e2e/studio run e2e:selfhosted",
+ "e2e:staging": "pnpm --prefix e2e/studio run e2e:staging",
+ "e2e:prod": "pnpm --prefix e2e/studio run e2e:prod",
+ "e2e:ci": "pnpm --prefix e2e/studio run e2e:ci",
+ "e2e:supabase:start": "pnpm --prefix e2e/studio run supabase:start",
+ "e2e:supabase:stop": "pnpm --prefix e2e/studio run supabase:stop",
+
"perf:kong": "ab -t 5 -c 20 -T application/json http://localhost:8000/",
"perf:meta": "ab -t 5 -c 20 -T application/json http://localhost:5555/tables",
"generate:types": "supabase gen types typescript --local > ./supabase/functions/common/database-types.ts",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6a8b855a62..4097bfed3d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -91,28 +91,28 @@ importers:
version: 3.40.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@payloadcms/next':
specifier: 3.33.0
- version: 3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ version: 3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
'@payloadcms/payload-cloud':
specifier: 3.33.0
version: 3.33.0(encoding@0.1.13)(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))
'@payloadcms/plugin-form-builder':
specifier: 3.33.0
- version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
'@payloadcms/plugin-nested-docs':
specifier: 3.33.0
version: 3.33.0(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))
'@payloadcms/plugin-seo':
specifier: 3.33.0
- version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
'@payloadcms/richtext-lexical':
specifier: 3.33.0
- version: 3.33.0(@faceless-ui/modal@3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@faceless-ui/scroll-info@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3))(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)(yjs@13.6.27)
+ version: 3.33.0(@faceless-ui/modal@3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@faceless-ui/scroll-info@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3))(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)(yjs@13.6.27)
'@payloadcms/storage-s3':
specifier: 3.33.0
- version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
'@payloadcms/ui':
specifier: 3.33.0
- version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
common:
specifier: workspace:*
version: link:../../packages/common
@@ -130,7 +130,7 @@ importers:
version: 16.10.0
next:
specifier: ~15.3.0
- version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
payload:
specifier: 3.33.0
version: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
@@ -182,10 +182,10 @@ importers:
version: 1.2.0
next:
specifier: 'catalog:'
- version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
next-contentlayer2:
specifier: 0.4.6
- version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
+ version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -327,7 +327,7 @@ importers:
version: 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@sentry/nextjs':
specifier: ^9.15.0
- version: 9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
+ version: 9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
'@supabase/supabase-js':
specifier: 'catalog:'
version: 2.49.3
@@ -435,7 +435,7 @@ importers:
version: 1.0.1
next:
specifier: 15.3.1
- version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
next-mdx-remote:
specifier: ^4.4.1
version: 4.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
@@ -447,7 +447,7 @@ importers:
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
nuqs:
specifier: ^1.19.1
- version: 1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))
+ version: 1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))
openai:
specifier: ^4.20.1
version: 4.71.1(encoding@0.1.13)(zod@3.23.8)
@@ -700,7 +700,7 @@ importers:
version: 0.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@sentry/nextjs':
specifier: ^8.52.1
- version: 8.52.1(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
+ version: 8.52.1(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
'@std/path':
specifier: npm:@jsr/std__path@^1.0.8
version: '@jsr/std__path@1.0.8'
@@ -739,7 +739,7 @@ importers:
version: 2.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@vercel/flags':
specifier: ^2.6.0
- version: 2.6.0(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ version: 2.6.0(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@vitejs/plugin-react':
specifier: ^4.3.4
version: 4.3.4(supports-color@8.1.1)(vite@6.2.6(@types/node@20.12.11)(jiti@2.4.2)(sass@1.77.4)(terser@5.39.0)(tsx@4.19.3)(yaml@2.4.5))
@@ -826,13 +826,13 @@ importers:
version: 0.52.2
next:
specifier: ~15.3.0
- version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
nuqs:
specifier: ^2.4.1
- version: 2.4.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+ version: 2.4.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
openai:
specifier: ^4.20.1
version: 4.71.1(encoding@0.1.13)(zod@3.23.8)
@@ -1085,7 +1085,7 @@ importers:
version: 2.4.11(typescript@5.5.2)
next-router-mock:
specifier: ^0.9.13
- version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
+ version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
postcss:
specifier: ^8.5.3
version: 8.5.3
@@ -1172,10 +1172,10 @@ importers:
version: 0.436.0(react@18.3.1)
next:
specifier: 'catalog:'
- version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
next-contentlayer2:
specifier: 0.4.6
- version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
+ version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -1407,16 +1407,16 @@ importers:
version: 1.2.0
next:
specifier: 'catalog:'
- version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
next-contentlayer2:
specifier: 0.5.3
- version: 0.5.3(contentlayer2@0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
+ version: 0.5.3(contentlayer2@0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
next-mdx-remote:
specifier: ^4.4.1
version: 4.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
next-seo:
specifier: ^6.5.0
- version: 6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ version: 6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -1551,6 +1551,15 @@ importers:
specifier: ^3.22.4
version: 3.23.8
+ e2e/studio:
+ dependencies:
+ '@playwright/test':
+ specifier: ^1.52.0
+ version: 1.52.0
+ dotenv:
+ specifier: ^16.5.0
+ version: 16.5.0
+
packages/ai-commands:
dependencies:
'@serafin/schema-builder':
@@ -1661,7 +1670,7 @@ importers:
version: 4.42.0
'@vercel/flags':
specifier: ^2.6.0
- version: 2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ version: 2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
api-types:
specifier: workspace:*
version: link:../api-types
@@ -1676,7 +1685,7 @@ importers:
version: 4.17.21
next:
specifier: 'catalog:'
- version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -1954,7 +1963,7 @@ importers:
version: 0.436.0(react@18.3.1)
next:
specifier: 'catalog:'
- version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -2123,7 +2132,7 @@ importers:
version: 0.52.2
next:
specifier: '*'
- version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
next-themes:
specifier: '*'
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -2232,7 +2241,7 @@ importers:
version: link:../api-types
next-router-mock:
specifier: ^0.9.13
- version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
+ version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
tsx:
specifier: ^4.19.3
version: 4.19.3
@@ -2252,18 +2261,6 @@ importers:
specifier: ^3.0.5
version: 3.0.9(@types/node@20.12.11)(jiti@2.4.2)(jsdom@20.0.3(supports-color@8.1.1))(msw@2.7.3(@types/node@20.12.11)(typescript@5.5.2))(sass@1.77.4)(supports-color@8.1.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.4.5)
- tests/studio-tests:
- devDependencies:
- '@playwright/test':
- specifier: ^1.49.0
- version: 1.49.1
- dotenv:
- specifier: ^16.4.7
- version: 16.4.7
- lodash:
- specifier: ^4.17.21
- version: 4.17.21
-
packages:
'@aashutoshrathi/word-wrap@1.2.6':
@@ -5816,8 +5813,8 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
- '@playwright/test@1.49.1':
- resolution: {integrity: sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==}
+ '@playwright/test@1.52.0':
+ resolution: {integrity: sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==}
engines: {node: '>=18'}
hasBin: true
@@ -10858,6 +10855,10 @@ packages:
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
engines: {node: '>=12'}
+ dotenv@16.5.0:
+ resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==}
+ engines: {node: '>=12'}
+
dotty@0.1.2:
resolution: {integrity: sha512-V0EWmKeH3DEhMwAZ+8ZB2Ao4OK6p++Z0hsDtZq3N0+0ZMVqkzrcEGROvOnZpLnvBg5PTNG23JEDLAm64gPaotQ==}
@@ -14907,13 +14908,13 @@ packages:
pkg-types@2.1.0:
resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==}
- playwright-core@1.49.1:
- resolution: {integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==}
+ playwright-core@1.52.0:
+ resolution: {integrity: sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==}
engines: {node: '>=18'}
hasBin: true
- playwright@1.49.1:
- resolution: {integrity: sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==}
+ playwright@1.52.0:
+ resolution: {integrity: sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==}
engines: {node: '>=18'}
hasBin: true
@@ -17508,11 +17509,6 @@ packages:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
- use-sync-external-store@1.4.0:
- resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
-
use-sync-external-store@1.5.0:
resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==}
peerDependencies:
@@ -20300,8 +20296,8 @@ snapshots:
'@fastify/ajv-compiler@3.6.0':
dependencies:
- ajv: 8.17.1
- ajv-formats: 2.1.1(ajv@8.17.1)
+ ajv: 8.12.0
+ ajv-formats: 2.1.1(ajv@8.12.0)
fast-uri: 2.4.0
'@fastify/busboy@3.1.1': {}
@@ -22825,12 +22821,12 @@ snapshots:
'@payloadcms/live-preview@3.40.0': {}
- '@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
+ '@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
dependencies:
'@dnd-kit/core': 6.0.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@payloadcms/graphql': 3.33.0(graphql@16.10.0)(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(typescript@5.7.3)
'@payloadcms/translations': 3.33.0
- '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
busboy: 1.6.0
dequal: 2.0.3
file-type: 19.3.0
@@ -22838,7 +22834,7 @@ snapshots:
graphql-http: 1.22.4(graphql@16.10.0)
graphql-playground-html: 1.6.30
http-status: 2.1.0
- next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
path-to-regexp: 6.3.0
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
qs-esm: 7.0.2
@@ -22867,9 +22863,9 @@ snapshots:
- aws-crt
- encoding
- '@payloadcms/plugin-cloud-storage@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
+ '@payloadcms/plugin-cloud-storage@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
dependencies:
- '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
find-node-modules: 2.1.3
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
range-parser: 1.2.1
@@ -22882,9 +22878,9 @@ snapshots:
- supports-color
- typescript
- '@payloadcms/plugin-form-builder@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
+ '@payloadcms/plugin-form-builder@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
dependencies:
- '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
escape-html: 1.0.3
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
react: 18.3.1
@@ -22900,10 +22896,10 @@ snapshots:
dependencies:
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
- '@payloadcms/plugin-seo@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
+ '@payloadcms/plugin-seo@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
dependencies:
'@payloadcms/translations': 3.33.0
- '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
@@ -22914,7 +22910,7 @@ snapshots:
- supports-color
- typescript
- '@payloadcms/richtext-lexical@3.33.0(@faceless-ui/modal@3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@faceless-ui/scroll-info@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3))(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)(yjs@13.6.27)':
+ '@payloadcms/richtext-lexical@3.33.0(@faceless-ui/modal@3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@faceless-ui/scroll-info@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3))(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)(yjs@13.6.27)':
dependencies:
'@faceless-ui/modal': 3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@faceless-ui/scroll-info': 2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -22928,9 +22924,9 @@ snapshots:
'@lexical/selection': 0.28.0
'@lexical/table': 0.28.0
'@lexical/utils': 0.28.0
- '@payloadcms/next': 3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ '@payloadcms/next': 3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
'@payloadcms/translations': 3.33.0
- '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ '@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
'@types/uuid': 10.0.0
acorn: 8.12.1
bson-objectid: 2.0.4
@@ -22956,12 +22952,12 @@ snapshots:
- typescript
- yjs
- '@payloadcms/storage-s3@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
+ '@payloadcms/storage-s3@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
dependencies:
'@aws-sdk/client-s3': 3.821.0
'@aws-sdk/lib-storage': 3.821.0(@aws-sdk/client-s3@3.821.0)
'@aws-sdk/s3-request-presigner': 3.821.0
- '@payloadcms/plugin-cloud-storage': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
+ '@payloadcms/plugin-cloud-storage': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
transitivePeerDependencies:
- '@types/react'
@@ -22977,7 +22973,7 @@ snapshots:
dependencies:
date-fns: 4.1.0
- '@payloadcms/ui@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
+ '@payloadcms/ui@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
dependencies:
'@date-fns/tz': 1.2.0
'@dnd-kit/core': 6.0.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -22991,7 +22987,7 @@ snapshots:
date-fns: 4.1.0
dequal: 2.0.3
md5: 2.3.0
- next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
object-to-formdata: 4.5.1
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
qs-esm: 7.0.2
@@ -23016,9 +23012,9 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
- '@playwright/test@1.49.1':
+ '@playwright/test@1.52.0':
dependencies:
- playwright: 1.49.1
+ playwright: 1.52.0
'@polka/url@1.0.0-next.25': {}
@@ -23727,7 +23723,7 @@ snapshots:
'@radix-ui/react-popper@1.2.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@floating-ui/react-dom': 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-arrow': 1.1.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-context': 1.1.2(@types/react@18.3.3)(react@18.3.1)
@@ -24561,7 +24557,7 @@ snapshots:
chokidar: 3.6.0
colorette: 1.4.0
core-js: 3.35.0
- dotenv: 16.4.7
+ dotenv: 16.5.0
form-data: 4.0.2
get-port-please: 3.1.2
glob: 7.2.3
@@ -24943,7 +24939,7 @@ snapshots:
'@babel/core': 7.26.10(supports-color@8.1.1)
'@sentry/babel-plugin-component-annotate': 2.22.7
'@sentry/cli': 2.39.1(encoding@0.1.13)(supports-color@8.1.1)
- dotenv: 16.4.7
+ dotenv: 16.5.0
find-up: 5.0.0
glob: 9.3.5
magic-string: 0.30.8
@@ -25050,7 +25046,7 @@ snapshots:
'@sentry/core@9.15.0': {}
- '@sentry/nextjs@8.52.1(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
+ '@sentry/nextjs@8.52.1(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/semantic-conventions': 1.28.0
@@ -25063,7 +25059,7 @@ snapshots:
'@sentry/vercel-edge': 8.52.1
'@sentry/webpack-plugin': 2.22.7(encoding@0.1.13)(supports-color@8.1.1)(webpack@5.94.0)
chalk: 3.0.0
- next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
resolve: 1.22.8
rollup: 3.29.5
stacktrace-parser: 0.1.10
@@ -25076,7 +25072,7 @@ snapshots:
- supports-color
- webpack
- '@sentry/nextjs@9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
+ '@sentry/nextjs@9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/semantic-conventions': 1.32.0
@@ -25089,7 +25085,7 @@ snapshots:
'@sentry/vercel-edge': 9.15.0
'@sentry/webpack-plugin': 3.3.1(encoding@0.1.13)(supports-color@8.1.1)(webpack@5.94.0)
chalk: 3.0.0
- next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
resolve: 1.22.8
rollup: 4.35.0
stacktrace-parser: 0.1.10
@@ -26425,7 +26421,7 @@ snapshots:
'@tanstack/store': 0.7.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- use-sync-external-store: 1.4.0(react@18.3.1)
+ use-sync-external-store: 1.5.0(react@18.3.1)
'@tanstack/react-virtual@3.13.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
@@ -27298,19 +27294,19 @@ snapshots:
lz-string: 1.5.0
uuid: 9.0.1
- '@vercel/flags@2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ '@vercel/flags@2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
jose: 5.2.1
optionalDependencies:
- next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- '@vercel/flags@2.6.0(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ '@vercel/flags@2.6.0(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
jose: 5.2.1
optionalDependencies:
- next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
@@ -27785,9 +27781,9 @@ snapshots:
optionalDependencies:
ajv: 8.17.1
- ajv-formats@3.0.1(ajv@8.17.1):
+ ajv-formats@3.0.1(ajv@8.12.0):
optionalDependencies:
- ajv: 8.17.1
+ ajv: 8.12.0
ajv-keywords@3.5.2(ajv@6.12.6):
dependencies:
@@ -27828,7 +27824,7 @@ snapshots:
js-cookie: 2.2.1
transitivePeerDependencies:
- encoding
-
+
animejs@4.0.2: {}
anser@2.3.2: {}
@@ -28254,7 +28250,7 @@ snapshots:
chokidar: 4.0.3
confbox: 0.1.8
defu: 6.1.4
- dotenv: 16.4.7
+ dotenv: 16.5.0
exsolve: 1.0.4
giget: 2.0.0
jiti: 2.4.2
@@ -29290,6 +29286,8 @@ snapshots:
dotenv@16.4.7: {}
+ dotenv@16.5.0: {}
+
dotty@0.1.2: {}
drange@1.1.1: {}
@@ -30147,8 +30145,8 @@ snapshots:
fast-json-stringify@5.16.1:
dependencies:
'@fastify/merge-json-schemas': 0.1.1
- ajv: 8.17.1
- ajv-formats: 3.0.1(ajv@8.17.1)
+ ajv: 8.12.0
+ ajv-formats: 3.0.1(ajv@8.12.0)
fast-deep-equal: 3.1.3
fast-uri: 2.4.0
json-schema-ref-resolver: 1.0.1
@@ -33645,12 +33643,12 @@ snapshots:
neo-async@2.6.2: {}
- next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1):
+ next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1):
dependencies:
'@contentlayer2/core': 0.4.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1)
'@contentlayer2/utils': 0.4.3
contentlayer2: 0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1)
- next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
transitivePeerDependencies:
@@ -33659,12 +33657,12 @@ snapshots:
- markdown-wasm
- supports-color
- next-contentlayer2@0.5.3(contentlayer2@0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1):
+ next-contentlayer2@0.5.3(contentlayer2@0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1):
dependencies:
'@contentlayer2/core': 0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1)
'@contentlayer2/utils': 0.5.3
contentlayer2: 0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1)
- next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
transitivePeerDependencies:
@@ -33688,14 +33686,14 @@ snapshots:
dependencies:
js-yaml-loader: 1.2.2
- next-router-mock@0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1):
+ next-router-mock@0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1):
dependencies:
- next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
react: 18.3.1
- next-seo@6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ next-seo@6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
- next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
@@ -33706,7 +33704,7 @@ snapshots:
next-tick@1.1.0: {}
- next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4):
+ next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4):
dependencies:
'@next/env': 14.2.26
'@swc/helpers': 0.5.5
@@ -33728,13 +33726,13 @@ snapshots:
'@next/swc-win32-ia32-msvc': 14.2.26
'@next/swc-win32-x64-msvc': 14.2.26
'@opentelemetry/api': 1.9.0
- '@playwright/test': 1.49.1
+ '@playwright/test': 1.52.0
sass: 1.77.4
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
- next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4):
+ next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4):
dependencies:
'@next/env': 15.3.1
'@swc/counter': 0.1.3
@@ -33755,7 +33753,7 @@ snapshots:
'@next/swc-win32-arm64-msvc': 15.3.1
'@next/swc-win32-x64-msvc': 15.3.1
'@opentelemetry/api': 1.9.0
- '@playwright/test': 1.49.1
+ '@playwright/test': 1.52.0
sass: 1.77.4
sharp: 0.34.1
transitivePeerDependencies:
@@ -34053,17 +34051,17 @@ snapshots:
number-flow@0.3.7: {}
- nuqs@1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)):
+ nuqs@1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)):
dependencies:
mitt: 3.0.1
- next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
- nuqs@2.4.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
+ nuqs@2.4.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
dependencies:
mitt: 3.0.1
react: 18.3.1
optionalDependencies:
- next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
+ next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
react-router: 7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
nwsapi@2.2.20:
@@ -34514,7 +34512,7 @@ snapshots:
periscopic@3.1.0:
dependencies:
- '@types/estree': 1.0.5
+ '@types/estree': 1.0.7
estree-walker: 3.0.3
is-reference: 3.0.3
@@ -34712,11 +34710,11 @@ snapshots:
exsolve: 1.0.4
pathe: 2.0.3
- playwright-core@1.49.1: {}
+ playwright-core@1.52.0: {}
- playwright@1.49.1:
+ playwright@1.52.0:
dependencies:
- playwright-core: 1.49.1
+ playwright-core: 1.52.0
optionalDependencies:
fsevents: 2.3.2
@@ -36628,7 +36626,7 @@ snapshots:
static-browser-server@1.0.3:
dependencies:
'@open-draft/deferred-promise': 2.2.0
- dotenv: 16.4.7
+ dotenv: 16.5.0
mime-db: 1.53.0
outvariant: 1.4.3
@@ -36935,7 +36933,7 @@ snapshots:
dependencies:
client-only: 0.0.1
react: 18.3.1
- use-sync-external-store: 1.4.0(react@18.3.1)
+ use-sync-external-store: 1.5.0(react@18.3.1)
swrev@4.0.0: {}
@@ -37874,10 +37872,6 @@ snapshots:
dependencies:
react: 18.3.1
- use-sync-external-store@1.4.0(react@18.3.1):
- dependencies:
- react: 18.3.1
-
use-sync-external-store@1.5.0(react@18.3.1):
dependencies:
react: 18.3.1
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 137fe7e0cf..f2ed1040ed 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,7 +1,7 @@
packages:
- 'apps/*'
- 'packages/*'
- - 'tests/*'
+ - 'e2e/*'
catalog:
'@types/node': ^20.0.0
diff --git a/tests/studio-tests/.env.staging.example b/tests/studio-tests/.env.staging.example
deleted file mode 100644
index 9595e3fa1f..0000000000
--- a/tests/studio-tests/.env.staging.example
+++ /dev/null
@@ -1,3 +0,0 @@
-EMAIL=
-PASSWORD=
-PROJECT_REF=
\ No newline at end of file
diff --git a/tests/studio-tests/README.md b/tests/studio-tests/README.md
deleted file mode 100644
index e877f2fc67..0000000000
--- a/tests/studio-tests/README.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Studio E2E Tests
-
-In an effort to make the local + hosted studio more stable, we've added tests which test features which are commonly used in local
-development. Built with [Playwright](https://playwright.dev/docs/intro).
-
-## How to run tests
-
-Before running the tests, make sure you've done the following:
-
-- Run `npm install` in the root folder of this repo
-- `docker` or `orbstack` is currently running
-- `supabase` CLI is already [installed](https://github.com/supabase/cli?tab=readme-ov-file#install-the-cli)
-- no other supabase local environment is running (infrastructure environment is ok)
-
-You can run the tests by running `npm run test` in this folder.
-
-When you run the command, it includes:
-
-1. Setting up the local environment using the `supabase` CLI
-2. Extracting the environment variables and saving them into a `.env.test` file in the studio app
-3. Running the `studio` app in dev mode (`npm run dev`)
-4. Running the tests
-5. Stopping the `studio` app and the local environment
-
-If the environment does't stop for some reason, you'll see `supabase start is already running` on the next run. In this
-case, just run `supabase stop` between test runs.
-
-## How to write tests
-
-Playwright has a nice [Codegen tool](https://playwright.dev/docs/codegen-intro#running-codegen) which you can use to
-record your actions:
-
-```bash
-pnpm codegen:setup
-# in a separate terminal
-pnpm codegen
-```
-
-## How to debug/fix tests
-
-If you've run the tests locally and you want to see the results, Playwright has a [UI mode](https://playwright.dev/docs/test-ui-mode)
-which you can use to run and replay specific tests:
-
-```bash
-pnpm test -- --ui
-```
-
-It will also record any failing tests when running `npm run test` in this folder.
diff --git a/tests/studio-tests/base.ts b/tests/studio-tests/base.ts
deleted file mode 100644
index 5484171153..0000000000
--- a/tests/studio-tests/base.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { test as base } from '@playwright/test'
-import dotenv from 'dotenv'
-import path from 'path'
-
-dotenv.config({
- path: path.resolve(__dirname, process.env.ENV === 'staging' ? '../.env.staging' : ''),
- override: true,
-})
-
-export interface TestOptions {
- env: string
- ref: string
- apiUrl: string
-}
-
-export const test = base.extend({
- env: process.env.ENV,
- ref: process.env.PROJECT_REF,
- apiUrl:
- process.env.ENV === 'local'
- ? 'http://localhost:8082/api'
- : process.env.ENV === 'staging'
- ? 'https://api.supabase.green'
- : '',
-})
diff --git a/tests/studio-tests/generate-local-env.js b/tests/studio-tests/generate-local-env.js
deleted file mode 100644
index d51ffb3775..0000000000
--- a/tests/studio-tests/generate-local-env.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const fs = require('fs')
-const generatedEnv = require('./keys.json')
-
-/**
- * This script takes the API keys from the local environment, merges them with some predefined variables and saves them
- * to a env.test file in the studio app. This is needed to prepare the studio so that it can be run with the local
- * environment as the backend.
- */
-
-const defaultEnv = {
- // POSTGRES_PASSWORD: 'postgres',
- // NEXT_ANALYTICS_BACKEND_PROVIDER: 'postgres',
- // SUPABASE_REST_URL: 'http://127.0.0.1:54321/rest/v1/',
- // NEXT_PUBLIC_ENABLE_LOGS: 'false',
- // NEXT_PUBLIC_IS_PLATFORM: 'false',
- SUPABASE_ANON_KEY: '$ANON_KEY',
- SUPABASE_SERVICE_KEY: '$SERVICE_ROLE_KEY',
- SUPABASE_URL: '$API_URL',
- STUDIO_PG_META_URL: '$API_URL/pg',
- SUPABASE_PUBLIC_URL: '$API_URL',
- SENTRY_IGNORE_API_RESOLUTION_ERROR: '1',
- LOGFLARE_URL: 'http://localhost:54329',
- LOGFLARE_API_KEY: 'api-key',
- NEXT_PUBLIC_SITE_URL: 'http://localhost:8082',
- NEXT_PUBLIC_GOTRUE_URL: '$SUPABASE_PUBLIC_URL/auth/v1',
- NEXT_PUBLIC_HCAPTCHA_SITE_KEY: '10000000-ffff-ffff-ffff-000000000001',
- NEXT_PUBLIC_NODE_ENV: 'test',
-}
-
-const environment = { ...generatedEnv, ...defaultEnv }
-
-fs.writeFileSync(
- '../../apps/studio/.env.test',
- Object.keys(environment)
- .map((key) => `${key}=${environment[key]}`)
- .join('\n')
-)
diff --git a/tests/studio-tests/package.json b/tests/studio-tests/package.json
deleted file mode 100644
index b96c92fd6a..0000000000
--- a/tests/studio-tests/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "name": "studio-tests",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "preinstall": "npx only-allow pnpm",
- "env:setup": "supabase start -x studio && supabase status --output json > keys.json && node generate-local-env.js",
- "pretest:local": "pnpm env:setup",
- "test:local": "pnpm env:setup && export ENV=local && export PROJECT_REF=default && playwright test",
- "posttest:local": "supabase stop --no-backup",
- "test:staging": "export ENV=staging && playwright test",
- "codegen:setup": "pnpm env:setup && NODE_ENV=test pnpm --prefix ../../apps/studio dev",
- "codegen": "playwright codegen http://localhost:8082/project/default",
- "clean": "rimraf node_modules"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "@playwright/test": "^1.49.0",
- "lodash": "^4.17.21",
- "dotenv": "^16.4.7"
- }
-}
diff --git a/tests/studio-tests/playwright.config.ts b/tests/studio-tests/playwright.config.ts
deleted file mode 100644
index 187369266f..0000000000
--- a/tests/studio-tests/playwright.config.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { defineConfig, devices } from '@playwright/test'
-
-// See https://playwright.dev/docs/test-configuration.
-
-export default defineConfig({
- fullyParallel: true,
- forbidOnly: !!process.env.CI,
- retries: process.env.CI ? 2 : 0,
- workers: process.env.CI ? 1 : undefined,
- timeout: 20000,
- reporter: 'html',
- use: {
- baseURL:
- process.env.ENV === 'local'
- ? 'http://localhost:8082'
- : process.env.ENV === 'staging'
- ? 'https://supabase.green/dashboard/'
- : '',
- trace: 'on-first-retry',
- video: 'retain-on-failure',
- launchOptions: {
- env: {
- NODE_ENV:
- process.env.ENV === 'local' ? 'test' : process.env.ENV === 'staging' ? 'staging' : '',
- },
- },
- },
- projects: [
- ...(process.env.ENV !== 'local'
- ? [
- {
- name: 'Authentication setup',
- testDir: './tests',
- testMatch: /.*\.setup\.ts/,
- },
- ]
- : []),
- {
- name: 'Common Functionality',
- use: {
- ...devices['Desktop Chrome'],
- ...(process.env.ENV !== 'local' ? { storageState: 'playwright/.auth/user.json' } : {}),
- viewport: { width: 1366, height: 768 },
- },
- testDir: './tests/common-functionality',
- dependencies: process.env.ENV !== 'local' ? ['Authentication setup'] : undefined,
- },
- ...(process.env.ENV !== 'local'
- ? [
- {
- name: 'Production Functionality',
- use: {
- ...devices['Desktop Chrome'],
- storageState: 'playwright/.auth/user.json',
- viewport: { width: 1366, height: 768 },
- },
- testDir: './tests/production-functionality',
- dependencies: ['Authentication setup'],
- },
- ]
- : []),
- ],
- /* Run your local dev server before starting the tests */
- webServer:
- process.env.ENV === 'local'
- ? {
- // using npm run dev instead of turbo because turbo doesn't stop the server after a test (doesn't handle SIGTERM).
- command: 'pnpm dev',
- cwd: '../../apps/studio',
- url: 'http://localhost:8082',
- reuseExistingServer: !process.env.CI,
- env: { NODE_ENV: 'test' },
- }
- : undefined,
-})
diff --git a/tests/studio-tests/supabase/.gitignore b/tests/studio-tests/supabase/.gitignore
deleted file mode 100644
index a3ad88055b..0000000000
--- a/tests/studio-tests/supabase/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-# Supabase
-.branches
-.temp
-.env
diff --git a/tests/studio-tests/supabase/config.toml b/tests/studio-tests/supabase/config.toml
deleted file mode 100644
index 4a8de47428..0000000000
--- a/tests/studio-tests/supabase/config.toml
+++ /dev/null
@@ -1,159 +0,0 @@
-# A string used to distinguish different Supabase projects on the same host. Defaults to the
-# working directory name when running `supabase init`.
-project_id = "local-studio-tests"
-
-[api]
-enabled = true
-# Port to use for the API URL.
-port = 54321
-# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API
-# endpoints. public and storage are always included.
-schemas = ["public", "storage", "graphql_public"]
-# Extra schemas to add to the search_path of every request. public is always included.
-extra_search_path = ["public", "extensions"]
-# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size
-# for accidental or malicious requests.
-max_rows = 1000
-
-[db]
-# Port to use for the local database URL.
-port = 54322
-# Port used by db diff command to initialize the shadow database.
-shadow_port = 54320
-# The database major version to use. This has to be the same as your remote database's. Run `SHOW
-# server_version;` on the remote database to check.
-major_version = 15
-
-[db.pooler]
-enabled = false
-# Port to use for the local connection pooler.
-port = 54329
-# Specifies when a server connection can be reused by other clients.
-# Configure one of the supported pooler modes: `transaction`, `session`.
-pool_mode = "transaction"
-# How many server connections to allow per user/database pair.
-default_pool_size = 20
-# Maximum number of client connections allowed.
-max_client_conn = 100
-
-[realtime]
-enabled = true
-# Bind realtime via either IPv4 or IPv6. (default: IPv6)
-# ip_version = "IPv6"
-# The maximum length in bytes of HTTP request headers. (default: 4096)
-# max_header_length = 4096
-
-[studio]
-enabled = true
-# Port to use for Supabase Studio.
-port = 54323
-# External URL of the API server that frontend connects to.
-api_url = "http://127.0.0.1"
-
-# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they
-# are monitored, and you can view the emails that would have been sent from the web interface.
-[inbucket]
-enabled = true
-# Port to use for the email testing server web interface.
-port = 54324
-# Uncomment to expose additional ports for testing user applications that send emails.
-# smtp_port = 54325
-# pop3_port = 54326
-
-[storage]
-enabled = true
-# The maximum file size allowed (e.g. "5MB", "500KB").
-file_size_limit = "50MiB"
-
-[auth]
-enabled = true
-# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
-# in emails.
-site_url = "http://127.0.0.1:3000"
-# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
-additional_redirect_urls = ["https://127.0.0.1:3000"]
-# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
-jwt_expiry = 3600
-# If disabled, the refresh token will never expire.
-enable_refresh_token_rotation = true
-# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
-# Requires enable_refresh_token_rotation = true.
-refresh_token_reuse_interval = 10
-# Allow/disallow new user signups to your project.
-enable_signup = true
-# Allow/disallow testing manual linking of accounts
-# enable_manual_linking = false
-
-[auth.email]
-# Allow/disallow new user signups via email to your project.
-enable_signup = true
-# If enabled, a user will be required to confirm any email change on both the old, and new email
-# addresses. If disabled, only the new email is required to confirm.
-double_confirm_changes = true
-# If enabled, users need to confirm their email address before signing in.
-enable_confirmations = false
-
-# Uncomment to customize email template
-# [auth.email.template.invite]
-# subject = "You have been invited"
-# content_path = "./supabase/templates/invite.html"
-
-[auth.sms]
-# Allow/disallow new user signups via SMS to your project.
-enable_signup = true
-# If enabled, users need to confirm their phone number before signing in.
-enable_confirmations = false
-# Template for sending OTP to users
-# template = "Your code is {{ .Code }} ."
-
-# Use pre-defined map of phone number to OTP for testing.
-[auth.sms.test_otp]
-# 4152127777 = "123456"
-
-# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used.
-# [auth.hook.custom_access_token]
-# enabled = true
-# uri = "pg-functions:////"
-
-
-# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`.
-[auth.sms.twilio]
-enabled = false
-account_sid = ""
-message_service_sid = ""
-# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:
-auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)"
-
-# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
-# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,
-# `twitter`, `slack`, `spotify`, `workos`, `zoom`.
-[auth.external.apple]
-enabled = false
-client_id = ""
-# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
-secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
-# Overrides the default auth redirectUrl.
-redirect_uri = ""
-# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
-# or any other third-party OIDC providers.
-url = ""
-
-[analytics]
-enabled = true
-port = 54329
-vector_port = 54328
-# Configure one of the supported backends: `postgres`, `bigquery`.
-backend = "postgres"
-
-# Experimental features may be deprecated any time
-# [experimental]
-# Configures Postgres storage engine to use OrioleDB (S3)
-# orioledb_version = ""
-# Configures S3 bucket URL, eg. .s3-.amazonaws.com
-# s3_host = "env(S3_HOST)"
-# Configures S3 bucket region, eg. us-east-1
-# s3_region = "env(S3_REGION)"
-# Configures AWS_ACCESS_KEY_ID for S3 bucket
-# s3_access_key = "env(S3_ACCESS_KEY)"
-# Configures AWS_SECRET_ACCESS_KEY for S3 bucket
-# s3_secret_key = "env(S3_SECRET_KEY)"
diff --git a/tests/studio-tests/supabase/seed.sql b/tests/studio-tests/supabase/seed.sql
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/tests/studio-tests/tests/auth.setup.ts b/tests/studio-tests/tests/auth.setup.ts
deleted file mode 100644
index 4bcd271525..0000000000
--- a/tests/studio-tests/tests/auth.setup.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { test as setup } from '@playwright/test'
-import dotenv from 'dotenv'
-import path from 'path'
-
-dotenv.config({
- path: path.resolve(__dirname, process.env.ENV === 'staging' ? '../.env.staging' : ''),
- override: true,
-})
-const authFile = path.join(__dirname, '../playwright/.auth/user.json')
-
-setup('Authenticate', async ({ page }) => {
- await page.goto('./sign-in')
- await page.getByLabel('Email').fill(process.env.EMAIL ?? '')
- await page.getByLabel('Password').fill(process.env.PASSWORD ?? '')
- await page.getByRole('button', { name: 'Sign In' }).click()
-
- await page.pause()
-
- await page.waitForURL('./projects')
- await page.context().storageState({ path: authFile })
-})
diff --git a/tests/studio-tests/tests/common-functionality/home.spec.ts b/tests/studio-tests/tests/common-functionality/home.spec.ts
deleted file mode 100644
index 9a590ce7a4..0000000000
--- a/tests/studio-tests/tests/common-functionality/home.spec.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { expect } from '@playwright/test'
-import { test } from '../../base'
-
-test.describe('Project', async () => {
- test('Can navigate to project home page', async ({ page, env, ref }) => {
- await page.goto(`./project/${ref}`)
- await expect(
- page.getByRole('heading', {
- name: env === 'local' ? 'Welcome to your project' : 'Playwright Test',
- })
- ).toBeVisible({ timeout: 10000 })
- })
-})
diff --git a/tests/studio-tests/tests/common-functionality/logs.spec.ts b/tests/studio-tests/tests/common-functionality/logs.spec.ts
deleted file mode 100644
index d272a9d37e..0000000000
--- a/tests/studio-tests/tests/common-functionality/logs.spec.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-import { expect } from '@playwright/test'
-import { test } from '../../base'
-
-const LOGS_PAGES = [
- { label: 'API Gateway', route: 'edge-logs' },
- { label: 'Postgres', route: 'postgres-logs' },
- { label: 'PostgREST', route: 'postgrest-logs' },
-]
-
-test.describe('Logs', async () => {
- test.describe.configure({ retries: 5 })
- for (const logPage of LOGS_PAGES) {
- test.describe(`${logPage.label} logs page`, () => {
- test('can navigate to logs page', async ({ page, ref }) => {
- await page.goto(`./project/${ref}`)
- await page.locator('a', { hasText: 'Logs' }).click({ timeout: 10000 })
- await expect(page.getByRole('heading', { name: 'Logs & Analytics' })).toBeVisible()
-
- // Click anywhere on the screen to close the sidebar
- await page.click('body')
-
- await page
- .getByRole('link', { name: logPage.label, exact: true })
- .click()
- .catch((e) => {
- console.log('๐ด Error clicking', logPage, e)
- throw e
- })
-
- // Wait for and verify the logs table is present
- const logsTable = page.getByRole('table')
- await expect(logsTable).toBeVisible({
- timeout: 20000,
- })
- })
-
- test('shows logs data without errors', async ({ page, ref, apiUrl }) => {
- // Navigate to page first
- await page.goto(`./project/${ref}/logs/${logPage.route}`)
-
- await page.waitForResponse((response) =>
- response
- .url()
- .includes(
- `${apiUrl}/platform/projects/${ref}/analytics/endpoints/logs.all?project=${ref}`
- )
- )
-
- // Wait a bit and check for errors with a longer timeout
- const error = page.getByText('Error fetching logs')
- await expect(error).not.toBeVisible({ timeout: 10000 })
-
- const emptyState = page.getByText('No results found')
- if (await emptyState.isVisible()) {
- // Empty state, no need to check further
- } else {
- // Check if the logs table has any rows
- const gridcells = page.getByRole('gridcell')
- await expect(gridcells.first()).toBeVisible({ timeout: 20000 })
- }
- })
-
- test('can select and view log details', async ({ page, ref, apiUrl }) => {
- // Navigate to page first
- await page.goto(`./project/${ref}/logs/${logPage.route}`)
-
- await page.waitForResponse((response) =>
- response
- .url()
- .includes(
- `${apiUrl}/platform/projects/${ref}/analytics/endpoints/logs.all?project=${ref}`
- )
- )
-
- const emptyState = page.getByText('No results found')
- if (await emptyState.isVisible()) {
- // Empty state, no need to check further
- } else {
- // Check if the logs table has any rows
- const gridcells = page.getByRole('gridcell')
-
- // Click first row and verify details
- await gridcells.first().click()
- const tabPanel = page.getByTestId('log-selection')
- await page.waitForResponse((response) =>
- response
- .url()
- .includes(
- `${apiUrl}/platform/projects/${ref}/analytics/endpoints/logs.all?project=${ref}`
- )
- )
- await expect(tabPanel).toBeVisible()
-
- const selectionPanelTimestamp = tabPanel.getByTestId('log-selection-timestamp')
- await expect(selectionPanelTimestamp).toBeVisible()
-
- const rawTimestamp = await selectionPanelTimestamp.textContent()
- const timestamp = rawTimestamp?.replace('timestamp', '')
- const rowText = await gridcells.first().textContent()
- expect(rowText).toContain(timestamp)
-
- // Click second row and verify different content
- await gridcells.nth(1).click()
- const tabPanelText2 = await tabPanel.textContent()
- expect(tabPanelText2).not.toBe(rowText)
- }
- })
- })
- }
-})
diff --git a/tests/studio-tests/tests/common-functionality/table-editor.spec.ts b/tests/studio-tests/tests/common-functionality/table-editor.spec.ts
deleted file mode 100644
index d05fe4462f..0000000000
--- a/tests/studio-tests/tests/common-functionality/table-editor.spec.ts
+++ /dev/null
@@ -1,168 +0,0 @@
-import { Page, expect } from '@playwright/test'
-import { kebabCase } from 'lodash'
-import { test } from '../../base'
-
-const dismissToast = async (page: Page) => {
- await page
- .locator('li.toast')
- .getByRole('button', { name: 'Opt out' })
- .waitFor({ state: 'visible' })
- await page.locator('li.toast').getByRole('button', { name: 'Opt out' }).click()
-}
-
-test.describe('Table Editor', () => {
- test.beforeEach(async ({ page, env, ref, apiUrl }) => {
- const tableResponsePromise = page.waitForResponse(
- `${apiUrl}/platform/pg-meta/${ref}/query?key=entity-types-public-0`,
- { timeout: 0 }
- )
- await page.goto(`./project/${ref}/editor`)
- if (env !== 'local') await dismissToast(page)
- await tableResponsePromise
- })
-
- test('should create a new table, view its definition, add new rows, sort and filter', async ({
- page,
- ref,
- apiUrl,
- }, testInfo) => {
- const tableName = `${kebabCase(testInfo.title).slice(0, 24)}-${testInfo.retry}-${Math.floor(Math.random() * 10000)}`
-
- // The page has been loaded with the table data, we can now interact with the page
- await page.getByRole('button', { name: 'New table', exact: true }).click()
-
- await page.getByTestId('table-name-input').waitFor({ state: 'visible' })
- await page.getByTestId('table-name-input').click()
- await page.getByTestId('table-name-input').fill(tableName)
-
- // make the built-in created_at column nullable
- await page.getByTestId('created_at-extra-options').click()
- await page.getByText('Is Nullable').click()
- // the force option is needed because the button is obscured by the popover but we just want to close the popover.
- await page.getByTestId('created_at-extra-options').click({ force: true })
-
- // add a new column and add default value
- await page.getByRole('button', { name: 'Add column' }).click()
- await page.getByRole('textbox', { name: 'column_name' }).click()
- await page.getByRole('textbox', { name: 'column_name' }).fill('defaultValueColumn')
- await page.locator('button').filter({ hasText: 'Choose a column type...' }).click()
- await page.getByText('Signed two-byte integer').click()
- await page.getByTestId('defaultValueColumn-default-value').click()
- await page.getByTestId('defaultValueColumn-default-value').fill('2')
-
- await page.getByRole('button', { name: 'Save' }).waitFor({ state: 'visible' })
- await page.getByRole('button', { name: 'Save' }).click()
-
- // hide React Query DevTools if present
- await page.evaluate(() => {
- const devtools = document.querySelector('.ReactQueryDevtools')
- if (devtools) {
- devtools.remove()
- }
- })
-
- // view its definition
- await page.getByText('definition').click()
- await expect(page.locator('div.view-lines')).toContainText(
- `CREATE TABLE public.${tableName} ( id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL, created_at timestamp with time zone NULL DEFAULT now(), \"defaultValueColumn\" smallint NULL DEFAULT '2'::smallint, CONSTRAINT ${tableName}_pkey PRIMARY KEY (id)) TABLESPACE pg_default;`
- )
-
- // add a new row
- await page.getByRole('button', { name: tableName }).click()
- await page.getByTestId('table-editor-insert-new-row').click()
- await page.getByText('Insert a new row into').click()
- await page.getByTestId('defaultValueColumn-input').click()
- await page.getByTestId('defaultValueColumn-input').fill('100')
- await page.getByTestId('action-bar-save-row').click()
-
- // add a second row
- await page.getByRole('button', { name: tableName }).click()
- await page.getByTestId('table-editor-insert-new-row').click()
- await page.getByText('Insert a new row into').click()
- // the default value should be '100' for defaultValueColumn
- await page.getByTestId('action-bar-save-row').click()
-
- // Wait for both rows to be visible in the grid
- await page.waitForResponse((response) =>
- response.url().includes(`${apiUrl}/platform/pg-meta/${ref}/query`)
- )
- await expect(page.getByRole('grid')).toContainText('2')
- await expect(page.getByRole('grid')).toContainText('100')
-
- // Make sure we can see both rows in the grid before sorting
- const rows = page.getByRole('row')
- await expect(rows).toHaveCount(3) // header row + 2 data rows
-
- // sort by the a column
- await page.getByRole('button', { name: 'Sort' }).click()
- await page.getByTestId('table-editor-pick-column-to-sort-button').click()
- await page.getByLabel('Pick a column to sort by').getByText('defaultValueColumn').click()
- await page.getByRole('button', { name: 'Apply sorting' }).click()
-
- // Close the sorting dialog
- await page.keyboard.down('Escape')
-
- // expect the row to be sorted by defaultValueColumn. They're inserted in the order 100, 2
- await expect(rows.nth(1)).toContainText('2')
- await expect(rows.nth(2)).toContainText('100')
- // remove the sorting
- await page.getByRole('button', { name: 'Sorted by 1 rule' }).click()
- await page.getByRole('dialog').getByRole('button').nth(1).click()
-
- // filter by a column
- await page.getByRole('button', { name: 'Filter' }).click()
- await page.getByRole('button', { name: 'Add filter' }).click()
- await page.getByRole('button', { name: 'id' }).click()
- await page.getByLabel('id').getByText('defaultValueColumn').click()
- await page.getByPlaceholder('Enter a value').click()
- await page.getByPlaceholder('Enter a value').fill('2')
- await page.getByRole('button', { name: 'Apply filter' }).click()
-
- // Close the filter dialog
- await page.keyboard.down('Escape')
-
- await expect(page.getByRole('grid')).toContainText('2')
- await expect(page.getByRole('grid')).not.toContainText('100')
-
- // Delete the table as clean up
- await page.getByLabel(`View ${tableName}`).click()
- await page.getByLabel(`View ${tableName}`).getByRole('button').nth(1).click()
- await page.getByText('Delete table').click()
- await page.getByRole('button', { name: 'Delete' }).click()
- await page.waitForResponse((response) =>
- response.url().includes(`${apiUrl}/platform/pg-meta/${ref}/tables`)
- )
- })
-
- test('should check the auth schema', async ({ page }) => {
- await page.getByTestId('schema-selector').click()
- await page.getByRole('option', { name: 'auth' }).click()
-
- // extract the tables names from the sidebar
- const tables = await page
- .getByTestId('tables-list')
- .innerText()
- .then((text) => text.split('\n'))
-
- // expect the tables list to contain the following tables (additional tables may be present)
- expect(tables).toEqual(
- expect.arrayContaining([
- 'audit_log_entries',
- 'flow_state',
- 'identities',
- 'instances',
- 'mfa_amr_claims',
- 'mfa_challenges',
- 'mfa_factors',
- 'refresh_tokens',
- 'saml_providers',
- 'saml_relay_states',
- 'schema_migrations',
- 'sessions',
- 'sso_domains',
- 'sso_providers',
- 'users',
- ])
- )
- })
-})
diff --git a/tests/studio-tests/tests/production-functionality/example.spec.ts b/tests/studio-tests/tests/production-functionality/example.spec.ts
deleted file mode 100644
index a550cd4481..0000000000
--- a/tests/studio-tests/tests/production-functionality/example.spec.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { expect } from '@playwright/test'
-import { test } from '../../base'
-
-// [Joshen] This file is redundant, so once we start putting in production specific spec tests, can remove this
-
-test.describe('Example', async () => {
- test('Can navigate to project home page', async ({ page, ref }) => {
- await page.goto(`./project/${ref}`)
- await expect(page.getByRole('heading', { name: 'Playwright Test' })).toBeVisible()
- })
-})