Помогите найти локатор элемента страницы

Имеется строка меню вот такого вида


Предсталена она следующим кодом

<div class="flex-fill">
    <div class="Flex-flex-3it1f Flex-fill-1esn4" style="align-items: stretch; justify-content: flex-start; flex-wrap: nowrap;">
        <div class="flex-fill">
            <div class="jss1222 Tabs-tabs-2HVTF">
                <div class="jss1223 Tabs-items-container-3SpWT">
                    <div class="jss1225 jss1226" role="tablist" style="margin-bottom: 0px;">
                        <div class="jss1223 Tabs-items-container-3SpWT jss1224">
                            <button class="jss180 jss1231 jss1234 jss1236 Tabs-tab-1jFd9" tabindex="0" type="button" role="tab" aria-selected="true"><span class="jss1239 Tabs-wrapper-2OuI8"><span class="jss1240 Tabs-label-container-Jr7ol"><span class="jss1241">General Properties</span></span>
                                </span><span class="jss1335"></span></button>
                            <button class="jss180 jss1231 jss1234 Tabs-tab-1jFd9" tabindex="0" type="button" role="tab" aria-selected="false"><span class="jss1239 Tabs-wrapper-2OuI8"><span class="jss1240 Tabs-label-container-Jr7ol"><span class="jss1241">Responses</span></span>
                                </span><span class="jss1335"></span></button>
                            <button class="jss180 jss1231 jss1234 Tabs-tab-1jFd9" tabindex="0" type="button" role="tab" aria-selected="false"><span class="jss1239 Tabs-wrapper-2OuI8"><span class="jss1240 Tabs-label-container-Jr7ol"><span class="jss1241">Hint / Help</span></span>
                                </span><span class="jss1335"></span></button>
                            <button class="jss180 jss1231 jss1234 Tabs-tab-1jFd9" tabindex="0" type="button" role="tab" aria-selected="false"><span class="jss1239 Tabs-wrapper-2OuI8"><span class="jss1240 Tabs-label-container-Jr7ol"><span class="jss1241">Parent Questions</span></span>
                                </span><span class="jss1335"></span></button>
                        </div><span class="jss1243 jss1244 jss1230" style="left: 20px; width: 178px;"></span></div>
                </div>
            </div>
        </div>
        <div class="Flex-flex-3it1f Flex-fill-1esn4" style="align-items: center; justify-content: flex-start; flex-wrap: nowrap;">
            <div id="jw1zpi0t" class="ActionBar-action-bar-27m6H Flex-flex-3it1f" style="align-items: center; justify-content: flex-start; flex-wrap: nowrap;">
                <button class="jss180 jss181 jss154 jss165 jss166 jss168 jss169 jss177 jss174 Action-action-2S3-B Action-button-2ZynF Button-button-5cFsn" tabindex="-1" role="button" type="button"><span class="jss155"><div class="Flex-flex-3it1f" style="align-items: center; justify-content: flex-start; flex-wrap: nowrap;"><svg class="jss183 jss190" focusable="false" viewBox="0 0 24 24" aria-hidden="true" role="presentation"><path d="M8 5v14l11-7z"></path><path fill="none" d="M0 0h24v24H0z"></path></svg><span class="Button-label-wIm4D">Preview</span></div>
            </span>
            </button>
        </div>
    </div>
</div>
</div>

Каким образом можно найти локатор элемента меню, скажем “Responses”?
По словам разрабочика используется css modules + react

По идее

 //span[text()='Responses']

Поиск по тексту, как мне кажется не всегда хорошая мысль. И в данном случае, с учетом планов, текст будет вероятно изменен и приложение будет поддерживать локализацию на разные языки. Хотелось бы какой-нибудь универсальный локатор.

Какие вообще существуют способы локации элементов, когда имена классов представлеы подобным образом

class="jss180 jss1231 jss1234 Tabs-tab-1jFd9"

А ID или Name элементов отсутствуют. А если и присутствуют, то очень сильно похожи на автосгенеренные

id="jw1zpi0t"

На проекте все написано в подобном стиле и все элементы лоцировать по тексту мне кажется ужасная мысль.

Кроме как по тексту не получится. Можно добавить строку для родительского элемента для надёжности.
Вот так:
//div[contains(@class, 'Tabs-items-container')]//span[contains(@class, 'Tabs-label-container')]/span[text()='<текст кнопки>']

Если нет Id, возможно такой вариант подойдет. Но нет гарантии. Если еще один элемент добавится перед - нужно будет менять поиск опять
//div[@class=‘jss1223 Tabs-items-container-3SpWT jss1224’]//span[1]

Проект еще пилится и 100% будут появляется еще элементы. Склоняюсь к тому, что этот вариант не очень подходит, но местами будет использоваться.

ну тут только по тексту или по индексу можно опять же привязаться к рутовому элементу и все еще исктаь по тексту, в случае добавлеия локализации просто добавить оператор “or”

А вы не пробовали поговорить с девелоперами на тему добавления дополнительного атрибута к вэбэлементам.
Например, в вашем случае это кнопки. Можно сделать примерно так

<button automation-id='someButton'>Some  Button</button>

Это сэкономит вам кучу времени, а тесты сделает стабильными.

Цитата
//div[@class=‘jss1223 Tabs-items-container-3SpWT jss1224’]//span[1]

Не стоит использовать в xPath какие-то генерируемые строки, велика вероятность что такой xPah сработает один раз или вообще не сработает.

Писал выше:

Цитата
Можно добавить строку для родительского элемента для надёжности.
Вот так:
//div[contains(@class, 'Tabs-items-container')]//span[contains(@class, 'Tabs-label-container')]/span[text()='<текст кнопки>']

Подстроки ‘Tabs-items-container’ и ‘Tabs-label-container’ скорее всего в классе элементов будут единственной неизменной частью.

На счёт поиска по тексту элемента:
В этом нет ничего плохого. Но вы сможете реализовать метод, который по названию нажмёт нужную кнопку меню, например:

ckickMenuItem(String text){<тут реализация>}

Тесты планируются для каждой локализации? Если да, то можно параметризировать (надеюсь я правильно написал слово) его, сделать метод, который принимает текст, соединяет его с селектором, и находит элемент, возвращает его, и вы уже дальше работаете с ним.
Еще один из вариантов - взять задефенировать кнопку по ее номеру. Но это будет работать лишь в том случае, если место положение кнопок не будет меняться, или будет очень редко меняться.

Если есть изменяемая часть - можно взять ту часть, которая не меняется и использовать contains. На счёт использования имени- тоже не гарантия успеха. Бывает элементы с одинаковым текстом или совсем без текста.

Если у вас есть доступ к беседе с разработчиком, а может даже и к самим исходникам, что мешает проставить id элементам? Это займет порядка 1 минуты.

Да, именно его (Contains) я и использовал в сообщении выше.

Номера лучше не использовать:

  1. Могут вылезти невидимые элементы, с тем же xPath.
  2. Могут вылезти элементы на другом уровне, то же с таким же xPath.

Да, в данном случае самое оптимальное - написать универсальный метод.
(Я уже писал про него выше, но почему то это осталось незамеченным :smile: )

Спасибо за помощь.
Буду опираться на 2 решения:

  1. Более менее универсальный метод по совету S_e_rgej и MOSTOR
  2. Пинать разработчиков