[Bug]: getByLabel (and accessible name) ignore <label> for form-associated custom elements
Maintainer thường phản hồi trong vòng 1 ngày
Một pull request liên quan đã được merge.
- #43900 của @microsoft-playwright-automation — đã merge
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 25/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- html, playwright, typescript
- Lĩnh vực
- accessibility, testing-qa
Hướng nghiên cứu
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.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- TypeScript
- Star
- 99.1k
- Fork
- 6.8k
- Merge trung bình
- 16 giờ 56 phút
- Pull request đã merge (30 ngày)
- 299
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của microsoft/playwright
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
microsoft/playwright#43998 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
microsoft/playwright#43990 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
microsoft/playwright#43999 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 69/100
microsoft/playwright#43996 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
microsoft/playwright#43995 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của microsoft/playwright
Issue tương tự
-
code-quality good-first-issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
OpenRailAssociation/netzgrafik-editor-frontend#1481 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug implicit-state
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
-
area:models enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug frontend ui
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Recording drops clicks on links, filters and checkboxes that share a form with a search fieldCó thể đã có người làm @columbia11 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Tencent/BrowserSkill#657 ·
Maintainer thường phản hồi trong vòng 1 ngày