Доброго дня!
j-test-id
компонентов экрана, находящихся внутри композитного компонента, содержит префикс, которого нет в id
, объявленных в проекте. (возможно дело не в композитном компоненте, но в обоих наших компонентах наблюдается такое)
<div class="v-label v-disabled v-widget v-has-width" j-test-id="IgEAtAsLlI_nameOfCreatorLabel" style="width: 100%;">Начальник производственного отдела</div>
Обстановка
Jmix version: 1.5.5
Jmix Studio plugin version: 2.2.1-241
IntelliJ version: IntelliJ IDEA 2024.1 (Community Edition)
selenide:6.12.4
jmix-masquerade:1.2.0
Проект и тесты в стадии миграции с CUBA .
Дескриптор композитного компонента
<composite xmlns="http://jmix.io/schema/ui/composite">
<hbox id="rootBox" width="100%" expand="labelBox" align="MIDDLE_LEFT">
<hbox id="labelBox" expand="nameOfCreatorLabel" enable="false" spacing="true" align="MIDDLE_LEFT">
<label id="captionLabel" align="MIDDLE_LEFT"
value="msg://<PROJECT>.web/captionForIdenticalBlocks.owner"/>
<label id="nameOfCreatorLabel" align="MIDDLE_LEFT"/>
<label id="dateOfCreationLabel" align="MIDDLE_LEFT"/>
</hbox>
<hbox id="buttonsBox" align="MIDDLE_RIGHT">
<popupView id="readersListPopupView"/>
<button id="readersListButton"
icon="font-icon:EYE"
stylename="borderless"
align="MIDDLE_RIGHT"/>
<popupButton id="detailedInfoButton"
icon="INFO_CIRCLE"
stylename="borderless"
closePopupOnOutsideClick="true">
<popup>
<!-- init in Controller-->
</popup>
</popupButton>
<popupButton id="copyHyperlinkButton"
icon="FILES_O"
stylename="borderless"
autoClose="false"
closePopupOnOutsideClick="true">
<popup>
<!-- init in Controller-->
</popup>
</popupButton>
<button id="openProjectBtn" visible="false" caption="msg://<PROJECT>.web/components.openProjectBtn.caption" description="msg://<PROJECT>.web/components.openProjectBtn.description" icon="LEVEL_UP" stylename="borderless"/>
</hbox>
</hbox>
</composite>
Контроллер композитного компонента (часть)
@CompositeDescriptor("headerinfo-component.xml")
public class HeaderInfoBox
extends CompositeComponent<HBoxLayout>
implements CompositeWithCaption, CompositeWithHtmlDescription, CompositeWithContextHelp {
public static final String NAME = "headerInfoBox";
private Label<String> captionLabel;
private Label<String> nameOfCreatorLabel;
private Label<String> dateOfCreationLabel;
private PopupView readersListPopupView;
private Button readersListButton;
private PopupButton detailedInfoButton;
private Label<String> createdByLabel;
private Label<String> dateCreateLabel;
private Label<String> changedByLabel;
private Label<String> dateChangedLabel;
private PopupButton copyHyperlinkButton;
private Label<String> copyLinkLabel;
private Button copyLinkButton;
private TextField<String> copyLinkTextField;
private Button openProjectBtn;
<inject some attributes>
public HeaderInfoBox() {
addCreateListener(this::onCreate);
}
private void onCreate(CreateEvent createEvent) {
captionLabel = getInnerComponent("captionLabel");
nameOfCreatorLabel = getInnerComponent("nameOfCreatorLabel");
dateOfCreationLabel = getInnerComponent("dateOfCreationLabel");
readersListPopupView = getInnerComponent("readersListPopupView");
readersListButton = getInnerComponent("readersListButton");
detailedInfoButton = getInnerComponent("detailedInfoButton");
copyHyperlinkButton = getInnerComponent("copyHyperlinkButton");
openProjectBtn = getInnerComponent("openProjectBtn");
<some code>
}
<some code>
}
Загрузчик композитного компонента
public class HeaderInfoBoxLoader extends AbstractComponentLoader<HeaderInfoBox> {
@Override
public void createComponent() {
resultComponent = factory.create(HeaderInfoBox.NAME);
loadId(resultComponent, element);
}
@Override
public void loadComponent() {
resultComponent.setScreensInterface(ComponentsHelper.getScreenContext(resultComponent).getScreens());
}
}
Дескриптор экрана, где размещен композитный компонент (часть)
<layout expand="scrollBox" spacing="true">
<scrollBox id="scrollBox">
<hbox id="headHbox" expand="infoHbox"
spacing="true"
width="100%">
<hbox id="infoHbox" spacing="true" expand="headerInfo" align="MIDDLE_LEFT">
<app:headerInfoBox id="headerInfo"/>
</hbox>
Описатель экрана для тестирования
public class RCDocEditWindow extends Composite<RCDocEditWindow> {
@Wire
public Label nameOfCreatorLabel;
<some components>
Место в Классе теста, которое вызывает ошибку
RCDocEditWindow rcDocEditWindow = $j(RCDocEditWindow.class);
Assert.assertEquals("Начальник производственного отдела",rcDocEditWindow.nameOfCreatorLabel.getValue());
Стэктрейс
Caused by: NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"[j-test-id='nameOfCreatorLabel']"}
Element not found {By.jTestId: nameOfCreatorLabel}
Expected: exist
DOM композитного компонента
<div tabindex="-1" class="v-horizontallayout v-layout v-horizontal v-widget v-has-width" j-test-id="headerInfo" style="width: 100%; height: 30px;">
<div class="v-expand" style="padding-left: 180px;">
<div class="v-slot v-align-middle" style="width: 100%; margin-left: -180px;">
<div tabindex="-1" class="v-horizontallayout v-layout v-horizontal v-disabled v-widget v-has-width" j test-id="IgEAtAsLlI_labelBox" style="width: 100%; height: 19px;">
<div class="v-expand" style="padding-left: 91px;">
<div class="v-slot v-align-middle" style="margin-left: -91px;">
<div class="v-label v-disabled v-widget v-label-undef-w" j-test-id="IgEAtAsLlI_captionLabel">Владелец:
</div>
</div>
<div class="v-spacing">
</div>
<div class="v-slot v-align-middle" style="width: 100%;">
<div class="v-label v-disabled v-widget v-has-width" j-test-id="IgEAtAsLlI_nameOfCreatorLabel" style="width: 100%;">Начальник производственного отдела
</div>
</div>
<div class="v-spacing">
</div>
<div class="v-slot v-align-middle">
<div class="v-label v-disabled v-widget v-label-undef-w v-label-empty" j-test-id="IgEAtAsLlI_dateOfCreationLabel">
</div>
</div>
</div>
</div>
</div>
<div class="v-slot v-align-right v-align-middle"><div tabindex="-1" class="v-horizontallayout v-layout v-horizontal v-widget" j-test-id="IgEAtAsLlI_buttonsBox" style="height: 30px;">
<div class="v-slot">
<div class="v-popupview v-widget" j-test-id="IgEAtAsLlI_readersListPopupView">
</div>
</div>
<div class="v-slot v-slot-borderless v-align-right v-align-middle">
<div tabindex="0" role="button" class="v-button v-widget borderless v-button-borderless icon" j-test-id="IgEAtAsLlI_readersListButton">
<span class="v-button-wrap">
<span class="v-icon FontAwesome">
</span>
<span class="v-button-caption">0
</span>
</span>
</div>
</div>
<div class="v-slot v-slot-borderless v-slot-icon">
<div tabindex="0" role="button" class="v-button v-widget borderless v-button-borderless icon v-button-icon v-popupbutton" j-test-id="IgEAtAsLlI_detailedInfoButton">
<span class="v-button-wrap">
<span class="v-icon FontAwesome">
</span>
<span class="v-button-caption">
</span>
<div class="v-popup-indicator">
</div>
</span>
</div>
</div>
<div class="v-slot v-slot-borderless v-slot-icon">
<div tabindex="0" role="button" class="v-button v-widget borderless v-button-borderless icon v-button-icon v-popupbutton" j-test-id="IgEAtAsLlI_copyHyperlinkButton">
<span class="v-button-wrap">
<span class="v-icon FontAwesome">
</span>
<span class="v-button-caption">
</span>
<div class="v-popup-indicator">
</div>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
- Пробовал добавить к аннотации
@Wire
параметрpath
, указав ближайший контейнер с корректнымj-test-id
- компонент определяется неверно. - Пробовал объявить через аннотацию
@FindBy
, указав в параметруid
искомыйid
- не находит. - Не хочется объявлять компонент через xpath, т.к. его расположение в контейнерах экранов может меняться.
Подскажите пожалуйста, в чем может быть дело, что компоненту присваивается j-test-id
с префиксом и как его можно объявить в описателе экрана тестирования? Может можно как-то объявить с частичным id
(containts или regexp)?
Предположения
- Загрузчик чиркает, что наследование от
AbstractComponentLoader
как нежелательное, может оно на это влияет. Композитный компонент немного сложноват (и скорее тянет на Фрагмент экрана), по этому затрудняюсь от какого еще класса загрузчика его можно наследовать. - Еще можно заметить, что в DOM отсутствует корневой контейнер компонента
rootBox
. И вообще некоторые компоненты композитного компонента имеют простыеid
, которые могут быть не уникальными на всем экране, но так было и в CUBA.
PS. В CUBA вся логика экранов и тестов работала в CUBA и cuba-id
совпадал с id
компонентов композитного компонента.