Как я могу хранить WebElement в json или свойстве, чтобы я мог легко его изменить - PullRequest
0 голосов
/ 19 декабря 2018
@FindBy(xpath="//button[@class='submitButton']")
WebElement submit;

Я использовал этот тип кода в среде тестирования с использованием POM.

Я хочу сохранить этот Xpath в файле свойств и хочу назначить ему только ключ.

например:

@FindBy(xpath=config.getsubmit())
WebElement submit;

Есть ли способ сохранить WebElement или создать репозиторий WebElement?

Ответы [ 4 ]

0 голосов
/ 21 декабря 2018

Vicky,

Вы можете создать репозиторий WebElement, создав модель POJO.

Public class WebElementRepo 
{
static WebElement01 = null;

// then create getter setter for all these webelements

public static void setWebElement01(WebElement WE)
{
WebElement01 = WE;
}

public static WebElement getWebElement01(WebElement WE)
{
return WebElement01;
}

}

Когда вам нужно сохранить веб-элемент в хранилище, просто передайте webelement вWebElementRepo.setWebElement () и используйте WebElementRepo.getWebElement () для получения веб-элемента.

0 голосов
/ 19 декабря 2018

Нельзя передавать значения в аннотации, определенные во время выполнения, допускаются только константы, такие как конечные поля или типы.Подробнее см. в спецификации .Это потому, что аннотации оцениваются во время компиляции.Их значение, возможно, сохраняется в файле класса.

Хотя вы можете найти элементы программно :

WebElement element = driver.findElement(By.xpath(config.getsubmit()));

Однако для этого требуется ссылка на WebDriver.экземпляр.

0 голосов
/ 20 декабря 2018

Вы не можете сделать это с простым ванильным ароматом PageObjects и PageFactory.

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

Чтобы это сделать, выв основном потребуется следующее

  • Настроенная реализация org.openqa.selenium.support.pagefactory.ElementLocator, чтобы вы могли иметь возможность обрабатывать вызовы findElement и findElements, используя предоставленный экземпляр WebDriver.Реализация по умолчанию просто запрашивает аннотации.
  • Настраиваемая реализация org.openqa.selenium.support.pagefactory.ElementLocatorFactory, так что она может создавать ваши настроенные ElementLocator экземпляры вместо стандартных.
  • Настраиваемый анализатор аннотаций, такчто вы можете анализировать пользовательские аннотации, добавленные к объектам WebElement, расширяя org.openqa.selenium.support.pagefactory.AbstractAnnotations
  • И последнее, но не менее важное: пользовательскую аннотацию, которая захватывает некоторые метаданные, которые можно использовать для чтения локатора.из файла JSON для данного веб-элемента

Со всеми этими функциями вы можете сделать следующее

  • Определить свою пользовательскую аннотацию таким образом, чтобы она позволяла идентифицировать локатор уникальным образом изfile.
  • Определите пользовательский анализатор аннотаций, который будет считывать атрибуты вашей пользовательской аннотации и создаст By объект
  • Определите пользовательский ElementLocator так, чтобы он использовал пользовательский анализатор аннотаций для поискаelements.
  • Определите пользовательский ElementLocatorFactory так, чтобы он создавал экземпляры пользовательского ElementLocator.

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

Чтобы получить полное представление о том, как работает PageFactory, взгляните на этот блог, который я создал.

Кто-то воспринял мой блог как отправную точку и создал библиотеку, которая может сделать все это для вас.Вы можете использовать его здесь https://github.com/shchukax/search-with

Ради полноты я включаю все фрагменты кода из моего блога

json будет выглядеть так

[
  {
    "pageName": "HomePage",
    "name": "abTesting",
    "locateUsing": "xpath",
    "locator": "//a[contains(@href,'abtest')]"
  },
  {
    "pageName": "HomePage",
    "name": "checkBox",
    "locateUsing": "xpath",
    "locator": "//a[contains(@href,'checkboxes')]"
  },
  {
    "pageName": "CheckboxPage",
    "name": "checkBox1",
    "locateUsing": "xpath",
    "locator": "//input[@type='checkbox'][1]"
  },
  {
    "pageName": "CheckboxPage",
    "name": "checkBox2",
    "locateUsing": "xpath",
    "locator": "//input[@type='checkbox'][2]"
  }
]

Пользовательская аннотация будет выглядеть следующим образом:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention (RetentionPolicy.RUNTIME)
@Target (ElementType.FIELD)
public @interface SearchWith {
    String inPage() default "";

    String locatorsFile() default "";

    String name() default "";
}

Пользовательская ElementLocator реализация

import org.openqa.selenium.By;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.pagefactory.AbstractAnnotations;
import org.openqa.selenium.support.pagefactory.ElementLocator;

import java.util.List;

public class FileBasedElementLocator implements ElementLocator {

    private final SearchContext searchContext;
    private final boolean shouldCache;
    private final By by;
    private WebElement cachedElement;
    private List<WebElement> cachedElementList;


    public FileBasedElementLocator(SearchContext searchContext, AbstractAnnotations annotations) {
        this.searchContext = searchContext;
        this.shouldCache = annotations.isLookupCached();
        this.by = annotations.buildBy();
    }

    @Override
    public WebElement findElement() {
        if (cachedElement != null && shouldCache) {
            return cachedElement;
        }

        WebElement element = searchContext.findElement(by);
        if (shouldCache) {
            cachedElement = element;
        }

        return element;

    }

    @Override
    public List<WebElement> findElements() {
        if (cachedElementList != null && shouldCache) {
            return cachedElementList;
        }

        List<WebElement> elements = searchContext.findElements(by);
        if (shouldCache) {
            cachedElementList = elements;
        }

        return elements;
    }
}

Пользовательская фабрика локатора элементов будет выглядеть следующим образом

