diff --git a/.github/workflows/test-with-allure-report.yml b/.github/workflows/test-with-allure-report.yml index f8f6c83..e47c31d 100644 --- a/.github/workflows/test-with-allure-report.yml +++ b/.github/workflows/test-with-allure-report.yml @@ -6,6 +6,7 @@ on: paths: - 'aquality-appium-mobile-template/**' - 'aquality-appium-mobile-template-cucumber/**' + - 'aquality-appium-mobile-template-testng/**' - 'scripts/**' push: branches: [ master ] @@ -23,6 +24,8 @@ on: jobs: build-and-test-android: env: + CUCUMBER_ALLURE_RESULTS: aquality-appium-mobile-template-cucumber/target/allure-results + TESTNG_ALLURE_RESULTS: aquality-appium-mobile-template-testng/target/allure-results SUBPROJECT_NAME: aquality-appium-mobile-template-cucumber ENVIRONMENT: ${{ github.event.inputs.environment == '' && 'stage' || github.event.inputs.environment }} ANDROID_PROFILE: Nexus 6 @@ -32,7 +35,7 @@ jobs: concurrency: test-android-${{ github.event.inputs.environment == '' && 'stage' || github.event.inputs.environment }} name: Run tests against Android - runs-on: macos-latest + runs-on: macos-12 outputs: maven_tests: ${{ steps.maven_tests.outcome }} steps: @@ -60,6 +63,10 @@ jobs: profile: ${{ env.ANDROID_PROFILE }} script: mvn test -DisRemote=true -DplatformName=android + - name: Copy TestNG allure result to the Cucumber allure result + if: always() + run: cp -r ${{ env.TESTNG_ALLURE_RESULTS }}/. ${{ env.CUCUMBER_ALLURE_RESULTS }} + - name: Upload results as artifacts if: always() uses: actions/upload-artifact@master @@ -69,13 +76,15 @@ jobs: build-and-test-ios: env: + CUCUMBER_ALLURE_RESULTS: aquality-appium-mobile-template-cucumber/target/allure-results + TESTNG_ALLURE_RESULTS: aquality-appium-mobile-template-testng/target/allure-results SUBPROJECT_NAME: aquality-appium-mobile-template-cucumber ENVIRONMENT: ${{ github.event.inputs.environment == '' && 'stage' || github.event.inputs.environment }} IOS_SIM_MODEL: iPhone 8 concurrency: test-ios-${{ github.event.inputs.environment == '' && 'stage' || github.event.inputs.environment }} name: Run tests against iOS - runs-on: macos-latest + runs-on: macos-12 outputs: maven_tests: ${{ steps.maven_tests.outcome }} steps: @@ -109,6 +118,10 @@ jobs: id: maven_tests run: mvn test -DisRemote=true -DplatformName=ios + - name: Copy TestNG allure result to the Cucumber allure result + if: always() + run: cp -r ${{ env.TESTNG_ALLURE_RESULTS }}/. ${{ env.CUCUMBER_ALLURE_RESULTS }} + - name: Upload results as artifacts if: always() uses: actions/upload-artifact@master diff --git a/aquality-appium-mobile-template-cucumber/pom.xml b/aquality-appium-mobile-template-cucumber/pom.xml index 1d0236b..d897103 100644 --- a/aquality-appium-mobile-template-cucumber/pom.xml +++ b/aquality-appium-mobile-template-cucumber/pom.xml @@ -33,6 +33,10 @@ com.google.guava guava + + com.google.inject + guice + @@ -45,6 +49,10 @@ com.google.guava guava + + com.google.inject + guice + @@ -63,7 +71,7 @@ io.qameta.allure allure-cucumber5-jvm - 2.13.3 + ${allure.version} \ No newline at end of file diff --git a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/features/Demo.feature b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/features/Demo.feature index 262d1f6..a365b24 100644 --- a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/features/Demo.feature +++ b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/features/Demo.feature @@ -1,6 +1,4 @@ Feature: Demo - Background: - Given Allure test name has been updated by the platform parameter @demo Scenario: I try to login with invalid credentials diff --git a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/hooks/ApplicationHooks.java b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/hooks/ApplicationHooks.java index 7c1ad7b..e5db681 100644 --- a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/hooks/ApplicationHooks.java +++ b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/hooks/ApplicationHooks.java @@ -3,12 +3,15 @@ import aquality.appium.mobile.application.AqualityServices; import io.cucumber.java.After; +import static aquality.appium.mobile.application.AqualityServices.getApplication; + public class ApplicationHooks { @After(order = 0) public void closeApplication() { if (AqualityServices.isApplicationStarted()) { - AqualityServices.getApplication().quit(); + getApplication().terminate(); + getApplication().quit(); } } } diff --git a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/CustomMobileModule.java b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/CustomMobileModule.java deleted file mode 100644 index 6ed3cd3..0000000 --- a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/CustomMobileModule.java +++ /dev/null @@ -1,18 +0,0 @@ -package aquality.appium.mobile.template.cucumber.objectfactory; - -import aquality.appium.mobile.application.Application; -import aquality.appium.mobile.application.MobileModule; -import aquality.appium.mobile.template.cucumber.utilities.AllureBasedLocalizedLogger; -import aquality.selenium.core.localization.ILocalizedLogger; -import com.google.inject.Provider; - -public class CustomMobileModule extends MobileModule { - public CustomMobileModule(Provider applicationProvider) { - super(applicationProvider); - } - - @Override - public Class getLocalizedLoggerImplementation() { - return AllureBasedLocalizedLogger.class; - } -} diff --git a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/CustomObjectFactory.java b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/CustomObjectFactory.java index 5c91d18..5f26c70 100644 --- a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/CustomObjectFactory.java +++ b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/CustomObjectFactory.java @@ -1,6 +1,8 @@ package aquality.appium.mobile.template.cucumber.objectfactory; import aquality.appium.mobile.application.AqualityServices; +import aquality.appium.mobile.template.modules.CustomMobileModule; +import aquality.appium.mobile.template.modules.ServiceModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Stage; @@ -13,7 +15,7 @@ public class CustomObjectFactory implements ObjectFactory { private final Injector injector; public CustomObjectFactory() { - CustomMobileModule mobileModule = new CustomMobileModule(AqualityServices::getApplication); + CustomMobileModule mobileModule = new CustomMobileModule(); AqualityServices.initInjector(mobileModule); this.injector = Guice.createInjector(Stage.PRODUCTION, CucumberModules.createScenarioModule(), new ServiceModule(), mobileModule); diff --git a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/stepdefinitions/AlertSteps.java b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/stepdefinitions/AlertSteps.java new file mode 100644 index 0000000..75aac3c --- /dev/null +++ b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/stepdefinitions/AlertSteps.java @@ -0,0 +1,32 @@ +package aquality.appium.mobile.template.cucumber.stepdefinitions; + +import aquality.appium.mobile.screens.screenfactory.IScreenFactory; +import aquality.appium.mobile.template.screens.Alert; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; + +import javax.inject.Inject; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +public class AlertSteps { + + private final Alert alert; + + @Inject + public AlertSteps(IScreenFactory screenFactory) { + alert = screenFactory.getScreen(Alert.class); + } + + @Then("'{}' alert appears") + public void alertAppears(String alertMessage) { + assertTrue(alert.state().waitForDisplayed(), "Alert appeared"); + assertEquals(alert.getMessage(), alertMessage, "Alert message is correct"); + } + + @When("I accept the alert") + public void acceptAlert() { + alert.tapOk(); + } +} diff --git a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/stepdefinitions/CommonSteps.java b/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/stepdefinitions/CommonSteps.java deleted file mode 100644 index 721253e..0000000 --- a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/stepdefinitions/CommonSteps.java +++ /dev/null @@ -1,51 +0,0 @@ -package aquality.appium.mobile.template.cucumber.stepdefinitions; - -import aquality.appium.mobile.application.AqualityServices; -import aquality.appium.mobile.screens.screenfactory.IScreenFactory; -import aquality.appium.mobile.template.screens.Alert; -import io.cucumber.java.en.Given; -import io.cucumber.java.en.Then; -import io.cucumber.java.en.When; -import io.qameta.allure.Allure; -import io.qameta.allure.model.Parameter; - -import javax.inject.Inject; -import java.util.List; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; - -public class CommonSteps { - - private final Alert alert; - - @Inject - public CommonSteps(IScreenFactory screenFactory) { - alert = screenFactory.getScreen(Alert.class); - } - - @Given("Allure test name has been updated by the platform parameter") - public void updateAllureTestName() { - Allure.getLifecycle().updateTestCase(testResult -> { - List oldParameters = testResult.getParameters(); - Parameter parameter = new Parameter(); - parameter.setName("platform"); - parameter.setValue(AqualityServices.getApplicationProfile().getPlatformName().toString()); - oldParameters.add(parameter); - testResult.setHistoryId(testResult.getHistoryId() + parameter.getValue()); - String oldName = testResult.getFullName(); - testResult.setFullName(String.format("%s: %s", oldName, parameter.getValue())); - }); - } - - @Then("'{}' alert appears") - public void alertAppears(String alertMessage) { - assertTrue(alert.state().waitForDisplayed(), "Alert appeared"); - assertEquals(alert.getMessage(), alertMessage, "Alert message is correct"); - } - - @When("I accept the alert") - public void acceptAlert() { - alert.tapOk(); - } -} diff --git a/aquality-appium-mobile-template-testng/pom.xml b/aquality-appium-mobile-template-testng/pom.xml new file mode 100644 index 0000000..c4ee58d --- /dev/null +++ b/aquality-appium-mobile-template-testng/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + com.github.aquality-automation + aquality-appium-mobile-java-template-project + 1.0.1-SNAPSHOT + + + aquality-appium-mobile-template-testng + + + 11 + 11 + UTF-8 + + + + + com.github.aquality-automation + aquality-appium-mobile-template + 1.0.1-SNAPSHOT + test + + + org.testng + testng + 7.9.0 + test + + + org.slf4j + slf4j-api + + + + + io.qameta.allure + allure-testng + ${allure.version} + test + + + org.assertj + assertj-core + 3.25.3 + test + + + org.slf4j + slf4j-simple + 2.0.10 + test + + + \ No newline at end of file diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/constants/AlertMessages.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/constants/AlertMessages.java new file mode 100644 index 0000000..2729529 --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/constants/AlertMessages.java @@ -0,0 +1,8 @@ +package aquality.appium.mobile.template.testng.constants; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class AlertMessages { + public static final String INVALID_CREDENTIALS = "Invalid login credentials, please try again"; +} diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/constants/ViewNames.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/constants/ViewNames.java new file mode 100644 index 0000000..124daa2 --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/constants/ViewNames.java @@ -0,0 +1,8 @@ +package aquality.appium.mobile.template.testng.constants; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class ViewNames { + public static final String LOGIN_SCREEN = "Login Screen"; +} diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/AlertSteps.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/AlertSteps.java new file mode 100644 index 0000000..764213f --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/AlertSteps.java @@ -0,0 +1,26 @@ +package aquality.appium.mobile.template.testng.steps; + +import aquality.appium.mobile.template.screens.Alert; +import io.qameta.allure.Step; + +import javax.inject.Inject; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +public class AlertSteps { + + @Inject + private Alert alert; + + @Step("'{alertMessage}' alert appears") + public void checkAlertAppears(String alertMessage) { + assertTrue(alert.state().waitForDisplayed(), "Alert appeared"); + assertEquals(alert.getMessage(), alertMessage, "Alert message is correct"); + } + + @Step("I accept the alert") + public void acceptAlert() { + alert.tapOk(); + } +} diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/ChooseViewSteps.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/ChooseViewSteps.java new file mode 100644 index 0000000..cc080c7 --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/ChooseViewSteps.java @@ -0,0 +1,17 @@ +package aquality.appium.mobile.template.testng.steps; + +import aquality.appium.mobile.template.screens.chooseview.ChooseViewScreen; +import io.qameta.allure.Step; + +import javax.inject.Inject; + +public class ChooseViewSteps { + + @Inject + private ChooseViewScreen chooseViewScreen; + + @Step("I open '{viewName}' view") + public void openView(String viewName) { + chooseViewScreen.openView(viewName); + } +} diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/LoginSteps.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/LoginSteps.java new file mode 100644 index 0000000..2ba0af1 --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/steps/LoginSteps.java @@ -0,0 +1,37 @@ +package aquality.appium.mobile.template.testng.steps; + +import aquality.appium.mobile.template.models.LoginModel; +import aquality.appium.mobile.template.screens.login.LoginScreen; +import io.qameta.allure.Step; + +import javax.inject.Inject; + +import static org.testng.Assert.assertTrue; + +public class LoginSteps { + + @Inject + private LoginScreen loginScreen; + + @Step("I log in with data:") + public void fillInLoginForm(LoginModel loginModel) { + loginScreen.setUsername(loginModel.getUsername()) + .setPassword(loginModel.getPassword()) + .tapLogin(); + } + + @Step("Login Screen is opened") + public void checkLoginScreenIsOpened() { + assertTrue(loginScreen.state().waitForDisplayed(), "Login Screen is opened"); + } + + @Step("I save Login Screen dump") + public void saveLoginScreenDump() { + loginScreen.dump().save(); + } + + @Step("Login Screen dump is different") + public void checkLoginScreenDumpIsDifferent() { + assertTrue(loginScreen.dump().compare() > 0, "The form dump should differ"); + } +} diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/tests/BaseTest.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/tests/BaseTest.java new file mode 100644 index 0000000..7668e3c --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/tests/BaseTest.java @@ -0,0 +1,56 @@ +package aquality.appium.mobile.template.testng.tests; + +import aquality.appium.mobile.application.AqualityServices; +import aquality.appium.mobile.application.IMobileApplication; +import aquality.appium.mobile.template.modules.CustomMobileModule; +import aquality.appium.mobile.template.testng.utilities.ModuleFactory; +import aquality.appium.mobile.template.utilities.IScreenshotProvider; +import aquality.selenium.core.localization.ILocalizedLogger; +import com.google.inject.Inject; +import io.qameta.allure.Allure; +import org.assertj.core.api.Assertions; +import org.assertj.core.description.Description; +import org.testng.ITestContext; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Guice; + +import java.io.ByteArrayInputStream; +import java.util.function.Consumer; + +@Guice(moduleFactory = ModuleFactory.class) +public class BaseTest { + @Inject + IScreenshotProvider screenshotProvider; + @Inject + ILocalizedLogger localizedLogger; + @Inject + CustomMobileModule customBrowserModule; + + private IMobileApplication application; + + @BeforeTest + public void beforeTest() { + Consumer descriptionConsumer = description -> localizedLogger.info("Assertion: %s", description.value()); + Assertions.setDescriptionConsumer(descriptionConsumer); + } + + @BeforeMethod + public void setup() { + AqualityServices.initInjector(customBrowserModule); + application = AqualityServices.getApplication(); + } + + @AfterMethod + public void cleanUp(ITestContext context) { + if (AqualityServices.isApplicationStarted()) { + Allure.addAttachment("page source", "text/html", + application.getDriver().getPageSource(), "html"); + Allure.addAttachment("screenshot", "image/png", + new ByteArrayInputStream(screenshotProvider.takeScreenshot()), "png"); + application.terminate(); + application.quit(); + } + } +} diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/tests/LoginTest.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/tests/LoginTest.java new file mode 100644 index 0000000..cd32495 --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/tests/LoginTest.java @@ -0,0 +1,33 @@ +package aquality.appium.mobile.template.testng.tests; + +import aquality.appium.mobile.template.models.LoginModel; +import aquality.appium.mobile.template.testng.constants.AlertMessages; +import aquality.appium.mobile.template.testng.constants.ViewNames; +import aquality.appium.mobile.template.testng.steps.AlertSteps; +import aquality.appium.mobile.template.testng.steps.ChooseViewSteps; +import aquality.appium.mobile.template.testng.steps.LoginSteps; +import aquality.appium.mobile.template.testng.utilities.JsonDataProvider; +import org.testng.annotations.Test; + +import javax.inject.Inject; + +public class LoginTest extends BaseTest { + @Inject + AlertSteps alertSteps; + @Inject + LoginSteps loginSteps; + @Inject + ChooseViewSteps chooseViewSteps; + + @Test(description = "Login with invalid credentials is impossible", + dataProvider = "getLoginData", dataProviderClass = JsonDataProvider.class) + public void testLoginWithInvalidCredentials(LoginModel loginModel) { + chooseViewSteps.openView(ViewNames.LOGIN_SCREEN); + loginSteps.checkLoginScreenIsOpened(); + loginSteps.saveLoginScreenDump(); + loginSteps.fillInLoginForm(loginModel); + alertSteps.checkAlertAppears(AlertMessages.INVALID_CREDENTIALS); + alertSteps.acceptAlert(); + loginSteps.checkLoginScreenDumpIsDifferent(); + } +} diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/utilities/JsonDataProvider.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/utilities/JsonDataProvider.java new file mode 100644 index 0000000..a2efeca --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/utilities/JsonDataProvider.java @@ -0,0 +1,36 @@ +package aquality.appium.mobile.template.testng.utilities; + +import aquality.appium.mobile.application.AqualityServices; +import aquality.appium.mobile.template.models.LoginModel; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; +import lombok.experimental.UtilityClass; +import org.testng.annotations.DataProvider; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; + +@UtilityClass +public class JsonDataProvider { + private static final ObjectMapper MAPPER = new ObjectMapper(); + + @DataProvider + @SneakyThrows + public Object[][] getLoginData() { + return getDataListFromJson("login", LoginModel[].class); + } + + private Object[][] getDataListFromJson(String filename, Class valueType) throws IOException { + Object[] dataList; + try { + File file = Paths.get(String.format("src/test/resources/data/%s.json", filename)).toFile(); + dataList = MAPPER.readValue(file, valueType); + } + catch (IOException exception) { + AqualityServices.getLogger().debug("IO error occurred while reading the data from the file " + filename, exception); + throw exception; + } + return new Object[][] {dataList}; + } +} diff --git a/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/utilities/ModuleFactory.java b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/utilities/ModuleFactory.java new file mode 100644 index 0000000..7433a93 --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/java/aquality/appium/mobile/template/testng/utilities/ModuleFactory.java @@ -0,0 +1,16 @@ +package aquality.appium.mobile.template.testng.utilities; + +import aquality.appium.mobile.template.modules.CustomMobileModule; +import aquality.appium.mobile.template.modules.ScreensModule; +import aquality.appium.mobile.template.modules.ServiceModule; +import com.google.inject.Module; +import com.google.inject.util.Modules; +import org.testng.IModuleFactory; +import org.testng.ITestContext; + +public class ModuleFactory implements IModuleFactory { + @Override + public Module createModule(ITestContext iTestContext, Class aClass) { + return Modules.combine(new CustomMobileModule(), new ServiceModule(), new ScreensModule()); + } +} diff --git a/aquality-appium-mobile-template-testng/src/test/resources/data/login.json b/aquality-appium-mobile-template-testng/src/test/resources/data/login.json new file mode 100644 index 0000000..3f84227 --- /dev/null +++ b/aquality-appium-mobile-template-testng/src/test/resources/data/login.json @@ -0,0 +1,6 @@ +[ + { + "username": "Username", + "password": "InVal1dPa$$w0rd" + } +] \ No newline at end of file diff --git a/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/CustomMobileModule.java b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/CustomMobileModule.java new file mode 100644 index 0000000..e134936 --- /dev/null +++ b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/CustomMobileModule.java @@ -0,0 +1,17 @@ +package aquality.appium.mobile.template.modules; + +import aquality.appium.mobile.application.AqualityServices; +import aquality.appium.mobile.application.MobileModule; +import aquality.appium.mobile.template.utilities.AllureBasedLocalizedLogger; +import aquality.selenium.core.localization.ILocalizedLogger; + +public class CustomMobileModule extends MobileModule { + public CustomMobileModule() { + super(AqualityServices::getApplication); + } + + @Override + public Class getLocalizedLoggerImplementation() { + return AllureBasedLocalizedLogger.class; + } +} diff --git a/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/ScreensModule.java b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/ScreensModule.java new file mode 100644 index 0000000..bb3c1c3 --- /dev/null +++ b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/ScreensModule.java @@ -0,0 +1,18 @@ +package aquality.appium.mobile.template.modules; + +import aquality.appium.mobile.application.AqualityServices; +import aquality.appium.mobile.screens.screenfactory.IScreenFactory; +import aquality.appium.mobile.template.screens.Alert; +import aquality.appium.mobile.template.screens.chooseview.ChooseViewScreen; +import aquality.appium.mobile.template.screens.login.LoginScreen; +import com.google.inject.AbstractModule; + +public class ScreensModule extends AbstractModule { + private static final IScreenFactory screenFactory = AqualityServices.getScreenFactory(); + @Override + protected void configure() { + bind(Alert.class).toInstance(screenFactory.getScreen(Alert.class)); + bind(ChooseViewScreen.class).toInstance(screenFactory.getScreen(ChooseViewScreen.class)); + bind(LoginScreen.class).toInstance(screenFactory.getScreen(LoginScreen.class)); + } +} diff --git a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/ServiceModule.java b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/ServiceModule.java similarity index 73% rename from aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/ServiceModule.java rename to aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/ServiceModule.java index 02ebed0..b7fdef5 100644 --- a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/objectfactory/ServiceModule.java +++ b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/modules/ServiceModule.java @@ -1,10 +1,10 @@ -package aquality.appium.mobile.template.cucumber.objectfactory; +package aquality.appium.mobile.template.modules; import aquality.appium.mobile.template.utilities.IScreenshotProvider; import aquality.appium.mobile.template.utilities.ScreenshotProvider; import com.google.inject.AbstractModule; -final class ServiceModule extends AbstractModule { +public final class ServiceModule extends AbstractModule { @Override protected void configure() { diff --git a/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/screens/chooseview/AndroidChooseViewScreen.java b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/screens/chooseview/AndroidChooseViewScreen.java index ce2514d..b90b44b 100644 --- a/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/screens/chooseview/AndroidChooseViewScreen.java +++ b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/screens/chooseview/AndroidChooseViewScreen.java @@ -1,14 +1,26 @@ package aquality.appium.mobile.template.screens.chooseview; import aquality.appium.mobile.application.PlatformName; +import aquality.appium.mobile.elements.interfaces.IButton; import aquality.appium.mobile.screens.screenfactory.ScreenType; +import org.openqa.selenium.By; import static org.openqa.selenium.By.xpath; @ScreenType(platform = PlatformName.ANDROID) public class AndroidChooseViewScreen extends ChooseViewScreen { + private final IButton waitBtn = getElementFactory().getButton(By.id("android:id/aerr_wait"), "Wait"); public AndroidChooseViewScreen() { super(xpath("//android.widget.TextView[@text='Choose An Awesome View']")); } + + @Override + public void openView(String viewName) { + if (!getChooseViewLabel(viewName).state().waitForDisplayed() && waitBtn.state().isDisplayed()) { + waitBtn.click(); + waitBtn.state().waitForNotDisplayed(); + } + super.openView(viewName); + } } diff --git a/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/screens/chooseview/ChooseViewScreen.java b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/screens/chooseview/ChooseViewScreen.java index e67bf1c..b83774f 100644 --- a/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/screens/chooseview/ChooseViewScreen.java +++ b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/screens/chooseview/ChooseViewScreen.java @@ -1,5 +1,6 @@ package aquality.appium.mobile.template.screens.chooseview; +import aquality.appium.mobile.elements.interfaces.ILabel; import aquality.appium.mobile.screens.Screen; import org.openqa.selenium.By; @@ -13,6 +14,10 @@ protected ChooseViewScreen(By locator) { } public void openView(final String viewName) { - getElementFactory().getLabel(accessibilityId(viewName), format("Choose %s view", viewName)).click(); + getChooseViewLabel(viewName).click(); + } + + protected ILabel getChooseViewLabel(final String viewName) { + return getElementFactory().getLabel(accessibilityId(viewName), format("Choose %s view", viewName)); } } diff --git a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/utilities/AllureBasedLocalizedLogger.java b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/utilities/AllureBasedLocalizedLogger.java similarity index 96% rename from aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/utilities/AllureBasedLocalizedLogger.java rename to aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/utilities/AllureBasedLocalizedLogger.java index 0ddc51c..f7e5426 100644 --- a/aquality-appium-mobile-template-cucumber/src/test/java/aquality/appium/mobile/template/cucumber/utilities/AllureBasedLocalizedLogger.java +++ b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/utilities/AllureBasedLocalizedLogger.java @@ -1,4 +1,4 @@ -package aquality.appium.mobile.template.cucumber.utilities; +package aquality.appium.mobile.template.utilities; import aquality.selenium.core.configurations.ILoggerConfiguration; import aquality.selenium.core.localization.ILocalizationManager; diff --git a/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/utilities/AllureListener.java b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/utilities/AllureListener.java new file mode 100644 index 0000000..7ad56c0 --- /dev/null +++ b/aquality-appium-mobile-template/src/main/java/aquality/appium/mobile/template/utilities/AllureListener.java @@ -0,0 +1,22 @@ +package aquality.appium.mobile.template.utilities; + +import aquality.appium.mobile.application.AqualityServices; +import io.qameta.allure.listener.TestLifecycleListener; +import io.qameta.allure.model.Parameter; +import io.qameta.allure.model.TestResult; + +import java.util.List; + +public class AllureListener implements TestLifecycleListener { + + public void afterTestStart(TestResult result) { + List oldParameters = result.getParameters(); + Parameter parameter = new Parameter(); + parameter.setName("platform"); + parameter.setValue(AqualityServices.getApplicationProfile().getPlatformName().toString()); + oldParameters.add(parameter); + result.setHistoryId(result.getHistoryId() + parameter.getValue()); + String oldName = result.getFullName(); + result.setFullName(String.format("%s: %s", oldName, parameter.getValue())); + } +} diff --git a/aquality-appium-mobile-template/src/main/resources/META-INF/services/io.qameta.allure.listener.TestLifecycleListener b/aquality-appium-mobile-template/src/main/resources/META-INF/services/io.qameta.allure.listener.TestLifecycleListener new file mode 100644 index 0000000..581c770 --- /dev/null +++ b/aquality-appium-mobile-template/src/main/resources/META-INF/services/io.qameta.allure.listener.TestLifecycleListener @@ -0,0 +1 @@ +aquality.appium.mobile.template.utilities.AllureListener \ No newline at end of file diff --git a/aquality-appium-mobile-template-cucumber/src/test/resources/applications/TheApp-v1.10.0.apk b/aquality-appium-mobile-template/src/main/resources/applications/TheApp-v1.10.0.apk similarity index 100% rename from aquality-appium-mobile-template-cucumber/src/test/resources/applications/TheApp-v1.10.0.apk rename to aquality-appium-mobile-template/src/main/resources/applications/TheApp-v1.10.0.apk diff --git a/aquality-appium-mobile-template-cucumber/src/test/resources/applications/TheApp-v1.10.0.app.zip b/aquality-appium-mobile-template/src/main/resources/applications/TheApp-v1.10.0.app.zip similarity index 100% rename from aquality-appium-mobile-template-cucumber/src/test/resources/applications/TheApp-v1.10.0.app.zip rename to aquality-appium-mobile-template/src/main/resources/applications/TheApp-v1.10.0.app.zip diff --git a/aquality-appium-mobile-template/src/main/resources/settings.json b/aquality-appium-mobile-template/src/main/resources/settings.json index 74a0ba6..8d581f4 100644 --- a/aquality-appium-mobile-template/src/main/resources/settings.json +++ b/aquality-appium-mobile-template/src/main/resources/settings.json @@ -7,20 +7,20 @@ "driverSettings": { "android": { "deviceKey": "Android_Emulator", - "applicationPath": "./src/test/resources/applications/TheApp-v1.10.0.apk", + "applicationPath": "../aquality-appium-mobile-template/src/main/resources/applications/TheApp-v1.10.0.apk", "capabilities": { "platformName": "Android", "automationName": "UiAutomator2", "appPackage": "io.cloudgrey.the_app", "appActivity": "io.cloudgrey.the_app.MainActivity", - "adbExecTimeout": 60000, - "androidInstallTimeout": 120000, - "uiautomator2ServerInstallTimeout": 120000 + "adbExecTimeout": 90000, + "androidInstallTimeout": 150000, + "uiautomator2ServerInstallTimeout": 150000 } }, "ios": { "deviceKey": "iOS_Simulator", - "applicationPath": "./src/test/resources/applications/TheApp-v1.10.0.app.zip", + "applicationPath": "../aquality-appium-mobile-template/src/main/resources/applications/TheApp-v1.10.0.app.zip", "capabilities": { "platformName": "iOS", "automationName": "XCUITest", @@ -48,7 +48,7 @@ "timeoutCommand":180 }, "retry": { - "number": 2, + "number": 3, "pollingInterval": 300 }, "logger": { diff --git a/pom.xml b/pom.xml index 5e2fe6f..02a3661 100644 --- a/pom.xml +++ b/pom.xml @@ -20,17 +20,19 @@ aquality-appium-mobile-template aquality-appium-mobile-template-cucumber + aquality-appium-mobile-template-testng - 1.8.10 + 1.9.7 + 2.19.0 com.github.aquality-automation aquality-appium-mobile - 5.0.0 + 5.1.0 org.projectlombok @@ -38,6 +40,11 @@ 1.18.30 provided + + io.qameta.allure + allure-java-commons + ${allure.version} +