diff --git a/.gitignore b/.gitignore index 904baeb..29efd40 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ target/ build/ logs/ +log/ .project .settings/ .classpath @@ -8,4 +9,6 @@ logs/ .gradle/ *.iml .DS_Store -!gradle/wrapper/* \ No newline at end of file +!gradle/wrapper/* +.vscode/ +local.log \ No newline at end of file diff --git a/README.md b/README.md index b10a954..483432a 100644 --- a/README.md +++ b/README.md @@ -23,50 +23,23 @@ Test execution using [TestNG](http://testng.org) on BrowserStack. ``` Website will open on `localhost:8000`. -#### Desktop browsers +#### Web browsers - Run a single test. ``` - mvn -P desktop-single test + mvn -P web-single test ``` - Run parallel tests. ``` - mvn -P desktop-parallel test + mvn -P web-parallel test ``` - Run a failed test. ``` - mvn -P desktop-fail test + mvn -P web-fail test ``` - Run a local test. ``` - mvn -P desktop-local test - ``` -- Run parallel local tests. - ``` - mvn -P desktop-local-parallel test - ``` - -#### Mobile browsers - -- Run a single test. - ``` - mvn -P mobile-single test - ``` -- Run parallel tests. - ``` - mvn -P mobile-parallel test - ``` -- Run a failed test. - ``` - mvn -P mobile-fail test - ``` -- Run a local test. - ``` - mvn -P mobile-local test - ``` -- Run parallel local tests. - ``` - mvn -P mobile-local-parallel test + mvn -P web-local test ``` ### App-Automate @@ -89,10 +62,6 @@ Test execution using [TestNG](http://testng.org) on BrowserStack. ``` mvn -P android-local test ``` -- Run parallel local tests. - ``` - mvn -P android-local-parallel test - ``` #### iOS devices @@ -112,10 +81,6 @@ Test execution using [TestNG](http://testng.org) on BrowserStack. ``` mvn -P ios-local test ``` -- Run parallel local tests. - ``` - mvn -P ios-local-parallel test - ``` #### Espresso tests @@ -156,46 +121,19 @@ Test execution using [TestNG](http://testng.org) on BrowserStack. - Run a single test ``` - ./gradlew clean desktop-single + ./gradlew webSingle ``` - Run parallel tests ``` - ./gradlew clean desktop-parallel + ./gradlew webParallel ``` - Run a failed test ``` - ./gradlew clean desktop-fail + ./gradlew webFail ``` - Run a local test ``` - ./gradlew clean desktop-local - ``` -- Run parallel local tests - ``` - ./gradlew clean desktop-local-parallel - ``` - -#### Mobile browsers - -- Run a single test - ``` - ./gradlew clean mobile-single - ``` -- Run parallel tests - ``` - ./gradlew clean mobile-parallel - ``` -- Run a failed test - ``` - ./gradlew clean mobile-fail - ``` -- Run a local test - ``` - ./gradlew clean mobile-local - ``` -- Run parallel local tests - ``` - ./gradlew clean mobile-local-parallel + ./gradlew webLocal ``` ### App-Automate @@ -204,68 +142,57 @@ Test execution using [TestNG](http://testng.org) on BrowserStack. - Run a single test ``` - ./gradlew clean android-single + ./gradlew androidSingle ``` - Run parallel tests ``` - ./gradlew clean android-parallel + ./gradlew androidParallel ``` - Run a failed test ``` - ./gradlew clean android-fail + ./gradlew androidFail ``` - Run a local test ``` - ./gradlew clean android-local - ``` -- Run parallel local tests - ``` - ./gradlew clean android-local-parallel + ./gradlew androidLocal ``` #### iOS devices - Run a single test ``` - ./gradlew clean ios-single + ./gradlew iosSingle ``` - Run parallel tests ``` - ./gradlew clean ios-parallel + ./gradlew iosParallel ``` - Run a failed test ``` - ./gradlew clean ios-fail + ./gradlew iosFail ``` - Run a local test ``` - ./gradlew clean ios-local - ``` -- Run parallel local tests - ``` - ./gradlew clean ios-local-parallel + ./gradlew iosLocal ``` #### Espresso tests - Run an Espresso test ``` - ./gradlew clean espresso + ./gradlew espresso ``` #### XCUI tests - Run a XCUI test ``` - ./gradlew clean xcuitest + ./gradlew xcuitest ``` ## Notes - You can view your Automate test results on the [BrowserStack Automate dashboard](https://automate.browserstack.com/). - You can view your App-Automate test results on the [BrowserStack App-Automate dashboard](https://app-automate.browserstack.com/). -- To use specific number of threads: - - For Maven use `-Dthreads=`. Example `-Dthreads=3` - - For Gradle use `-Pthreads=`. Example `-Pthreads=3` - Apps used to test on Android: - Demo App: [WikipediaSample.apk](https://www.browserstack.com/app-automate/sample-apps/android/WikipediaSample.apk) - Local App: [LocalSample.apk](https://www.browserstack.com/app-automate/sample-apps/android/LocalSample.apk) @@ -280,5 +207,5 @@ Test execution using [TestNG](http://testng.org) on BrowserStack. - Test-suite: [BrowserStack-SampleXCUITest.zip](https://www.browserstack.com/app-automate/sample-apps/ios/BrowserStack-SampleXCUITest.zip) - Export the environment variables for the Username and Access Key of your BrowserStack account. ```sh - export BROWSERSTACK_USERNAME= && export BROWSERSTACK_ACCESS_KEY= - ``` + export BROWSERSTACK_USERNAME= && export BROWSERSTACK_ACCESS_KEY= + ``` \ No newline at end of file diff --git a/browserstack.yml b/browserstack.yml new file mode 100644 index 0000000..11d0461 --- /dev/null +++ b/browserstack.yml @@ -0,0 +1,82 @@ +# ============================= +# Set BrowserStack Credentials +# ============================= +# Add your BrowserStack userName and accessKey here or set BROWSERSTACK_USERNAME and +# BROWSERSTACK_ACCESS_KEY as env variables +userName: YOUR_USERNAME +accessKey: YOUR_ACCESS_KEY + +# ====================== +# BrowserStack Reporting +# ====================== +# The following capabilities are used to set up reporting on BrowserStack: +# Set 'projectName' to the name of your project. Example, Marketing Website +projectName: BrowserStack Samples +# Set `buildName` as the name of the job / testsuite being run +buildName: browserstack build +# `buildIdentifier` is a unique id to differentiate every execution that gets appended to +# buildName. Choose your buildIdentifier format from the available expressions: +# ${BUILD_NUMBER} (Default): Generates an incremental counter with every execution +# ${DATE_TIME}: Generates a Timestamp with every execution. Eg. 05-Nov-19:30 +# Read more about buildIdentifiers here -> https://www.browserstack.com/docs/automate/selenium/organize-tests +buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression} +# Set `framework` of your test suite. Example, `testng`, `cucumber`, `cucumber-testng` +# This property is needed to send test context to BrowserStack (test name, status) +framework: testng + +# ======================================= +# Platforms (Browsers / Devices to test) +# ======================================= +# Platforms object contains all the browser / device combinations you want to test on. +# Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate) +platforms: + - os: OS X + osVersion: Big Sur + browserName: Chrome + browserVersion: latest + - os: Windows + osVersion: 10 + browserName: Edge + browserVersion: latest + - deviceName: Samsung Galaxy S22 Ultra + browserName: chrome # Try 'samsung' for Samsung browser + osVersion: 12.0 + +# ======================= +# Parallels per Platform +# ======================= +# The number of parallel threads to be used for each platform set. +# BrowserStack's SDK runner will select the best strategy based on the configured value +# +# Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack +# +# Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack +parallelsPerPlatform: 10 + +source: testng:sample-master:v1.1 + +# ========================================== +# BrowserStack Local +# (For localhost, staging/private websites) +# ========================================== +# Set browserStackLocal to true if your website under test is not accessible publicly over the internet +# Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction +browserstackLocal: true # (Default false) + +# Options to be passed to BrowserStack local in-case of advanced configurations +browserStackLocalOptions: + localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. + forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. + # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections + +# =================== +# Debugging features +# =================== +debug: false # # Set to true if you need screenshots for every selenium command ran +networkLogs: false # Set to true to enable HAR logs capturing +consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors) +# Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors) + +# Test Observability is an intelligent test reporting & debugging product. It collects data using the SDK. Read more about what data is collected at https://www.browserstack.com/docs/test-observability/references/terms-and-conditions +# Visit observability.browserstack.com to see your test reports and insights. To disable test observability, specify `testObservability: false` in the key below. +testObservability: true diff --git a/build.gradle b/build.gradle index e344a56..fcca293 100644 --- a/build.gradle +++ b/build.gradle @@ -1,237 +1,147 @@ +plugins { + id 'java' +} + group = 'com.browserstack' version = '1.0' description = 'browserstack-demo-testng' -apply plugin: 'java' - -apply plugin: 'application' -mainClassName = "com.local.server.MyHttpServer" - repositories { mavenCentral() } -sourceSets { - test.java.srcDirs = ['src/test/java'] - test.resources.srcDirs = ['src/test/resources'] -} - dependencies { - implementation 'io.appium:java-client:7.5.1' - implementation 'org.testng:testng:7.4.0' - implementation 'com.browserstack:browserstack-local-java:1.0.3' + implementation 'io.appium:java-client:8.6.0' + implementation 'org.seleniumhq.selenium:selenium-java:4.13.0' + implementation 'org.testng:testng:7.9.0' + implementation 'com.browserstack:browserstack-java-sdk:1.41.0' implementation 'io.rest-assured:rest-assured:4.3.3' } -tasks.register('execute', JavaExec) { - main = project.hasProperty("mainClass") ? getProperty("mainClass") : "NULL" - classpath = sourceSets.main.runtimeClasspath -} +def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' } -tasks.register('desktop-single', Test) { - useTestNG() - include '**/desktop/SingleTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" - } +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' } -tasks.register('desktop-parallel', Test) { +tasks.withType(Test) { + systemProperties = System.properties + dependsOn compileTestJava + testClassesDirs = sourceSets.test.output.classesDirs + classpath = sourceSets.test.runtimeClasspath + outputs.upToDateWhen { false } useTestNG() { - suites 'src/test/resources/web/suites/parallel.testng.xml' - systemProperty 'config', 'desktop' - parallel project.property('parallel') - threadCount Integer.parseInt(project.property('threads')) - } - testLogging { - events "PASSED", "FAILED", "SKIPPED" + useDefaultListeners = true } + jvmArgs "-javaagent:${browserstackSDKArtifact.file}" } -tasks.register('desktop-fail', Test) { - useTestNG() - include '**/desktop/FailTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" - } -} - -tasks.register('desktop-local', Test) { - useTestNG() - include '**/desktop/LocalTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" - } -} - -tasks.register('desktop-local-parallel', Test) { - useTestNG() { - suites 'src/test/resources/web/suites/local.testng.xml' - systemProperty 'config', 'desktop' - parallel project.property('parallel') - threadCount Integer.parseInt(project.property('threads')) - } - testLogging { - events "PASSED", "FAILED", "SKIPPED" - } -} - -tasks.register('mobile-single', Test) { - useTestNG() - include '**/mobile/SingleTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" - } -} - -tasks.register('mobile-parallel', Test) { - useTestNG() { - suites 'src/test/resources/web/suites/parallel.testng.xml' - systemProperty 'config', 'mobile' - parallel project.property('parallel') - threadCount Integer.parseInt(project.property('threads')) - } - testLogging { - events "PASSED", "FAILED", "SKIPPED" - } +test { + systemProperty 'browserstack.config', 'src/test/resources/web/config/web_single.yml' + include '**/desktop/SingleTest.class' } -tasks.register('mobile-fail', Test) { - useTestNG() - include '**/mobile/FailTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task webSingle(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/web/config/web_single.yml' + filter { + includeTestsMatching 'com.test.web.desktop.SingleTest' } } -tasks.register('mobile-local', Test) { - useTestNG() - include '**/mobile/LocalTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task webParallel(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/web/config/web_parallel.yml' + filter { + includeTestsMatching 'com.test.web.desktop.SingleTest' } } -tasks.register('mobile-local-parallel', Test) { - useTestNG() { - suites 'src/test/resources/web/suites/local.testng.xml' - systemProperty 'config', 'mobile' - parallel project.property('parallel') - threadCount Integer.parseInt(project.property('threads')) - } - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task webLocal(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/web/config/web_local.yml' + filter { + includeTestsMatching 'com.test.web.desktop.LocalTest' } } -tasks.register('android-single', Test) { - useTestNG() - include '**/android/SingleTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task webFail(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/web/config/web_single.yml' + filter { + includeTestsMatching 'com.test.web.desktop.FailTest' } } -tasks.register('android-parallel', Test) { - useTestNG() { - suites 'src/test/resources/app/suites/android.parallel.testng.xml' - systemProperty 'config', 'android' - parallel project.property('parallel') - threadCount Integer.parseInt(project.property('threads')) - } - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task androidSingle(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/app/config/android_single.yml' + filter { + includeTestsMatching 'com.test.app.appium.android.SingleTest' } } -tasks.register('android-fail', Test) { - useTestNG() - include '**/android/FailTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task androidParallel(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/app/config/android_parallel.yml' + filter { + includeTestsMatching 'com.test.app.appium.android.SingleTest' } } -tasks.register('android-local', Test) { - useTestNG() - include '**/android/LocalTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task androidLocal(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/app/config/android_local.yml' + filter { + includeTestsMatching 'com.test.app.appium.android.LocalTest' } } -tasks.register('android-local-parallel', Test) { - useTestNG() { - suites 'src/test/resources/app/suites/android.local.testng.xml' - systemProperty 'config', 'android' - parallel project.property('parallel') - threadCount Integer.parseInt(project.property('threads')) - } - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task androidFail(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/app/config/android_single.yml' + filter { + includeTestsMatching 'com.test.app.appium.android.FailTest' } } -tasks.register('ios-single', Test) { - useTestNG() - include '**/ios/SingleTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task iosSingle(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/app/config/ios_single.yml' + filter { + includeTestsMatching 'com.test.app.appium.ios.SingleTest' } } -tasks.register('ios-parallel', Test) { - useTestNG() { - suites 'src/test/resources/app/suites/ios.parallel.testng.xml' - systemProperty 'config', 'ios' - parallel project.property('parallel') - threadCount Integer.parseInt(project.property('threads')) - } - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task iosParallel(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/app/config/ios_parallel.yml' + filter { + includeTestsMatching 'com.test.app.appium.ios.SingleTest' } } -tasks.register('ios-fail', Test) { - useTestNG() - include '**/ios/FailTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task iosLocal(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/app/config/ios_local.yml' + filter { + includeTestsMatching 'com.test.app.appium.ios.LocalTest' } } -tasks.register('ios-local', Test) { - useTestNG() - include '**/ios/LocalTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task iosFail(type: Test) { + systemProperty 'browserstack.config', 'src/test/resources/app/config/ios_single.yml' + filter { + includeTestsMatching 'com.test.app.appium.ios.FailTest' } } -tasks.register('ios-local-parallel', Test) { - useTestNG() { - suites 'src/test/resources/app/suites/ios.local.testng.xml' - systemProperty 'config', 'ios' - parallel project.property('parallel') - threadCount Integer.parseInt(project.property('threads')) - } - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task espresso(type: Test) { + jvmArgs = [] + filter { + includeTestsMatching 'com.test.app.espresso.EspressoTest' } } -tasks.register('espresso', Test) { - useTestNG() - include '**/EspressoTest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" +task xcuitest(type: Test) { + jvmArgs = [] + filter { + includeTestsMatching 'com.test.app.xcui.XCUITest' } } -tasks.register('xcuitest', Test) { - useTestNG() - include '**/XCUITest.class' - testLogging { - events "PASSED", "FAILED", "SKIPPED" - } +task runServer(type: JavaExec) { + group = 'application' + description = 'Run the HTTP server' + classpath = sourceSets.main.runtimeClasspath + mainClass = 'com.local.server.MyHttpServer' } diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index c1de52e..0000000 --- a/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -parallel=tests -threads=5 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c..f8e1ee3 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8d3103b..23449a2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists \ No newline at end of file +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 744e882..adff685 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,81 +15,114 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MSYS* | MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,88 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..e509b2d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,8 +13,10 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +27,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,32 +59,33 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/pom.xml b/pom.xml index 659e47b..27f697d 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,6 @@ 1.8 UTF-8 UTF-8 - 5 @@ -21,18 +20,26 @@ io.appium java-client - 7.5.1 + 8.6.0 + + + + org.seleniumhq.selenium + selenium-java + 4.13.0 org.testng testng - 7.4.0 + 7.9.0 + com.browserstack - browserstack-local-java - 1.0.3 + browserstack-java-sdk + 1.41.0 + compile @@ -42,9 +49,35 @@ + + + + maven-dependency-plugin + + + getClasspathFilenames + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + -javaagent:${com.browserstack:browserstack-java-sdk:jar} + + + + + + - desktop-single + web-single true @@ -55,67 +88,14 @@ maven-surefire-plugin 3.0.0-M5 - - **/desktop/SingleTest.java - - - - - - - - desktop-parallel - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - tests - ${threads} - config - desktop + browserstack.config + src/test/resources/web/config/web_single.yml - - src/test/resources/web/suites/parallel.testng.xml - - - - - - - - desktop-fail - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - - **/desktop/FailTest.java - - - - - - - - desktop-local - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - **/desktop/LocalTest.java + **/desktop/SingleTest.java @@ -123,7 +103,7 @@ - desktop-local-parallel + web-parallel @@ -131,33 +111,14 @@ maven-surefire-plugin 3.0.0-M5 - tests - ${threads} - config - desktop + browserstack.config + src/test/resources/web/config/web_parallel.yml - - src/test/resources/web/suites/local.testng.xml - - - - - - - - mobile-single - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - **/mobile/SingleTest.java + **/desktop/SingleTest.java @@ -165,7 +126,7 @@ - mobile-parallel + web-fail @@ -173,50 +134,14 @@ maven-surefire-plugin 3.0.0-M5 - tests - ${threads} - config - mobile + browserstack.config + src/test/resources/web/config/web_single.yml - - src/test/resources/web/suites/parallel.testng.xml - - - - - - - - mobile-fail - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - **/mobile/FailTest.java - - - - - - - - mobile-local - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - - **/mobile/LocalTest.java + **/desktop/FailTest.java @@ -224,7 +149,7 @@ - mobile-local-parallel + web-local @@ -232,17 +157,15 @@ maven-surefire-plugin 3.0.0-M5 - tests - ${threads} - config - mobile + browserstack.config + src/test/resources/web/config/web_local.yml - - src/test/resources/web/suites/local.testng.xml - + + **/desktop/LocalTest.java + @@ -272,6 +195,12 @@ maven-surefire-plugin 3.0.0-M5 + + + browserstack.config + src/test/resources/app/config/android_single.yml + + **/android/SingleTest.java @@ -289,17 +218,15 @@ maven-surefire-plugin 3.0.0-M5 - tests - ${threads} - config - android + browserstack.config + src/test/resources/app/config/android_parallel.yml - - src/test/resources/app/suites/android.parallel.testng.xml - + + **/android/SingleTest.java + @@ -314,6 +241,12 @@ maven-surefire-plugin 3.0.0-M5 + + + browserstack.config + src/test/resources/app/config/android_single.yml + + **/android/FailTest.java @@ -331,6 +264,12 @@ maven-surefire-plugin 3.0.0-M5 + + + browserstack.config + src/test/resources/app/config/android_local.yml + + **/android/LocalTest.java @@ -340,7 +279,7 @@ - android-local-parallel + ios-single @@ -348,24 +287,22 @@ maven-surefire-plugin 3.0.0-M5 - tests - ${threads} - config - android + browserstack.config + src/test/resources/app/config/ios_single.yml - - src/test/resources/app/suites/android.local.testng.xml - + + **/ios/SingleTest.java + - ios-single + jlp-ios @@ -373,8 +310,14 @@ maven-surefire-plugin 3.0.0-M5 + + + browserstack.config + src/test/resources/app/config/jlp_ios_single.yml + + - **/ios/SingleTest.java + **/ios/JLPTest.java @@ -390,17 +333,15 @@ maven-surefire-plugin 3.0.0-M5 - tests - ${threads} - config - ios + browserstack.config + src/test/resources/app/config/ios_parallel.yml - - src/test/resources/app/suites/ios.parallel.testng.xml - + + **/ios/SingleTest.java + @@ -415,6 +356,12 @@ maven-surefire-plugin 3.0.0-M5 + + + browserstack.config + src/test/resources/app/config/ios_single.yml + + **/ios/FailTest.java @@ -432,34 +379,15 @@ maven-surefire-plugin 3.0.0-M5 - - **/ios/LocalTest.java - - - - - - - - ios-local-parallel - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - tests - ${threads} - config - ios + browserstack.config + src/test/resources/app/config/ios_local.yml - - src/test/resources/app/suites/ios.local.testng.xml - + + **/ios/LocalTest.java + diff --git a/src/test/java/com/test/app/appium/android/FailTest.java b/src/test/java/com/test/app/appium/android/FailTest.java index a1a9c3c..de8ffee 100644 --- a/src/test/java/com/test/app/appium/android/FailTest.java +++ b/src/test/java/com/test/app/appium/android/FailTest.java @@ -1,11 +1,10 @@ package com.test.app.appium.android; import com.utils.AppUtils; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; +import io.appium.java_client.AppiumBy; import io.appium.java_client.android.AndroidDriver; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.NotFoundException; +import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; @@ -15,7 +14,6 @@ import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; @@ -26,11 +24,7 @@ public class FailTest { - private MobileDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; + private AndroidDriver driver; @BeforeSuite(alwaysRun = true) public void setupApp() { @@ -38,43 +32,27 @@ public void setupApp() { } @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { + public void setup() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "Google Pixel 7"); - caps.setCapability("os_version", "13.0"); - caps.setCapability("app", "AndroidDemoApp"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - - driver = new AndroidDriver<>(new URL(HUB_URL), caps); + driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test public void searchWikipedia() { - Wait> wait = new FluentWait<>(driver) + Wait wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(10)) .ignoring(NotFoundException.class); - driver.findElementByAccessibilityId("Search Wikipedia").click(); - MobileElement insertTextElement = wait.until(d -> d.findElementById("org.wikipedia.alpha:id/search_src_text")); + driver.findElement(AppiumBy.accessibilityId("Search Wikipedia")).click(); + WebElement insertTextElement = wait.until(d -> d.findElement(AppiumBy.id("org.wikipedia.alpha:id/search_src_text"))); insertTextElement.sendKeys("BrowserStack"); - wait.until(d -> d.findElementByClassName("android.widget.ListView").isDisplayed()); - List companyNames = driver.findElementsByClassName("android.widget.TextView") - .stream().map(MobileElement::getText).collect(toList()); + wait.until(d -> d.findElement(AppiumBy.className("android.widget.ListView"))); + List companyNames = driver.findElements(AppiumBy.className("android.widget.TextView")) + .stream().map(WebElement::getText).collect(toList()); assertFalse(companyNames.contains("BrowserStack"), "Company is present in the list"); } @AfterMethod(alwaysRun = true) public void teardown(ITestResult tr) { - JavascriptExecutor js = (JavascriptExecutor) driver; - String reason = tr.getThrowable().getMessage().split("\\n")[0].replaceAll("[\\\\{}\"]", ""); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"failed\", \"reason\": \"" + reason + "\"}}"); driver.quit(); } diff --git a/src/test/java/com/test/app/appium/android/LocalParallelTest.java b/src/test/java/com/test/app/appium/android/LocalParallelTest.java deleted file mode 100644 index 553b366..0000000 --- a/src/test/java/com/test/app/appium/android/LocalParallelTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.test.app.appium.android; - -import com.utils.AppUtils; -import com.utils.LocalUtils; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; -import io.appium.java_client.android.AndroidDriver; -import io.restassured.path.json.JsonPath; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.testng.annotations.*; - -import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import static java.util.stream.Collectors.joining; -import static org.testng.Assert.assertTrue; - -public class LocalParallelTest { - - private static final ThreadLocal> driverThread = new ThreadLocal<>(); - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeSuite(alwaysRun = true) - public void setupApp() { - AppUtils.uploadApp("AndroidLocalApp", "android/LocalSample.apk"); - LocalUtils.startLocal(); - } - - @BeforeMethod(alwaysRun = true) - @Parameters({"config", "capability"}) - public void setupDriver(String configFile, String capability, Method m) throws MalformedURLException { - JsonPath jsonPath = JsonPath.from(new File("src/test/resources/app/config/" + configFile + ".json")); - Map capabilitiesMap = new HashMap<>(); - capabilitiesMap.putAll(jsonPath.getMap("commonCapabilities")); - capabilitiesMap.putAll(jsonPath.getMap("capabilities[" + capability + "]")); - capabilitiesMap.put("name", m.getName()); - capabilitiesMap.put("app", "AndroidLocalApp"); - capabilitiesMap.put("browserstack.user", USERNAME); - capabilitiesMap.put("browserstack.key", ACCESS_KEY); - capabilitiesMap.put("browserstack.local", "true"); - driverThread.set(new AndroidDriver<>(new URL(HUB_URL), new DesiredCapabilities(capabilitiesMap))); - } - - @Test - public void testLocalConnection() { - MobileDriver driver = driverThread.get(); - driver.findElementById("com.example.android.basicnetworking:id/test_action").click(); - String allText = driver.findElementsByClassName("android.widget.TextView") - .stream().map(MobileElement::getText).collect(joining()); - assertTrue(allText.contains("The active connection is wifi."), "Text is not present"); - assertTrue(allText.contains("Response is: Up and running"), "Text is not present"); - } - - @AfterMethod(alwaysRun = true) - public void tearDown() { - JavascriptExecutor js = (JavascriptExecutor) driverThread.get(); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); - driverThread.get().quit(); - driverThread.remove(); - } - - @AfterSuite(alwaysRun = true) - public void closeLocal() { - LocalUtils.stopLocal(); - } - -} diff --git a/src/test/java/com/test/app/appium/android/LocalTest.java b/src/test/java/com/test/app/appium/android/LocalTest.java index be20133..f40631a 100644 --- a/src/test/java/com/test/app/appium/android/LocalTest.java +++ b/src/test/java/com/test/app/appium/android/LocalTest.java @@ -1,15 +1,15 @@ package com.test.app.appium.android; import com.utils.AppUtils; -import com.utils.LocalUtils; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; +import io.appium.java_client.AppiumBy; import io.appium.java_client.android.AndroidDriver; -import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; -import org.testng.annotations.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -18,57 +18,31 @@ public class LocalTest { - private MobileDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; + private AndroidDriver driver; @BeforeSuite(alwaysRun = true) public void setupAppAndLocal() { AppUtils.uploadApp("AndroidLocalApp", "android/LocalSample.apk"); - LocalUtils.startLocal(); } @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { + public void setup() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "Google Pixel 7"); - caps.setCapability("os_version", "13.0"); - caps.setCapability("app", "AndroidLocalApp"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - caps.setCapability("browserstack.local", true); - - driver = new AndroidDriver<>(new URL(HUB_URL), caps); + driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test public void testLocalConnection() { - driver.findElementById("com.example.android.basicnetworking:id/test_action").click(); - String allText = driver.findElementsByClassName("android.widget.TextView") - .stream().map(MobileElement::getText).collect(joining()); + driver.findElement(AppiumBy.id("com.example.android.basicnetworking:id/test_action")).click(); + String allText = driver.findElements(AppiumBy.className("android.widget.TextView")) + .stream().map(WebElement::getText).collect(joining()); assertTrue(allText.contains("The active connection is wifi"), "Text is not present"); assertTrue(allText.contains("Up and running"), "Text is not present"); } @AfterMethod(alwaysRun = true) public void closeDriver() { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); driver.quit(); } - @AfterSuite(alwaysRun = true) - public void closeLocal() { - LocalUtils.stopLocal(); - } - } \ No newline at end of file diff --git a/src/test/java/com/test/app/appium/android/ParallelTest.java b/src/test/java/com/test/app/appium/android/ParallelTest.java deleted file mode 100644 index 353a8ac..0000000 --- a/src/test/java/com/test/app/appium/android/ParallelTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.test.app.appium.android; - -import com.utils.AppUtils; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; -import io.appium.java_client.android.AndroidDriver; -import io.restassured.path.json.JsonPath; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.NotFoundException; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.support.ui.FluentWait; -import org.openqa.selenium.support.ui.Wait; -import org.testng.annotations.*; - -import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.time.Duration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static java.util.stream.Collectors.toList; -import static org.testng.Assert.assertTrue; - -public class ParallelTest { - - private static final ThreadLocal> driverThread = new ThreadLocal<>(); - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeSuite(alwaysRun = true) - public void setupApp() { - AppUtils.uploadApp("AndroidDemoApp", "android/WikipediaSample.apk"); - } - - @BeforeMethod(alwaysRun = true) - @Parameters({"config", "capability"}) - public void setupDriver(String configFile, String capability, Method m) throws MalformedURLException { - JsonPath jsonPath = JsonPath.from(new File("src/test/resources/app/config/" + configFile + ".json")); - Map capabilitiesMap = new HashMap<>(); - capabilitiesMap.putAll(jsonPath.getMap("commonCapabilities")); - capabilitiesMap.putAll(jsonPath.getMap("capabilities[" + capability + "]")); - capabilitiesMap.put("name", m.getName()); - capabilitiesMap.put("app", "AndroidDemoApp"); - capabilitiesMap.put("browserstack.user", USERNAME); - capabilitiesMap.put("browserstack.key", ACCESS_KEY); - driverThread.set(new AndroidDriver<>(new URL(HUB_URL), new DesiredCapabilities(capabilitiesMap))); - } - - @Test - public void searchWikipedia() { - MobileDriver driver = driverThread.get(); - Wait> wait = new FluentWait<>(driver) - .withTimeout(Duration.ofSeconds(10)) - .ignoring(NotFoundException.class); - driver.findElementByAccessibilityId("Search Wikipedia").click(); - MobileElement insertTextElement = wait.until(d -> d.findElementById("org.wikipedia.alpha:id/search_src_text")); - insertTextElement.sendKeys("BrowserStack"); - wait.until(d -> d.findElementByClassName("android.widget.ListView").isDisplayed()); - List companyNames = driver.findElementsByClassName("android.widget.TextView") - .stream().map(MobileElement::getText).collect(toList()); - assertTrue(companyNames.contains("BrowserStack"), "Company is not present in the list"); - } - - @AfterMethod(alwaysRun = true) - public void tearDown() { - JavascriptExecutor js = (JavascriptExecutor) driverThread.get(); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); - driverThread.get().quit(); - driverThread.remove(); - } - -} diff --git a/src/test/java/com/test/app/appium/android/SingleTest.java b/src/test/java/com/test/app/appium/android/SingleTest.java index e82e8cd..64c0961 100644 --- a/src/test/java/com/test/app/appium/android/SingleTest.java +++ b/src/test/java/com/test/app/appium/android/SingleTest.java @@ -1,11 +1,10 @@ package com.test.app.appium.android; import com.utils.AppUtils; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; +import io.appium.java_client.AppiumBy; import io.appium.java_client.android.AndroidDriver; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.NotFoundException; +import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; @@ -14,7 +13,6 @@ import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; @@ -25,11 +23,7 @@ public class SingleTest { - private MobileDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; + private AndroidDriver driver; @BeforeSuite(alwaysRun = true) public void setupApp() { @@ -37,42 +31,27 @@ public void setupApp() { } @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { + public void setup() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "Google Pixel 7"); - caps.setCapability("os_version", "13.0"); - caps.setCapability("app", "AndroidDemoApp"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - - driver = new AndroidDriver<>(new URL(HUB_URL), caps); + driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test - public void searchWikipedia() { - Wait> wait = new FluentWait<>(driver) + public void searchWikipedia() throws InterruptedException { + Wait wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(10)) .ignoring(NotFoundException.class); - driver.findElementByAccessibilityId("Search Wikipedia").click(); - MobileElement insertTextElement = wait.until(d -> d.findElementById("org.wikipedia.alpha:id/search_src_text")); + driver.findElement(AppiumBy.accessibilityId("Search Wikipedia")).click(); + WebElement insertTextElement = wait.until(d -> d.findElement(AppiumBy.id("org.wikipedia.alpha:id/search_src_text"))); insertTextElement.sendKeys("BrowserStack"); - wait.until(d -> d.findElementByClassName("android.widget.ListView").isDisplayed()); - List companyNames = driver.findElementsByClassName("android.widget.TextView") - .stream().map(MobileElement::getText).collect(toList()); - assertTrue(companyNames.contains("BrowserStack"), "Company is not present in the list"); + wait.until(d -> d.findElement(AppiumBy.className("android.widget.ListView"))); + List companyNames = driver.findElements(AppiumBy.className("android.widget.TextView")) + .stream().map(WebElement::getText).collect(toList()); + assertTrue(companyNames.contains("BrowserStack"), "Company is present in the list"); } @AfterMethod(alwaysRun = true) public void tearDown() { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); driver.quit(); } } \ No newline at end of file diff --git a/src/test/java/com/test/app/appium/ios/FailTest.java b/src/test/java/com/test/app/appium/ios/FailTest.java index 9fd40af..1ecf7f9 100644 --- a/src/test/java/com/test/app/appium/ios/FailTest.java +++ b/src/test/java/com/test/app/appium/ios/FailTest.java @@ -1,10 +1,8 @@ package com.test.app.appium.ios; import com.utils.AppUtils; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; +import io.appium.java_client.AppiumBy; import io.appium.java_client.ios.IOSDriver; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; import org.openqa.selenium.remote.DesiredCapabilities; import org.testng.ITestResult; @@ -13,7 +11,6 @@ import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -21,11 +18,7 @@ public class FailTest { - private MobileDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; + private IOSDriver driver; @BeforeSuite(alwaysRun = true) public void setupApp() { @@ -33,38 +26,22 @@ public void setupApp() { } @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { + public void setup() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "iPhone 14"); - caps.setCapability("os_version", "16"); - caps.setCapability("app", "iOSDemoApp"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - - driver = new IOSDriver<>(new URL(HUB_URL), caps); + driver = new IOSDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test public void printText() { - driver.findElementByAccessibilityId("Text Button").click(); - driver.findElementByAccessibilityId("Text Input").click(); - driver.findElementByAccessibilityId("Text Input").sendKeys("Welcome to BrowserStack" + Keys.ENTER); - assertNotEquals(driver.findElementByAccessibilityId("Text Output").getText(), + driver.findElement(AppiumBy.accessibilityId("Text Button")).click(); + driver.findElement(AppiumBy.accessibilityId("Text Input")).click(); + driver.findElement(AppiumBy.accessibilityId("Text Input")).sendKeys("Welcome to BrowserStack" + Keys.ENTER); + assertNotEquals(driver.findElement(AppiumBy.accessibilityId("Text Output")).getText(), "Welcome to BrowserStack", "Incorrect text"); } @AfterMethod(alwaysRun = true) public void teardown(ITestResult tr) { - JavascriptExecutor js = (JavascriptExecutor) driver; - String reason = tr.getThrowable().getMessage().split("\\n")[0].replaceAll("[\\\\{}\"]", ""); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"failed\", \"reason\": \"" + reason + "\"}}"); driver.quit(); } diff --git a/src/test/java/com/test/app/appium/ios/LocalParallelTest.java b/src/test/java/com/test/app/appium/ios/LocalParallelTest.java deleted file mode 100644 index 5d06ff7..0000000 --- a/src/test/java/com/test/app/appium/ios/LocalParallelTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.test.app.appium.ios; - -import com.utils.AppUtils; -import com.utils.LocalUtils; -import io.appium.java_client.MobileBy; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; -import io.appium.java_client.ios.IOSDriver; -import io.restassured.path.json.JsonPath; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.NotFoundException; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.support.ui.FluentWait; -import org.openqa.selenium.support.ui.Wait; -import org.testng.annotations.*; - -import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; - -import static org.testng.Assert.assertEquals; - -public class LocalParallelTest { - - private static final ThreadLocal> driverThread = new ThreadLocal<>(); - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeSuite(alwaysRun = true) - public void setupApp() { - AppUtils.uploadApp("iOSLocalApp", "ios/LocalSample.ipa"); - LocalUtils.startLocal(); - } - - @BeforeMethod(alwaysRun = true) - @Parameters({"config", "capability"}) - public void setupDriver(String configFile, String capability, Method m) throws MalformedURLException { - JsonPath jsonPath = JsonPath.from(new File("src/test/resources/app/config/" + configFile + ".json")); - Map capabilitiesMap = new HashMap<>(); - capabilitiesMap.putAll(jsonPath.getMap("commonCapabilities")); - capabilitiesMap.putAll(jsonPath.getMap("capabilities[" + capability + "]")); - capabilitiesMap.put("name", m.getName()); - capabilitiesMap.put("app", "iOSLocalApp"); - capabilitiesMap.put("browserstack.user", USERNAME); - capabilitiesMap.put("browserstack.key", ACCESS_KEY); - capabilitiesMap.put("browserstack.local", "true"); - driverThread.set(new IOSDriver<>(new URL(HUB_URL), new DesiredCapabilities(capabilitiesMap))); - } - - @Test - public void testLocalConnection() { - MobileDriver driver = driverThread.get(); - Wait> wait = new FluentWait<>(driver) - .withTimeout(Duration.ofSeconds(10)) - .pollingEvery(Duration.ofMillis(500)) - .ignoring(NotFoundException.class); - driver.findElementByAccessibilityId("TestBrowserStackLocal").click(); - By result = MobileBy.AccessibilityId("ResultBrowserStackLocal"); - wait.until(d -> d.findElement(result).getText().contains("Response is:")); - String resultText = driver.findElement(result).getText(); - assertEquals(resultText, "Response is: Up and running", "Local connection is not up"); - } - - @AfterTest(alwaysRun = true) - public void tearDown() { - JavascriptExecutor js = (JavascriptExecutor) driverThread.get(); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); - driverThread.get().quit(); - driverThread.remove(); - } - - @AfterSuite(alwaysRun = true) - public void closeLocal() throws Exception { - LocalUtils.stopLocal(); - } - -} diff --git a/src/test/java/com/test/app/appium/ios/LocalTest.java b/src/test/java/com/test/app/appium/ios/LocalTest.java index 28ade91..320f3b0 100644 --- a/src/test/java/com/test/app/appium/ios/LocalTest.java +++ b/src/test/java/com/test/app/appium/ios/LocalTest.java @@ -1,20 +1,18 @@ package com.test.app.appium.ios; import com.utils.AppUtils; -import com.utils.LocalUtils; -import io.appium.java_client.MobileBy; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; +import io.appium.java_client.AppiumBy; import io.appium.java_client.ios.IOSDriver; import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.NotFoundException; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; -import org.testng.annotations.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; @@ -23,46 +21,27 @@ public class LocalTest { - private MobileDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; + private IOSDriver driver; @BeforeSuite(alwaysRun = true) public void setupAppAndLocal() { AppUtils.uploadApp("iOSLocalApp", "ios/LocalSample.ipa"); - LocalUtils.startLocal(); } @BeforeMethod(alwaysRun = true) - public void setupDriver(Method m) throws MalformedURLException { + public void setupDriver() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "iPhone 14"); - caps.setCapability("os_version", "16"); - caps.setCapability("app", "iOSLocalApp"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - caps.setCapability("browserstack.local", true); - - driver = new IOSDriver<>(new URL(HUB_URL), caps); + driver = new IOSDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test public void testLocalConnection() { - Wait> wait = new FluentWait<>(driver) + Wait wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(10)) .pollingEvery(Duration.ofMillis(500)) .ignoring(NotFoundException.class); - driver.findElementByAccessibilityId("TestBrowserStackLocal").click(); - By result = MobileBy.AccessibilityId("ResultBrowserStackLocal"); + driver.findElement(AppiumBy.accessibilityId("TestBrowserStackLocal")).click(); + By result = AppiumBy.accessibilityId("ResultBrowserStackLocal"); wait.until(d -> d.findElement(result).getText().contains("Up and running")); String resultText = driver.findElement(result).getText(); assertEquals(resultText, "Up and running", "Local connection is not up"); @@ -70,14 +49,7 @@ public void testLocalConnection() { @AfterMethod(alwaysRun = true) public void closeDriver() { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); driver.quit(); } - @AfterSuite(alwaysRun = true) - public void closeLocal() { - LocalUtils.stopLocal(); - } - } \ No newline at end of file diff --git a/src/test/java/com/test/app/appium/ios/ParallelTest.java b/src/test/java/com/test/app/appium/ios/ParallelTest.java deleted file mode 100644 index a51c9a7..0000000 --- a/src/test/java/com/test/app/appium/ios/ParallelTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.test.app.appium.ios; - -import com.utils.AppUtils; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; -import io.appium.java_client.ios.IOSDriver; -import io.restassured.path.json.JsonPath; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.Keys; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.testng.annotations.*; - -import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import static org.testng.Assert.assertEquals; - -public class ParallelTest { - - private static final ThreadLocal> driverThread = new ThreadLocal<>(); - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeSuite(alwaysRun = true) - public void setupApp() { - AppUtils.uploadApp("iOSDemoApp", "ios/BStackSampleApp.ipa"); - } - - @BeforeMethod(alwaysRun = true) - @Parameters({"config", "capability"}) - public void setupDriver(String configFile, String capability, Method m) throws MalformedURLException { - JsonPath jsonPath = JsonPath.from(new File("src/test/resources/app/config/" + configFile + ".json")); - Map capabilitiesMap = new HashMap<>(); - capabilitiesMap.putAll(jsonPath.getMap("commonCapabilities")); - capabilitiesMap.putAll(jsonPath.getMap("capabilities[" + capability + "]")); - capabilitiesMap.put("name", m.getName()); - capabilitiesMap.put("app", "iOSDemoApp"); - capabilitiesMap.put("browserstack.user", USERNAME); - capabilitiesMap.put("browserstack.key", ACCESS_KEY); - driverThread.set(new IOSDriver<>(new URL(HUB_URL), new DesiredCapabilities(capabilitiesMap))); - } - - @Test - public void printText() { - MobileDriver driver = driverThread.get(); - driver.findElementByAccessibilityId("Text Button").click(); - driver.findElementByAccessibilityId("Text Input").click(); - driver.findElementByAccessibilityId("Text Input").sendKeys("Welcome to BrowserStack" + Keys.ENTER); - assertEquals(driver.findElementByAccessibilityId("Text Output").getText(), - "Welcome to BrowserStack", "Incorrect text"); - } - - @AfterTest(alwaysRun = true) - public void tearDown() { - JavascriptExecutor js = (JavascriptExecutor) driverThread.get(); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); - driverThread.get().quit(); - driverThread.remove(); - } - -} diff --git a/src/test/java/com/test/app/appium/ios/SingleTest.java b/src/test/java/com/test/app/appium/ios/SingleTest.java index 949a99b..e93998b 100644 --- a/src/test/java/com/test/app/appium/ios/SingleTest.java +++ b/src/test/java/com/test/app/appium/ios/SingleTest.java @@ -1,10 +1,8 @@ package com.test.app.appium.ios; import com.utils.AppUtils; -import io.appium.java_client.MobileDriver; -import io.appium.java_client.MobileElement; +import io.appium.java_client.AppiumBy; import io.appium.java_client.ios.IOSDriver; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; import org.openqa.selenium.remote.DesiredCapabilities; import org.testng.annotations.AfterMethod; @@ -12,7 +10,6 @@ import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -20,11 +17,7 @@ public class SingleTest { - private MobileDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; + private IOSDriver driver; @BeforeSuite(alwaysRun = true) public void setupApp() { @@ -32,37 +25,22 @@ public void setupApp() { } @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { + public void setup() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "iPhone 14"); - caps.setCapability("os_version", "16"); - caps.setCapability("app", "iOSDemoApp"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - - driver = new IOSDriver<>(new URL(HUB_URL), caps); + driver = new IOSDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test public void printText() { - driver.findElementByAccessibilityId("Text Button").click(); - driver.findElementByAccessibilityId("Text Input").click(); - driver.findElementByAccessibilityId("Text Input").sendKeys("Welcome to BrowserStack" + Keys.ENTER); - assertEquals(driver.findElementByAccessibilityId("Text Output").getText(), + driver.findElement(AppiumBy.accessibilityId("Text Button")).click(); + driver.findElement(AppiumBy.accessibilityId("Text Input")).click(); + driver.findElement(AppiumBy.accessibilityId("Text Input")).sendKeys("Welcome to BrowserStack" + Keys.ENTER); + assertEquals(driver.findElement(AppiumBy.accessibilityId("Text Output")).getText(), "Welcome to BrowserStack", "Incorrect text"); } @AfterMethod(alwaysRun = true) public void tearDown() { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); driver.quit(); } } \ No newline at end of file diff --git a/src/test/java/com/test/web/desktop/FailTest.java b/src/test/java/com/test/web/desktop/FailTest.java index 8c33919..629c3ce 100644 --- a/src/test/java/com/test/web/desktop/FailTest.java +++ b/src/test/java/com/test/web/desktop/FailTest.java @@ -1,7 +1,6 @@ package com.test.web.desktop; import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; @@ -11,9 +10,9 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; +import java.time.Duration; import static org.openqa.selenium.Keys.TAB; import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable; @@ -24,33 +23,15 @@ public class FailTest { private WebDriver driver; - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { + public void setup() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("os", "Windows"); - caps.setCapability("os_version", "10"); - caps.setCapability("browser", "Chrome"); - caps.setCapability("browser_version", "latest"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - - driver = new RemoteWebDriver(new URL(HUB_URL), caps); + driver = new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test public void bStackDemoLogin() { - WebDriverWait wait = new WebDriverWait(driver, 10); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); driver.get("https://bstackdemo.com"); wait.until(elementToBeClickable(By.id("signin"))).click(); wait.until(elementToBeClickable(By.cssSelector("#username input"))).sendKeys("fav_user" + TAB); @@ -62,10 +43,6 @@ public void bStackDemoLogin() { @AfterMethod(alwaysRun = true) public void closeDriver(ITestResult tr) { - JavascriptExecutor js = (JavascriptExecutor) driver; - String reason = tr.getThrowable().getMessage().split("\\n")[0].replaceAll("[\\\\{}\"]", ""); - System.out.println(reason); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"failed\", \"reason\": \"" + reason + "\"}}"); driver.quit(); } diff --git a/src/test/java/com/test/web/desktop/LocalParallelTest.java b/src/test/java/com/test/web/desktop/LocalParallelTest.java deleted file mode 100644 index 9deb2c7..0000000 --- a/src/test/java/com/test/web/desktop/LocalParallelTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.test.web.desktop; - -import com.utils.LocalUtils; -import io.restassured.path.json.JsonPath; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.testng.annotations.*; - -import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import static org.testng.Assert.assertEquals; - -public class LocalParallelTest { - - private static final ThreadLocal driverThread = new ThreadLocal<>(); - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeSuite(alwaysRun = true) - public void before() { - LocalUtils.startLocal(); - } - - @BeforeMethod(alwaysRun = true) - @Parameters({"config", "capability"}) - public void setup(String configFile, String capability, Method m) throws MalformedURLException { - JsonPath jsonPath = JsonPath.from(new File("src/test/resources/web/config/" + configFile + ".json")); - Map capabilitiesMap = new HashMap<>(); - capabilitiesMap.putAll(jsonPath.getMap("commonCapabilities")); - capabilitiesMap.putAll(jsonPath.getMap("capabilities[" + capability + "]")); - capabilitiesMap.put("name", m.getName()); - capabilitiesMap.put("browserstack.user", USERNAME); - capabilitiesMap.put("browserstack.key", ACCESS_KEY); - capabilitiesMap.put("browserstack.local", "true"); - driverThread.set(new RemoteWebDriver(new URL(HUB_URL), new DesiredCapabilities(capabilitiesMap))); - } - - @Test - public void openLocalWebPage() { - WebDriver driver = driverThread.get(); - driver.get("http://localhost:8000"); - assertEquals(driver.getTitle(), "Local Server", "Incorrect title"); - } - - @AfterMethod(alwaysRun = true) - public void closeDriver() { - JavascriptExecutor js = (JavascriptExecutor) driverThread.get(); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); - driverThread.get().quit(); - driverThread.remove(); - } - - @AfterSuite(alwaysRun = true) - public void closeLocal() { - LocalUtils.stopLocal(); - } - -} diff --git a/src/test/java/com/test/web/desktop/LocalTest.java b/src/test/java/com/test/web/desktop/LocalTest.java index 28f4d98..ec7d263 100644 --- a/src/test/java/com/test/web/desktop/LocalTest.java +++ b/src/test/java/com/test/web/desktop/LocalTest.java @@ -1,13 +1,12 @@ package com.test.web.desktop; -import com.utils.LocalUtils; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; -import org.testng.annotations.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -17,34 +16,10 @@ public class LocalTest { private WebDriver driver; - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeSuite(alwaysRun = true) - public void setupLocal() { - LocalUtils.startLocal(); - } - @BeforeMethod(alwaysRun = true) - public void setupDriver(Method m) throws MalformedURLException { + public void setupDriver() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("os", "Windows"); - caps.setCapability("os_version", "10"); - caps.setCapability("browser", "Chrome"); - caps.setCapability("browser_version", "latest"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - caps.setCapability("browserstack.local", true); - - driver = new RemoteWebDriver(new URL(HUB_URL), caps); + driver = new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test @@ -55,14 +30,7 @@ public void openLocalWebPage() { @AfterMethod(alwaysRun = true) public void closeDriver() { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); driver.quit(); } - @AfterSuite(alwaysRun = true) - public void closeLocal() { - LocalUtils.stopLocal(); - } - } diff --git a/src/test/java/com/test/web/desktop/ParallelTest.java b/src/test/java/com/test/web/desktop/ParallelTest.java deleted file mode 100644 index b14743e..0000000 --- a/src/test/java/com/test/web/desktop/ParallelTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.test.web.desktop; - -import io.restassured.path.json.JsonPath; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.ui.WebDriverWait; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Parameters; -import org.testng.annotations.Test; - -import java.io.File; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import static org.openqa.selenium.Keys.TAB; -import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable; -import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated; -import static org.testng.Assert.assertEquals; - -public class ParallelTest { - - private static final ThreadLocal driverThread = new ThreadLocal<>(); - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeMethod(alwaysRun = true) - @Parameters({"config", "capability"}) - public void setup(String configFile, String capability, Method m) throws MalformedURLException { - JsonPath jsonPath = JsonPath.from(new File("src/test/resources/web/config/" + configFile + ".json")); - Map capabilitiesMap = new HashMap<>(); - capabilitiesMap.putAll(jsonPath.getMap("commonCapabilities")); - capabilitiesMap.putAll(jsonPath.getMap("capabilities[" + capability + "]")); - capabilitiesMap.put("name", m.getName()); - capabilitiesMap.put("browserstack.user", USERNAME); - capabilitiesMap.put("browserstack.key", ACCESS_KEY); - driverThread.set(new RemoteWebDriver(new URL(HUB_URL), new DesiredCapabilities(capabilitiesMap))); - } - - @Test - public void bStackDemoLogin() { - WebDriver driver = driverThread.get(); - WebDriverWait wait = new WebDriverWait(driver, 10); - driver.get("https://bstackdemo.com"); - wait.until(elementToBeClickable(By.id("signin"))).click(); - wait.until(elementToBeClickable(By.cssSelector("#username input"))).sendKeys("fav_user" + TAB); - driver.findElement(By.cssSelector("#password input")).sendKeys("testingisfun99" + TAB); - driver.findElement(By.id("login-btn")).click(); - String username = wait.until(presenceOfElementLocated(By.className("username"))).getText(); - assertEquals(username, "fav_user", "Incorrect username"); - } - - @AfterMethod(alwaysRun = true) - public void closeDriver() { - JavascriptExecutor js = (JavascriptExecutor) driverThread.get(); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); - driverThread.get().quit(); - driverThread.remove(); - } - -} diff --git a/src/test/java/com/test/web/desktop/SingleTest.java b/src/test/java/com/test/web/desktop/SingleTest.java index e6dceac..88087d8 100644 --- a/src/test/java/com/test/web/desktop/SingleTest.java +++ b/src/test/java/com/test/web/desktop/SingleTest.java @@ -1,7 +1,15 @@ package com.test.web.desktop; +import static org.openqa.selenium.Keys.TAB; +import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable; +import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated; +import static org.testng.Assert.assertEquals; + +import java.net.MalformedURLException; +import java.net.URL; +import java.time.Duration; + import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; @@ -10,46 +18,19 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; - -import static org.openqa.selenium.Keys.TAB; -import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable; -import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated; -import static org.testng.Assert.assertEquals; - public class SingleTest { private WebDriver driver; - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { + public void setup() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("os", "Windows"); - caps.setCapability("os_version", "10"); - caps.setCapability("browser", "Chrome"); - caps.setCapability("browser_version", "latest"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - - driver = new RemoteWebDriver(new URL(HUB_URL), caps); + driver = new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test public void bStackDemoLogin() { - WebDriverWait wait = new WebDriverWait(driver, 10); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); driver.get("https://bstackdemo.com"); wait.until(elementToBeClickable(By.id("signin"))).click(); wait.until(elementToBeClickable(By.cssSelector("#username input"))).sendKeys("fav_user" + TAB); @@ -61,8 +42,6 @@ public void bStackDemoLogin() { @AfterMethod(alwaysRun = true) public void closeDriver() { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); driver.quit(); } diff --git a/src/test/java/com/test/web/mobile/FailTest.java b/src/test/java/com/test/web/mobile/FailTest.java deleted file mode 100644 index a7c4d06..0000000 --- a/src/test/java/com/test/web/mobile/FailTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.test.web.mobile; - -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.ui.WebDriverWait; -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; - -import static org.openqa.selenium.Keys.TAB; -import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable; -import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated; -import static org.testng.Assert.assertNotEquals; - -public class FailTest { - - private WebDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { - DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "Google Pixel 7"); - caps.setCapability("os_version", "13.0"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - - driver = new RemoteWebDriver(new URL(HUB_URL), caps); - } - - @Test - public void bStackDemoLogin() { - WebDriverWait wait = new WebDriverWait(driver, 10); - driver.get("https://bstackdemo.com"); - wait.until(elementToBeClickable(By.id("signin"))).click(); - wait.until(elementToBeClickable(By.cssSelector("#username input"))).sendKeys("fav_user" + TAB); - driver.findElement(By.cssSelector("#password input")).sendKeys("testingisfun99" + TAB); - driver.findElement(By.id("login-btn")).click(); - String username = wait.until(presenceOfElementLocated(By.className("username"))).getText(); - assertNotEquals(username, "fav_user", "Incorrect username"); - } - - @AfterMethod(alwaysRun = true) - public void closeDriver(ITestResult tr) { - JavascriptExecutor js = (JavascriptExecutor) driver; - String reason = tr.getThrowable().getMessage().split("\\n")[0].replaceAll("[\\\\{}\"]", ""); - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"failed\", \"reason\": \"" + reason + "\"}}"); - driver.quit(); - } - -} diff --git a/src/test/java/com/test/web/mobile/LocalTest.java b/src/test/java/com/test/web/mobile/LocalTest.java deleted file mode 100644 index 6e4d7db..0000000 --- a/src/test/java/com/test/web/mobile/LocalTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.test.web.mobile; - -import com.utils.LocalUtils; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.testng.annotations.*; - -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; - -import static org.testng.Assert.assertEquals; - -public class LocalTest { - - private WebDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeSuite(alwaysRun = true) - public void setupLocal() { - LocalUtils.startLocal(); - } - - @BeforeMethod(alwaysRun = true) - public void setupDriver(Method m) throws MalformedURLException { - DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "Google Pixel 7"); - caps.setCapability("os_version", "13.0"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - caps.setCapability("browserstack.local", true); - - driver = new RemoteWebDriver(new URL(HUB_URL), caps); - } - - @Test - public void openLocalWebPage() { - driver.get("http://localhost:8000"); - assertEquals(driver.getTitle(), "Local Server", "Incorrect title"); - } - - @AfterMethod(alwaysRun = true) - public void closeDriver() { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); - driver.quit(); - } - - @AfterSuite(alwaysRun = true) - public void closeLocal() { - LocalUtils.stopLocal(); - } - -} diff --git a/src/test/java/com/test/web/mobile/SingleTest.java b/src/test/java/com/test/web/mobile/SingleTest.java deleted file mode 100644 index 335e80b..0000000 --- a/src/test/java/com/test/web/mobile/SingleTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.test.web.mobile; - -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.ui.WebDriverWait; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; - -import static org.openqa.selenium.Keys.TAB; -import static org.openqa.selenium.support.ui.ExpectedConditions.elementToBeClickable; -import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated; -import static org.testng.Assert.assertEquals; - -public class SingleTest { - - private WebDriver driver; - - private static final String USERNAME = System.getenv("BROWSERSTACK_USERNAME"); - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - private static final String HUB_URL = "https://hub.browserstack.com/wd/hub"; - - @BeforeMethod(alwaysRun = true) - public void setup(Method m) throws MalformedURLException { - DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability("project", "BrowserStack Demo TestNG"); - caps.setCapability("build", "Demo"); - caps.setCapability("name", m.getName()); - - caps.setCapability("device", "Google Pixel 7"); - caps.setCapability("os_version", "13.0"); - - caps.setCapability("browserstack.user", USERNAME); - caps.setCapability("browserstack.key", ACCESS_KEY); - caps.setCapability("browserstack.debug", true); - caps.setCapability("browserstack.networkLogs", true); - - driver = new RemoteWebDriver(new URL(HUB_URL), caps); - } - - @Test - public void bStackDemoLogin() { - WebDriverWait wait = new WebDriverWait(driver, 10); - driver.get("https://bstackdemo.com"); - wait.until(elementToBeClickable(By.id("signin"))).click(); - wait.until(elementToBeClickable(By.cssSelector("#username input"))).sendKeys("fav_user" + TAB); - driver.findElement(By.cssSelector("#password input")).sendKeys("testingisfun99" + TAB); - driver.findElement(By.id("login-btn")).click(); - String username = wait.until(presenceOfElementLocated(By.className("username"))).getText(); - assertEquals(username, "fav_user", "Incorrect username"); - } - - @AfterMethod(alwaysRun = true) - public void closeDriver() { - JavascriptExecutor js = (JavascriptExecutor) driver; - js.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"passed\"}}"); - driver.quit(); - } - -} diff --git a/src/test/java/com/utils/LocalUtils.java b/src/test/java/com/utils/LocalUtils.java deleted file mode 100644 index 0661c29..0000000 --- a/src/test/java/com/utils/LocalUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.utils; - -import com.browserstack.local.Local; - -import java.util.HashMap; -import java.util.Map; - -public final class LocalUtils { - - private static Local local; - private static final String ACCESS_KEY = System.getenv("BROWSERSTACK_ACCESS_KEY"); - - private LocalUtils() {} - - public static void startLocal() { - local = new Local(); - Map options = new HashMap<>(); - options.put("key", ACCESS_KEY); - try { - local.start(options); - } catch (Exception e) { - throw new RuntimeException("Unable to start a local connection", e); - } - System.out.println("Local testing connection established"); - } - - public static void stopLocal() { - try { - local.stop(); - } catch (Exception e) { - throw new RuntimeException("Unable to stop the local connection", e); - } - System.out.println("Local testing connection terminated"); - } - -} diff --git a/src/test/resources/app/config/android.json b/src/test/resources/app/config/android.json deleted file mode 100644 index 38ecd69..0000000 --- a/src/test/resources/app/config/android.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "commonCapabilities": { - "project": "BrowserStack Demo TestNG", - "build": "Demo", - "browserstack.debug": true, - "browserstack.networkLogs": true - }, - "capabilities": [ - { - "device": "Google Pixel 7", - "os_version": "13.0" - }, - { - "device": "OnePlus 9", - "os_version": "11.0" - }, - { - "device": "Google Pixel 7 Pro", - "os_version": "13.0" - }, - { - "device": "Samsung Galaxy S23 Ultra", - "os_version": "13.0" - }, - { - "device": "Samsung Galaxy S22 Plus", - "os_version": "12.0" - } - ] -} \ No newline at end of file diff --git a/src/test/resources/app/config/android_local.yml b/src/test/resources/app/config/android_local.yml new file mode 100644 index 0000000..c508ad4 --- /dev/null +++ b/src/test/resources/app/config/android_local.yml @@ -0,0 +1,17 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build +buildIdentifier: '#${BUILD_NUMBER}' + +framework: testng +source: testng:appium-sample-sdk:v1.1 + +app: AndroidLocalApp + +platforms: + - deviceName: Samsung Galaxy S22 Ultra + osVersion: 12.0 + +browserstackLocal: true \ No newline at end of file diff --git a/src/test/resources/app/config/android_parallel.yml b/src/test/resources/app/config/android_parallel.yml new file mode 100644 index 0000000..3bacca0 --- /dev/null +++ b/src/test/resources/app/config/android_parallel.yml @@ -0,0 +1,17 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build +buildIdentifier: '#${BUILD_NUMBER}' + +framework: testng +source: testng:appium-sample-sdk:v1.1 + +app: AndroidDemoApp + +platforms: + - deviceName: Samsung Galaxy S22 Ultra + - deviceName: Samsung Galaxy S21 + - deviceName: Google Pixel 6 Pro + diff --git a/src/test/resources/app/config/android_single.yml b/src/test/resources/app/config/android_single.yml new file mode 100644 index 0000000..0a52d7e --- /dev/null +++ b/src/test/resources/app/config/android_single.yml @@ -0,0 +1,23 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build +buildIdentifier: '#${BUILD_NUMBER}' + +framework: testng +source: testng:appium-sample-sdk:v1.1 + +app: AndroidDemoApp + +platforms: + - deviceName: Samsung Galaxy S22 Ultra + osVersion: 12.0 + +debug: true +networkLogs: true +interactiveDebugging: true +appProfiling: true +accessibility: true +accessibilityOptions: + screenReaderAutomationReport: true \ No newline at end of file diff --git a/src/test/resources/app/config/espresso.json b/src/test/resources/app/config/espresso.json index 764a570..8047212 100644 --- a/src/test/resources/app/config/espresso.json +++ b/src/test/resources/app/config/espresso.json @@ -2,8 +2,8 @@ "app": "CalculatorApp", "testSuite": "CalculatorAppTest", "devices": [ - "Samsung Galaxy S20-10.0", - "Google Pixel 3-9.0" + "Samsung Galaxy S23-13.0", + "Google Pixel 9-16.0" ], "project": "BrowserStack Demo TestNG", "deviceLogs": true, diff --git a/src/test/resources/app/config/ios.json b/src/test/resources/app/config/ios.json deleted file mode 100644 index 8d6d5e8..0000000 --- a/src/test/resources/app/config/ios.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "commonCapabilities": { - "project": "BrowserStack Demo TestNG", - "build": "Demo", - "browserstack.debug": true, - "browserstack.networkLogs": true - }, - "capabilities": [ - { - "device": "iPhone 14 Pro", - "os_version": "16" - }, - { - "device": "iPhone 14 Pro Max", - "os_version": "16" - }, - { - "device": "iPhone 13 Pro", - "os_version": "15" - }, - { - "device": "iPhone 13 Pro Max", - "os_version": "15" - }, - { - "device": "iPhone SE 2020", - "os_version": "13" - } - ] -} \ No newline at end of file diff --git a/src/test/resources/app/config/ios_local.yml b/src/test/resources/app/config/ios_local.yml new file mode 100644 index 0000000..ede1776 --- /dev/null +++ b/src/test/resources/app/config/ios_local.yml @@ -0,0 +1,17 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build +buildIdentifier: '#${BUILD_NUMBER}' + +framework: testng +source: testng:appium-sample-sdk:v1.1 + +app: iOSLocalApp + +platforms: + - deviceName: iPhone 15 + osVersion: 17 + +browserstackLocal: true \ No newline at end of file diff --git a/src/test/resources/app/config/ios_parallel.yml b/src/test/resources/app/config/ios_parallel.yml new file mode 100644 index 0000000..2d361bf --- /dev/null +++ b/src/test/resources/app/config/ios_parallel.yml @@ -0,0 +1,19 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build +buildIdentifier: '#${BUILD_NUMBER}' + +framework: testng +source: testng:appium-sample-sdk:v1.1 + +app: iOSDemoApp + +platforms: + - deviceName: iPhone 15 + osVersion: 17 + - deviceName: iPhone 14 + osVersion: 16 + - deviceName: iPhone 13 + osVersion: 15 \ No newline at end of file diff --git a/src/test/resources/app/config/ios_single.yml b/src/test/resources/app/config/ios_single.yml new file mode 100644 index 0000000..663a37e --- /dev/null +++ b/src/test/resources/app/config/ios_single.yml @@ -0,0 +1,18 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build + +app: iOSDemoApp + +platforms: + - deviceName: iPhone 13 + osVersion: 15 + +debug: true +networkLogs: true +appProfiling: true +accessibility: true +accessibilityOptions: + screenReaderAutomationReport: true \ No newline at end of file diff --git a/src/test/resources/app/config/xcuitest.json b/src/test/resources/app/config/xcuitest.json index 78b9593..04759fb 100644 --- a/src/test/resources/app/config/xcuitest.json +++ b/src/test/resources/app/config/xcuitest.json @@ -2,8 +2,8 @@ "app": "SampleApp", "testSuite": "SampleTest", "devices": [ - "iPhone 8-11", - "iPhone 8 Plus-11" + "iPhone 17-26", + "iPhone 17 Pro-26" ], "project": "BrowserStack Demo TestNG", "deviceLogs": true, diff --git a/src/test/resources/app/suites/android.local.testng.xml b/src/test/resources/app/suites/android.local.testng.xml deleted file mode 100644 index fe5dc64..0000000 --- a/src/test/resources/app/suites/android.local.testng.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/app/suites/android.parallel.testng.xml b/src/test/resources/app/suites/android.parallel.testng.xml deleted file mode 100644 index 4cc3163..0000000 --- a/src/test/resources/app/suites/android.parallel.testng.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/app/suites/ios.local.testng.xml b/src/test/resources/app/suites/ios.local.testng.xml deleted file mode 100644 index f444379..0000000 --- a/src/test/resources/app/suites/ios.local.testng.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/app/suites/ios.parallel.testng.xml b/src/test/resources/app/suites/ios.parallel.testng.xml deleted file mode 100644 index 4f6a4be..0000000 --- a/src/test/resources/app/suites/ios.parallel.testng.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/web/config/desktop.json b/src/test/resources/web/config/desktop.json deleted file mode 100644 index d6ea996..0000000 --- a/src/test/resources/web/config/desktop.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "commonCapabilities": { - "project": "BrowserStack Demo TestNG", - "build": "Demo", - "browserstack.debug": true, - "browserstack.networkLogs": true - }, - "capabilities": [ - { - "os": "OS X", - "os_version": "Big Sur", - "browser": "Chrome", - "browser_version": "latest" - }, - { - "os": "Windows", - "os_version": "10", - "browser": "Firefox", - "browser_version": "latest" - }, - { - "os": "Windows", - "os_version": "10", - "browser": "Edge", - "browser_version": "latest" - }, - { - "os": "OS X", - "os_version": "Big Sur", - "browser": "Safari", - "browser_version": "latest" - }, - { - "os": "Windows", - "os_version": "10", - "browser": "Chrome", - "browser_version": "latest" - } - ] -} - diff --git a/src/test/resources/web/config/mobile.json b/src/test/resources/web/config/mobile.json deleted file mode 100644 index 35a0a36..0000000 --- a/src/test/resources/web/config/mobile.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "commonCapabilities": { - "project": "BrowserStack Demo TestNG", - "build": "Demo", - "browserstack.debug": true, - "browserstack.networkLogs": true - }, - "capabilities": [ - { - "device": "Google Pixel 7", - "os_version": "13.0" - }, - { - "device": "Samsung Galaxy S23", - "os_version": "13.0" - }, - { - "device": "iPhone 14", - "os_version": "16" - }, - { - "device": "iPhone 13 Mini", - "os_version": "15" - }, - { - "device": "iPhone 12 Pro", - "os_version": "14" - } - ] -} \ No newline at end of file diff --git a/src/test/resources/web/config/web_local.yml b/src/test/resources/web/config/web_local.yml new file mode 100644 index 0000000..1a564f9 --- /dev/null +++ b/src/test/resources/web/config/web_local.yml @@ -0,0 +1,13 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build + +platforms: + - os: OS X + osVersion: Sonoma + browserName: Chrome + browserVersion: latest + +browserstackLocal: true \ No newline at end of file diff --git a/src/test/resources/web/config/web_parallel.yml b/src/test/resources/web/config/web_parallel.yml new file mode 100644 index 0000000..ae4d83a --- /dev/null +++ b/src/test/resources/web/config/web_parallel.yml @@ -0,0 +1,17 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build + +platforms: + - os: OS X + osVersion: Sonoma + browserName: Chrome + browserVersion: latest + - os: Windows + osVersion: 11 + browserName: Edge + browserVersion: latest + - deviceName: iPhone 15 + osVersion: 17 \ No newline at end of file diff --git a/src/test/resources/web/config/web_single.yml b/src/test/resources/web/config/web_single.yml new file mode 100644 index 0000000..9104243 --- /dev/null +++ b/src/test/resources/web/config/web_single.yml @@ -0,0 +1,18 @@ +userName: BROWSERSTACK_USERNAME +accessKey: BROWSERSTACK_ACCESS_KEY + +projectName: BrowserStack Samples +buildName: BrowserStack Demo Build + +platforms: + - os: Windows + osVersion: 10 + browserName: Chrome + browserVersion: latest + +debug: true +networkLogs: true +consoleLogs: verbose +accessibility: true +performance: report +browserProfiling: true \ No newline at end of file diff --git a/src/test/resources/web/suites/local.testng.xml b/src/test/resources/web/suites/local.testng.xml deleted file mode 100644 index 86e5d9e..0000000 --- a/src/test/resources/web/suites/local.testng.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/web/suites/parallel.testng.xml b/src/test/resources/web/suites/parallel.testng.xml deleted file mode 100644 index bbfba33..0000000 --- a/src/test/resources/web/suites/parallel.testng.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file