Skip to content

Commit

Permalink
Smoke tests kotlin demo (#453)
Browse files Browse the repository at this point in the history
* wrote ui tests for banner 320x50

* added tests for display interstitial

* added tests for video rewarded

* added tests for video banner and configured circleci workflow

* changed workflow for running builds simultaneously

* fixed circle ci build error

* changed build matrix name and removed alias

* Updated config.yml

* Updated config.yml

* added testPrebidDemo.sh script to config.yml

* added manual start of android emulators to circle ci config

* changed avd name

* added working directory for android test

* added post-emulator-launch-assemble-command to android test configuration

* Updated config.yml

* changed tests and added retryCount for test restart

* configured admob display interstitial case

* modified display interstitial check

* added ads for testing in Prebid Kotlin Demo and removed Android 8 emulator from circle ci config

* added smoke tests for other cases

* fixed tests configuration

* small fixes

* returned assembleAndroidTest command

* added tests for video rewarded original api and include prebid internal test app build step

* increased timeout

* fixed internal test app build and changed video tests

* changed jobs name in circle ci build steps

* changed build Commands for demo apps

* configured buildPrebidMobile.sh for circle ci build

* update buildPrebidMobile.sh

* fix: remove useless dependency and correct build script

Co-authored-by: Valentin Petrovych <valentin.petrovich@postindustria.com>
  • Loading branch information
MaksPetrukhnoPI and ValentinPostindustria authored May 26, 2022
1 parent 4e6e882 commit abba78f
Show file tree
Hide file tree
Showing 29 changed files with 1,319 additions and 176 deletions.
35 changes: 26 additions & 9 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,25 @@ version: 2.1
# See: https://circleci.com/docs/2.0/orb-intro/
orbs:
android: circleci/android@1.0.3

# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
android-test:
executor:
name: android/android-machine
steps:
- checkout
- android/start-emulator-and-run-tests:
post-emulator-launch-assemble-command: ./gradlew PrebidDemoKotlin:assembleAndroidTest
test-command: ./gradlew PrebidDemoKotlin:connectedDebugAndroidTest
system-image: system-images;android-30;google_apis;x86
# Below is the definition of your job to build and test your app, you can rename and customize it as you want.
build:
# These next lines define the Android machine image executor.
# See: https://circleci.com/docs/2.0/executor-types/
parameters:
buildCommand:
type: string
executor:
name: android/android-machine

Expand All @@ -24,25 +35,20 @@ jobs:
steps:
# Checkout the code as the first step.
- checkout

# And finally run the release build
- run:
name: Build Frameworks
command: scripts/buildPrebidMobile.sh
command: << parameters.buildCommand >>

# Below is the definition of your job to build and test your app, you can rename and customize it as you want.
test:
# These next lines define the Android machine image executor.
# See: https://circleci.com/docs/2.0/executor-types/
executor:
name: android/android-machine

# Add steps to the job
# See: https://circleci.com/docs/2.0/configuration-reference/#steps
steps:
# Checkout the code as the first step.
- checkout

# And finally run the release build
- run:
name: Test Frameworks
Expand All @@ -54,5 +60,16 @@ workflows:
sample: # This is the name of the workflow, feel free to change it to better match your workflow.
# Inside the workflow, you define the jobs you want to run.
jobs:
- build
- test
- build:
name: Build Java Demo
buildCommand: ./gradlew PrebidDemoJava:assembleDebug
- build:
name: Build Internal Test App
buildCommand: ./gradlew PrebidInternalTestApp:assembleDebug
- build:
name: Build PrebidMobile Frameworks
buildCommand: scripts/buildPrebidMobile.sh -nojar
- test:
name: Run Unit Tests - Prebid Mobile
- android-test:
name: Run Smoke UI Tests - Demo App Kotlin - Android 11
1 change: 1 addition & 0 deletions Example/PrebidDemoKotlin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.prebid.mobile.prebidkotlindemo.ui

import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import junit.framework.Assert.assertNotNull
import junit.framework.Assert.assertTrue
import org.junit.Test
import org.prebid.mobile.prebidkotlindemo.utils.TestConstants

class BannerAdsTest : BaseAdsTest() {
@Test
fun bannerAdsShouldBeDisplayed() {
testAd(TestConstants.GAM,TestConstants.BANNER_320x50)
testAd(TestConstants.IN_APP,TestConstants.BANNER_320x50)
testAd(TestConstants.IN_APP_GAM,TestConstants.BANNER_320x50)
testAd(TestConstants.IN_APP_ADMOB,TestConstants.BANNER_320x50)
testAd(TestConstants.IN_APP,TestConstants.BANNER_MULTISIZE)
testAd(TestConstants.GAM,TestConstants.BANNER_MULTISIZE)
}

override fun checkAd(adServer: String,adName:String) {
val frameAdWrapperSelector = By.textContains("banner")
val findAd = device.wait(Until.findObject(frameAdWrapperSelector), timeout)
assertNotNull(findAd)
device.pressBack()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package org.prebid.mobile.prebidkotlindemo.ui

import android.content.Context
import android.content.Intent
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.*
import junit.framework.AssertionFailedError
import org.hamcrest.CoreMatchers.notNullValue
import org.junit.After
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.runner.RunWith
import androidx.test.uiautomator.UiSelector

import androidx.test.uiautomator.UiObject




@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = 18)
abstract class BaseAdsTest {
protected val packageName = "org.prebid.mobile.prebidkotlindemo"
protected val timeout = 7000L
protected lateinit var device: UiDevice

private lateinit var adServerSpinner: UiObject
private lateinit var adTypeSpinner: UiObject
private lateinit var showAdButton: UiObject

private val adsErrorMessagesQueue = ArrayDeque<String>()

@Before
fun startMainActivityFromHomeScreen() {
initDevice()
startActivity()
device.wait(
Until.hasObject(By.pkg(packageName).depth(0)),
timeout
)
initMainScreenComponents()

}
@After
fun checkErrors(){
displayErrorMessages()
}

private fun initDevice() {
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.pressHome()
val launcherPackage: String = device.launcherPackageName
assertThat(launcherPackage, notNullValue())
device.wait(
Until.hasObject(By.pkg(launcherPackage).depth(0)),
timeout
)
}

private fun startActivity() {
val context = ApplicationProvider.getApplicationContext<Context>()
val intent = context.packageManager.getLaunchIntentForPackage(
packageName
).apply {
this?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
}
context.startActivity(intent)

}

private fun initMainScreenComponents() {
adServerSpinner = device.findObject(
UiSelector().resourceId("$packageName:id/spinnerAdServer")
)
adTypeSpinner = device.findObject(
UiSelector().resourceId("$packageName:id/spinnerAdType")
)
showAdButton = device.findObject(
UiSelector().resourceId("$packageName:id/btnShowAd")
)
}

protected fun testAd(adServer: String, adName: String, retryCount: Int = 2) {
runCatching {
goToAd(adServer, adName)
checkAd(adServer,adName)
}.getOrElse { throwable ->
if (retryCount != 0) {
restartApp()
testAd(adServer, adName, retryCount - 1)
} else {
adsErrorMessagesQueue.add("$adServer - $adName ${throwable.stackTraceToString()}")
restartApp()
}
}
}
private fun displayErrorMessages() {
val failedTestsMessage = adsErrorMessagesQueue.joinToString(separator = System.lineSeparator())
if (failedTestsMessage.isNotEmpty()){
adsErrorMessagesQueue.clear()
throw AssertionError(failedTestsMessage)
}
}

protected abstract fun checkAd(adServer: String,adName: String)

private fun goToAd(adServer: String, adName: String) {
adServerSpinner.click()
selectSpinnerValue(adServer)
adTypeSpinner.click()
selectSpinnerValue(adName)
showAdButton.click()
}

private fun selectSpinnerValue(value: String) {
device.findObject(By.text(value)).click()
}
private fun restartApp(){
Runtime.getRuntime().exec(arrayOf("am", "force-stop", packageName))
device.pressHome()
startActivity()
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.prebid.mobile.prebidkotlindemo.ui

import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import junit.framework.Assert.assertNotNull
import org.junit.Test
import org.prebid.mobile.prebidkotlindemo.utils.TestConstants

class DisplayInterstitialAdsTest : BaseAdsTest() {
@Test
fun displayInterstitialAdsShouldBeDisplayed() {
testAd(TestConstants.IN_APP, TestConstants.DISPLAY_INTERSTITIAL)
testAd(TestConstants.GAM, TestConstants.DISPLAY_INTERSTITIAL)
testAd(TestConstants.IN_APP_ADMOB, TestConstants.DISPLAY_INTERSTITIAL)
testAd(TestConstants.IN_APP_GAM, TestConstants.DISPLAY_INTERSTITIAL)
}

@Test
fun multiformatInterstitialAdsShouldBeDisplayed() {
testAd(TestConstants.IN_APP, TestConstants.MULTIFORMAT_INTERSTITIAL)
}

override fun checkAd(adServer: String, adName: String) {
val closeButton = By.res(packageName, "iv_close_interstitial")
val gamCloseButton = By.desc("Interstitial close button")
val ad = By.clazz("android.view.View")
val videoAd = By.res(packageName, "exo_subtitles")

val findAd = if (adName == TestConstants.MULTIFORMAT_INTERSTITIAL) {
val findVideoAd = device.wait(Until.findObject(videoAd), timeout)
findVideoAd ?: device.wait(Until.findObject(ad), timeout)
} else {
device.wait(Until.findObject(ad), timeout)
}
assertNotNull(findAd)

val findCloseButton = if (adServer == TestConstants.GAM) {
device.wait(Until.findObject(gamCloseButton), timeout)
} else {
device.wait(Until.findObject(closeButton), timeout)
}
assertNotNull(findCloseButton)

findCloseButton.click()
Thread.sleep(1000)
device.pressBack()


}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package org.prebid.mobile.prebidkotlindemo.ui

import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import junit.framework.TestCase.assertNotNull
import org.junit.Test
import org.prebid.mobile.prebidkotlindemo.utils.TestConstants

class MraidAdsTest:BaseAdsTest() {
@Test
fun mraidAdsShouldBeDisplayed(){
testAd(TestConstants.IN_APP,TestConstants.MRAID_RESIZE)
testAd(TestConstants.IN_APP,TestConstants.MRAID_RESIZE_WITH_ERRORS)
testAd(TestConstants.IN_APP,TestConstants.MRAID_EXPAND)
}

override fun checkAd(adServer: String,adName:String) {
when (adName){
TestConstants.MRAID_EXPAND -> checkMraidExpand()
TestConstants.MRAID_RESIZE -> checkMraidResize()
TestConstants.MRAID_RESIZE_WITH_ERRORS -> checkMraidResizeWithErrors()
}
}

private fun checkMraidResize() {
val clickToResize = By.text("Click to Resize")
val findClickToResize = device.wait(Until.findObject(clickToResize), timeout)
assertNotNull(findClickToResize)
findClickToResize.click()

val closeButton = By.text("X")
val findCloseButton = device.wait(Until.findObject(closeButton), timeout)
assertNotNull(findCloseButton)
findCloseButton.click()
device.pressBack()
}
private fun checkMraidResizeWithErrors() {
val clickToggleScreen = By.res("toggleOffscreenDiv")
val findClickToggleScreen = device.wait(Until.findObject(clickToggleScreen), timeout)
assertNotNull(findClickToggleScreen)
findClickToggleScreen.click()

val resizeLeft = By.res("resizeLeftText")
val findResizeLeft = device.wait(Until.findObject(resizeLeft), timeout)
assertNotNull(findResizeLeft)
findResizeLeft.click()

val resizeRight = By.res("resizeRightText")
val findResizeRight = device.wait(Until.findObject(resizeRight), timeout)
assertNotNull(findResizeRight)
findResizeRight.click()

val resizeUp = By.res("resizeUpText")
val findResizeUp = device.wait(Until.findObject(resizeUp), timeout)
assertNotNull(findResizeUp)
findResizeUp.click()

val resizeDown = By.res("resizeDownText")
val findResizeDown = device.wait(Until.findObject(resizeDown), timeout)
assertNotNull(findResizeDown)
findResizeDown.click()

val closeButton = By.res("closeButtonDiv")
val findCloseButton = device.wait(Until.findObject(closeButton),timeout)
assertNotNull(findCloseButton)
findCloseButton.click()

device.pressBack()
}
private fun checkMraidExpand() {
val clickToExpand = By.res("maindiv")
val findClickToExpand = device.wait(Until.findObject(clickToExpand), timeout)
assertNotNull(findClickToExpand)
findClickToExpand.click()

val closeButton = By.res("closediv")
val findCloseButton = device.wait(Until.findObject(closeButton), timeout)
assertNotNull(findCloseButton)
findCloseButton.click()
device.pressBack()
}

}
Loading

0 comments on commit abba78f

Please sign in to comment.