简体   繁体   中英

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

It appears there is a long-standing issue within TestCafe, where the manual calling of the .focus() method fails to work and causes issues afterward:

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

Possibly related: https://github.com/DevExpress/testcafe/issues/3348

And I believe this is at least partly the reason that react-select fails to behave correctly when being tested via TestCafe.

The desire is to be able to type into react-select s input and then select the desired option. Unfortunately, a previously asked and answered SO thread fails to work. Possibly due to updates since when that thread was active.

Another option is to select the option directly, however, in our project we ended up needing to utilize react-virtualized due to the substantial number of select items available. You can find my related posting on SO here .

Approaches that I've tried:

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

With this first approach, the elements appear to be found (TestCafe doesn't fail/timeout stating element not found) but the input never receives a text and the menu items are not filtered.

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

With this approach, the menu opens, but the input is not focused, and input again does not receive text and menu items are not filtered.

Update 1

Turns out when trying a basic replication of the issue, there is no issue. So the problem must be more complicated. I will continue to debug and update in the future. Here is the basic replication test:

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()
})

Update 2

It appears there's a conflict with Office UI Fabric's Layer component . Our project has the Select rendered inside of the Panel component and I initially thought one of it's children (FocusTrapZone) was the culprit, but after rendering the Select on its own and individually wrapping components around it, the Layer component seems to be the cause.

My initial thinking was that it was a conflict with the event bubbling, but I switched the eventBubblingEnabled prop to true and no change in behavior. Then I thought it might be an issue with React Portals, but after removing Layer and rendering via a Portal directly, the Select focused as expected.

It all comes down to visibility !

Office UI Fabric's Layer component has the CSS style visibility: hidden set on it's root element, even though its children have visibility: visible . Ref: https://github.com/OfficeDev/office-ui-fabric-react/blob/master/packages/office-ui-fabric-react/src/components/Layer/Layer.styles.ts#L28

By overriding visibility:

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

On Layer component: styles={ layerStyles }

Or on Panel component: layerProps={{ styles: layerStyles }}

the Select becomes focusable .

However, this introduces another issue which is that the layer now covers the entire app. So, we have to update layerStyles to ignore pointer events.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM