Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

[Bug]: ariaSnapshot({ mode: 'ai' }) drops the name of dialogs, landmarks, tables and column headers when it comes from a visible descendant

Abierto
#43,809 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@microsoft-playwright-automation ya está trabajando en esto.

Desde el 30/10/2026.

  • #43810 de @microsoft-playwright-automation — abierto

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
25/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Estancado
Stack tecnológico
html, typescript
Área
testing-qa

Línea de trabajo

Start with removeRedundantNames in packages/injected/src/ariaSnapshotDistiller.ts and the existing AR-060 case in tests/page/page-aria-snapshot-ai.spec.ts; compare how names from visible descendants are handled. Use the reported repro cases to check the behavior across container roles. Done means container names remain available in AI-mode snapshots without changing AR-060's expected behavior.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

needs-triage
Version

1.64.1 (latest release; the same code is on main)

Steps to reproduce
  1. Clone https://github.com/Meet-Pansuriya/playwright-ai-snapshot-names-repro
  2. npm ci && npx playwright install chromium webkit
  3. npm run repro (Playwright Test, public API: ariaSnapshot({ mode: 'ai' }) vs default mode; 10 cases: 5 where the name is kept, 5 where it's dropped; Chromium + WebKit)
  4. Optional: npm run repro:cli shows the same through npx playwright cli snapshot

Minimal version of the failing case:

test('AI-mode snapshot keeps a container name that comes from a visible descendant', async ({ page }) => {
  await page.setContent(`<main>
    <dialog open aria-labelledby="t"><h2 id="t">Delete item?</h2><button>OK</button></dialog>
    <table><caption>Monthly totals</caption><tr><td>1</td></tr></table>
  </main>`);
  await expect(page.getByRole('dialog', { name: 'Delete item?' })).toHaveCount(1);       // passes
  expect(await page.locator('main').ariaSnapshot()).toContain('dialog "Delete item?"');   // passes
  const ai = await page.locator('main').ariaSnapshot({ mode: 'ai' });
  expect(ai).toContain('dialog "Delete item?"');   // fails: "- dialog [ref=e2]:"
  expect(ai).toContain('table "Monthly totals"');  // fails: "- table [ref=e5]:"
});
Expected behavior

The AI-mode snapshot prints the accessible name of containers whose name identifies them, as default mode does: dialog "Delete item?", navigation "Nav E", columnheader "Price", table "Monthly totals".

Actual behavior

The name is dropped whenever every element contributing it is printed as a descendant (identical on Chromium and WebKit):

Name source AI mode
aria-label; aria-labelledby → element outside; → hidden element kept
aria-labelledby → visible heading inside a region / navigation / dialog dropped
a button inside a columnheader (sortable header) dropped
<caption> inside a <table> dropped
<legend> in <fieldset>, <figcaption> in <figure> kept

AI-mode output for the minimal case above:

- main [ref=e1]:
  - dialog [ref=e2]:
    - heading "Delete item?" [level=2] [ref=e3]
    - button "OK" [ref=e4]
  - table [ref=e5]:
    - caption [ref=e6]: Monthly totals
    - rowgroup [ref=e7]:
      - row [ref=e8]:
        - cell "1" [ref=e9]

getByRole(role, { name }) finds every one of these elements, and ariaSnapshot() in default mode prints every name.

Additional context

This comes from removeRedundantNames in packages/injected/src/ariaSnapshotDistiller.ts (aiPlugins), which clears node.name when all of nameFromContentRefs are rendered below. That's intended for cases like AR-060 in tests/page/page-aria-snapshot-ai.spec.ts (a heading whose name repeats its link), and this issue doesn't ask to change that. But the rule ignores the role: for containers the name is the identifier people and agents use (getByRole('dialog', { name }), getByRole('columnheader', { name })), and the contributing heading or caption is printed as an ordinary child with nothing linking it to the container.

Why it matters: agents read playwright-cli snapshot / browser_snapshot to choose locators. With the name gone they concluded dialogs and landmarks had no accessible name, reported false accessibility issues, and fell back to locator('dialog'), which then hit strict-mode violations on a page with several dialogs.

Possible fix: skip the removal for roles whose name identifies a container (dialog, alertdialog, region, navigation, main, complementary, form, search, group, table, grid, treegrid, columnheader, rowheader, tabpanel…), or replace it with a short marker such as dialog "Delete item?" (from heading). Either keeps AR-060 as it is.

Related but different: #41985 (fixed by #41988). No existing report found for this case.

Environment
System:
    OS: macOS 27.2
    CPU: (8) arm64 Apple M1
    Memory: 16 GB
  Binaries:
    Node: 22.14.0
    npm: 10.9.2
  npmPackages:
    @playwright/test: 1.64.1 => 1.64.1
  Browsers (Playwright):
    chromium: 156.0.8078.4
    webkit: 27.2
Lenguaje dominante
TypeScript
Estrellas
98.5k
Forks
6.7k
Merge medio
17 h 5 min
PR fusionados (30 d)
326

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de microsoft/playwright

Todos los issues de microsoft/playwright

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.