mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 01:15:03 +03:00
## What kind of change does this PR introduce? UI copy + agent guidance. ## What is the current behavior? - The Table Editor labels the Data API setting as "Data API Access" (title case). - Agents have no scoped pointer to our copywriting rules ## What is the new behavior? - Label uses sentence case: "Data API access" (e2e and test docs updated). - Agents are pointed at `apps/design-system/content/docs/copywriting.mdx` via `studio-copy.instructions.md` and `studio-ui-patterns` skill. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Standardized the **“Data API access”** label casing across the Studio UI. * Updated end-to-end tests to assert the corrected label text. * **Documentation** * Updated Studio E2E test review instructions and examples to use **“Data API access”**. * Added/expanded Studio UI copywriting guidance, including where to source copy and how to apply consistent casing. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.2 KiB
Markdown
87 lines
2.2 KiB
Markdown
---
|
|
applyTo: 'e2e/studio/**,apps/studio/**'
|
|
---
|
|
|
|
# Studio E2E Test Review Rules
|
|
|
|
All comments are **advisory**.
|
|
|
|
## Selector Priority (best to worst)
|
|
|
|
1. **`getByRole` with accessible name** — most robust, tests accessibility
|
|
|
|
```typescript
|
|
page.getByRole('button', { name: 'Save' })
|
|
```
|
|
|
|
2. **`getByTestId`** — stable, explicit test hooks
|
|
|
|
```typescript
|
|
page.getByTestId('table-editor-side-panel')
|
|
```
|
|
|
|
3. **`getByText` with exact match** — good for unique text
|
|
|
|
```typescript
|
|
page.getByText('Data API access', { exact: true })
|
|
```
|
|
|
|
4. **`locator` with CSS** — use sparingly, more fragile
|
|
```typescript
|
|
page.locator('[data-state="open"]')
|
|
```
|
|
|
|
## Patterns to Flag
|
|
|
|
- **XPath selectors** — fragile to DOM changes
|
|
|
|
```typescript
|
|
// BAD
|
|
locator('xpath=ancestor::div[contains(@class, "space-y")]')
|
|
```
|
|
|
|
- **Parent traversal with `locator('..')`** — breaks when structure changes
|
|
|
|
```typescript
|
|
// BAD
|
|
element.locator('..').getByRole('button')
|
|
```
|
|
|
|
- **`waitForTimeout`** — never use; wait for something specific instead
|
|
|
|
```typescript
|
|
// BAD
|
|
await page.waitForTimeout(1000)
|
|
|
|
// GOOD — wait for UI element
|
|
await expect(page.getByText('Success')).toBeVisible()
|
|
|
|
// GOOD — wait for API response
|
|
const apiPromise = waitForApiResponse(page, 'pg-meta', ref, 'query?key=table-create')
|
|
await saveButton.click()
|
|
await apiPromise
|
|
```
|
|
|
|
- **`force: true` on clicks** — make elements visible first instead
|
|
|
|
```typescript
|
|
// BAD
|
|
await menuButton.click({ force: true })
|
|
|
|
// GOOD — hover to reveal, then click
|
|
await tableRow.hover()
|
|
await expect(menuButton).toBeVisible()
|
|
await menuButton.click()
|
|
```
|
|
|
|
- **Broad `filter({ hasText })` on generic elements** — may match multiple elements; scope to specific containers instead
|
|
|
|
## Good Practices to Encourage
|
|
|
|
- Scope selectors to containers: `page.getByTestId('side-panel').getByRole('switch')`
|
|
- Add `aria-label` to icon-only buttons in source code for better test selectors
|
|
- Use `test.describe.configure({ mode: 'serial' })` for tests sharing database state
|
|
- Add messages to expects: `await expect(locator, 'why').toBeVisible({ timeout: 30000 })`
|
|
|
|
Canonical standard: `.claude/skills/studio-e2e-tests/SKILL.md`
|