Skip to content

Commit

Permalink
Add new implementation of base Screen (#22)
Browse files Browse the repository at this point in the history
* Add new implementation of base Screen

* Add javadoc to ScreenPlatform annotation

* Rename annotation ScreenPlatform to ScreenType
  • Loading branch information
paveliam authored May 15, 2020
1 parent 897eb21 commit ab8d4a2
Show file tree
Hide file tree
Showing 26 changed files with 119 additions and 184 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import aquality.appium.mobile.configuration.ILocalServiceSettings;
import aquality.appium.mobile.elements.interfaces.IElementFactory;
import aquality.appium.mobile.screens.screenfactory.IScreenFactory;
import aquality.appium.mobile.screens.screenfactory.IScreenFactoryProvider;
import aquality.selenium.core.localization.ILocalizedLogger;
import aquality.selenium.core.logging.Logger;
import aquality.selenium.core.waitings.IConditionalWait;
Expand Down Expand Up @@ -162,7 +161,7 @@ public static IElementFactory getElementFactory() {
* @return Factory of screens.
*/
public static IScreenFactory getScreenFactory() {
return get(IScreenFactoryProvider.class).getScreenFactory();
return get(IScreenFactory.class);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import aquality.appium.mobile.configuration.ILocalServiceSettings;
import aquality.appium.mobile.elements.IElementsModule;
import aquality.appium.mobile.elements.interfaces.IElementFactory;
import aquality.appium.mobile.screens.screenfactory.IScreenFactoryProvider;
import aquality.appium.mobile.screens.screenfactory.IScreenFactory;
import aquality.appium.mobile.screens.screenfactory.IScreensModule;
import aquality.selenium.core.applications.AqualityModule;
import com.google.inject.Provider;
Expand All @@ -25,6 +25,6 @@ protected void configure() {
bind(ILocalServiceSettings.class).to(getLocalServiceSettingsImplementation()).in(Singleton.class);
bind(IConfiguration.class).to(getConfigurationImplementation());
bind(IElementFactory.class).to(getElementFactoryImplementation());
bind(IScreenFactoryProvider.class).to(getScreenFactoryProviderImplementation());
bind(IScreenFactory.class).to(getScreenFactoryImplementation());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ public enum ElementType {
RADIOBUTTON(IRadioButton.class),
TEXTBOX(ITextBox.class);

private Class<? extends IElement> clazz;
private final Class<? extends IElement> clazz;

<T extends IElement> ElementType(Class<T> clazz){
this.clazz = clazz;
}

@SuppressWarnings("unchecked")
public <T extends IElement> Class<T> getClazz() {
return (Class<T>) clazz;
}
Expand Down
33 changes: 0 additions & 33 deletions src/main/java/aquality/appium/mobile/screens/AndroidScreen.java

This file was deleted.

24 changes: 0 additions & 24 deletions src/main/java/aquality/appium/mobile/screens/IOSScreen.java

This file was deleted.

30 changes: 5 additions & 25 deletions src/main/java/aquality/appium/mobile/screens/Screen.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package aquality.appium.mobile.screens;

import aquality.appium.mobile.application.AqualityServices;
import aquality.appium.mobile.application.PlatformName;
import aquality.appium.mobile.elements.interfaces.IElementFactory;
import aquality.appium.mobile.elements.interfaces.ILabel;
import aquality.selenium.core.elements.interfaces.IElementStateProvider;
import io.appium.java_client.AppiumDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.InvalidArgumentException;

public abstract class Screen<T extends AppiumDriver> implements IScreen {
public abstract class Screen implements IScreen {

private final By locator;
private final String name;
Expand All @@ -25,27 +22,6 @@ protected Screen(By locator, String name) {
this.screenLabel = getElementFactory().getLabel(locator, name);
}

protected IElementFactory getElementFactory(){
return AqualityServices.getElementFactory();
}

@SuppressWarnings("unchecked")
protected T getDriver() {
ensureApplicationPlatformCorrect(getPlatform());
return (T) AqualityServices.getApplication().getDriver();
}

protected abstract PlatformName getPlatform();

private void ensureApplicationPlatformCorrect(PlatformName targetPlatform) {
PlatformName currentPlatform = AqualityServices.getApplication().getPlatformName();
if (targetPlatform != currentPlatform) {
throw new InvalidArgumentException(String.format(
"Cannot perform this operation. Current platform %s don't match to target %s",
currentPlatform, targetPlatform));
}
}

public By getLocator() {
return locator;
}
Expand All @@ -61,4 +37,8 @@ public Dimension getSize() {
public IElementStateProvider state() {
return screenLabel.state();
}

protected IElementFactory getElementFactory(){
return AqualityServices.getElementFactory();
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
public interface IScreensModule {

/**
* @return class which implements {@link IScreenFactoryProvider}
* @return class which implements {@link IScreenFactory}
*/
default Class<? extends IScreenFactoryProvider> getScreenFactoryProviderImplementation() {
return ScreenFactoryProvider.class;
default Class<? extends IScreenFactory> getScreenFactoryImplementation() {
return ScreenFactory.class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,44 @@
import aquality.appium.mobile.application.AqualityServices;
import aquality.appium.mobile.configuration.IApplicationProfile;
import aquality.appium.mobile.screens.IScreen;
import aquality.appium.mobile.screens.Screen;
import org.reflections.Reflections;
import org.reflections.ReflectionsException;

import javax.inject.Inject;
import java.util.Set;
import java.util.stream.Collectors;

public abstract class ScreenFactory<TPlatformScreen extends Screen> implements IScreenFactory {
public class ScreenFactory implements IScreenFactory {

private final IApplicationProfile applicationProfile;

@Inject
public ScreenFactory(IApplicationProfile applicationProfile) {
this.applicationProfile = applicationProfile;
}

@SuppressWarnings("unchecked")
@Override
public <T extends IScreen> T getScreen(Class<T> clazz) {
Class<? extends TPlatformScreen> tClass = getPlatformClasses().stream()
Class<?> tClass = getPlatformClasses().stream()
.filter(clazz::isAssignableFrom)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
String.format("Implementation for Screen %s was not found in package %s",
clazz.getName(), getPackageWithScreens())));

try {
return (T) tClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException("Something went wrong during screen casting", e);
}
}

private Set<Class<? extends TPlatformScreen>> getPlatformClasses() {
private Set<Class<?>> getPlatformClasses() {
Reflections reflections = new Reflections(getPackageWithScreens());
try {
return reflections.getSubTypesOf(getPlatformClass());
return reflections.getTypesAnnotatedWith(ScreenType.class).stream()
.filter(clazz -> clazz.getAnnotation(ScreenType.class).platform() == applicationProfile.getPlatformName())
.collect(Collectors.toSet());
} catch (ReflectionsException e) {
throw new IllegalArgumentException(String.format("Could not find package \"%s\" with Screens. " +
"Please specify value \"screensLocation\" in settings file.", getPackageWithScreens()), e);
Expand All @@ -41,6 +50,4 @@ private Set<Class<? extends TPlatformScreen>> getPlatformClasses() {
private String getPackageWithScreens() {
return AqualityServices.get(IApplicationProfile.class).getScreensLocation();
}

protected abstract Class<TPlatformScreen> getPlatformClass();
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package aquality.appium.mobile.screens.screenfactory;

import aquality.appium.mobile.application.PlatformName;

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

/**
* Attribute that identifies platform of screen.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ScreenType {

/**
* Name of platform that screen relates to.
*/
PlatformName platform();
}
18 changes: 9 additions & 9 deletions src/test/java/integration/ScreenFactoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import aquality.appium.mobile.application.AqualityServices;
import aquality.appium.mobile.application.MobileModule;
import aquality.appium.mobile.screens.AndroidScreen;
import aquality.appium.mobile.screens.IOSScreen;
import integration.screens.IFakeLoginScreen;
import integration.screens.ILoginScreen;
import integration.screens.AndroidLoginScreen;
import integration.screens.FakeLoginScreen;
import integration.screens.IOSLoginScreen;
import integration.screens.LoginScreen;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
Expand All @@ -17,34 +17,34 @@ public class ScreenFactoryTest {

@Test
public void shouldBePossibleToGetScreenViaFactory() {
Assert.assertNotNull(AqualityServices.getScreenFactory().getScreen(ILoginScreen.class));
Assert.assertNotNull(AqualityServices.getScreenFactory().getScreen(LoginScreen.class));
}

@Test
public void shouldBePossibleToGetAndroidScreenViaFactory() {
System.setProperty(PLATFORM_NAME_VARIABLE_NAME, "android");
AqualityServices.initInjector(new MobileModule(AqualityServices::getApplication));
Assert.assertTrue(AqualityServices.getScreenFactory().getScreen(ILoginScreen.class) instanceof AndroidScreen);
Assert.assertTrue(AqualityServices.getScreenFactory().getScreen(LoginScreen.class) instanceof AndroidLoginScreen);
}

@Test
public void shouldBePossibleToGetIOSScreenViaFactory() {
System.setProperty(PLATFORM_NAME_VARIABLE_NAME, "ios");
AqualityServices.initInjector(new MobileModule(AqualityServices::getApplication));
Assert.assertTrue(AqualityServices.getScreenFactory().getScreen(ILoginScreen.class) instanceof IOSScreen);
Assert.assertTrue(AqualityServices.getScreenFactory().getScreen(LoginScreen.class) instanceof IOSLoginScreen);
}

@Test
public void shouldThrowIllegalArgumentExceptionOnNotImplementedScreenInterface() {
Assert.assertThrows(IllegalArgumentException.class, () -> AqualityServices.getScreenFactory().getScreen(IFakeLoginScreen.class));
Assert.assertThrows(IllegalArgumentException.class, () -> AqualityServices.getScreenFactory().getScreen(FakeLoginScreen.class));
}

@Test
public void shouldThrowIllegalArgumentExceptionOnNotValidScreensLocationValue()
{
System.setProperty(SCREENS_LOCATION_VARIABLE_NAME, "fake.package");
AqualityServices.initInjector(new MobileModule(AqualityServices::getApplication));
Assert.assertThrows(IllegalArgumentException.class, () -> AqualityServices.getScreenFactory().getScreen(ILoginScreen.class));
Assert.assertThrows(IllegalArgumentException.class, () -> AqualityServices.getScreenFactory().getScreen(LoginScreen.class));
}

@AfterClass
Expand Down
6 changes: 4 additions & 2 deletions src/test/java/integration/screens/AndroidLoginScreen.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package integration.screens;

import aquality.appium.mobile.screens.AndroidScreen;
import aquality.appium.mobile.application.PlatformName;
import aquality.appium.mobile.screens.screenfactory.ScreenType;
import org.openqa.selenium.By;

public class AndroidLoginScreen extends AndroidScreen implements ILoginScreen {
@ScreenType(platform = PlatformName.ANDROID)
public class AndroidLoginScreen extends LoginScreen {

/**
* Constructor with parameters
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/integration/screens/FakeLoginScreen.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package integration.screens;

import aquality.appium.mobile.screens.Screen;
import org.openqa.selenium.By;

public abstract class FakeLoginScreen extends Screen {

protected FakeLoginScreen(By locator, String name) {
super(locator, name);
}
}
Loading

0 comments on commit ab8d4a2

Please sign in to comment.