[Bug]: getByLabel (and accessible name) ignore <label> for form-associated custom elements
メンテナーはふだん 1 日以内に返信
関連するプルリクエストがすでにマージされています。
- #43900 @microsoft-playwright-automation による — マージ済み
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 25/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 技術スタック
- html, playwright, typescript
調査の方向性
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.
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- TypeScript
- スター
- 99.1k
- フォーク
- 6.8k
- 平均マージ
- 17時間 6分
- マージ済み PR(30日)
- 306
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/playwright のほかの issue
-
難易度 3/5 1〜2日 初心者へのやさしさ 76/100
microsoft/playwright#43987 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
microsoft/playwright#43986 ·
メンテナーはふだん 1 日以内に返信
-
[Bug]: Embedded number/range inputs contribute their `value` attribute, not their current value, to accessible names対応中かも @lazerg が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 35/100
microsoft/playwright#43984 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 64/100
microsoft/playwright#43983 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
microsoft/playwright#43981 ·
メンテナーはふだん 1 日以内に返信
microsoft/playwright の issue をすべて見る
似ている issue
-
desktop v3 windows
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
esengine/DeepSeek-Reasonix#15016 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
readest/readest#7413 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
enhancement good first issue priority: medium size: XS
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
メンテナーはふだん 1 日以内に返信
-
content triage
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
eliasstravik/herdr-projects#788 ·