Aria-hidden 不会隐藏查询中的元素

Aria-hidden does not hide the element from queries

为什么 RTL 将隐藏元素显示为可见?

expect(screen.queryByText(/months in operation\?/i)).not.toBeVisible()

Received element is visible: <label aria-hidden="true" for="monthsDropdown" />

expect(screen.queryByText(/months in operation \?/i)).not.toBeInTheDocument()

expected document not to contain element, found <label aria-hidden="true" for="monthsDropdown">Months in operation?</label> instead

该标签的父div也有显示样式:none;可见性:隐藏;高度:0;

这是预期的行为吗?

TL;DR: aria-hidden 属性仅在 *ByRole 查询中隐藏元素。


假设我们有以下带有两个按钮的组件。

const TestComponent = () => {
  return (
    <>
      <div style={{ display: "none", visibility: "hidden", height: 0 }}>
        <button>Hidden Button</button>
      </div>
      <button aria-hidden="true">Aria Hidden Button</button>
    </>
  );
};

即使第一个元素由于父元素的样式而不可见,并且第二个元素被 aria-hidden 从可访问性树中排除,它们都可以通过 getByText 查询访问,因为它们都出现在 DOM.

// Both assertions will be pass
expect(screen.getByText("Hidden Button")).toBeInTheDocument();
expect(screen.getByText("Aria Hidden Button")).toBeInTheDocument();

但是,尝试使用 getByRole 查询访问它们是不可能的,因为该查询查找可访问性树 - 除非在查询中传递 hidden 选项。

// Will not find the elements
const [hiddenButton, visibleButton] = screen.getAllByRole("button")

// Will return both elements
const [hiddenButton, visibleButton] = screen.getAllByRole("button", { hidden: true })

在可见性方面,第二个按钮可见,而第一个按钮不可见。

// Both assertions will be pass
const [hiddenButton, visibleButton] = screen.getAllByRole("button", { hidden: true })
expect(hiddenButton).not.toBeVisible();
expect(visibleButton).toBeVisible();