diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8824d3f5..5eea682b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,3 +127,58 @@ jobs: name: playwright-results path: test/e2e/.results retention-days: 7 + + a11y: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v7 + + - name: Install pnpm + uses: pnpm/action-setup@v6 + + - name: Set node + uses: actions/setup-node@v7 + with: + node-version: lts/* + + - name: Setup + run: npm i -g @antfu/ni + + - name: Install + run: nci + + # The orchestrator runs `pnpm build` + `pnpm web:build` itself; no + # separate build step needed here. + + - name: Get Playwright version + id: pw-version + run: | + version=$(node -p "require('@playwright/test/package.json').version") + echo "version=$version" >> "$GITHUB_OUTPUT" + + - name: Cache Playwright browsers + uses: actions/cache@v6 + id: pw-cache + with: + path: ~/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ steps.pw-version.outputs.version }} + + - name: Install Playwright browser + if: steps.pw-cache.outputs.cache-hit != 'true' + run: pnpm exec playwright install --with-deps chromium + + - name: Install Playwright system deps + if: steps.pw-cache.outputs.cache-hit == 'true' + run: pnpm exec playwright install-deps chromium + + - name: A11y + run: nr test:a11y + + - name: Upload Playwright artifacts + if: failure() + uses: actions/upload-artifact@v7 + with: + name: playwright-results-a11y + path: test/e2e/.results + retention-days: 7 diff --git a/AGENTS.md b/AGENTS.md index 10752523..2a12129e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,7 +14,7 @@ RPC functions live in `packages/node-modules-inspector/src/node/rpc/.ts` - `pnpm dev` — dev server - `pnpm build` — full build -- `pnpm test` / `pnpm test:e2e` — vitest / playwright +- `pnpm test` / `pnpm test:e2e` / `pnpm test:a11y` — vitest / playwright e2e / playwright accessibility (axe-core) - `pnpm lint` / `pnpm typecheck` ## Conventions diff --git a/package.json b/package.json index 590e1e70..710113a3 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "prepare": "npx simple-git-hooks && pnpm -C packages/node-modules-inspector run dev:prepare && skills-npm", "lint": "pnpm -C packages/node-modules-inspector run dev:prepare && eslint .", "test": "vitest", - "test:e2e": "playwright test", + "test:e2e": "playwright test --project=dev --project=build --project=webcontainer --project=instant --project=build-subbase", + "test:a11y": "playwright test --project=a11y", "test:e2e:install": "playwright install chromium", "release": "bumpp -r", "typecheck": "vue-tsc --noEmit" diff --git a/packages/node-modules-inspector/src/app/components/panel/Overview.vue b/packages/node-modules-inspector/src/app/components/panel/Overview.vue index 969d54a2..e77a4111 100644 --- a/packages/node-modules-inspector/src/app/components/panel/Overview.vue +++ b/packages/node-modules-inspector/src/app/components/panel/Overview.vue @@ -71,7 +71,7 @@ const timepassed = computed(() => rawPayload.value?.timestamp ? Date.now() - raw flex="~ gap-2 items-center" >
- npm registry + npm registry { it('excludes a package and its exclusively-reachable dependencies', async () => { const { fetch, requests } = createMockRegistry({ - nuxt: { versions: { '3.0.0': { dependencies: { '@nuxt/kit': '^3.0.0', 'h3': '^1.0.0' } } } }, - '@nuxt/kit': { versions: { '3.0.0': { dependencies: { 'unctx': '^2.0.0' } } } }, - unctx: { versions: { '2.0.0': {} } }, - h3: { versions: { '1.0.0': {} } }, + 'nuxt': { versions: { '3.0.0': { dependencies: { '@nuxt/kit': '^3.0.0', 'h3': '^1.0.0' } } } }, + '@nuxt/kit': { versions: { '3.0.0': { dependencies: { unctx: '^2.0.0' } } } }, + 'unctx': { versions: { '2.0.0': {} } }, + 'h3': { versions: { '1.0.0': {} } }, }) const result = await resolveRegistryDependencies({ @@ -341,9 +341,9 @@ describe('resolveRegistryDependencies', () => { it('keeps a shared dep still reachable from a non-excluded path', async () => { const { fetch } = createMockRegistry({ - nuxt: { versions: { '3.0.0': { dependencies: { '@nuxt/kit': '^3.0.0', 'vite': '^5.0.0' } } } }, + 'nuxt': { versions: { '3.0.0': { dependencies: { '@nuxt/kit': '^3.0.0', 'vite': '^5.0.0' } } } }, '@nuxt/kit': { versions: { '3.0.0': { dependencies: { vite: '^5.0.0' } } } }, - vite: { versions: { '5.0.0': {} } }, + 'vite': { versions: { '5.0.0': {} } }, }) const result = await resolveRegistryDependencies({ diff --git a/test/e2e/instant.spec.ts b/test/e2e/instant.spec.ts index ef6ba862..d5f9d2b0 100644 --- a/test/e2e/instant.spec.ts +++ b/test/e2e/instant.spec.ts @@ -87,7 +87,7 @@ async function mockRegistry(page: Page): Promise { test.describe('hosted instant mode', () => { test('landing defaults to Instant mode with a Sandbox toggle', async ({ page }) => { await page.goto('/') - await expect(page.getByRole('button', { name: 'Instant', exact: true })).toBeVisible({ timeout: 30_000 }) + await expect(page.getByRole('button', { name: 'Registry Query', exact: true })).toBeVisible({ timeout: 30_000 }) await expect(page.getByRole('button', { name: 'Sandbox Install' })).toBeVisible() await expect(page.getByPlaceholder('Enter package names')).toBeVisible()