import org.openqa.selenium.SearchContext;
import org.openqa.selenium.support.pagefactory.ElementLocator;
import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;

import java.lang.reflect.Field;

public class FileBasedElementLocatorFactory implements ElementLocatorFactory {
    private final SearchContext searchContext;

    public FileBasedElementLocatorFactory(SearchContext searchContext) {
        this.searchContext = searchContext;
    }

    @Override
    public ElementLocator createLocator(Field field) {
        return new FileBasedElementLocator(searchContext, new CustomAnnotations(field));
    }
}

Customреализация AbstractAnnotations

import com.google.common.base.Preconditions;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.openqa.selenium.By;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.pagefactory.AbstractAnnotations;
import organized.chaos.annotations.SearchWith;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.lang.reflect.Field;
import java.util.Iterator;

class CustomAnnotations extends AbstractAnnotations {
    private final Field field;

    CustomAnnotations(Field field) {
        this.field = field;
    }

    @Override
    public By buildBy() {
        SearchWith search = field.getAnnotation(SearchWith.class);
        Preconditions.checkArgument(search != null, "Failed to locate the annotation @SearchWith");
        String elementName = search.name();
        String pageName = search.inPage();
        String locatorsFile = search.locatorsFile();
        Preconditions
            .checkArgument(isNotNullAndEmpty(elementName), "Element name is not found.");
        Preconditions.checkArgument(isNotNullAndEmpty(pageName), "Page name is missing.");
        Preconditions.checkArgument(isNotNullAndEmpty(locatorsFile), "Locators File name not provided");
        File file = new File(locatorsFile);
        Preconditions.checkArgument(file.exists(), "Unable to locate " + locatorsFile);
        try {
            JsonArray array = new JsonParser().parse(new FileReader(file)).getAsJsonArray();
            Iterator&amp;lt;JsonElement&amp;gt; iterator = array.iterator();
            JsonObject foundObject = null;
            while (iterator.hasNext()) {
                JsonObject object = iterator.next().getAsJsonObject();
                if (pageName.equalsIgnoreCase(object.get("pageName").getAsString()) &&
                    elementName.equalsIgnoreCase(object.get("name").getAsString())) {
                    foundObject = object;
                    break;
                }
            }
            Preconditions.checkState(foundObject != null, "No entry found for the page [" + pageName + "] in the "
                + "locators file [" + locatorsFile + "]");
            String locateUsing = foundObject.get("locateUsing").getAsString();
            if (! ("xpath".equalsIgnoreCase(locateUsing))) {
                throw new UnsupportedOperationException("Currently " + locateUsing + " is NOT supported. Only xPaths "
                    + "are supported");
            }

            String locator = foundObject.get("locator").getAsString();
            Preconditions.checkArgument(isNotNullAndEmpty(locator), "Locator cannot be null (or) empty.");
            return new By.ByXPath(locator);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public boolean isLookupCached() {
        return (field.getAnnotation(CacheLookup.class) != null);
    }

    private boolean isNotNullAndEmpty(String arg) {
        return ((arg != null) && (! arg.trim().isEmpty()));
    }
}

Вот как может выглядеть класс объекта страницы

import org.openqa.selenium.WebElement;
import organized.chaos.annotations.SearchWith;

public class HomePage {
    public static final String PAGE = "HomePage";
    @SearchWith (inPage = HomePage.PAGE, locatorsFile = "src/main/resources/locators.json", name = "abTesting")
    private WebElement abTestingLink = null;

    @SearchWith (inPage = HomePage.PAGE, locatorsFile = "src/main/resources/locators.json", name = "checkBox")
    private WebElement checkBoxLink = null;

    public HomePage() {
    }

    public CheckBoxPage navigateToCheckBoxPage() {
        checkBoxLink.click();
        return new CheckBoxPage();
    }
}

Другой класс страницы

import org.openqa.selenium.WebElement;
import organized.chaos.annotations.SearchWith;

public class CheckBoxPage {
    private static final String PAGE = "CheckBoxPage";

    @SearchWith (inPage = CheckBoxPage.PAGE, locatorsFile = "src/main/resources/locators.json", name = "checkBox1")
    private WebElement checkBoxOne;

    @SearchWith (inPage = CheckBoxPage.PAGE, locatorsFile = "src/main/resources/locators.json", name = "checkBox2")
    private WebElement checkBoxTwo;

    public void unCheckCheckBoxTwo() {
        if (checkBoxTwo.isSelected()) {
            checkBoxTwo.click();
        }
    }

    public boolean isCheckBoxTwoUnchecked() {
        return (! checkBoxTwo.isSelected());
    }
}

А вот тестовый класс, которыйпотребляет это

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import organized.chaos.pages.CheckBoxPage;
import organized.chaos.pages.HomePage;
import organized.chaos.support.FileBasedElementLocatorFactory;

public class AlteredPageFactoryDemo {

    private RemoteWebDriver driver;

    @BeforeClass
    public void setup() {
        driver = new ChromeDriver();
    }

    @AfterClass
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void testMethod() {
        driver.get("https://the-internet.herokuapp.com/");
        HomePage homePage = new HomePage();
        ElementLocatorFactory factory = new FileBasedElementLocatorFactory(driver);
        PageFactory.initElements(factory, homePage);
        CheckBoxPage checkboxPage = homePage.navigateToCheckBoxPage();
        PageFactory.initElements(factory, checkboxPage);
        checkboxPage.unCheckCheckBoxTwo();
        Assert.assertTrue(checkboxPage.isCheckBoxTwoUnchecked());
    }
}
0 голосов
/ 19 декабря 2018

@FindBy принимает final String

static final String xpath;
xpath=config.getsubmit(); 
@FindBy(xpath)
WebElement submit;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...