Кроссплатформенное унифицированное решение Serenity
Я пытаюсь заставить существующее решение работать на любой платформе. Легко сделать собственный драйвер, расширяющий класс DriverSource, но мне все еще нужно разрешить внедрение различных объектов страницы (например, на мобильном устройстве другой макет). Для этого я хотел бы использовать Google Guice
Я собираюсь поделиться решением без DI, который прекрасно работает, но должен быть лучший способ сделать это.
public interface GooglePageInterface {
public void enter_keywords(String keyword);
public void lookup_terms();
public void navigateToHomePage();
}
(Вы также можете использовать абстрактный класс вместо интерфейса, так как, вероятно, большинство методов будут одинаковыми для мобильных и настольных компьютеров)
И две реализации интерфейса:
public class GoogleMobilePage extends PageObject implements GooglePageInterface {
@FindBy(name = "q")
private WebElementFacade searchTerms;
@FindBy(id = "tsbb")
private WebElementFacade lookupButton;
@Override
public void enter_keywords(String keyword) {
element(searchTerms).waitUntilVisible();
searchTerms.sendKeys(keyword);
}
@Override
public void lookup_terms() {
lookupButton.click();
}
// demo purpose- there are better ways for this
@Override
public void navigateToHomePage() {
getDriver().get("https://www.google.ro/");
}
}
а также
public class GoogleDesktopPage extends PageObject implements GooglePageInterface {
@FindBy(name = "q")
private WebElementFacade searchTerms;
@FindBy(css = "button[name='btnG']")
private WebElementFacade lookupButton;
@Override
public void enter_keywords(String keyword) {
element(searchTerms).waitUntilVisible();
searchTerms.sendKeys(keyword);
}
@Override
public void lookup_terms() {
lookupButton.click();
}
@Override
public void navigateToHomePage() {
System.out.println("You are in GoogleDesktopPage")
getDriver().get("https://www.google.ro/");
}
AbstractSteps будет принимать решение, основываясь на системном свойстве, указанном в Cmd.
public class AbstractSteps extends ScenarioSteps {
private static final long serialVersionUID = 1L;
public GooglePageInterface getDictionaryPage() {
switch (System.getProperty("runPlatform")) {
case "desktop":
return getPages().currentPageAt(GoogleDesktopPage.class);
case "mobile":
return getPages().currentPageAt(GoogleMobilePage.class);
default:
return null;
}
}
}
EndUserStep расширит AbstractSteps и будет использовать методы
public class EndUserSteps extends AbstractSteps{
private static final long serialVersionUID = 1L;
@Step
public void enters(String keyword) {
getDictionaryPage().enter_keywords(keyword);
}
@Step
public void starts_search() {
getDictionaryPage().lookup_terms();
}
@Step
public void navigateToHomePage() {
getDictionaryPage().navigateToHomePage();
}
@Step
public void looks_for(String term) {
enters(term);
starts_search();
}
}
И основной тест:
@RunWith(SerenityRunner.class)
public class SearchByKeywordStory {
@Managed(uniqueSession = true)
public WebDriver webdriver;
@Steps
public EndUserSteps endUserSteps;
@Test
public void searching_by_keyword_apple_should_display_the_corresponding_article() {
endUserSteps.navigateToHomePage();
endUserSteps.looks_for("something");
}
}
Я запускаю тест с помощью команды:
mvn test -Dtest = SearchByKeywordStory -Dwebdriver.driver = при условии -DrunPlatform=mobile -DrunEnv=staging-env проверить, где предоставлен пользовательский драйвер для мобильного устройства:
public class CustomDriver implements DriverSource {
@Override
public WebDriver newDriver() {
return setChromeMobile();
}
@Override
public boolean takesScreenshots() {
return true;
}
private WebDriver setChromeMobile() {
Map<String, Object> deviceMetrics = new HashMap<String, Object>();
//landscape
deviceMetrics.put("width", 732);
deviceMetrics.put("height", 412);
deviceMetrics.put("pixelRatio", 3.0);
Map<String, Object> mobileEmulation = new HashMap<String, Object>();
mobileEmulation.put("deviceMetrics", deviceMetrics);
mobileEmulation.put("userAgent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Mobile Safari/537.36");
Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("mobileEmulation", mobileEmulation);
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
return new ChromeDriver(capabilities);
}
}
В безмятежности.свойства
webdriver.driver=provided
webdriver.provided.type = mydriver
webdriver.provided.mydriver = com.tools.customerDrivers.CustomDriver
thucydides.driver.capabilities = mydriver
Готово, это работает!
Но, как я уже говорил ранее, я хочу попытаться заставить это работать с помощью Guice, но я столкнулся с проблемами, поскольку Serenity создает драйвер и действия, используя Google Guice.
Интерфейс страницы и реализации страниц остаются прежними.
Шаг:
public class EndUserSteps2 extends ScenarioSteps{
private static final long serialVersionUID = 1L;
@Inject
GooglePageInterface dictionaryPage;
@Step
public void enters(String keyword) {
dictionaryPage.enter_keywords(keyword);
}
@Step
public void starts_search() {
dictionaryPage.lookup_terms();
}
@Step
public void navigateToHomePage() {
dictionaryPage.navigateToHomePage();
}
@Step
public void looks_for(String term) {
enters(term);
starts_search();
}
Я создал BaseTest, где создается injecor (это можно сделать разными способами). Модуль, в котором выполняется привязка, --bind (GooglePageInterface.class).to (GoogleDesktopPage.class)- может быть в другом классе.
@RunWith(SerenityRunner.class)
public class BaseTest {
protected Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(GooglePageInterface.class).to(GoogleDesktopPage.class);
}
});
@Before
public void setup() {
injector.injectMembers(this);
}
}
И тест:
@RunWith(SerenityRunner.class)
public class SearchByKeywordStory2 extends BaseTest {
@Managed(uniqueSession = true)
public WebDriver webdriver;
//here is the issue
@Inject
@Steps
public EndUserSteps2 endUserSteps;
@Test
public void searching_by_keyword_apple_should_display_the_corresponding_article() {
endUserSteps.navigateToHomePage();
endUserSteps.looks_for("something");
}
}
Тест запускается, но драйвер не передается в GoogleDesktopPage.class, поэтому тест завершается неудачно, но класс внедряется при выводе сообщения "Вы находитесь в GoogleDesktopPage" от navigateToHomePage()
Я знаю, что Serenity внедряет веб-драйвер и шаги с использованием аннотаций, и я немного застрял здесь
Я был бы очень признателен, если бы кто-нибудь мог помочь мне сделать эту работу как-то (возможно, другой подход с DI, потому что он не кажется хорошим)