React Select 无法在带有 TestCafe 的 Office UI Fabric 层内聚焦

React Select fails to focus inside Office UI Fabric Layer with TestCafe

TestCafe 中似乎存在一个长期存在的问题,即手动调用 .focus() 方法无法正常工作并导致后续问题:

https://github.com/DevExpress/testcafe/issues/2029

可能相关: https://github.com/DevExpress/testcafe/issues/3348

而且我相信这至少是 react-select 在通过 TestCafe 进行测试时无法正确运行的部分原因。

希望能够输入 react-select 的输入,然后 select 所需的选项。不幸的是, 无法工作。可能是由于该线程处于活动状态后的更新。

另一种选择是直接 select 选项,但是,在我们的项目中,由于有大量 select 可用项目,我们最终需要使用 react-virtualized。你可以找到我的 .

我尝试过的方法:

await t.hover(
        ReactSelector('Select').find('input') // also .findReact('Placeholder')
    )
    .click(
        ReactSelector('Select').find('input') // also .findReact('Placeholder')
    )
    .typeText(
        ReactSelector('Select').find('input'),
        'option'
    )

使用第一种方法,似乎找到了元素(TestCafe 没有 fail/timeout 声明元素未找到)但输入从未收到文本并且菜单项未被过滤。

await t.click(
        ReactSelector('Select').findReact('DropdownIndicator')
    )
    .typeText(
        ReactSelector('Select').find('input'),
        'option'
    )

使用这种方法,菜单打开,但输入未获得焦点,再次输入不会收到文本,菜单项也不会被过滤。

更新 1

事实证明,在尝试基本复制问题时,没有问题。所以问题一定更复杂。以后我会继续调试和更新。这是基本的复制测试:

import 'testcafe'
import { ReactSelector } from 'testcafe-react-selectors'

fixture('React Select').page('https://react-select.com/home')

test('Select should focus', async (t) => {
    const select = ReactSelector('BasicMulti').findReact('Select')

    await t.click(select)

    await t.debug()

    await t.expect(select.find('input').focused).ok()
})

更新 2

似乎与 Office UI Fabric 的 Layer component 存在冲突。我们的项目在 Panel 组件内部渲染了 Select,我最初认为它的一个子项 (FocusTrapZone) 是罪魁祸首,但是在单独渲染 Select 并在其周围单独包装组件之后,图层组件似乎是原因。

我最初的想法是它与事件冒泡有冲突,但我将 eventBubblingEnabled prop 切换为 true 并且行为没有变化。然后我认为这可能是 React Portals 的问题,但是在删除 Layer 并直接通过 Portal 进行渲染后,Select 按预期聚焦。

这一切都归结为 visibility

Office UI Fabric 的层组件在其根元素上设置了 CSS 样式 visibility: hidden,即使其子元素具有 visibility: visible。 参考:https://github.com/OfficeDev/office-ui-fabric-react/blob/master/packages/office-ui-fabric-react/src/components/Layer/Layer.styles.ts#L28

通过覆盖可见性:

const layerStyles = { root: { visibility: 'visible'}}

图层组件:styles={ layerStyles }

或在 Panel 组件上:layerProps={{ styles: layerStyles }}

Select 变得可聚焦

然而,这引入了另一个问题,即图层现在覆盖了整个应用程序。因此,我们必须更新 layerStyles 以忽略指针事件。

const layerStyles = {
    root: {
        visibility: 'visible',
        pointerEvents: 'none',
    },
    content: {
        pointerEvents: 'auto',
    },
}