Просто чтобы прояснить, что происходит под капотом: я использую фреймворк веб-автоматизации WebdriverIO, но этот вопрос не об этом. Вот почему я не включил его в теги
Команда $("selector")
возвращает веб-элемент. И я могу вызывать различные команды WDIO для этого элемента (например, setValue
или click
)
"Команда $ - это короткий способ вызова команды findElement для извлечения одного элемента на страница, похожая на команду $ из области видимости браузера. "
Моя цель состоит в том, чтобы мой класс MainPage
выглядел так:
import { searchInput, searchButton } from "./main.page.elements"
class MainPage {
searchFor(query: string) {
searchInput.setValue(query);
searchButton.click()
}
}
Как вы можете видеть Я пытаюсь создать модель, в которой я могу импортировать одноэлементные геттеры и работать с ними. Общая «лучшая практика» может выглядеть так:
import { MainPageElements } from "./main.page.elements"
class MainPage {
searchFor(query: string) {
MainPageElements.searchInput.setValue(query);
MainPageElements.searchButton.click()
}
}
Однако через некоторое время это приводит к большому количеству дублированного кода и / или необходимости импортировать классы WHOLE PageElements
друг в друга только ради использование одного единственного элемента
Вот пример:
import { LoginFormElements } from "./login.form"
import { ConfirmDialog } from "./confirm.dialog"
import { MainPage } from "./main.page.elements"
// etc
// etc
class LoginPage {
login(username: string, password: string) {
LoginFormElements.loginInput.setValue(username)
LoginFormElements.passwordInput.setValue(password)
LoginFormElements.loginButton.click()
ConfirmDialog.confirmButton.click()
MainPage.header.waitForDisplayed()
// etc
// etc
}
}
Я хочу добиться того, чтобы импортировать только те элементы, которые мне нужны, вместо импорта всего класса. И вызов метода получения элемента в этом классе заставляет меня писать длинные цепочки, как указано выше
Теперь давайте вернемся к желаемому конечному результату:
import { searchInput, searchButton } from "./main.page.elements"
class MainPage {
searchFor(query: string) {
searchInput.setValue(query);
searchButton.click()
}
}
Мой MainPageElements
класс (./main.page.elements.ts
)
export class MainPageElements {
get searchInput() {
return $(".input-locator")
}
get searchButton() {
return $(".search-button-locator")
}
}
Одна из важных вещей для понимания - я не могу использовать IIFE, потому что команда $
должна выполняться на странице после загрузки страницы
Я пытался сделать что-то вроде этого:
class MainPageElements {
get _searchInput() {
return $(".input-locator")
}
get _searchButton() {
return $(".search-button-locator")
}
}
export function searchInput = new MainPageElements()._searchInput()
Я могу успешно импортировать эту функцию, но мне нужно вызвать это с круглыми скобками, как searchInput().setValue()
Это странно для меня что я могу вызвать метод "get" класса, такой как MyClass.myMethod (без скобок), и он будет выполнять команду $ именно тогда, когда я ее вызываю. Когда я пытался сохранить результат этого метода в переменной, мне пришлось вызывать метод перед сохранением результата (дух), и это не работает для меня, так как это происходит, когда я запускаю код, и что конкретные элементы не существуют в этой точке время
Как экспортировать этот единственный метод, чтобы я мог сделать то же самое, но без MyClass.
? Чтобы прояснить ситуацию, MainPageClass не обязательно должен быть классом. Это может быть куча экспортируемых функций (наверное?). Но мне кажется, что использование class
является более правильным способом, чем экспорт 20 функций одна за другой ...
Также get _searchInput()
не может быть get
методами. Я сделал это get
только потому, что его можно вызвать без скобок, но этого пока недостаточно.