Пример 13
Ещё достаточно популярные сущности – это разнообразные свитчеры. Рассмотрим пару различных свитчеров приведённых ниже:
Смотрим их HTML код:
<!-- Switcher 1: Classic Toggle Switch -->
<div class="mb-4">
<h5>Classic Toggle Switch</h5>
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
</div>
<!-- Switcher 2: Button Toggle -->
<div class="mb-4">
<h5>Button Toggle</h5>
<button id="toggleBtn" class="toggle-btn off">Off</button>
</div>
Поскольку свитчеры разные – первый представляет собой классический переключатель, а второй – кнопку, меняющую цвет и текст, описать их одним классом не получится.
Однако как и в предыдущем примере с каруселью, у нас есть абстрактный класс AbstractSwitcher
с которым легко можно описать переключатели любых типов.
Создадим для каждого переключателя свой класс и переопределим 4 основных абстрактных метода:
getState()
toggle()
switchOn()
switchOff()
Таким образом каждый будет использовать свою логику но иметь один интерфейс, через который фреймворк будет считывать действия и строить отчёт.
public class ClassicToggleSwitcher extends AbstractSwitcher {
public ClassicToggleSwitcher(String selenideLocator) {
super(selenideLocator);
}
@Override
public boolean getState() {
return getRoot().$("input").isSelected();
}
@Override
public void toggle() {
getRoot().click();
}
@Override
public void switchOn() {
if (!getState()) {
getRoot().click();
}
}
@Override
public void switchOff() {
if (getState()) {
getRoot().click();
}
}
}
public class ButtonToggle extends AbstractSwitcher {
public ButtonToggle(String selenideLocator) {
super(selenideLocator);
}
@Override
public boolean getState() {
return getRoot().has(Condition.cssClass("off"));
}
@Override
public void toggle() {
getRoot().click();
}
@Override
public void switchOn() {
if (getState()) {
getRoot().click();
}
}
@Override
public void switchOff() {
if (!getState()) {
getRoot().click();
}
}
}
@PageObject
@Getter
@Accessors(fluent = true)
public class SwitcherPage {
@Name("CTU")
protected ClassicToggleSwitcher classicToggleSwitcher = new ClassicToggleSwitcher(".switch");
@Name("SBT")
protected ButtonToggle buttonToggle = new ButtonToggle("#toggleBtn");
}
@Test
@DisplayName("Switcher (Toggle) example")
public void switcherExample() {
UiSteps.openBrowser(switcherPageUrl);
carouselPage.classicToggleSwitcher().switchOn();
carouselPage.classicToggleSwitcher().switchOff();
carouselPage.classicToggleSwitcher().toggle();
carouselPage.classicToggleSwitcher().switchOff();
carouselPage.buttonToggle().switchOn();
carouselPage.buttonToggle().switchOff();
carouselPage.buttonToggle().toggle();
carouselPage.buttonToggle().switchOff();
}
Запускаем тест и смотрим отчёт – все используемые шаги занесены в отчёт с соответствующими именами и типами.
В отчёте отображается тип элемента как просто "switcher" (так как мы не переопределили имя через метод setUiElementType
).
Это можно изменить при желании, добавив в констркуктор setUiElementType('custom type')
Тоесть вот так:
public ClassicToggleSwitcher(String selenideLocator) {
super(selenideLocator);
setUiElementType("custom switcher type")
}
Напоследок, давайте взглянем, что покажет отчёт, если допустить ошибку. Например, присвоим элементу неверный локатор:
@Name("SBT")
protected ButtonToggle buttonToggle = new ButtonToggle("#ttoggleBtn");
Запустим тест, и в отчёте увидим ожидаемую ошибку в месте вызова шага элемента.