Jacobvu84 / serenity-archetype-mobile

Sample project
0 stars 1 forks source link

Hook #13

Open Jacobvu84 opened 5 years ago

Jacobvu84 commented 5 years ago
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.openqa.selenium.WebDriver;

import net.serenitybdd.screenplay.actors.OnStage;
import net.thucydides.core.annotations.Managed;
import net.thucydides.core.webdriver.SerenityWebdriverManager;

import com.linecorp.model.LineActor;
import com.linecorp.model.LineCast;
import com.linecorp.model.LineCharacter;
import com.linecorp.rules.TestMethodAnnotations;
import com.linecorp.utils.SimpleCache;

import io.appium.java_client.service.local.AppiumDriverLocalService;

public abstract class Hook {

    private static AppiumDriverLocalService appiumService = null;

    @Rule
    public TestMethodAnnotations methodAnnotation = new TestMethodAnnotations();
    @Rule
    public CacheWatcher ruleExample = new CacheWatcher();

    @Managed(driver = "Appium")
    public WebDriver mobileDevice;

    private LineCast lineCast;

//    @BeforeClass
//    public static void startAppiumServer() {
//        appiumService = AppiumDriverLocalService.buildDefaultService();
//        appiumService.start();
//    }
//
//    @AfterClass
//    public static void stopAppiumServer() {
//        if (appiumService != null && appiumService.isRunning()) {
//            appiumService.stop();
//        }
//    }

    @Before
    public void createTheStage() {
        OnStage.setTheStage(lineCast = new LineCast());
    }

    @After
    public void closeDriver() {
        SerenityWebdriverManager.inThisTestThread().closeAllDrivers();
    }

    protected LineActor theActorCalled(LineCharacter actor) {
        return theActorCalled(actor.getName());
    }

    protected LineActor theActorCalled(String actor) {
        final String driverOptions = methodAnnotation.getDriverOptions();
        lineCast.setDriverOptions(driverOptions);

        return (LineActor) OnStage.theActorCalled(actor);
    }

    public static class CacheWatcher extends TestWatcher {
        protected void succeeded(Description description) {
            SimpleCache.getCurrentCache().submit();
        }

        protected void failed(Throwable e, Description description) {
            SimpleCache.getCurrentCache().clear();
        }
    }
}
Jacobvu84 commented 5 years ago
package xyz.rules;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

import com.linecorp.driver.WithDriverOption;
import com.linecorp.driver.WithDriverOptions;

public class TestMethodAnnotations extends TestWatcher {
    private Description description;

    @Override
    protected void starting(Description d) {
        this.description = d;
    }

    /**
     * @return the annotation of the currently-running test method
     */
    public <T extends Annotation> T getAnnotation(Class<T> clazz) {
        return Optional.ofNullable(description.getAnnotation(clazz))
                       .orElse(description.getTestClass().getAnnotation(clazz));
    }

    public String getDriverOptions() {
        Map<String, String> driverOptions = getMethodDriverOptionsAnnotation();
        if (driverOptions.isEmpty()) {
            driverOptions = getClassDriverOptionsAnnotation();
        }
        return driverOptions.entrySet()
                            .stream()
                            .map(e -> e.getKey() + "=" + e.getValue())
                            .collect(Collectors.joining(";"));

    }

    private Map<String, String> getMethodDriverOptionsAnnotation() {
        return buildDriverOptionsFrom(description.getAnnotation(WithDriverOptions.class),
                                      description.getAnnotation(WithDriverOption.class));
    }

    private Map<String, String> getClassDriverOptionsAnnotation() {
        return buildDriverOptionsFrom(description.getTestClass().getAnnotation(WithDriverOptions.class),
                                      description.getTestClass().getAnnotation(WithDriverOption.class));
    }

    private Map<String, String> buildDriverOptionsFrom(WithDriverOptions withDriverOptions, WithDriverOption withDriverOption) {
        Map<String, String> result = new HashMap<>();
        Optional.ofNullable(withDriverOptions)
                .ifPresent(driverOptions -> Arrays.stream(driverOptions.value())
                                                  .forEach(driverOption -> result.put(driverOption.capability(),
                                                                                      driverOption.value())));
        Optional.ofNullable(withDriverOption)
                .ifPresent(driverOption -> result.put(driverOption.capability(),
                                                      driverOption.value()));
        return result;
    }
}
Jacobvu84 commented 5 years ago

package xyz.model;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.serenitybdd.core.collect.NewList;
import net.serenitybdd.screenplay.Ability;
import net.serenitybdd.screenplay.Actor;
import net.serenitybdd.screenplay.abilities.BrowseTheWeb;
import net.serenitybdd.screenplay.actors.Cast;
import net.thucydides.core.webdriver.ThucydidesWebDriverSupport;
import net.thucydides.core.webdriver.WebDriverFacade;
import net.thucydides.core.webdriver.WebdriverManager;

import com.linecorp.testplatforms.util.CapabilitiesUtil;
import com.linecorp.utils.SimpleCache;

import io.appium.java_client.HasSettings;
import io.appium.java_client.Setting;
import io.appium.java_client.android.AndroidDriver;

public class LineCast extends Cast {
    private static final Logger LOGGER = LoggerFactory.getLogger(LineCast.class);
    private final Map<String, LineActor> actors = new HashMap<>();
    private String driverOptions;

    @Override
    public Actor actorNamed(String name, Ability... abilities) {
        final LineCharacter character = LineCharacter.valueOf(name.toUpperCase());
        if (!actors.containsKey(name)) {
            final LineActor newActor = new LineActor(name);
            if (newActor.abilityTo(BrowseTheWeb.class) == null) {
                final WebDriver driver = theDefaultBrowserFor(character);
                if (Platform.ANDROID.name().equals(CapabilitiesUtil.getPlatformName(driver))) {
                    setWaitForIdleTimeout(driver);
                    LOGGER.info("Set idle timeout for android platform");
                }
                newActor.can(BrowseTheWeb.with(driver));
            }

            actors.put(name, newActor);
        }

        return actors.get(name);
    }

    public List<Actor> getActors() {
        return NewList.copyOf(actors.values());
    }

    public void setDriverOptions(String driverOptions) {
        this.driverOptions = driverOptions;
    }

    private WebDriver theDefaultBrowserFor(LineCharacter character) {
        final String deviceId = character.getDeviceUdid();
        WebdriverManager webdriverManager = ThucydidesWebDriverSupport.getWebdriverManager()
                                                                      .withProperty(getAppiumCapability("udid"), deviceId);

        final Map<String, String> deviceSpec = character.getDeviceSpecifications();
        for (Entry<String, String> property : deviceSpec.entrySet()) {
            webdriverManager = webdriverManager.withProperty(getAppiumCapability(property.getKey()),
                                                             property.getValue());
        }

        if (!character.getName().equalsIgnoreCase(SimpleCache.getCurrentCache().getCache(deviceId))) {
            webdriverManager = webdriverManager.withProperty(getAppiumCapability("noReset"), "false");
            SimpleCache.getCurrentCache().setCache(deviceId, character.getName());
        }

        if (StringUtils.isNotEmpty(driverOptions)) {
            webdriverManager = webdriverManager.withOptions(driverOptions);
        }

        return webdriverManager.getWebdriverByName(character.getName());
    }

    private void setWaitForIdleTimeout(WebDriver webdriver) {
        if ((webdriver instanceof WebDriverFacade) &&
            ((WebDriverFacade) webdriver).getProxiedDriver() instanceof AndroidDriver) {
            ((HasSettings) ((WebDriverFacade) webdriver).getProxiedDriver()).setSetting(Setting.WAIT_FOR_IDLE_TIMEOUT, 1000);
        }
    }

    private String getAppiumCapability(String key) {
        return "appium." + key;
    }
}