Skip to content

Commit

Permalink
Scan implementation using Scanbot, test cases added and Scan Event tr…
Browse files Browse the repository at this point in the history
…acking.

Scanbot migration 1.89.0 -> 4.0.0
  • Loading branch information
surinder-tsys committed Jun 26, 2024
1 parent 95c84b4 commit 059254b
Show file tree
Hide file tree
Showing 79 changed files with 4,708 additions and 39 deletions.
20 changes: 16 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ android {
resources {
excludes += 'META-INF/LICENSE*'
excludes += 'META-INF/versions/9/OSGI-INF/MANIFEST*'
excludes += 'META-INF/DEPENDENCIES'
pickFirst 'MANIFEST.MF' // workaround for duplicated manifest on some dependencies
}
}
Expand Down Expand Up @@ -294,7 +295,9 @@ dependencies {
implementation "androidx.fragment:fragment-ktx:1.8.0"
implementation 'com.github.albfernandez:juniversalchardet:2.0.3' // need this version for Android <7
compileOnly 'com.google.code.findbugs:annotations:3.0.1u2'
implementation 'commons-io:commons-io:2.16.1'
//Note: Do not change the commons-io:commons-io version from 2.4 to any other
//this is required for ScanBot SDK to work on low end devices ie. 6 & 7 Api levels
implementation 'commons-io:commons-io:2.4'
implementation 'org.greenrobot:eventbus:3.3.1'
implementation 'com.googlecode.ez-vcard:ez-vcard:0.12.1'
implementation 'org.lukhnos:nnio:0.3.1'
Expand All @@ -315,10 +318,11 @@ dependencies {
implementation "com.github.nextcloud-deps.hwsecurity:hwsecurity-fido:$fidoVersion"
implementation "com.github.nextcloud-deps.hwsecurity:hwsecurity-fido2:$fidoVersion"

//NextCloud scan is not required in NMC
// document scanner not available on FDroid (generic) due to OpenCV binaries
gplayImplementation project(':appscan')
huaweiImplementation project(':appscan')
qaImplementation project(':appscan')
/* gplayImplementation project(':appscan')
huaweiImplementation project(':appscan')
qaImplementation project(':appscan') */

spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.13.0'
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.6.4'
Expand Down Expand Up @@ -424,6 +428,14 @@ dependencies {

// splash screen dependency ref: https://developer.android.com/develop/ui/views/launch/splash-screen/migrate
implementation 'androidx.core:core-splashscreen:1.0.1'

//scanbot sdk: https://github.com/doo/scanbot-sdk-example-android
implementation "io.scanbot:sdk-package-2:$scanbotSdkVersion"

//apache pdf-box for encrypting pdf files
implementation(group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.1') {
exclude group: "commons-logging"
}
}

configurations.configureEach {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.nmc.android.scans

import android.Manifest
import androidx.test.espresso.Espresso
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.rule.GrantPermissionRule
import com.owncloud.android.AbstractIT
import com.owncloud.android.R
import junit.framework.TestCase
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@LargeTest
/*
* Scan test to test the max number of possible scans till device throws exception or unexpected error occurs
*/
class ScanActivityMultipleTest : AbstractIT() {
@get:Rule
val activityRule = ActivityScenarioRule(ScanActivity::class.java)

@get:Rule
val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.CAMERA)

private var docScanCount = 0

@Test
fun runAllScanTests() {
captureAndVerifyDocScan()
for (i in 0 until MAX_NUMBER_OF_SCAN) {
println("Scan no: $docScanCount")
verifyScanMoreDocument()
}
}

private fun captureAndVerifyDocScan() {
Espresso.onView(ViewMatchers.withId(R.id.shutterButton)).perform(ViewActions.click())
shortSleep()
shortSleep()
shortSleep()
shortSleep()
docScanCount++
TestCase.assertEquals(docScanCount, ScanActivity.originalScannedImages.size)
}

private fun verifyScanMoreDocument() {
Espresso.onView(ViewMatchers.withId(R.id.scanMoreButton)).perform(ViewActions.click())
captureAndVerifyDocScan()
}

companion object {
/**
* variable to define max number of scans to test
*/
private const val MAX_NUMBER_OF_SCAN = 40
}
}
246 changes: 246 additions & 0 deletions app/src/androidTest/java/com/nmc/android/scans/ScanActivityTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
package com.nmc.android.scans

import android.Manifest
import androidx.test.espresso.Espresso
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.matcher.RootMatchers
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.rule.GrantPermissionRule
import com.owncloud.android.AbstractIT
import com.owncloud.android.R
import junit.framework.TestCase
import org.hamcrest.core.IsNot
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@LargeTest
/*
*Scan test to test the full flow of document scan from Scanning to Save page.
*/
class ScanActivityTest : AbstractIT() {
@get:Rule
val activityRule = ActivityScenarioRule(ScanActivity::class.java)

@get:Rule
val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.CAMERA)

private var docScanCount = 0

/*
* running all test in one test will create a flow from scanning to saving the scans
*/
@Test
fun runAllScanTests() {
verifyIfToolbarHidden()
verifyIfScanFragmentReplaced()
verifyToggleAutomatic()
verifyToggleFlash()
captureAndVerifyDocScan()
verifyScanMoreDocument()
verifyApplyFilter()
verifyRotateDocument()
verifyImageCrop()
verifyImageDeletion()
verifySaveScannedDocs()
verifyPasswordSwitch()
verifyPdfPasswordSwitchToggle()
}

private fun verifyIfToolbarHidden() {
Espresso.onView(ViewMatchers.withId(R.id.toolbar))
.check(ViewAssertions.matches(IsNot.not(ViewMatchers.isDisplayed())))
}

private fun verifyIfScanFragmentReplaced() {
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_automatic))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_flash))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_cancel))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.shutterButton))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
}

