Кроссплатформенное унифицированное решение 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, потому что он не кажется хорошим)

0 ответов

Другие вопросы по тегам