mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 19:05:06 +03:00
The page scan stops at the article wrapper, so nothing checked the top nav, sidebar nav, table-of-contents sidebar, breadcrumbs, or footer. A violation in any of those lands on every docs page. Adds a global-elements Playwright project that scans the document with the article excluded, across six pages, one per layout, at two viewports, plus one pass with the mobile menu open. It runs from a docs_components paths filter in the existing workflow, so a content-only pull request never triggers it. Rules that pass today are enforced, so they catch a newly introduced violation without failing on existing debt. Everything else annotates. Supersedes #48909, which predated e2e/shared.
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import type { Page } from '@playwright/test'
|
|
|
|
import type { ViewportName } from '../../shared/viewports.ts'
|
|
import { GUIDE_ARTICLE_SELECTOR, TROUBLESHOOTING_ARTICLE_SELECTOR } from './docs-links.js'
|
|
|
|
interface GlobalElementConfig {
|
|
selector: string
|
|
label: string
|
|
// Defaults to both viewports.
|
|
viewports?: readonly ViewportName[]
|
|
}
|
|
|
|
const ELEMENT_TABLE = {
|
|
topNav: { selector: '[data-testid="sb-docs-top-nav"]', label: 'top navigation bar' },
|
|
sidebarNav: {
|
|
selector: '[data-testid="sb-docs-sidebar-nav"]',
|
|
label: 'sidebar navigation',
|
|
// In the DOM at mobile, but collapsed to `w-0 -left-full`.
|
|
viewports: ['desktop'],
|
|
},
|
|
tocSidebar: {
|
|
selector: '[data-testid="sb-docs-toc-sidebar"]',
|
|
label: 'content sidebar',
|
|
// `hidden md:flex`, so axe skips it below 768px.
|
|
viewports: ['desktop'],
|
|
},
|
|
breadcrumbs: { selector: '[data-testid="sb-docs-breadcrumbs"]', label: 'breadcrumbs' },
|
|
footer: { selector: '[data-testid="sb-docs-footer"]', label: 'site footer' },
|
|
menuTrigger: {
|
|
selector: '[data-testid="sb-docs-mobile-menu-trigger"]',
|
|
label: 'mobile menu trigger',
|
|
viewports: ['mobile'],
|
|
},
|
|
} as const
|
|
|
|
export type GlobalElement = keyof typeof ELEMENT_TABLE
|
|
|
|
export const GLOBAL_ELEMENTS: Record<GlobalElement, GlobalElementConfig> = ELEMENT_TABLE
|
|
|
|
export const MOBILE_MENU_SELECTOR = '[data-testid="sb-docs-mobile-menu"]'
|
|
|
|
export interface GlobalElementPage {
|
|
path: string
|
|
layout: string
|
|
elements: GlobalElement[]
|
|
}
|
|
|
|
// A second page on a covered layout would scan the same markup.
|
|
export const GLOBAL_ELEMENT_PAGES: GlobalElementPage[] = [
|
|
{
|
|
path: '/docs',
|
|
layout: 'home',
|
|
elements: ['topNav', 'menuTrigger', 'footer'],
|
|
},
|
|
{
|
|
path: '/docs/guides/getting-started',
|
|
layout: 'guides section landing',
|
|
elements: ['topNav', 'menuTrigger', 'sidebarNav', 'tocSidebar', 'footer'],
|
|
},
|
|
{
|
|
path: '/docs/guides/database/postgres/row-level-security',
|
|
layout: 'guide with table of contents',
|
|
elements: ['topNav', 'menuTrigger', 'sidebarNav', 'tocSidebar', 'breadcrumbs', 'footer'],
|
|
},
|
|
{
|
|
path: '/docs/guides/troubleshooting',
|
|
layout: 'troubleshooting index',
|
|
elements: ['topNav', 'menuTrigger', 'footer'],
|
|
},
|
|
{
|
|
path: '/docs/guides/troubleshooting/all-about-supabase-egress-a_Sg_e',
|
|
layout: 'troubleshooting entry',
|
|
elements: ['topNav', 'menuTrigger', 'breadcrumbs', 'footer'],
|
|
},
|
|
{
|
|
path: '/docs/reference/cli/introduction',
|
|
layout: 'reference',
|
|
elements: ['topNav', 'menuTrigger', 'sidebarNav', 'footer'],
|
|
},
|
|
]
|
|
|
|
const ARTICLE_SELECTORS = [GUIDE_ARTICLE_SELECTOR, TROUBLESHOOTING_ARTICLE_SELECTOR]
|
|
|
|
// Excluding a selector that matches nothing would silently widen the scan.
|
|
export async function articleSelectorsOnPage(page: Page): Promise<string[]> {
|
|
const present: string[] = []
|
|
for (const selector of ARTICLE_SELECTORS) {
|
|
if ((await page.locator(selector).count()) > 0) present.push(selector)
|
|
}
|
|
return present
|
|
}
|