private fun verifyToggleAutomatic() {
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_automatic)).perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_automatic)).check(
ViewAssertions.matches(
ViewMatchers.hasTextColor(
R.color.grey_60
)
)
)

Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_automatic)).perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_automatic)).check(
ViewAssertions.matches(
ViewMatchers.hasTextColor(
R.color.primary
)
)
)
}

private fun verifyToggleFlash() {
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_flash)).perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_flash)).check(
ViewAssertions.matches(
ViewMatchers.hasTextColor(
R.color.primary
)
)
)

Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_flash)).perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.scan_doc_btn_flash)).check(
ViewAssertions.matches(
ViewMatchers.hasTextColor(
R.color.grey_60
)
)
)
}

private fun captureAndVerifyDocScan() {
Espresso.onView(ViewMatchers.withId(R.id.shutterButton)).perform(ViewActions.click())
shortSleep()
shortSleep()
shortSleep()
docScanCount++
TestCase.assertEquals(docScanCount, ScanActivity.originalScannedImages.size)
}

private fun verifyScanMoreDocument() {
Espresso.onView(ViewMatchers.withId(R.id.scanMoreButton)).perform(ViewActions.click())
captureAndVerifyDocScan()
}

private fun verifyApplyFilter() {
Espresso.onView(ViewMatchers.withId(R.id.filterDocButton)).perform(ViewActions.click())

Espresso.onView(ViewMatchers.withText(R.string.edit_scan_filter_dialog_title))
.inRoot(RootMatchers.isDialog())
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))

Espresso.onView(ViewMatchers.withText(R.string.edit_scan_filter_b_n_w))
.inRoot(RootMatchers.isDialog())
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
.perform(ViewActions.click())

shortSleep()
shortSleep()
shortSleep()
}

private fun verifyRotateDocument() {
Espresso.onView(ViewMatchers.withId(R.id.rotateDocButton)).perform(ViewActions.click())
}

private fun verifyImageCrop() {
Espresso.onView(ViewMatchers.withId(R.id.cropDocButton)).perform(ViewActions.click())

Espresso.onView(ViewMatchers.withId(R.id.crop_polygon_view))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.crop_btn_reset_borders))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))

Espresso.onView(ViewMatchers.withId(R.id.action_save)).perform(ViewActions.click())
}

private fun verifyImageDeletion() {
Espresso.onView(ViewMatchers.withId(R.id.deleteDocButton)).perform(ViewActions.click())
docScanCount--
TestCase.assertEquals(docScanCount, ScanActivity.originalScannedImages.size)
}

private fun verifySaveScannedDocs() {
Espresso.onView(ViewMatchers.withId(R.id.action_save)).perform(ViewActions.click())

Espresso.onView(ViewMatchers.withId(R.id.scan_save_filename_input))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_location_input))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_nested_scroll_view)).perform(ViewActions.swipeUp())

Espresso.onView(ViewMatchers.withId(R.id.scan_save_without_txt_recognition_pdf_checkbox))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_without_txt_recognition_png_checkbox))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_without_txt_recognition_jpg_checkbox))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_with_txt_recognition_pdf_checkbox))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_with_txt_recognition_txt_checkbox))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))

Espresso.onView(ViewMatchers.withId(R.id.scan_save_without_txt_recognition_pdf_checkbox)).check(
ViewAssertions.matches(
IsNot.not(ViewMatchers.isChecked())
)
)
Espresso.onView(ViewMatchers.withId(R.id.scan_save_without_txt_recognition_png_checkbox)).check(
ViewAssertions.matches(
IsNot.not(ViewMatchers.isChecked())
)
)
Espresso.onView(ViewMatchers.withId(R.id.scan_save_without_txt_recognition_jpg_checkbox)).check(
ViewAssertions.matches(
IsNot.not(ViewMatchers.isChecked())
)
)
Espresso.onView(ViewMatchers.withId(R.id.scan_save_with_txt_recognition_pdf_checkbox))
.check(ViewAssertions.matches(ViewMatchers.isChecked()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_with_txt_recognition_txt_checkbox)).check(
ViewAssertions.matches(
IsNot.not(ViewMatchers.isChecked())
)
)

Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch))
.check(ViewAssertions.matches(ViewMatchers.isEnabled()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch))
.check(ViewAssertions.matches(IsNot.not(ViewMatchers.isChecked())))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_text_input))
.check(ViewAssertions.matches(IsNot.not(ViewMatchers.isDisplayed())))

Espresso.onView(ViewMatchers.withId(R.id.save_scan_btn_cancel))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Espresso.onView(ViewMatchers.withId(R.id.save_scan_btn_save))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
}

private fun verifyPasswordSwitch() {
Espresso.onView(ViewMatchers.withId(R.id.scan_save_with_txt_recognition_pdf_checkbox))
.perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch))
.check(ViewAssertions.matches(IsNot.not(ViewMatchers.isEnabled())))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch))
.check(ViewAssertions.matches(IsNot.not(ViewMatchers.isChecked())))

Espresso.onView(ViewMatchers.withId(R.id.scan_save_without_txt_recognition_pdf_checkbox))
.perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch))
.check(ViewAssertions.matches(ViewMatchers.isEnabled()))
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch))
.check(ViewAssertions.matches(IsNot.not(ViewMatchers.isChecked())))
}

private fun verifyPdfPasswordSwitchToggle() {
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch)).perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_text_input))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))

Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_switch)).perform(ViewActions.click())
Espresso.onView(ViewMatchers.withId(R.id.scan_save_pdf_password_text_input))
.check(ViewAssertions.matches(IsNot.not(ViewMatchers.isDisplayed())))
}
}
Loading

0 comments on commit 059254b

Please sign in to comment.