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',
},
}
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',
},
}