From 51c57a5a63a76a017a73e982413e1f804dd37f22 Mon Sep 17 00:00:00 2001 From: neiger Date: Wed, 19 Jul 2023 11:49:03 -0600 Subject: [PATCH] added appium scripts for storage --- testAppium/FWStorageApp/README.md | 56 +++ testAppium/FWStorageApp/pom.xml | 68 +++ .../src/main/java/general/BaseScreen.java | 387 ++++++++++++++++++ .../src/main/java/general/ErrorsManager.java | 60 +++ .../java/general/MobileDriverManager.java | 112 +++++ .../src/main/java/general/TestUtilities.java | 85 ++++ .../FWStorageApp/src/test/configStorage.xml | 81 ++++ .../screens/FileUploadExplorerScreen.java | 54 +++ .../screens/StorageSampleLoggedScreen.java | 250 +++++++++++ .../screens/StorageSampleLoginScreen.java | 128 ++++++ .../java/screens/WebViewBrowserScreen.java | 94 +++++ .../tests/FileUploadExplorerScreenTests.java | 50 +++ .../test/java/tests/LogOutScreenTests.java | 48 +++ .../tests/StorageSampleLoggedScreenTests.java | 65 +++ .../tests/StorageSampleLoginScreenTests.java | 76 ++++ 15 files changed, 1614 insertions(+) create mode 100644 testAppium/FWStorageApp/README.md create mode 100644 testAppium/FWStorageApp/pom.xml create mode 100644 testAppium/FWStorageApp/src/main/java/general/BaseScreen.java create mode 100644 testAppium/FWStorageApp/src/main/java/general/ErrorsManager.java create mode 100644 testAppium/FWStorageApp/src/main/java/general/MobileDriverManager.java create mode 100644 testAppium/FWStorageApp/src/main/java/general/TestUtilities.java create mode 100644 testAppium/FWStorageApp/src/test/configStorage.xml create mode 100644 testAppium/FWStorageApp/src/test/java/screens/FileUploadExplorerScreen.java create mode 100644 testAppium/FWStorageApp/src/test/java/screens/StorageSampleLoggedScreen.java create mode 100644 testAppium/FWStorageApp/src/test/java/screens/StorageSampleLoginScreen.java create mode 100644 testAppium/FWStorageApp/src/test/java/screens/WebViewBrowserScreen.java create mode 100644 testAppium/FWStorageApp/src/test/java/tests/FileUploadExplorerScreenTests.java create mode 100644 testAppium/FWStorageApp/src/test/java/tests/LogOutScreenTests.java create mode 100644 testAppium/FWStorageApp/src/test/java/tests/StorageSampleLoggedScreenTests.java create mode 100644 testAppium/FWStorageApp/src/test/java/tests/StorageSampleLoginScreenTests.java diff --git a/testAppium/FWStorageApp/README.md b/testAppium/FWStorageApp/README.md new file mode 100644 index 0000000..14f2584 --- /dev/null +++ b/testAppium/FWStorageApp/README.md @@ -0,0 +1,56 @@ +# ANDROID AUTOMATION WITH APPIUM + +## Getting started + +This guide will show how to use the automation scripts written in Java using Appium. +The basics configuration needed as well as common tools that need to be modified in +order to do a proper setup. + +### ==================================================== + +#### SETUP REQUIREMENTS +Appium server installation v1: + +FOR MACOS + +_**NOTE**: Homebrew must be set previously. If is not, follow this link for instructions: +[Homebrew Setup](https://docs.brew.sh/Installation)_ +* brew install node +* npm install -g appium +* npm install wd +* appium & + +The needed dependencies are located in the ```pom.xml``` file. +To take in consideration: +1. TestNG v7.5 still works with Java v8, newer versions require Java v11 or above. +2. Selenium v4.8.1 still works with Java v8. Newer version are backward compatible. +3. For more info check this link [Java Client migration from 7 to 8](https://github.com/appium/java-client/blob/master/docs/v7-to-v8-migration-guide.md). +4. This works with IntelliJ IDE as default. If another is used like Eclipse or VSCode, an effort research is required. + +#### HOW TO EXECUTE THE CODE? + +* Launch IntelliJ IDE +* Open the project +* Look for ```pom.xml``` file, right click then click "Reload project" +* Once is finished, look in "test>java>configMaps.xml" file +* Modify the section `````` with your devices + ``` + + + ``` +* Save the file +* Right click then click "Run '.../src/test/'configMaps.xml'" + + +#### ADDITIONAL NOTES + +Keep in mind that this is for macOS supported configuration. If you are on windows, +the easiest way is to execute Appium GUI app. + + +#### HELPFUL LINKS +* http://appium.io/docs/en/2.0/ +* https://github.com/appium +* https://www.browserstack.com/guide/download-and-install-appium +* https://testng.org/doc/documentation-main.html +* https://www.selenium.dev/ \ No newline at end of file diff --git a/testAppium/FWStorageApp/pom.xml b/testAppium/FWStorageApp/pom.xml new file mode 100644 index 0000000..564ada1 --- /dev/null +++ b/testAppium/FWStorageApp/pom.xml @@ -0,0 +1,68 @@ + + + + + + 4.0.0 + + com.qaautomation.appiumframeworktests + AppiumFrameworkTests + 1.0-SNAPSHOT + + + + + + io.appium + java-client + 8.3.0 + + + org.testng + testng + 7.7.1 + + + org.seleniumhq.selenium + selenium-java + 4.8.1 + + + org.apache.commons + commons-io + 1.3.2 + + + + + org.slf4j + slf4j-simple + 2.0.7 + test + + + + + + + 8 + 8 + + + \ No newline at end of file diff --git a/testAppium/FWStorageApp/src/main/java/general/BaseScreen.java b/testAppium/FWStorageApp/src/main/java/general/BaseScreen.java new file mode 100644 index 0000000..4f17880 --- /dev/null +++ b/testAppium/FWStorageApp/src/main/java/general/BaseScreen.java @@ -0,0 +1,387 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package general; + +import java.time.Duration; +import java.util.Arrays; +import java.util.Collections; +import java.util.concurrent.TimeUnit; + +import io.appium.java_client.AppiumFluentWait; +import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.android.nativekey.AndroidKey; +import io.appium.java_client.android.nativekey.KeyEvent; +import org.openqa.selenium.*; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.interactions.Pause; +import org.openqa.selenium.interactions.PointerInput; +import org.openqa.selenium.interactions.Sequence; + + +public abstract class BaseScreen { + + protected AndroidDriver driver; + private final AppiumFluentWait wait; + private final Actions touchAction; + private final int staticTimeOut; + + // CONSTRUCTOR - Receiving web driver as a parameter to save it on a global variable to be used later + public BaseScreen(AndroidDriver driver) { + this.driver = driver; + this.staticTimeOut = MobileDriverManager.getStaticTime(); + int dynamicTimeOut = MobileDriverManager.getDynamicTime(); + this.wait = new AppiumFluentWait<>(driver); + this.wait.withTimeout(Duration.ofSeconds(dynamicTimeOut)); + touchAction = new Actions(this.driver); + } + + /****** GENERIC METHODS ******/ + + public abstract boolean verifyLoads(); + + // method to wait for the visibility of an element + protected boolean waitForMobElementToBeVisible(WebElement element) { + boolean flag; + flag = this.wait.until(arg -> element != null && element.isDisplayed()); + return flag; + } + + protected boolean waitForMobElementToBeTappable(WebElement element) { + boolean flag; + flag = this.wait.until(arg -> element.isEnabled()); + return flag; + } + + // method to wait for an element to be clickable + protected boolean tapMobElement(WebElement element) { + boolean flag; + flag = waitForMobElementToBeVisible(element) && waitForMobElementToBeTappable(element) && + this.wait.until(arg0 -> { + touchAction.click(element).perform(); + return true; + }); + return flag; + } + + // method to tap on element by coordinates + protected boolean tapOnScreenXY(int getX, int getY) { + boolean flag = false; + try { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence tap = new Sequence(finger, 1); + tap.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), getX, getY)); + tap.addAction(finger.createPointerDown(0)); + tap.addAction(finger.createPointerUp(0)); + driver.perform(Collections.singletonList(tap)); + implicityWaitTimeOnScreen(); + flag = true; + }catch (Exception e){ErrorsManager.errNExpManager(e);} + return flag; + } + + // method to enter text on a specific field + protected boolean sendTextOnEmptyMobElement(WebElement element, String txt) { + + boolean validationReturn = false; + + if (waitForMobElementToBeTappable(element)) { + touchAction.click(element).perform(); + element.clear(); + validationReturn = typeTxtOnMobElement(element, txt); + } + return validationReturn; + } + + private boolean typeTxtOnMobElement(WebElement element, String txt) { + element.sendKeys(txt); + return element.isEnabled(); + } + + + // method to verify text on a certain element + protected boolean verifyTextOnMobElement(WebElement element, String text) { + boolean flag; + flag = waitForMobElementToBeVisible(element) && + this.wait.until(arg0 -> { + element.getText().equals(text); + //System.out.println(text); + return true; + }); + return flag; + } + + + protected String getTextFromMobElement(WebElement element) { + String flag = ""; + if (waitForMobElementToBeVisible(element)) + { + flag = element.getText(); + } + return flag; + } + + // halt wait execution via xml config file + protected boolean implicityWaitTimeOnScreen() { + try { + TimeUnit.SECONDS.sleep(this.staticTimeOut); + return true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e); + return false; + } + } + + // halt wait execution set manually by the user + protected boolean implicityWaitTimeOnScreenManual(int secs) { + try { + TimeUnit.SECONDS.sleep(secs); + return true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e); + return false; + } + } + + // generic method to press any android key + protected boolean pressAndroidKey(AndroidKey keyValue) { + boolean flag = false; + if(keyValue != null) { + driver.pressKey(new KeyEvent(keyValue)); + flag = true; + } else { + System.out.println(TestUtilities.basicErrorMsg("There is a problem with the Key pressed")); + } + return flag; + } + + /***** ANDROID GESTURES *****/ + + protected boolean horizontalSwipeOnScreenXY(WebElement element) { + boolean flag = false; + + + int centerY = element.getRect().y + (element.getSize().height/2); + double stStartXcc = element.getRect().x + (element.getSize().width * 0.9); + double stEndXcc = element.getRect().x + (element.getSize().width * 0.1); + + + try { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence swipe = new Sequence(finger,1); + swipe.addAction(finger.createPointerMove(Duration.ofSeconds(0), PointerInput.Origin.viewport(), (int) stStartXcc, centerY)); + swipe.addAction(finger.createPointerDown(0)); + swipe.addAction(finger.createPointerMove(Duration.ofMillis(700), PointerInput.Origin.viewport(), (int) stEndXcc, centerY)); + swipe.addAction(finger.createPointerUp(0)); + + driver.perform(Collections.singletonList(swipe)); + + flag = true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e);} + return flag; + } + + protected boolean verticalSwipeOnScreenXY(WebElement element) { + boolean flag = false; + + int centerX = element.getRect().x + (element.getSize().width/2); + double stStartYcc = element.getRect().y + (element.getSize().height * 0.8); + double stEndYcc = element.getRect().y + (element.getSize().height * 0.1); + + try { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence swipe = new Sequence(finger,1); + swipe.addAction(finger.createPointerMove(Duration.ofSeconds(0), PointerInput.Origin.viewport(), centerX, (int) stStartYcc)); + swipe.addAction(finger.createPointerDown(0)); + swipe.addAction(finger.createPointerMove(Duration.ofMillis(700), PointerInput.Origin.viewport(), centerX, (int) stEndYcc)); + swipe.addAction(finger.createPointerUp(0)); + + driver.perform(Collections.singletonList(swipe)); + + flag = true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e);} + return flag; + } + + protected boolean customUsersSwipeXLoc(WebElement element, int getStartX, int getEndX) { + boolean flag = false; + + int centerY = element.getRect().y + (element.getSize().height/2); + double stStartXcc = getStartX; + double stEndXcc = getEndX; + + try { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence swipe = new Sequence(finger,1); + swipe.addAction(finger.createPointerMove(Duration.ofSeconds(0), PointerInput.Origin.viewport(), (int) stStartXcc, centerY)); + swipe.addAction(finger.createPointerDown(0)); + swipe.addAction(finger.createPointerMove(Duration.ofMillis(700), PointerInput.Origin.viewport(), (int) stEndXcc, centerY)); + swipe.addAction(finger.createPointerUp(0)); + + driver.perform(Collections.singletonList(swipe)); + + flag = true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e);} + + return flag; + } + + protected boolean customUsersSwipeYLoc(WebElement element, int getStartY, int getEndY) { + boolean flag = false; + + int centerX = element.getRect().x + (element.getSize().width/2); + double stStartYcc = getStartY; + double stEndYcc = getEndY; + + try { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence swipe = new Sequence(finger,1); + swipe.addAction(finger.createPointerMove(Duration.ofSeconds(0), PointerInput.Origin.viewport(), centerX, (int) stStartYcc)); + swipe.addAction(finger.createPointerDown(0)); + swipe.addAction(finger.createPointerMove(Duration.ofMillis(700), PointerInput.Origin.viewport(), centerX, (int) stEndYcc)); + swipe.addAction(finger.createPointerUp(0)); + + driver.perform(Collections.singletonList(swipe)); + + flag = true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e);} + + return flag; + } + + + // method to double tap by coordinates + protected boolean doubleTapWithOneFingerOnScreenXY(int getX, int getY) { + boolean flag = false; + try { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence tap = new Sequence(finger, 1); + tap.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), getX, getY)); + tap.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + tap.addAction(new Pause(finger, Duration.ofMillis(50))); // Adding a short delay between taps + tap.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + tap.addAction(new Pause(finger, Duration.ofMillis(50))); // Adding a short delay between taps + tap.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + tap.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + + driver.perform(Collections.singletonList(tap)); + implicityWaitTimeOnScreenManual(1); + System.out.println("ZOOM IN => Double Tap with one finger"); + flag = true; + }catch (Exception e){ErrorsManager.errNExpManager(e);} + return flag; + } + + // method to single tap with two fingers by coordinates + protected boolean singleTapWithTwoFingersOnScreenXY(int getX, int getY) { + boolean flag = false; + try { + PointerInput finger1 = new PointerInput(PointerInput.Kind.TOUCH, "finger1"); + PointerInput finger2 = new PointerInput(PointerInput.Kind.TOUCH, "finger2"); + + Sequence finger1Sequence = new Sequence(finger1, 1); + finger1Sequence.addAction(finger1.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), getX - 50, getY - 50)); + finger1Sequence.addAction(finger1.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + finger1Sequence.addAction(new Pause(finger1, Duration.ofMillis(100))); // Adding a pause between tap down and tap up + finger1Sequence.addAction(finger1.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + + Sequence finger2Sequence = new Sequence(finger2, 1); + finger2Sequence.addAction(finger2.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), getX + 50, getY + 50)); + finger2Sequence.addAction(finger2.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + finger2Sequence.addAction(new Pause(finger2, Duration.ofMillis(100))); // Adding a pause between tap down and tap up + finger2Sequence.addAction(finger2.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + + driver.perform(Arrays.asList(finger1Sequence, finger2Sequence)); + implicityWaitTimeOnScreenManual(1); + System.out.println("ZOOM OUT => Single Tap with two fingers"); + flag = true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e); + } + return flag; + } + + + protected boolean doubleTapWithOneFingerHoldAndSwipeUpOnScreenXY(int getX, int getY) { + boolean flag = false; + try { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence tapAndSwipe = new Sequence(finger, 1); + tapAndSwipe.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), getX, getY)); + tapAndSwipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + tapAndSwipe.addAction(new Pause(finger, Duration.ofMillis(50))); // Adding a short delay between taps + tapAndSwipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + tapAndSwipe.addAction(new Pause(finger, Duration.ofMillis(50))); // Adding a short delay between taps + tapAndSwipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + + // Holding the second tap + tapAndSwipe.addAction(new Pause(finger, Duration.ofMillis(200))); // Adding a pause for holding the second tap + + // Swiping up + tapAndSwipe.addAction(finger.createPointerMove(Duration.ofMillis(500), PointerInput.Origin.viewport(), getX, getY - 600)); + tapAndSwipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + + driver.perform(Collections.singletonList(tapAndSwipe)); + implicityWaitTimeOnScreenManual(1); + System.out.println("ZOOM OUT => Double Tap with one finger and swipe up"); + flag = true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e); + } + return flag; + } + + + protected boolean doubleTapWithOneFingerHoldAndSwipeDownOnScreenXY(int getX, int getY) { + boolean flag = false; + try { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence tapAndSwipe = new Sequence(finger, 1); + tapAndSwipe.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), getX, getY)); + tapAndSwipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + tapAndSwipe.addAction(new Pause(finger, Duration.ofMillis(50))); // Adding a short delay between taps + tapAndSwipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + tapAndSwipe.addAction(new Pause(finger, Duration.ofMillis(50))); // Adding a short delay between taps + tapAndSwipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + + // Holding the second tap + tapAndSwipe.addAction(new Pause(finger, Duration.ofMillis(200))); // Adding a pause for holding the second tap + + // Swiping down + tapAndSwipe.addAction(finger.createPointerMove(Duration.ofMillis(500), PointerInput.Origin.viewport(), getX, getY + 500)); + tapAndSwipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + + driver.perform(Collections.singletonList(tapAndSwipe)); + implicityWaitTimeOnScreenManual(1); + System.out.println("ZOOM IN => Double Tap with one finger and swipe down"); + flag = true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e); + } + return flag; + } + + + /* + UNDER CONSTRUCTION + */ + + +} \ No newline at end of file diff --git a/testAppium/FWStorageApp/src/main/java/general/ErrorsManager.java b/testAppium/FWStorageApp/src/main/java/general/ErrorsManager.java new file mode 100644 index 0000000..64e7f3f --- /dev/null +++ b/testAppium/FWStorageApp/src/main/java/general/ErrorsManager.java @@ -0,0 +1,60 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package general; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public abstract class ErrorsManager { + + private static final String LOG_FILE_NAME = "exceptionLogger.txt"; + private static final String DATE_TIME_PATTERN = "MM-dd-yyyy HH:mm:ss"; + + public static void errNExpManager(Exception e) { + try { + logExceptionToFile(e); + } catch (IOException i) { + System.err.println("Unable to log the exception: " + i); + } + } + + private static void logExceptionToFile(Exception e) throws IOException { + String error = e.toString(); + File txtObj = new File(LOG_FILE_NAME); + + if (txtObj.createNewFile()) { + System.out.println("File created: " + txtObj.getName()); + } else { + System.out.println("File already exists."); + } + + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_PATTERN); + String dateAndTime = LocalDateTime.now().format(dateTimeFormatter); + + String logMessage = String.format("\n\nDate and Time: %s\nERROR MESSAGE LOG\n%s", dateAndTime, error); + + try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(LOG_FILE_NAME), StandardOpenOption.APPEND)) { + writer.write(logMessage); + } + } +} diff --git a/testAppium/FWStorageApp/src/main/java/general/MobileDriverManager.java b/testAppium/FWStorageApp/src/main/java/general/MobileDriverManager.java new file mode 100644 index 0000000..f8213a9 --- /dev/null +++ b/testAppium/FWStorageApp/src/main/java/general/MobileDriverManager.java @@ -0,0 +1,112 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package general; + +import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.android.options.UiAutomator2Options; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; + +import java.net.URL; +import java.time.Duration; +import java.util.Arrays; +import java.util.List; + + +public class MobileDriverManager extends TestUtilities { + + private static final ThreadLocal mobAndroidDriver = new ThreadLocal<>(); + + private static int staticTime; + private static int dynamicTime; + + public static int getStaticTime() { + return staticTime; + } + public static int getDynamicTime() { + return dynamicTime; + } + + @Parameters({"tmStatic", "tmDynamic"}) + @BeforeMethod + public void setMobDriverTimes(int tmStatic, int tmDynamic) { + MobileDriverManager.staticTime = tmStatic; + MobileDriverManager.dynamicTime = tmDynamic; + } + + + @Parameters({"deviceType","platformName", "platformVersion", "deviceName", "automationName", "appPackage","appActivity", "noReset", "appiumServer"}) + @BeforeMethod(alwaysRun = true) + public final void setMobDriver(String deviceType, String platformName, String platformVersion, String deviceName, + String automationName, String appPackage, String appActivity, + boolean noReset, String appiumServer) { + List platformVersionList = Arrays.asList(platformVersion.split(",")); + List deviceNameList = Arrays.asList(deviceName.split(",")); + + try { + System.out.println("[DRIVER MSG] ----> The mobile test driver is being initialized now"); + + UiAutomator2Options capability = new UiAutomator2Options(); + + // Android Device capabilities + capability.setPlatformName(platformName); + + if (deviceType.equals("GMS")) { + capability.setPlatformVersion(platformVersionList.get(0)); // + capability.setDeviceName(deviceNameList.get(0)); // + capability.setAutomationName(automationName); + + } else { + capability.setPlatformVersion(platformVersionList.get(1)); + capability.setDeviceName(deviceNameList.get(1)); + } + capability.setAppPackage(appPackage); + capability.setAppActivity(appActivity); + capability.setNoReset(noReset); + capability.setNewCommandTimeout(Duration.ofSeconds(0)); + + mobAndroidDriver.set(new AndroidDriver(new URL(appiumServer), capability)); + + } catch (Exception e) {ErrorsManager.errNExpManager(e);} + + } + + // driver initiator which gets ready in the @BeforeMethod and does not require to be passed + // as parameter in the ScreenTests classes + public AndroidDriver getDriver() { + return mobAndroidDriver.get(); + } + + @AfterMethod(alwaysRun = true) + public void deleteDriver() throws NullPointerException{ + try { + System.out.println("[DRIVER MSG] ----> The browser driver is being close now"); + getDriver().quit(); + } catch (NullPointerException e) {ErrorsManager.errNExpManager(e);} + } + + @Override + public void onTestFailure(ITestResult iTestResult) { + String testName = iTestResult.getInstance().getClass().getSimpleName(); + if(iTestResult.getStatus() == 2) { + System.out.println("[FAILED TEST NAME:] -----> " + testName); + takeDeviceSnapshot(mobAndroidDriver, testName); + } + } +} \ No newline at end of file diff --git a/testAppium/FWStorageApp/src/main/java/general/TestUtilities.java b/testAppium/FWStorageApp/src/main/java/general/TestUtilities.java new file mode 100644 index 0000000..53d38db --- /dev/null +++ b/testAppium/FWStorageApp/src/main/java/general/TestUtilities.java @@ -0,0 +1,85 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package general; + +import io.appium.java_client.android.AndroidDriver; +import org.apache.commons.io.FileUtils; +import org.openqa.selenium.OutputType; +import org.testng.ITestResult; +import org.testng.Reporter; +import org.testng.TestListenerAdapter; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.asserts.SoftAssert; + +import java.io.File; +import java.io.IOException; +import java.util.Date; + +public class TestUtilities extends TestListenerAdapter { + + private static final ThreadLocal assertGeneric = new ThreadLocal<>(); + + protected void assertTrue(boolean validation, String msg){ + assertGeneric.get().assertTrue(validation,msg); + } + + protected void assertFalse(boolean validation, String msg){ + assertGeneric.get().assertFalse(validation,msg); + } + + protected void assertAll(){ + assertGeneric.get().assertAll(); + } + + @BeforeMethod + protected void setSoftAssertValidation() { + assertGeneric.set(new SoftAssert()); + } + + protected void takeDeviceSnapshot(ThreadLocal mobAndroidDriver, String testName) { + try { + File srcFile = mobAndroidDriver.get().getScreenshotAs(OutputType.FILE); + Date d = new Date(); + String TimeStamp = d.toString().replace(":","_").replace(" ","_"); + FileUtils.copyFile(srcFile, new File("./Screenshots/" + + testName + "_" + TimeStamp + ".png")); + } catch (IOException e) { + ErrorsManager.errNExpManager(e); + } + } + + @BeforeMethod + protected void testStartingMsg() { + System.out.println("[STARTING THE TEST]...\n..."); + } + + @AfterMethod + protected void testEndingMsg() { + System.out.println("[ENDING THE TEST]...\n..."); + } + + protected static String basicErrorMsg(String msg) { + return "[error] -----> " + msg; + } + + @Override + public void onTestSuccess(ITestResult tr) { + Reporter.log("Listener: onTestSuccess"); + super.onTestSuccess(tr); + } +} diff --git a/testAppium/FWStorageApp/src/test/configStorage.xml b/testAppium/FWStorageApp/src/test/configStorage.xml new file mode 100644 index 0000000..523b818 --- /dev/null +++ b/testAppium/FWStorageApp/src/test/configStorage.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testAppium/FWStorageApp/src/test/java/screens/FileUploadExplorerScreen.java b/testAppium/FWStorageApp/src/test/java/screens/FileUploadExplorerScreen.java new file mode 100644 index 0000000..aa3650f --- /dev/null +++ b/testAppium/FWStorageApp/src/test/java/screens/FileUploadExplorerScreen.java @@ -0,0 +1,54 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package screens; + +import general.BaseScreen; +import general.ErrorsManager; +import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.pagefactory.AppiumFieldDecorator; +import org.openqa.selenium.support.PageFactory; + +public class FileUploadExplorerScreen extends BaseScreen { + + public FileUploadExplorerScreen(AndroidDriver driver) { + super(driver); + PageFactory.initElements(new AppiumFieldDecorator(driver), this); } + + @Override + public boolean verifyLoads() { return false; } + + /* + It might be possible to validate the view but can trigger errors + 1. Locate a file by XY coordinates and tap on it + 2. Wait then redirect the driver to the StorageSampleLoggedScreen + */ + + private boolean selectAFileToUploadFromFileExplorer() { + return tapOnScreenXY(450, 1080); + } + + public StorageSampleLoggedScreen storageSampleLoggedScreen() { + try { + selectAFileToUploadFromFileExplorer(); + return new StorageSampleLoggedScreen(this.driver); + } catch (Exception e) { + ErrorsManager.errNExpManager(e); + return null; + } + } + +} diff --git a/testAppium/FWStorageApp/src/test/java/screens/StorageSampleLoggedScreen.java b/testAppium/FWStorageApp/src/test/java/screens/StorageSampleLoggedScreen.java new file mode 100644 index 0000000..01584ed --- /dev/null +++ b/testAppium/FWStorageApp/src/test/java/screens/StorageSampleLoggedScreen.java @@ -0,0 +1,250 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package screens; + +import general.BaseScreen; +import general.ErrorsManager; +import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.android.nativekey.AndroidKey; +import io.appium.java_client.pagefactory.AndroidFindBy; +import io.appium.java_client.pagefactory.AppiumFieldDecorator; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.PageFactory; + +import java.util.List; +import java.util.Random; + +public class StorageSampleLoggedScreen extends BaseScreen { + public StorageSampleLoggedScreen(AndroidDriver driver) { + super(driver); + PageFactory.initElements(new AppiumFieldDecorator(driver), this); + } + + @Override + public boolean verifyLoads() { + return waitForMobElementToBeVisible(androidTextViewList.get(0)) && waitForMobElementToBeVisible(sortLbl) + && waitForMobElementToBeVisible(moreOptionsBtn); + } + + /* + UI Elements + */ + + @AndroidFindBy(className="android.widget.TextView") + private List androidTextViewList; + + @AndroidFindBy(id="com.omh.android.storage.sample:id/sortByName") + private WebElement sortLbl; + + // Ellipsis more button + @AndroidFindBy(xpath="//android.widget.ImageView[@content-desc=\"More options\"]") + private WebElement moreOptionsBtn; + + // Ellipsis options + @AndroidFindBy(className="android.widget.LinearLayout") + private List listViewOptions; + + /* + POPUP Create + */ + @AndroidFindBy(id="com.omh.android.storage.sample:id/alertTitle") + private WebElement alertTitle; + + @AndroidFindBy(id="android:id/button2") + private WebElement cancelBtn; + + @AndroidFindBy(id="android:id/button1") + private WebElement createBtn; + + /* + POPUP fields to complete + */ + @AndroidFindBy(id="com.omh.android.storage.sample:id/fileName") + private WebElement fileNameTxtField; + + @AndroidFindBy(id="com.omh.android.storage.sample:id/fileType") + private WebElement fileTypeDownArrow; + + @AndroidFindBy(className="android.widget.CheckedTextView") + private List fileTypeCheckedTextView; + + /* + Methods + */ + + public boolean listFilesInDrive() { + return tapMobElement(moreOptionsBtn) && implicityWaitTimeOnScreenManual(2) + && tapMobElement(listViewOptions.get(0)) && implicityWaitTimeOnScreenManual(2); + } + + public boolean navigateBackAndForthInsideAFolder(int getX, int getY) { + return tapOnScreenXY(getX, getY) && implicityWaitTimeOnScreenManual(2) && getFolderText() + && returnToMainDriveScreen() && implicityWaitTimeOnScreenManual(2); + } + + private boolean returnToMainDriveScreen() { + boolean flag = false; + try { + pressAndroidKey(AndroidKey.BACK); + flag = true; + } catch (Exception e) { ErrorsManager.errNExpManager(e);} + return flag; + } + + private boolean getFolderText() { + boolean flag = false; + try { + System.out.println(getTextFromMobElement(androidTextViewList.get(1))); + flag = true; + } catch (Exception e) {ErrorsManager.errNExpManager(e);} + return flag; + } + + /* + AFTER LOGGED IN VALIDATIONS + */ + + public boolean verifySignInState() { + System.out.println("The app is returned in Signed In state"); + return implicityWaitTimeOnScreenManual(WAIT_TIME_MEDIUM) /*&& waitForMobElementToBeVisible(sortLbl) && waitForMobElementToBeVisible(moreOptionsBtn)*/; + } + + /* + CREATION FILE OR FOLDERS METHODS + */ + + private static final int SCREEN_X_COORDINATE = 675; + private static final int SCREEN_Y_COORDINATE = 365; + private static final int WAIT_TIME_SHORT = 1; + private static final int WAIT_TIME_MEDIUM = 3; + private static final int WAIT_TIME_LONG = 5; + + public boolean tapAndCreateFolderOrFile(boolean createFolder) { + try { + tapMoreOptionsButton(); + waitOnScreen(WAIT_TIME_SHORT); + tapOnScreenXY(SCREEN_X_COORDINATE, SCREEN_Y_COORDINATE); + waitOnScreen(WAIT_TIME_SHORT); + writeASimpleNameOnField(); + + if (!createFolder) { + tapMobElement(fileTypeDownArrow); + int randomIndex = generateRandomIndex(1, 3); + tapMobElement(fileTypeCheckedTextView.get(randomIndex)); + } + + tapCreateButton(); + + if (createFolder) { + waitOnScreen(WAIT_TIME_MEDIUM); + } else { + waitOnScreen(WAIT_TIME_LONG); + } + + return true; + } catch (Exception e) { + return false; + } + } + + private int generateRandomIndex(int min, int max) { + Random random = new Random(); + return random.nextInt(max - min + 1) + min; + } + + private void tapMoreOptionsButton() { + tapMobElement(moreOptionsBtn); + } + + private void writeASimpleNameOnField() { + String randomName = generateRandomName(); + fileNameTxtField.sendKeys(randomName); + //typeTxtOnMobElement(fileNameTxtField, randomName); + } + + private String generateRandomName() { + Random random = new Random(); + int randomNumber = random.nextInt(1000); // Adjust the range of random numbers as needed + return "Auto-File-Folder " + randomNumber; + } + + + private void tapCreateButton() { + tapMobElement(createBtn); + } + + private void waitOnScreen(int seconds) { + implicityWaitTimeOnScreenManual(seconds); + } + + public boolean deleteAFileFolder(boolean deleteFile) { + if(deleteFile) { + return tapOnScreenXY(445,460); + } else + return tapOnScreenXY(980,460); + } + + @AndroidFindBy(xpath="/hierarchy/android.widget.Toast") + private WebElement toastMsgDel; + + + /* + REDIRECTS TO FILE EXPLORER APP TO UPLOAD A FILE + */ + + public FileUploadExplorerScreen fileUploadExplorerScreen() { + + try { + // call a method to tap the more button + tapMoreOptionsButton(); + // locate by XY coordinates to tap Upload + waitOnScreen(WAIT_TIME_SHORT); + tapOnScreenXY(SCREEN_X_COORDINATE, 510); + // wait and return driver with the new view screen + implicityWaitTimeOnScreenManual(WAIT_TIME_SHORT); + return new FileUploadExplorerScreen(this.driver); + } catch (Exception e) { + ErrorsManager.errNExpManager(e); + return null; + } + } + + // A method that tap on Upload button + // Implicity wait until file is uploaded. Toast can't be validated + // Exit the app + + public boolean tapToUploadTheFile() { + return tapMobElement(createBtn) && implicityWaitTimeOnScreenManual(WAIT_TIME_LONG); + } + + + /* + Sign out session + */ + + private boolean signOutSession() { + tapMoreOptionsButton(); + return implicityWaitTimeOnScreenManual(WAIT_TIME_SHORT) && tapOnScreenXY(SCREEN_X_COORDINATE, 675) + && implicityWaitTimeOnScreenManual(WAIT_TIME_SHORT); + } + + public StorageSampleLoginScreen signOutUserSession() { + if(signOutSession()) { + return new StorageSampleLoginScreen(driver); + } else return null; + } +} diff --git a/testAppium/FWStorageApp/src/test/java/screens/StorageSampleLoginScreen.java b/testAppium/FWStorageApp/src/test/java/screens/StorageSampleLoginScreen.java new file mode 100644 index 0000000..97e9c67 --- /dev/null +++ b/testAppium/FWStorageApp/src/test/java/screens/StorageSampleLoginScreen.java @@ -0,0 +1,128 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package screens; + +import general.BaseScreen; +import general.ErrorsManager; +import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.pagefactory.AndroidFindBy; +import io.appium.java_client.pagefactory.AppiumFieldDecorator; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.PageFactory; + +public class StorageSampleLoginScreen extends BaseScreen { + public StorageSampleLoginScreen(AndroidDriver driver) { + super(driver); + PageFactory.initElements(new AppiumFieldDecorator(driver), this); + } + + @Override + public boolean verifyLoads() { + return waitForMobElementToBeVisible(topActionBar); + } + + /* + UI ELEMENTS + */ + + // logged out elements + @AndroidFindBy(id="com.omh.android.storage.sample:id/toolbar") + private WebElement topActionBar; + + @AndroidFindBy(className="android.widget.TextView") + private WebElement topActionBarTxt; + + @AndroidFindBy(id="com.omh.android.storage.sample:id/btn_login") + private WebElement loginBtn; + + // Messages UI + + @AndroidFindBy(id="com.omh.android.storage.sample:id/alertTitle") + private WebElement alertTitle; + + @AndroidFindBy(id="android:id/message") + private WebElement alertMsg; + + // account picker popup + @AndroidFindBy(id="com.google.android.gms:id/container") + private WebElement pickAccount; + + /* + METHODS + */ + + public boolean verifySignInBtnDisplayed() { + getTextFromMobElement(loginBtn); + return waitForMobElementToBeVisible(loginBtn); + } + + private boolean tapOnLoginBtn() { + boolean flag; + flag = tapMobElement(loginBtn) && implicityWaitTimeOnScreenManual(1); + return flag; + } + + private boolean printAlertMsgs() { + boolean flag = false; + try { + String text = getTextFromMobElement(alertTitle) + "\n" + getTextFromMobElement(alertMsg); + System.out.println(" \n==================\n" + text + " \n==================\n"); + flag = true; + } catch (Exception e) { + ErrorsManager.errNExpManager(e);} + return flag; + } + + public boolean checkAlerMsgPrint() { + return printAlertMsgs(); + } + + public boolean tapOutsideModal() { + return tapOnLoginBtn() && implicityWaitTimeOnScreenManual(1) && tapOnScreenXY(880, 2265) + && printAlertMsgs() && tapOnScreenXY(880, 2265); + } + + public boolean verifySignInPopUpShown() { + boolean flag = false; + if(tapOnLoginBtn()) { + flag = waitForMobElementToBeVisible(pickAccount) && tapMobElement(pickAccount) && implicityWaitTimeOnScreenManual(3); + } + return flag; + } + + + /* + RETURN-REDIRECT PAGE CALLS + */ + public WebViewBrowserScreen signInFromBrowser() { + if(tapOnLoginBtn()) { + return new WebViewBrowserScreen(this.driver); + } else {return null;} + } + + public StorageSampleLoggedScreen signedUser() { + implicityWaitTimeOnScreenManual(3); + return new StorageSampleLoggedScreen(this.driver); + } + + + /* + AFTER SIGNED IN VALIDATIONS + */ + + +} diff --git a/testAppium/FWStorageApp/src/test/java/screens/WebViewBrowserScreen.java b/testAppium/FWStorageApp/src/test/java/screens/WebViewBrowserScreen.java new file mode 100644 index 0000000..b9a0a42 --- /dev/null +++ b/testAppium/FWStorageApp/src/test/java/screens/WebViewBrowserScreen.java @@ -0,0 +1,94 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package screens; + +import general.BaseScreen; +import general.ErrorsManager; +import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.pagefactory.AndroidFindBy; +import io.appium.java_client.pagefactory.AppiumFieldDecorator; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.PageFactory; + + +public class WebViewBrowserScreen extends BaseScreen { + + public WebViewBrowserScreen(AndroidDriver driver) { + super(driver); + PageFactory.initElements(new AppiumFieldDecorator(driver), this); + } + + @Override + public boolean verifyLoads() {return false;} + + + /* + UI ELEMENTS - Since they are in browser view, the interactions will be handled as web actions rather than mobile's + */ + + @AndroidFindBy(id="com.huawei.browser:id/close_button") + private WebElement closeTabBtn; + + @AndroidFindBy(id="com.huawei.browser:id/url_text") + private WebElement urlBar; + + @AndroidFindBy(xpath="//android.view.View[@content-desc=\"Neiger PK Drake neiger.drake@gmail.com\"]") + private WebElement loggedAccount; + + // custom tab browser test + @AndroidFindBy(id="com.huawei.browser:id/custom_tab_menu") + private WebElement customBrowsertab; + + /* + METHODS + */ + + + public boolean verifySignPageLoads() { + return waitForMobElementToBeVisible(closeTabBtn) + && waitForMobElementToBeVisible(urlBar) + && printCustomTabElements(); + + } + + private boolean printCustomTabElements() { + boolean flag = false; + try { + System.out.println(getTextFromMobElement(urlBar)); + flag = true; + }catch (Exception e) {ErrorsManager.errNExpManager(e);} + return flag; + } + + public boolean clickLoggedInAccountXY(int getX, int getY){ + return tapOnScreenXY(getX, getY); + } + + public boolean clickTheXOnBrowser() { + return tapMobElement(closeTabBtn); + } + /* + RETURN-REDIRECT PAGE CALLS + */ + + public StorageSampleLoginScreen returnAsSignInState(int getX, int getY) { + if(customUsersSwipeYLoc(customBrowsertab, 1700, 900) && clickLoggedInAccountXY(getX, getY)) { + return new StorageSampleLoginScreen(driver); + } else {return null;} + } + +} diff --git a/testAppium/FWStorageApp/src/test/java/tests/FileUploadExplorerScreenTests.java b/testAppium/FWStorageApp/src/test/java/tests/FileUploadExplorerScreenTests.java new file mode 100644 index 0000000..94452a6 --- /dev/null +++ b/testAppium/FWStorageApp/src/test/java/tests/FileUploadExplorerScreenTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tests; + +import general.MobileDriverManager; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import screens.FileUploadExplorerScreen; +import screens.StorageSampleLoggedScreen; +import screens.StorageSampleLoginScreen; + +public class FileUploadExplorerScreenTests extends MobileDriverManager { + + private StorageSampleLoginScreen storageSampleLoginScreen; + private StorageSampleLoggedScreen storageSampleLoggedScreen; + private FileUploadExplorerScreen fileUploadExplorerScreen; + + @BeforeMethod //Launch app and confirm that user is signed in + public void setAuthSampleLoginScreen() { + storageSampleLoginScreen = new StorageSampleLoginScreen(getDriver()); + assertTrue(storageSampleLoginScreen.verifyLoads(), basicErrorMsg("Unable to load the screen")); + storageSampleLoggedScreen = storageSampleLoginScreen.signedUser(); + assertTrue(storageSampleLoggedScreen.verifyLoads(), basicErrorMsg("The logged in user was not loaded")); + assertAll(); + } + + @Test + public void FW_29_verifyThatAFileCanBeUploadedCorrectly() { + fileUploadExplorerScreen = storageSampleLoggedScreen.fileUploadExplorerScreen(); + storageSampleLoggedScreen = fileUploadExplorerScreen.storageSampleLoggedScreen(); + assertTrue(storageSampleLoggedScreen.tapToUploadTheFile(), basicErrorMsg("Unable to tap to upload the file")); + assertTrue(storageSampleLoggedScreen.deleteAFileFolder(false), basicErrorMsg("Unable to delete the file")); + assertAll(); + } + +} diff --git a/testAppium/FWStorageApp/src/test/java/tests/LogOutScreenTests.java b/testAppium/FWStorageApp/src/test/java/tests/LogOutScreenTests.java new file mode 100644 index 0000000..6666445 --- /dev/null +++ b/testAppium/FWStorageApp/src/test/java/tests/LogOutScreenTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tests; + +import general.MobileDriverManager; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import screens.StorageSampleLoggedScreen; +import screens.StorageSampleLoginScreen; +import screens.WebViewBrowserScreen; + +public class LogOutScreenTests extends MobileDriverManager { + + private StorageSampleLoginScreen storageSampleLoginScreen; + private WebViewBrowserScreen webViewBrowserScreen; + private StorageSampleLoggedScreen storageSampleLoggedScreen; + + @BeforeMethod + public void setAuthSampleLoginScreen() { + storageSampleLoginScreen = new StorageSampleLoginScreen(getDriver()); + assertTrue(storageSampleLoginScreen.verifyLoads(), basicErrorMsg("Unable to load the screen")); + storageSampleLoggedScreen = storageSampleLoginScreen.signedUser(); + assertTrue(storageSampleLoggedScreen.verifyLoads(), basicErrorMsg("The logged in user was not loaded")); + assertAll(); + } + + @Test + public void FW_101_verifyThatUserCanlogOutTheSession() { + storageSampleLoginScreen = storageSampleLoggedScreen.signOutUserSession(); + System.out.println("The user session has been closed successfully"); + assertTrue(storageSampleLoginScreen.verifyLoads(), basicErrorMsg("Unable to load login screen")); + assertAll(); + } +} diff --git a/testAppium/FWStorageApp/src/test/java/tests/StorageSampleLoggedScreenTests.java b/testAppium/FWStorageApp/src/test/java/tests/StorageSampleLoggedScreenTests.java new file mode 100644 index 0000000..992ed8d --- /dev/null +++ b/testAppium/FWStorageApp/src/test/java/tests/StorageSampleLoggedScreenTests.java @@ -0,0 +1,65 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tests; + +import general.MobileDriverManager; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import screens.StorageSampleLoggedScreen; +import screens.StorageSampleLoginScreen; + +public class StorageSampleLoggedScreenTests extends MobileDriverManager { + + private StorageSampleLoginScreen storageSampleLoginScreen; + private StorageSampleLoggedScreen storageSampleLoggedScreen; + + @BeforeMethod + public void setAuthSampleLoginScreen() { + storageSampleLoginScreen = new StorageSampleLoginScreen(getDriver()); + assertTrue(storageSampleLoginScreen.verifyLoads(), basicErrorMsg("Unable to load the screen")); + storageSampleLoggedScreen = storageSampleLoginScreen.signedUser(); + assertTrue(storageSampleLoggedScreen.verifyLoads(), basicErrorMsg("The logged in user was not loaded")); + assertAll(); + } + + @Test + public void FW_102_FW_103_verifyUserCanChangeGridOrLinearLayoutViewInDrive() { + assertTrue(storageSampleLoggedScreen.listFilesInDrive(), basicErrorMsg("The list of files has failed to be tapped")); + assertAll(); + } + + @Test + public void FW_43_FW_116_verifyUserCanNavigateBetweenFolders() { + assertTrue(storageSampleLoggedScreen.navigateBackAndForthInsideAFolder(270, 585), basicErrorMsg("Unable to navigate between folders")); + assertAll(); + } + + @Test + public void FW_47_FW_49_FW_117_verifyUserCanSeeAddDeleteFolders() { + assertTrue(storageSampleLoggedScreen.tapAndCreateFolderOrFile(true), basicErrorMsg("The folder can't be created")); + assertTrue(storageSampleLoggedScreen.deleteAFileFolder(true), basicErrorMsg("The folder can't be deleted")); + assertAll(); + } + + @Test //(invocationCount = 10) + public void FW_19_FW_20_FW_22_verifyUserCanSeeAddDeleteFiles() { + assertTrue(storageSampleLoggedScreen.tapAndCreateFolderOrFile(false), basicErrorMsg("The file can't be created")); + assertTrue(storageSampleLoggedScreen.deleteAFileFolder(false), basicErrorMsg("The file can't be deleted")); + assertAll(); + } + +} diff --git a/testAppium/FWStorageApp/src/test/java/tests/StorageSampleLoginScreenTests.java b/testAppium/FWStorageApp/src/test/java/tests/StorageSampleLoginScreenTests.java new file mode 100644 index 0000000..3c122c5 --- /dev/null +++ b/testAppium/FWStorageApp/src/test/java/tests/StorageSampleLoginScreenTests.java @@ -0,0 +1,76 @@ +/* + * Copyright 2023 Open Mobile Hub + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package tests; + +import general.MobileDriverManager; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; +import screens.StorageSampleLoggedScreen; +import screens.StorageSampleLoginScreen; +import screens.WebViewBrowserScreen; + +public class StorageSampleLoginScreenTests extends MobileDriverManager { + + private StorageSampleLoginScreen storageSampleLoginScreen; + private WebViewBrowserScreen webViewBrowserScreen; + private StorageSampleLoggedScreen storageSampleLoggedScreen; + + @BeforeMethod + public void setAuthSampleLoginScreen() { + storageSampleLoginScreen = new StorageSampleLoginScreen(getDriver()); + assertTrue(storageSampleLoginScreen.verifyLoads(), basicErrorMsg("Unable to load the screen")); + assertAll(); + } + + @Test + public void FW_17_FW_18_verifyThatStorageLoginBtnIsDisplayed() { + assertTrue(storageSampleLoginScreen.verifySignInBtnDisplayed(), basicErrorMsg("Unable to get the button info")); + assertAll(); + } + + @Test @Parameters({"deviceType"}) + public void FW_98_FW_114_FW_115_verifyThatUserCanTapXInBrowserOrTapOusideModal(String deviceType) { + if(deviceType.equals("GMS")) { + assertTrue(storageSampleLoginScreen.tapOutsideModal(), basicErrorMsg("It can't be tapped outside")); + } else { + webViewBrowserScreen = storageSampleLoginScreen.signInFromBrowser(); + assertTrue(webViewBrowserScreen.verifySignPageLoads(), basicErrorMsg("The signin web view was not loaded correctly")); + assertTrue(webViewBrowserScreen.clickTheXOnBrowser(), basicErrorMsg("Unable to tap on the X close browser")); + assertTrue(storageSampleLoginScreen.checkAlerMsgPrint(), basicErrorMsg("Alert message has not been triggered")); + } + assertAll(); + } + + + @Test @Parameters({"deviceType"}) + public void FW_23_FW_97_verifyThatUserIsReturnedToSampleAppInLoggedInState(String deviceType) { + if(deviceType.equals("nonGMS")) { + webViewBrowserScreen = storageSampleLoginScreen.signInFromBrowser(); + assertTrue(webViewBrowserScreen.verifySignPageLoads(), basicErrorMsg("The signIn web view was not loaded correctly")); + assertTrue(webViewBrowserScreen.clickLoggedInAccountXY(540,700), basicErrorMsg("Unable to click on the XY location given")); + storageSampleLoginScreen = webViewBrowserScreen.returnAsSignInState(800,1920); + } else { + assertTrue(storageSampleLoginScreen.verifySignInPopUpShown(), basicErrorMsg("Unable to shown the pop up account")); + } + storageSampleLoggedScreen = storageSampleLoginScreen.signedUser(); + assertTrue(storageSampleLoggedScreen.verifySignInState(), basicErrorMsg("The signed in state fails the validation")); + assertAll(); + } + + +}