[Bug]: getByLabel (and accessible name) ignore <label> for form-associated custom elements
Los mantenedores suelen responder en 1 día
@microsoft-playwright-automation ya está trabajando en esto.
Desde el 4/11/2026.
- #43900 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, playwright, typescript
- Área
- accessibility, testing-qa
Línea de trabajo
Start in packages/injected/src/selectorUtils.ts and read getElementLabels, then trace how those labels feed getByLabel and accessible name computation. A linked pull request (#43900) is already open; completion would require both locators in the reproduction to resolve to the custom element and the related tests to pass.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Version
1.64.1
Steps to reproduce
import { test, expect } from '@playwright/test';
test('label of a form-associated custom element', async ({ page }) => {
await page.setContent(`
<label for="city">City</label><my-field id="city">Pick one</my-field>
<label>Street <my-field>Pick one</my-field></label>`);
await page.addScriptTag({ content: `
customElements.define('my-field', class extends HTMLElement {
static formAssociated = true;
constructor() { super(); this.attachInternals(); }
connectedCallback() { this.tabIndex = 0; }
});` });
// The browser associates both labels with the custom elements:
expect(await page.evaluate(() => [...document.querySelectorAll('label')].map((l) => l.control?.localName)))
.toEqual(['my-field', 'my-field']);
await expect(page.getByLabel('City')).toHaveCount(1); // ❌ 0
await expect(page.getByLabel('Street')).toHaveCount(1); // ❌ 0
});
Expected behavior
getByLabel('City') and getByLabel('Street') each resolve to the <my-field> element.
Form-associated custom elements are labelable elements. The browser associates the <label> with them, both for for= and for nesting: label.control returns the element, and Chrome's accessibility tree names it from the label (with role = 'combobox' set through ElementInternals, Chrome exposes combobox "City").
Actual behavior
Both locators resolve to 0 elements.
getElementLabels (packages/injected/src/selectorUtils.ts) reads element.labels only for a fixed list of native elements:
const isNonHiddenInput = element.nodeName === 'INPUT' && element.type !== 'hidden';
if (['BUTTON', 'METER', 'OUTPUT', 'PROGRESS', 'SELECT', 'TEXTAREA'].includes(element.nodeName) || isNonHiddenInput) {
const labels = element.labels;
...
A form-associated custom element has no public .labels (only ElementInternals.labels, which is private to the element), so the element side can't be read. The label side can: HTMLLabelElement.control returns the custom element for both for= and nesting, so no new browser API is needed.
Additional context
- Related, but different: #34264 (roles and states set through
ElementInternals). That one needs access to the element's internals. This one doesn't: the association is readable today throughlabel.control. - Possible fix: when the element is a form-associated custom element (
customElements.get(el.localName)?.formAssociated), collect the<label>elements in its tree whosecontrol === el, and use their text, excluding the text of the control nested inside a label (as is already done for native controls). The same labels should feed the accessible name computation (step 2D) used bygetByRole({ name }). - It matters more and more: design systems build form controls as form-associated custom elements precisely so that
<label for>works as with native controls.
Environment
Playwright 1.64.1, Chrome. The lookup happens in Playwright's injected script, so it shouldn't depend on the browser.
- Lenguaje dominante
- TypeScript
- Estrellas
- 99.1k
- Forks
- 6.8k
- Merge medio
- 16 h 7 min
- PR fusionados (30 d)
- 325
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/playwright
-
[Regression]: APIRequestContext JSON-encodes string data for "application/json;charset=UTF-8" since 1.65 (not in release notes)Posiblemente ocupada @microsoft-playwright-automation la tomó hoy. Abiertoneeds-triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
microsoft/playwright#43937 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
needs-triage
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
microsoft/playwright#43926 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
-
[Feature]: Expose Advanced WebAuthn Virtual Authenticator Options in Cross-Browser Credentials APIAbierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 45/100
microsoft/playwright#43921 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
[Bug]: Firefox: `page.emulateMedia({ contrast })` updates `matchMedia()` but never restyles the pageAbiertoneeds-triage
Dificultad 4/5 3-5 días Aptitud para principiantes 44/100
microsoft/playwright#43916 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
[Bug]: Videos are not generated when reusing a single page between testsPosiblemente ocupada @microsoft-playwright-automation la tomó hoy. Abiertoneeds-triage
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
microsoft/playwright#43915 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
Todos los issues de microsoft/playwright
Issues similares
-
Navbar avatar and name stay stale after saving profile changesPosiblemente ocupada @alexechoi la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
marmelab/atomic-crm#416 ·
Los mantenedores suelen responder en 1 día
-
feature-request
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
bluesky-social/social-app#12343 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
lucide-icons/lucide#5165 ·
Los mantenedores suelen responder en 1 día
-
[Feature] Preferences - Keep the theme selection popover open after selection for quick previewAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
marktext/marktext#6033 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
area:desktop bug has repro platform:macos
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
anthropics/claude-code#107903 ·