Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class SmartFilteredByConditionCollection extends AbstractSmartCollection {
- ...
- @Override
- public List<WebElement> getWrappedEntity() {
- List<WebElement> innerCollection = new ArrayList<>();
- for (SmartElement smartElement:collection) {
- if (smartElement.is(condition)) {
- innerCollection.add(smartElement);
- }
- }
- return innerCollection;
- }
- /*
- ну да метод красивый
- почти)
- убери лишние комментарии
- не согласна я с термином innerCollection )
- корректнее - filteredCollection
- а главное - в список правильнее помещать именно вебэлемент
- а не завернутый в смартэлемент
- не innerCollection.add(smartElement);
- в innerCollection.add(smartElement.getWrappedEntity());
- нам ведь в getWrappedEntity() - надо кончательно от смарт-сущностей
- перейти к вебэлементам или их спискам
- за нашей красотой
- на самом деле кроются потери времени)
- что по факту мы делаем
- сначала - заворачиваем каждый вебэлемент списка коллекции
- (чтобы воспользоваться итератором для нашей коллекции)
- а потом - на каждом шаге - разворачиваем (получаем wrappedElement = element.getWrappedEntity())
- т е - делаем таки кучу не нужной работы
- хоть код и красивый, конечно...
- правильнее - для оптимизации реально выполняемых действий -
- отказаться от идеи обхода коллекции таким образом
- for (SmartElement smartElement:collection)
- а реализовать вот так
- получить список вебэлементов collection.getWrappedEntity()
- обойти полученный список вебэлементов в цикле
- и применять к вебэлементу - метод check
- правда, для этого объявление метода check придется вынести на уровень интерфейса Condition
- сэкономим на заворачиваниях-разворачиваниях)
- поправь и в SmartCollectionFoundByConditionElement
- */
- *******************************
- public interface Condition<T> {
- T apply(SmartEntity<T> entity);
- boolean check(T wrappedEntity);
- }
- /*
- делаем красиво)
- сейчас в этом интерфейсе - объявлены методы
- служащие как для принятия решения - прошли-не прошли
- так и для получения результата ожидания
- нарушаем Single Responsibility Principle )
- реализуй интерфейс Matcher <T> с объявленным методом boolean check(T wrappedEntity);
- а в Condition <T> - останется apply
- Condition <T> - отнаследуй от Matcher <T>
- и реализацию is стоит поправить - с check она будет нагляднее
- */
- ************************************
- /*
- еще немного challenge )
- в интерфейсе SmartElement
- объяви методы
- SmartCollection findAll(By innerLocator);
- SmartCollection findAll(String innerCssSelector);
- и реализуй их в AbstractLazyElement
- этот метод позволит у элемента - по селектору или локатору - получить коллекцию внутренних элементов
- отладиться можно - используя
- SmartCollection tasks = $("#todo-list").findAll("li");
- или
- SmartCollectionLazyCollection emails = $("[role='main']").findAll(".zA");
- Иногда такой метод findAll будет очень полезным
- принципы - те же
- как ты до этого реализовывала методы get, find, filter ...
- так сказать - для закрепления результатов)
- */
- **************************************
- public class Text extends ElementCondition {
- protected String expectedText;
- protected String actualText;
- /*
- насчет использования модификатора доступа protected
- есть такая точка зрения, что использовать protected - это самообман
- т к в рамках потомков можно для отнаследованного protected-метода
- этот метод сделать публичным
- когда мы использовали protected, мы хотели, чтобы что-то было с возможностью наследования
- и не хотели его внешнего использования.
- а кто-то отнаследовался от нашего класса и объявил это как public
- и вот то, что мы прятали внутри класса - уже "торчит" наружу
- есть good practice - избегать применения protected
- то, что мы что-то объявим внутри класса-кондишена как public
- не будет нам особо мешать при работе с нашим фреймворком
- т к в итоге - используем для кондишена тип интерфейс,
- и это позволит не светить нашими публичными переменными/методами
- когда будем юзать фреймворк
- идеально про протектед-методы
- http://programmers.stackexchange.com/questions/162643/why-is-clean-code-suggesting-avoiding-protected-variables
- http://joxi.ru/52akqzoUGnqYGr
- http://stackoverflow.com/questions/3631176/why-are-many-developers-opposed-to-using-the-protected-modifier-in-oop
- http://stackoverflow.com/questions/37011/should-you-ever-use-protected-member-variables
- http://stackoverflow.com/questions/4913025/reasons-to-use-private-instead-of-protected-for-fields-and-methods
- http://www.javalobby.org/java/forums/t77911.html
- Просмотри весь проект, перейди на использование public
- */
- ***************************
- public interface Condition<V> {
- V apply(SmartEntity<V> smartEntity);
- }
- /*
- просмотри конвеншенсы и подправь
- тут для дженерик-типа - вместо <V> - надо бы <T> использовать
- остальные классы просмотри
- http://stackoverflow.com/questions/2900881/generic-type-parameter-naming-convention-for-java-with-multiple-chars
- https://docs.oracle.com/javase/tutorial/java/generics/types.html
- */
- ******************************
- public abstract class ElementConditions {
- public static Condition<WebElement> visible() {
- return new Visible();
- }
- /*
- по идее - можно было еще короче)
- */
- public static Condition<WebElement> visible = new Visible();
- /*
- т е - реализовывать не метод, а статическую переменную
- вроде бы - лаконичнее, что хорошо
- но - не так уж и хорошо)
- Тут есть такая тонкость)
- мы создали статические переменные = объект-кондишен
- и используем их в проекте, который поддерживает параллелизацию
- если мы в параллельных тестах будем использовать ОДИН объект-кондишен ОДНОВРЕМЕННО
- могут возникать странные ошибки
- чтобы избежать этого
- вместо переменных стоит использовать методы
- тогда для каждого вызова кондишена мы будем использовать свой объект
- и таких проблем не будет
- наш текущий вариант с методом - грамотнее)
- */
- ***********************************************
- public static Condition<List<WebElement>> listNthElementHasText(int index, String text) {
- return new ListNthElementHasText(index, text);
- }
- /*
- нам такое сложное теперь и не нужно
- мы вполне можем и так делать
- $$(...).get(...).shouldHave(...)
- убираем гибрида ужа с ежом)
- и тут, и сам класс ListNthElementHasText
- */
- *********************************
- public class Present extends ElementCondition {
- boolean isPresent;
- /*
- просмотри классы
- я бы все же была более конкретной
- и явно указывала модификатор доступа (access modifier)
- */
- *********************************************
- public abstract class ElementCondition extends AbstractCondition<WebElement> {
- }
- /*
- кажется, уже єто обсуждали
- по большому счету - класс реализован только ради его наследников
- если наводим японский минимализм - можно и прибить
- а наследников єтого класса - наследовать от AbstractCondition<WebElement>
- не настаиваю
- */
- ***********************
- public class SizeOf extends CollectionCondition {
- ...
- protected int actualSize = 0;
- /*
- вполне можно было и не инициализировать
- http://stackoverflow.com/questions/19131336/java-default-values-and-initialization
- */
- *************************
- public class Empty extends SizeOf {
- /*
- вообще не стоило реаизовывать
- на уровне CollectionConditions
- в методе empty() - используй кондишен SizeOf
- кстати имя SizeOf - подправь на Size
- раньше - когда первым параметром кондишена был локатор - оно было разумно
- SizeOf(locator
- TextOf(locator...
- Of - сейчас оно потеряло актуальность
- просмотри кондишены
- */
- ***********************************
- public void pressEnter() {
- public void pressEscape() {
- public void pressTab() {
- /*
- спокойно можно переиспользовать this.sendKeys
- с setValue - так лучше не делать
- думаю - и сам понимаешь почему)
- */
- **************************
- public void sendKeys(final String text) {
- /*
- не поняла - зачем такой метод
- наверное - подзастрял со старых версий
- */
- **********************************
- public String toString() {
- return "element from parentCollection = " + parentCollection + "found by condition = " + condition;
- }
- /*
- тут лучше бы про кондишен писать - только его класс
- toString() кондишена тут будет не уместен
- parentCollection.toString() + " find(" + condition.getClass().getSimpleName() + ")" ?
- */
- ****************************************
- public String toString() {
- return "element from parentCollection = " + parentCollection + ", index = " + index;
- }
- /*
- parentCollection.toString() + "[" + index + "]" ?
- */
- **************************
- public class SmartElementInnerElement extends AbstractSmartElement {
- SmartElement element;
- /*
- именуй родительские смарт-сущности в некой одной логике
- */
- By cssSelector;
- /*
- значение типа By - это не cssSelector
- это локатор
- это может быть и By.xPath(..), Bi.id(...), By.partialLinkText(...)
- ну и By.cssSelector )
- и тут переименуй
- и в toString подправь
- и соответствующий метод - где создаешь такой смарт-єлемент - проверь
- */
- **************************
Advertisement
Add Comment
Please, Sign In to add comment