Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions collect_app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ dependencies {
implementation(libs.androidXConstraintLayoutCompose)
implementation(libs.androidXComposeMaterialIcons)
implementation(libs.androidXComposePreview)
implementation(libs.coil)

testImplementation project(':forms-test')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.odk.collect.android.support.pages.ProjectSettingsPage
import org.odk.collect.android.support.rules.FormEntryActivityTestRule
import org.odk.collect.android.support.rules.TestRuleChain.chain
import org.odk.collect.androidtest.RecordedIntentsRule
import org.odk.collect.testshared.AssertionFramework
import java.io.File
import java.io.FileOutputStream
import java.util.Random
Expand Down Expand Up @@ -234,9 +235,9 @@ class FieldListUpdateTest {
.clickOnGroup("Push off screen binary")
.clickOnQuestion("Source10")
.assertNoQuestion("Target10-15")
.clickOnString(org.odk.collect.strings.R.string.capture_image)
.clickOnString(org.odk.collect.strings.R.string.capture_image, FormEntryPage("fieldlist-updates"), AssertionFramework.COMPOSE)
.assertQuestion("Target10-15")
.assertText(org.odk.collect.strings.R.string.capture_image)
.assertText(org.odk.collect.strings.R.string.capture_image, AssertionFramework.COMPOSE)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import android.os.Bundle
import android.os.Environment
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.junit4.createEmptyComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.core.content.FileProvider
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
Expand All @@ -35,18 +36,14 @@ import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents.intending
import androidx.test.espresso.intent.matcher.IntentMatchers.isInternal
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withClassName
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withTagValue
import androidx.test.espresso.matcher.ViewMatchers.withText
import com.google.android.material.textfield.TextInputEditText
import org.hamcrest.CoreMatchers
import org.hamcrest.Matchers
import org.hamcrest.core.StringEndsWith
import org.junit.Rule
import org.junit.Test
Expand Down Expand Up @@ -277,16 +274,18 @@ class IntentGroupTest {
}

private fun assertImageWidgetWithoutAnswer() {
onView(CoreMatchers.allOf(
withTagValue(Matchers.`is`("ImageView")),
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(doesNotExist())
val context = ApplicationProvider.getApplicationContext<Application>()
composeRule
.onNodeWithText(context.getString(R.string.capture_image))
.assertDoesNotExist()

onView(withId(org.odk.collect.android.R.id.capture_button))
.check(matches(CoreMatchers.not(isDisplayed())))
composeRule
.onNodeWithText(context.getString(R.string.choose_image))
.assertDoesNotExist()

onView(withId(org.odk.collect.android.R.id.choose_button))
.check(matches(CoreMatchers.not(isDisplayed())))
composeRule
.onNodeWithClickLabel(R.string.open_file)
.assertDoesNotExist()
}

private fun assertAudioWidgetWithoutAnswer() {
Expand All @@ -296,7 +295,7 @@ class IntentGroupTest {

private fun assertVideoWidgetWithoutAnswer() {
composeRule
.onNodeWithClickLabel(ApplicationProvider.getApplicationContext<Application>().getString(R.string.play_video))
.onNodeWithClickLabel(R.string.play_video)
.assertDoesNotExist()
}

Expand All @@ -306,17 +305,18 @@ class IntentGroupTest {
.assertDoesNotExist()
}

@OptIn(ExperimentalTestApi::class)
private fun assertImageWidgetWithAnswer() {
onView(CoreMatchers.allOf(
withTagValue(Matchers.`is`("ImageView")),
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(CoreMatchers.not(doesNotExist())))
val context = ApplicationProvider.getApplicationContext<Application>()
composeRule
.onNodeWithText(context.getString(R.string.capture_image))
.assertDoesNotExist()

onView(withId(org.odk.collect.android.R.id.capture_button))
.check(matches(CoreMatchers.not(isDisplayed())))
composeRule
.onNodeWithText(context.getString(R.string.choose_image))
.assertDoesNotExist()

onView(withId(org.odk.collect.android.R.id.choose_button))
.check(matches(CoreMatchers.not(isDisplayed())))
composeRule.waitUntilAtLeastOneExists(hasClickLabel(R.string.open_file))
}

private fun assertAudioWidgetWithAnswer() {
Expand All @@ -330,10 +330,9 @@ class IntentGroupTest {
composeRule.waitUntilExactlyOneExists(hasClickLabel(R.string.play_video))
}

@OptIn(ExperimentalTestApi::class)
private fun assertFileWidgetWithAnswer() {
composeRule
.onNodeWithClickLabel(ApplicationProvider.getApplicationContext<Application>().getString(R.string.open_file))
.assertExists()
composeRule.waitUntilAtLeastOneExists(hasClickLabel(R.string.open_file))
}

@Throws(IOException::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.odk.collect.android.support.pages.FormEntryPage
import org.odk.collect.android.support.rules.BlankFormTestRule
import org.odk.collect.android.support.rules.TestRuleChain.chain
import org.odk.collect.strings.R.string
import org.odk.collect.testshared.AssertionFramework

/**
* Integration test that runs through a form with all question types.
Expand Down Expand Up @@ -47,7 +48,7 @@ class AllWidgetsFormTest {
.swipeToNextQuestion("Image widget")
.swipeToNextQuestion("Image widget without Choose button")
.swipeToNextQuestion("Selfie widget")
.clickOnText("Take Picture")
.clickOnText("Take Picture", AssertionFramework.COMPOSE)
.pressBack(FormEntryPage("All widgets"))
.swipeToNextQuestion("Draw widget")
.swipeToNextQuestion("Annotate widget")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,13 +322,22 @@ abstract class Page<T : Page<T>> {
return FormHierarchyPage(formName)
}

fun clickOnText(text: String): T {
EspressoInteractions.clickOn(
allOf(
withText(text),
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)
)
)
@JvmOverloads
fun clickOnText(text: String, assertionFramework: AssertionFramework = AssertionFramework.ESPRESSO): T {
when (assertionFramework) {
AssertionFramework.ESPRESSO -> {
EspressoInteractions.clickOn(
allOf(
withText(text),
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)
)
)
}

AssertionFramework.COMPOSE -> {
ComposeInteractions.clickOn(composeRule!!, hasText(text))
}
}
return this as T
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.odk.collect.android.utilities.MediaUtils
import org.odk.collect.android.utilities.QuestionMediaManager
import org.odk.collect.androidshared.utils.getVideoThumbnail
import org.odk.collect.async.Scheduler
import java.io.File

class MediaWidgetAnswerViewModel(
private val scheduler: Scheduler,
Expand All @@ -30,6 +31,10 @@ class MediaWidgetAnswerViewModel(
return bitmapState
}

fun getImage(answer: String?): File? {
return questionMediaManager.getAnswerFile(answer)
}

fun openFile(context: Context, answer: String?, mimeType: String? = null) {
val file = questionMediaManager.getAnswerFile(answer)
if (file != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package org.odk.collect.android.widgets

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AttachFile
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import org.javarosa.core.model.Constants
import org.javarosa.form.api.FormEntryPrompt
import org.odk.collect.android.widgets.image.ImageWidgetAnswer
import org.odk.collect.android.widgets.video.VideoWidgetAnswer
import org.odk.collect.icons.R

Expand Down Expand Up @@ -49,6 +56,19 @@ fun WidgetAnswer(
)
}
}
Constants.CONTROL_IMAGE_CHOOSE -> ImageWidgetAnswer(
if (summaryView) {
modifier
.height(200.dp)
.wrapContentWidth(Alignment.Start)
} else {
modifier.fillMaxWidth()
},
answer,
if (summaryView) ContentScale.Fit else ContentScale.FillWidth,
mediaWidgetAnswerViewModel,
onLongClick
)
Constants.CONTROL_VIDEO_CAPTURE -> VideoWidgetAnswer(modifier, answer, mediaWidgetAnswerViewModel, onLongClick)
Constants.CONTROL_FILE_CAPTURE -> {
val context = LocalContext.current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.odk.collect.android.widgets.datetime.DateTimeWidget;
import org.odk.collect.android.widgets.datetime.DateWidget;
import org.odk.collect.android.widgets.datetime.TimeWidget;
import org.odk.collect.android.widgets.image.ImageWidget;
import org.odk.collect.android.widgets.items.LabelWidget;
import org.odk.collect.android.widgets.items.LikertWidget;
import org.odk.collect.android.widgets.items.ListMultiWidget;
Expand Down
Loading