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
NMC-3671 -- e2ee folder selection if e2ee is already setup
NMC-3670 -- crash fix while saving into e2ee folder without e2ee setup
NMC-3699 & NMC-3701 -- fix e2ee folder path
NMC-3702 -- create sub-folder and open them properly for e2ee folders
  • Loading branch information
surinder-tsys committed Jan 6, 2025
1 parent a12f1cc commit 8b4a82d
Show file tree
Hide file tree
Showing 78 changed files with 4,782 additions and 36 deletions.
10 changes: 7 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ apply plugin: 'pmd'
apply from: "$rootProject.projectDir/jacoco.gradle"
apply plugin: 'com.github.spotbugs'
apply plugin: 'io.gitlab.arturbosch.detekt'
// apply scanbot SDK for NMC
apply from: "$rootProject.projectDir/nmc_scan-dependencies.gradle"

// needed to make renovate run without shot, as shot requires Android SDK
// https://github.com/pedrovgs/Shot/issues/300
Expand Down Expand Up @@ -199,6 +201,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 @@ -318,10 +321,11 @@ dependencies {
implementation 'com.vanniktech:emoji-google:0.21.0'
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")

//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.8'
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 8b4a82d

Please sign in to comment.