React Select не может сфокусироваться на уровне Office UI Fabric Layer с TestCafe

Похоже, что в TestCafe существует давняя проблема, когда ручной вызов метода .focus() не работает и впоследствии вызывает проблемы:

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

Возможно, связано: https://github.com/DevExpress/testcafe/issues/3348

И я считаю, что это, по крайней мере, отчасти причина того, что react-select не работает корректно при тестировании через TestCafe.

Желание состоит в том, чтобы иметь возможность вводить react-selects input, а затем выбирать желаемый вариант. К сожалению, ранее заданный и отвеченный SO поток не работает. Возможно, из-за обновлений с тех пор, когда этот поток был активен.

Другой вариант - выбрать опцию напрямую, однако в нашем проекте нам пришлось использовать 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 не дает сбой / тайм-аут, указывающий, что элемент не найден), но ввод никогда не получает текст, а элементы меню не фильтруются.

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

Похоже, существует конфликт с Layer компонент. В нашем проекте Select отображается внутри компонента Panel, и я изначально думал, что один из его дочерних элементов (FocusTrapZone) был виновником, но после рендеринга Select самостоятельно и индивидуального обертывания компонентов вокруг него, компонент Layer, похоже, был причиной.

Сначала я подумал, что это конфликт с всплыванием событий, но я переключил опору eventBubblingEnabled на true и не изменил поведение. Затем я подумал, что это может быть проблема с порталами React, но после удаления слоя и рендеринга напрямую через портал Select сфокусировался, как и ожидалось.


person ArrayKnight    schedule 16.12.2019    source источник
comment
Трудно определить причину проблемы, не воспроизведя ее на нашей стороне. Не могли бы вы предоставить свой URL-адрес или минимальный проект, чтобы мы могли его изучить?   -  person Vladimir A.    schedule 19.12.2019
comment
@ V.Airich Я нашел дополнительную информацию о точке отказа. Достаточно ли этого, чтобы вы могли воспроизвести / проверить / протестировать?   -  person ArrayKnight    schedule 23.12.2019


Ответы (1)


Все сводится к visibility!

Компонент Layer 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'}}

В компоненте Layer: styles={ layerStyles }

Или в компоненте Panel: layerProps={{ styles: layerStyles }}

Выбор становится доступным.

Однако при этом возникает другая проблема: теперь слой покрывает все приложение. Итак, мы должны обновить layerStyles, чтобы игнорировать события указателя.

const layerStyles = {
    root: {
        visibility: 'visible',
        pointerEvents: 'none',
    },
    content: {
        pointerEvents: 'auto',
    },
}
person ArrayKnight    schedule 23.12.2019