Issue#104 Create Test verifying screenshot pulling works
This commit is contained in:
parent
69f5f15c3a
commit
bae8c0fc96
8 changed files with 212 additions and 80 deletions
114
.github/workflows/pull-request-jobs.yml
vendored
114
.github/workflows/pull-request-jobs.yml
vendored
|
|
@ -74,60 +74,60 @@ jobs:
|
|||
path: ./**/build/reports/tests/**/index.html
|
||||
retention-days: 1
|
||||
|
||||
run-tests-on-emulator:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [ 21, 30 ]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
- name: Gradle cache
|
||||
uses: gradle/gradle-build-action@v2
|
||||
- name: AVD cache
|
||||
uses: actions/cache@v3
|
||||
id: avd-cache
|
||||
with:
|
||||
path: |
|
||||
~/.android/avd/*
|
||||
~/.android/adb*
|
||||
key: avd-${{ matrix.api-level }}
|
||||
- name: create AVD and generate snapshot for caching
|
||||
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
arch: 'x86_64'
|
||||
api-level: ${{ matrix.api-level }}
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: false
|
||||
script: echo "Generated AVD snapshot for caching."
|
||||
- name: Run Android Tests
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
arch: 'x86_64'
|
||||
api-level: ${{ matrix.api-level }}
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
script: ./gradlew connectedDebugAndroidTest
|
||||
- name: Upload Test Results
|
||||
uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: Emulator-Test-Results-${{ matrix.api-level }}
|
||||
path: ./**/build/reports/androidTests/**/*.html
|
||||
retention-days: 1
|
||||
- name: Upload Test Screenshots
|
||||
uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: Emulator-Test-Results-${{ matrix.api-level }}
|
||||
path: ./**/build/testscreenshots/*
|
||||
retention-days: 1
|
||||
# run-tests-on-emulator:
|
||||
# runs-on: macos-latest
|
||||
# strategy:
|
||||
# matrix:
|
||||
# api-level: [ 21, 30 ]
|
||||
# fail-fast: false
|
||||
# steps:
|
||||
# - name: checkout
|
||||
# uses: actions/checkout@v3
|
||||
# - name: Setup Java
|
||||
# uses: actions/setup-java@v2
|
||||
# with:
|
||||
# distribution: 'adopt'
|
||||
# java-version: '11'
|
||||
# - name: Gradle cache
|
||||
# uses: gradle/gradle-build-action@v2
|
||||
# - name: AVD cache
|
||||
# uses: actions/cache@v3
|
||||
# id: avd-cache
|
||||
# with:
|
||||
# path: |
|
||||
# ~/.android/avd/*
|
||||
# ~/.android/adb*
|
||||
# key: avd-${{ matrix.api-level }}
|
||||
# - name: create AVD and generate snapshot for caching
|
||||
# if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||
# uses: reactivecircus/android-emulator-runner@v2
|
||||
# with:
|
||||
# arch: 'x86_64'
|
||||
# api-level: ${{ matrix.api-level }}
|
||||
# force-avd-creation: false
|
||||
# emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
# disable-animations: false
|
||||
# script: echo "Generated AVD snapshot for caching."
|
||||
# - name: Run Android Tests
|
||||
# uses: reactivecircus/android-emulator-runner@v2
|
||||
# with:
|
||||
# arch: 'x86_64'
|
||||
# api-level: ${{ matrix.api-level }}
|
||||
# force-avd-creation: false
|
||||
# emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
# disable-animations: true
|
||||
# script: ./gradlew connectedDebugAndroidTest
|
||||
# - name: Upload Test Results
|
||||
# uses: actions/upload-artifact@v2
|
||||
# if: always()
|
||||
# with:
|
||||
# name: Emulator-Test-Results-${{ matrix.api-level }}
|
||||
# path: ./**/build/reports/androidTests/**/*.html
|
||||
# retention-days: 1
|
||||
# - name: Upload Test Screenshots
|
||||
# uses: actions/upload-artifact@v2
|
||||
# if: always()
|
||||
# with:
|
||||
# name: Emulator-Test-Results-${{ matrix.api-level }}
|
||||
# path: ./**/build/testscreenshots/*
|
||||
# retention-days: 1
|
||||
55
.github/workflows/screenshot-tests.yml
vendored
Normal file
55
.github/workflows/screenshot-tests.yml
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
name: Verify Screenshots can be created and pulled
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
|
||||
env:
|
||||
GITHUB_USERNAME: "fknives"
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
run-screenshot-test-on-emulator:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [ 21, 23, 24, 26, 28, 29, 30, 31 ]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
- name: Gradle cache
|
||||
uses: gradle/gradle-build-action@v2
|
||||
- name: AVD cache
|
||||
uses: actions/cache@v3
|
||||
id: avd-cache
|
||||
with:
|
||||
path: |
|
||||
~/.android/avd/*
|
||||
~/.android/adb*
|
||||
key: avd-${{ matrix.api-level }}
|
||||
- name: create AVD and generate snapshot for caching
|
||||
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
arch: 'x86_64'
|
||||
api-level: ${{ matrix.api-level }}
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: false
|
||||
script: echo "Generated AVD snapshot for caching."
|
||||
- name: Run Android Tests
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
arch: 'x86_64'
|
||||
api-level: ${{ matrix.api-level }}
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
script: ./pullscreenshottest.sh
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package org.fnives.test.showcase.rule
|
||||
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.fnives.test.showcase.android.testutil.activity.SafeCloseActivityRule
|
||||
import org.fnives.test.showcase.android.testutil.screenshot.ScreenshotRule
|
||||
import org.fnives.test.showcase.android.testutil.synchronization.MainDispatcherTestRule
|
||||
import org.fnives.test.showcase.ui.splash.SplashActivity
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.test.KoinTest
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ScreenshotTest : KoinTest {
|
||||
|
||||
private lateinit var activityScenario: ActivityScenario<SplashActivity>
|
||||
|
||||
private val mainDispatcherTestRule = MainDispatcherTestRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val ruleOrder: RuleChain = RuleChain.outerRule(mainDispatcherTestRule)
|
||||
.around(SafeCloseActivityRule { activityScenario })
|
||||
.around(ScreenshotRule(prefix = "screenshot-rule", takeOnSuccess = true))
|
||||
|
||||
/** GIVEN loggedInState WHEN opened after some time THEN MainActivity is started */
|
||||
@Test
|
||||
fun screenshot() {
|
||||
activityScenario = ActivityScenario.launch(SplashActivity::class.java)
|
||||
activityScenario.moveToState(Lifecycle.State.RESUMED)
|
||||
}
|
||||
}
|
||||
13
app/verifyfiles.sh
Executable file
13
app/verifyfiles.sh
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# if given folder is empty throws error
|
||||
if [ -d "$1" ]; then
|
||||
if [ $(ls -A $1 | wc -l) ];
|
||||
then
|
||||
echo ""
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -29,47 +29,64 @@ def packageName = propertyOrNull("screenshotsPackageName") ?: "$android.defaultC
|
|||
def screenshotDirectory = propertyOrNull("screenshotsDirectory") ?: "test-screenshots"
|
||||
def savePath = propertyOrNull("screenshotsSavePath") ?: "build/testscreenshots/"
|
||||
def adb = propertyOrNull("adbPath") ?: findAdbFromLocal()
|
||||
def internalFullPath = "/sdcard/Android/data/$packageName/files/Pictures/$screenshotDirectory/"
|
||||
def deprecatedFullPath = "/sdcard/Pictures/$packageName/$screenshotDirectory/"
|
||||
def contextInternalFullPath = "/data/data/$packageName/files/$screenshotDirectory/"
|
||||
def contextExternalFullPath = "/sdcard/Android/data/$packageName/files/Pictures/$screenshotDirectory/"
|
||||
def environmentExternalFullPath = "/sdcard/Pictures/$packageName/$screenshotDirectory/"
|
||||
|
||||
task pullScreenshotsInternal(type: Exec) {
|
||||
task pullScreenshotsContextInternal(type: Exec) {
|
||||
group = 'Test-Screenshots'
|
||||
description = 'Pull screenshots From internal Storage'
|
||||
description = 'Pull screenshots From context.external Storage'
|
||||
|
||||
ignoreExitValue(true)
|
||||
commandLine "$adb", 'pull', "$internalFullPath", "$savePath/"
|
||||
commandLine "$adb", 'pull', "$contextInternalFullPath", "$savePath/"
|
||||
}
|
||||
|
||||
task pullScreenshotsDeprecated(type: Exec) {
|
||||
task pullScreenshotsContextExternal(type: Exec) {
|
||||
group = 'Test-Screenshots'
|
||||
description = 'Pull screenshots From deprecated External Storage'
|
||||
description = 'Pull screenshots From context.external Storage'
|
||||
|
||||
ignoreExitValue(true)
|
||||
commandLine "$adb", 'pull', "$deprecatedFullPath", "$savePath/"
|
||||
commandLine "$adb", 'pull', "$contextExternalFullPath", "$savePath/"
|
||||
}
|
||||
|
||||
task pullScreenshots(dependsOn: [pullScreenshotsInternal, pullScreenshotsDeprecated]) {
|
||||
task pullScreenshotsEnvironmentExternal(type: Exec) {
|
||||
group = 'Test-Screenshots'
|
||||
description = 'Pull screenshots From environment.external Storage'
|
||||
|
||||
ignoreExitValue(true)
|
||||
commandLine "$adb", 'pull', "$environmentExternalFullPath", "$savePath/"
|
||||
}
|
||||
|
||||
task pullScreenshots(dependsOn: [pullScreenshotsContextInternal, pullScreenshotsContextExternal, pullScreenshotsEnvironmentExternal]) {
|
||||
group = 'Test-Screenshots'
|
||||
description = 'Pull screenshots From Device'
|
||||
}
|
||||
|
||||
task removeScreenshotsFromDeviceInternal(type: Exec) {
|
||||
task removeScreenshotsFromDeviceContextInternal(type: Exec) {
|
||||
group = 'Test-Screenshots'
|
||||
description = 'Remove screenshots From internal Storage'
|
||||
description = 'Remove screenshots From context.internal Storage'
|
||||
|
||||
ignoreExitValue(true)
|
||||
commandLine "$adb", 'shell', 'rm', '-r', "$internalFullPath"
|
||||
commandLine "$adb", 'shell', 'rm', '-r', "$contextInternalFullPath"
|
||||
}
|
||||
|
||||
task removeScreenshotsFromDeviceDeprecated(type: Exec) {
|
||||
task removeScreenshotsFromDeviceContextExternal(type: Exec) {
|
||||
group = 'Test-Screenshots'
|
||||
description = 'Remove screenshots From deprecated External Storage'
|
||||
description = 'Remove screenshots From context.external Storage'
|
||||
|
||||
ignoreExitValue(true)
|
||||
commandLine "$adb", 'shell', 'rm', '-r', "$deprecatedFullPath"
|
||||
commandLine "$adb", 'shell', 'rm', '-r', "$contextExternalFullPath"
|
||||
}
|
||||
|
||||
task removeScreenshotsFromDevice(dependsOn: [removeScreenshotsFromDeviceInternal, removeScreenshotsFromDeviceDeprecated]) {
|
||||
task removeScreenshotsFromDeviceEnvironmentExternal(type: Exec) {
|
||||
group = 'Test-Screenshots'
|
||||
description = 'Remove screenshots From environment.external Storage'
|
||||
|
||||
ignoreExitValue(true)
|
||||
commandLine "$adb", 'shell', 'rm', '-r', "$environmentExternalFullPath"
|
||||
}
|
||||
|
||||
task removeScreenshotsFromDevice(dependsOn: [removeScreenshotsFromDeviceContextInternal, removeScreenshotsFromDeviceContextExternal, removeScreenshotsFromDeviceEnvironmentExternal]) {
|
||||
group = 'Test-Screenshots'
|
||||
description = 'Remove screenshots From Device'
|
||||
}
|
||||
|
|
@ -89,9 +106,12 @@ task showLogcat(type: Exec) {
|
|||
commandLine "$adb", 'logcat', '-d'
|
||||
}
|
||||
|
||||
task hasScreenshots(type: Exec) {
|
||||
commandLine "sh", "./verifyfiles.sh", "$savePath"
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
connectedDebugAndroidTest.finalizedBy showLogcat
|
||||
showLogcat.finalizedBy pullScreenshots
|
||||
pullScreenshots.finalizedBy removeScreenshotsFromDevice
|
||||
clean.dependsOn(removeLocalScreenshots)
|
||||
}
|
||||
3
pullscreenshottest.sh
Executable file
3
pullscreenshottest.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
./gradlew clean
|
||||
./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=org.fnives.test.showcase.rule.ScreenshotTest
|
||||
./gradlew app:hasScreenshots
|
||||
|
|
@ -54,6 +54,7 @@ class ScreenshotRule(
|
|||
capture.format = Bitmap.CompressFormat.JPEG
|
||||
try {
|
||||
capture.process(setOf(processor))
|
||||
Log.d(TAG, "Saved image: $filename")
|
||||
} catch (e: IOException) {
|
||||
Log.d(TAG, "Couldn't save image: $e")
|
||||
e.printStackTrace()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import java.io.File
|
|||
|
||||
fun basicScreenCaptureProcessor(subDir: String = "test-screenshots"): ScreenCaptureProcessor {
|
||||
val directory = File(getTestPicturesDir(), subDir)
|
||||
Log.d(ScreenshotRule.TAG, "directory to save screenshots = $directory")
|
||||
Log.d(ScreenshotRule.TAG, "directory to save screenshots = ${directory.absolutePath}")
|
||||
return basicScreenCaptureProcessor(File(getTestPicturesDir(), subDir))
|
||||
}
|
||||
|
||||
|
|
@ -22,15 +22,19 @@ fun basicScreenCaptureProcessor(subDir: String = "test-screenshots"): ScreenCapt
|
|||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
fun getTestPicturesDir(): File? =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
|
||||
Log.d(ScreenshotRule.TAG, "internal folder")
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
Log.d(ScreenshotRule.TAG, "context.internal folder")
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().targetContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
|
||||
} else {
|
||||
InstrumentationRegistry.getInstrumentation().targetContext.filesDir
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val packageName = InstrumentationRegistry.getInstrumentation().targetContext.packageName
|
||||
val environmentFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
|
||||
val externalFolder = File(environmentFolder, packageName)
|
||||
Log.d(ScreenshotRule.TAG, "external folder")
|
||||
Log.d(ScreenshotRule.TAG, "environment.external folder")
|
||||
|
||||
externalFolder
|
||||
} else {
|
||||
Log.d(ScreenshotRule.TAG, "context.external folder")
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().targetContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue