Перейти к содержимому

Фотография

PageFactory, DefaultFieldDecorator и CacheLookup


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 6

#1 FibYar

FibYar

    Новый участник

  • Members
  • Pip
  • 57 сообщений
  • ФИО:Большаков Виталий

Отправлено 19 апреля 2017 - 14:20

Добрый день!

У меня возникла такая проблема. Я создал обёртку над шаблоном PageFactory с помощью DefaultFieldDecorator. Теперь использую свои аннотации и способы поиска элементов.

Но у меня возникла проблема с "ленивой инициализацией". Иногда мне бы хотелось закэшировать веб-элементы, свойства которых я получаю, но не знаю как. Аннотация @CacheLookup не работает после "расширения" PageFactory с помощью DefaultFieldDecorator. Да и хотелось бы не "всегда кэшировать отдельный элемент", а "на время включать кэширование, а затем (после получения нескольких свойств) отключать".

Кусок кода, где поиск происходит дважды:

webElement.clear();
webElement.click();

Переопределение делаю как-то так (сам понимаю с трудом, так как делал года три назад):

public class MyFieldDecorator extends DefaultFieldDecorator {

    public MyFieldDecorator(ElementLocatorFactory factory) {
        super(factory);
    }
public class MyElementLocator implements ElementLocator {
private final SearchContext searchContext;
private final By by;
public MyElementLocator(SearchContext searchContext, Field field) {
this.searchContext = searchContext;
MyAnnotations annotations = new MyAnnotations(field);
by = annotations.buildFirstBy();
}
public final class MyElementLocatorFactory implements ElementLocatorFactory, SearchContext {
PageFactory.initElements(new MyFieldDecorator(new MyElementLocatorFactory(driver)), webPage);

Надеюсь, что удалось объяснить, что я хочу :)


  • 0

#2 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 19 апреля 2017 - 14:55

1)у тебя все как-то архисложно. DefaultFieldDecorator надо примерно использовать, как описано тут:

http://internetka.in...fielddecorator/

 

2)@CacheLookup от данной аннотации не так много профита, а места много в коде занимает. Чтобы она работала для элементов нужно... да хз. Еще ты хочешь, чтобы она не всегда срабатывала ))


  • 0

#3 checo

checo

    Опытный участник

  • Members
  • PipPipPipPip
  • 400 сообщений
  • Город:Н.Новгород

Отправлено 19 апреля 2017 - 15:16

А что кешируется? Свойства элемента, сам WebElement или только локатор?

WebElement кешировать небезопасно, поскольку это лишь некий временный ID, который выдает браузер, и после любого действия на странице он может стать недействительным. Тогда нужно дополнительно писать логику на то, в какой момент этот кэш будет сбрасываться.


  • 0

#4 FibYar

FibYar

    Новый участник

  • Members
  • Pip
  • 57 сообщений
  • ФИО:Большаков Виталий

Отправлено 19 апреля 2017 - 17:39

1)у тебя все как-то архисложно. DefaultFieldDecorator надо примерно использовать, как описано тут:

http://internetka.in...fielddecorator/

Вот как-то оттуда я всё и почерпнул) А сложно лишь для того, чтобы можно было написать свою аннотацию со своими особыми вариантами поиска.

 

А что кешируется? Свойства элемента, сам WebElement или только локатор?

WebElement кешировать небезопасно, поскольку это лишь некий временный ID, который выдает браузер, и после любого действия на странице он может стать недействительным. Тогда нужно дополнительно писать логику на то, в какой момент этот кэш будет сбрасываться.

Я хочу кешировать вебЭлемент лишь на короткий промежуток кода - когда я подряд провожу над ним несколько действий. Например, как в изначальном сообщении: сначала выполнить clear, затем sendKeys. Или же есть другая ситуация: я получаю свойства какого-то элемента (например, значение определенного атрибута или видимость элемента) и, в зависимости от него, делаю определенные действия уже над другим элементом. При этом результат записываю в переменную. И ещё результат переменной отписываю в лог. Самое главное - при каждом этом действии вызывается поиск элемента (а хочется лишь один раз - при присвоении переменной (а не при каждом считывании её значения)):

Boolean enabled = webElement.isEnabled(); //Поиск происходит здесь (запись значения)
logger.debug(enabled);                    //Поиск происходит здесь (а тут не хочу)
if (enabled) {                            //Поиск происходит здесь (и тут не хочу)
   //do something
}

  • 0

#5 checo

checo

    Опытный участник

  • Members
  • PipPipPipPip
  • 400 сообщений
  • Город:Н.Новгород

Отправлено 21 апреля 2017 - 07:16

Если заглянете в реализацию DefaultElementLocator, увидите, что аннотация @CacheLookup работает приблизительно так же. Проблема в том, что элемент кешируется навсегда, и повлиять на это нельзя.

 

Поэтому опять надо решить вопрос: как хочется управлять кешированием? Чтобы чистить кэш автоматически, нужно писать довольно сложный механизм.

 

В вашем варианте, если действия выполняет один участок кода, можно сделать ручное управление:

try {
    SomethingToStartCaching();
    element.clear();
    element.sendKeys("abc");
} finally {
    SomethingToDisableCaching();
}

Самое простое решение, которое позволит так делать (но не потокобезопасное):

 

  1. Создаем CacheTriggeringElementLocatorFactory implements ElementLocatorFactory, которая будет возвращать CacheTriggeringElementLocator.
  2. Создаем CacheTriggeringElementLocator implements ElementLocator, который содержит поле static boolean и 2 public static метода для изменения этого поля (причем метод, устанавливающий false, должен также обнулять кешированные значения).
  3. Передираем реализацию DefaultElementLocator с той разницей, что вместо shouldCache используем наше поле.

 

Самое простое решение для параллелизации - превратить static boolean в static Map<Long, Boolean>, где в качестве ключа брать Thread.currentThread.getId().


  • 1

#6 checo

checo

    Опытный участник

  • Members
  • PipPipPipPip
  • 400 сообщений
  • Город:Н.Новгород

Отправлено 21 апреля 2017 - 09:17

Выше глупость написал. Конечно, статический метод не будет сбрасывать кэши в отдельных локаторах.
  • 0

#7 FibYar

FibYar

    Новый участник

  • Members
  • Pip
  • 57 сообщений
  • ФИО:Большаков Виталий

Отправлено 22 апреля 2017 - 16:13

Выше глупость написал. Конечно, статический метод не будет сбрасывать кэши в отдельных локаторах.

Не знаю, относится ли этот комментарий ко всему ответу или только части, но за ответ спасибо. Как я понял, придётся сильно менять реализацию всего. Буду пробовать.


  • 0


Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных