Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public boolean containsOrEquals(List<String> actualTexts, String[] expectedTexts) {
- for (int i = 0; i < expectedTexts.length; i++) {
- if (!actualTexts.get(i).contains(expectedTexts[i])) {
- return false;
- }
- }
- return true;
- }
- /*
- можно было сэкономить еще больше )
- */
- public boolean check(List<WebElement> elements) {
- actualTexts = getTexts(elements);
- if (actualTexts.size() != expectedTexts.length) {
- return false;
- }
- for (int i = 0; i < expectedTexts.length; ++i) {
- if (!checkElement(i)) {
- return false;
- }
- }
- return true;
- }
- public boolean checkElement(int index) {
- return actualTexts.get(index).contains(expectedTexts[index]);
- }
- /*
- и в потомке - реализуем checkElement
- а в check предка - оставляем всю схему проверки
- что тоже очень наглядно
- */
- **********************************
- if (!(element == null))
- {isPresent = true;}
- /*
- перепиши проще
- isPresent = (element != null)
- форматирование - не забывай)
- видно - что на автопилоте ты многое форматируешь нестандартно
- я тоже так делаю)
- поэтому - в конце каждого цикла разработки - реформатирую код)
- это здорово снижает градус в рабочей обстановке))))
- */
- ************************************
- public class Text extends ElementCondition {
- ...
- @Override
- public boolean check(WebElement element) {
- actualText = element.getText();
- return (containsOrEquals (actualText, expectedText));
- }
- ....
- public boolean containsOrEquals (String actualText, String expectedText){
- return(actualText.contains(expectedText));
- }
- /*
- а тут - экономия на спичках)
- check - и так в 2 строчки
- ради экономии одной строчки организовывать метод - расточительство)
- в данном случае - мы усложнили код )
- избавляйся от containsOrEquals тут и в потомке
- check - и так хорош
- а наследование позволит не создавать кучу вспомогательного и упростить конструктор
- */
- public class ExactText extends Text {
- public ExactText(String expectedText) {
- super(expectedText);
- }
- /*
- конструктор - ок упростила
- */
- @Override
- public boolean check(WebElement element) {
- return super.check(element);
- }
- /*
- этот метод - будет и в предке и в потомке
- */
- @Override
- public String expected() {
- return null;
- }
- @Override
- public String actual() {
- return null;
- }
- /*
- вот это не правильно
- если бы мы эти методы тут не перереализовали - вызывались бы
- сотвествующие методы предка
- что хорошо)
- а мы - эти методы перереализовали, причем бесполезно
- просто - убери их
- пусть работает логика предка - она нам подходит
- */
- @Override
- public boolean containsOrEquals (String actualText, String expectedText){
- return(actualText.equals(expectedText));
- }
- /*
- это уйдет
- */
- }
- *************************************
- public class ExactTexts extends Texts {
- public ExactTexts (String... texts) {
- super(texts);
- if (expectedTexts.length == 0) {
- throw new IllegalArgumentException("Array of expected texts is empty.");
- }
- }
- /*
- посмотри на логику конструктора предка
- нам тут отлично подойдет super(texts);
- */
- @Override
- public boolean check(List<WebElement> elements) {
- return super.check(elements);
- }
- /*
- этот метод можно просто не реализовывать - раз логика check
- полностью совпадает с логикой check предка
- с конструктором такие номера не проходят
- а с остальными методами - вполне
- http://stackoverflow.com/questions/2319817/how-to-inherit-constructor-from-super-class-to-sub-class
- http://www.programcreek.com/2013/04/what-are-the-frequently-asked-questions-about-constructors-in-java/
- */
- @Override
- public String expected() {
- return Arrays.toString(expectedTexts);
- }
- @Override
- public String actual() {
- return String.join(", ", actualTexts);
- }
- /*
- нам подходит функциональность этих методов у предка
- можно тут не реализовывать
- */
- @Override
- public boolean containsOrEquals (List<String> actualTexts, String[] expectedTexts) {
- for (int i = 0; i < expectedTexts.length; i++) {
- if (!actualTexts.get(i).equals(expectedTexts[i])){}
- }
- return areTexts;}
- /*
- этот метод - будет попроще
- форматирование )))
- */
- }
- ****************************************
- src / main / java / core / lazy /
- /*
- мы оперируем ленивыми ... чем?
- сущностями или обертками
- как тебе нравится)
- переименуй пекедж lazy в
- lazywrappers / lazyentities/ wrappers / entities
- как понравится )
- */
- ************************
- public interface Lazy <T> {
- public T getWrappedEntity();
- }
- /*
- реализация - ок
- лучше переименуй интерфейс в - LazyEntity
- */
- ***************************************
- public abstract class AbstractLazyCollection<V> implements Lazy <List<WebElement>> {
- /*
- направление верное )
- после реализации интерфейса - реализовать абстрактный класс,
- реализовать все что можно на его уровне
- и далее - в классах-потомках абстрактного класса - уже делать все остальноное)
- все так)
- только вот еще момент - нам потом жедательно объявлять переменные типа интерфейс
- и инициализировать их объектами наших классов
- значит - на уровне интерфейса должны быть объявлены все нужные нам методы
- значит - на не хватает в дереве иерархии - еще одного уровня
- реализуй интерфейс
- LazyCollection
- наследника LazyEntity <List<WebElement>>
- в котором объяви методы shouldBe и shouldHave
- getWrappedEntity() - уже объявлен в предке, повторяться не надо,
- будем только дополнять
- и AbstractLazyCollection будет имплементировать LazyCollection
- и LazyCollection и AbstractLazyCollection уже не нуждаются в объявлении
- AbstractLazyCollection<V>
- LazyCollection<V>
- наоборот - мы уточнили этот тип - наследуясь от LazyEntity <List<WebElement>>
- */
- public By locator;
- /*
- в абстрактном классе - рано объявлять локатор
- у нас будет целое семейство классов лейзи-коллекций
- один из них - и правла будет оперировать локатором, а остальные - нет
- поле локатор уже в потомке объявишь
- */
- public abstract List<WebElement> getWrappedEntity();
- /*
- раз метод объявлен в интерфейсе
- и ты его не собираешься реализовывать в абстрактном классе -
- тут его не надо объхявлять
- мы его уже в интервейсе объявили
- нам этого хватит
- */
- public abstract Lazy shouldBe(Condition <List<WebElement>> condition);
- public abstract Lazy shouldHave (Condition <List<WebElement>> condition);
- /*
- а вот эти методы - мы запросто тут можем реализовать
- все объекты-лейзи-коллекции - будут проверяться одинаково
- что есть should...(condition) ?
- это ждущая проверка
- мы ее уже на прошлом шаге реализовали
- смотри реализацию метода assertThat
- return waitFor(locator).until(condition, timeout);
- если класс WaitFor - научить оперировать не локатором -
- а лейзи сущностью (LazyEnity - т к WaitFor - должен работать как с лейзи-элементами, так и с лейзи-коллекциями)
- то тут в should-методах
- return waitFor(this).until(condition);
- вот неплохие линки - про использование this
- https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
- http://stackoverflow.com/questions/2411270/when-should-i-use-this-in-a-class
- */
- public abstract String identity();
- }
- /*
- хм...
- свежая мысль)
- ты знаешь, соглашусь с тобой
- на уровне интерфейса LazyEntity объявляй такой метод)
- и тут - реализовывай)
- для всех коллекций - это "elements"
- а еще лучше - "collection" - так быстрее в глаза бросается - что речь не про элемент
- */
- ******************************************
- public class WaitFor {
- private static By locator;
- public WaitFor(By locator) {
- this.locator = locator;
- }
- public static WaitFor waitFor(By locator) {
- return new WaitFor(locator);
- }
- /*
- принимай не локатор, а LazyEntity
- */
- public static <T> T until(Condition<T> condition, long timeout) {
- ....
- T result = condition.apply(locator);
- /*
- передавай не локатор, а LazyEntity
- */
- *******************************************************
- public abstract class AbstractCondition<V> implements Condition<V> {
- public By locator;
- /*
- тут тоже оперируем не локатором, а LazyEntity
- */
- public abstract V getWrappedEntity();
- /*
- этот метод уйдет
- */
- public abstract boolean check(V entity);
- public V apply(By locator) {
- /*
- измени параметр метода - не локатор, а LazyEntity
- и на уровне интерфейса тоже
- */
- this.locator = locator;
- V entity = getWrappedEntity();
- /*
- и getWrappedEntity() - теперь вызывай у этой LazyEntity )
- соотвественно - убирай реализацию getWrappedEntity()
- в этом классе и классах-потоках
- это был костыль)
- теперь лейзи-сущность
- сама про себя это расскажет
- */
- return check(entity) ? entity : null;
- }
- *******************************************************
- public abstract class CollectionCondition extends AbstractCondition<List<WebElement>> {
- public String identity() {
- return "elements";
- }
- public List<WebElement> getWrappedEntity(){
- return getDriver().findElements(locator);
- }
- }
- /*
- оба метода уйдут отсюда
- аналогично - для ElementCondition
- это будем получать уже от лейзи-сущности
- что логично)
- фактически - этот класс - просто уточнит тип
- поскольку будет куча наследников-кондишенов
- это не так мало)
- так что пусть такой класс будет)
- на уровне конечных кондишенов - уже наши навороты никак не скажутся
- */
- *********************************
- public class LazyCollection extends AbstractLazyCollection <List<WebElement>>{
- /*
- раз мы AbstractLazyCollection не объявляли как AbstractLazyCollection<V>
- то и тут уже не придется уточняться до List<WebElement>
- на самом деле - мы это на предыдущем шаге сделали
- а вот на уровне класса лейзи-коллекции, оперирующей локатором
- реализуй поле для локатора и конструктор, получающий локатор и фиксирующий его в поле
- */
- @Override
- public List<WebElement> getWrappedEntity() {
- return getDriver().findElements(locator);
- }
- /*
- да, как раз тут и надо реализовать getWrappedEntity()
- и реализация верная
- конечные классы лейзи-сущностей - будем называть по схеме
- Lazy+Откуда+Уточнение+Element/Collection
- это будет LazyWebDriverCollection (т к откуда = WebDriver)
- также реализуй для класса toString()
- тут будет ок - если мы вернем локатор
- */
- @Override
- public Lazy shouldBe(Condition<List<WebElement>> condition) {
- return null;
- }
- @Override
- public Lazy shouldHave(Condition<List<WebElement>> condition) {
- return null;
- }
- @Override
- public String identity() {
- return "elements";
- }
- /*
- эти методы - с общей функциональностью для всех лейзи-коллекций
- и мы их реализовали на уровне абстрактного предка
- все - в потомках не морочимся с ними вообще)
- тут - в потомке абстрактного класса - удаляй код)
- все уже реализовано в абстрактном предке
- */
- /*
- аналогично описанному - проработай и лейзи-элемент
- */
Advertisement
Add Comment
Please, Sign In to add comment