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 .gemini/styleguide.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ When reviewing a pull request, focus on the following key areas:
* **Scrutinize Debug Logs:** Question the use of `Log.d`, `Log.v`, and especially `println()`. These are often remnants of debugging and should be removed before merging unless they provide essential, long-term value. Calls to `println()` should always be replaced with a proper `Log` method.
* **KDoc for Complexity:** For new or significantly modified functions that are complex, have non-obvious logic, or a large number of parameters, suggest adding KDoc comments. Good documentation should explain the function's purpose, its parameters, and what it returns.
* **Keep KDoc Synchronized:** If a PR modifies a function with existing KDocs, verify that the comments are still accurate. Outdated documentation can be more misleading than no documentation at all.
* **Trace Naming Scheme:** Standardize on `ComponentName.actionName` or `ClassName.methodName` for custom trace sections to make them easily searchable in Perfetto. [Introduced in PR #518]

11. **KDoc Documentation Standards**
* **Document all non-private members:** All non-private classes, functions, and composables must have KDoc documentation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.printToString
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.action.ViewActions.swipeDown
import androidx.tracing.trace
import com.google.common.truth.Truth.assertThat
import com.google.errorprone.annotations.CanIgnoreReturnValue
import com.google.jetpackcamera.model.CaptureMode
Expand Down Expand Up @@ -249,60 +250,87 @@ fun ComposeTestRule.pressAndDragToLockVideoRecording(
onNodeWithTag(VIDEO_CAPTURE_FAILURE_TAG).assertIsNotDisplayed()
}
) {
onNodeWithTag(CAPTURE_BUTTON)
.assertExists()
.performTouchInput {
down(center)
trace("pressAndDragToLockVideoRecording") {
onNodeWithTag(CAPTURE_BUTTON).assertExists().performTouchInput {
trace("down(center)") { down(center) }
trace("wait for long press and trigger onDragStart") {
advanceEventTime(viewConfiguration.longPressTimeoutMillis + 100)
moveBy(delta = Offset(1f, 0f))
}
}
waitUntil(timeoutMillis = ELAPSED_TIME_TEXT_TIMEOUT_MILLIS) {
checkWhileWaiting()
onNodeWithTag(ELAPSED_TIME_TAG).isDisplayed()
}
onNodeWithTag(CAPTURE_BUTTON)
.assertExists()
.performTouchInput {
moveBy(delta = Offset(-400f, 0f))
up()

// Wait for recording to start (timer displayed)
trace("wait for ELAPSED_TIME_TAG") {
waitUntil(timeoutMillis = ELAPSED_TIME_TEXT_TIMEOUT_MILLIS) {
onNodeWithTag(ELAPSED_TIME_TAG).isDisplayed()
}
}
waitUntilVideoRecordingDurationAtLeast(durationMillis, checkWhileWaiting)

onNodeWithTag(CAPTURE_BUTTON).performTouchInput {
trace("drag to lock") {
val steps = 10
val deltaX = -400f / steps
for (i in 1..steps) {
moveBy(delta = Offset(deltaX, 0f))
}
}
}

onNodeWithTag(CAPTURE_BUTTON).performTouchInput { trace("up()") { up() } }

// Wait for the recording to reach desired duration
trace("waitUntilVideoRecordingDurationAtLeast") {
waitUntilVideoRecordingDurationAtLeast(durationMillis, checkWhileWaiting)
}
}
}

fun ComposeTestRule.longClickForVideoRecordingCheckingElapsedTime(
durationMillis: Long = VIDEO_DURATION_MILLIS,
checkWhileWaiting: () -> Unit = {
// If the video capture fails, there is no point to continue waiting. Assert.
onNodeWithTag(VIDEO_CAPTURE_FAILURE_TAG).assertIsNotDisplayed()
if (onAllNodesWithTag(VIDEO_CAPTURE_FAILURE_TAG).fetchSemanticsNodes().isNotEmpty()) {
throw AssertionError("Video capture failed!")
}
}
) {
onNodeWithTag(CAPTURE_BUTTON)
.assertExists()
.performTouchInput {
down(center)
trace("longClickForVideoRecordingCheckingElapsedTime") {
onNodeWithTag(CAPTURE_BUTTON).assertExists().performTouchInput {
trace("down(center)") { down(center) }

trace("wait for long press and trigger onDragStart") {
advanceEventTime(viewConfiguration.longPressTimeoutMillis + 100)
moveBy(delta = Offset(1f, 0f))
}
}
waitUntil(timeoutMillis = ELAPSED_TIME_TEXT_TIMEOUT_MILLIS) {
checkWhileWaiting()
onNodeWithTag(ELAPSED_TIME_TAG).isDisplayed()
}
waitUntilVideoRecordingDurationAtLeast(durationMillis, checkWhileWaiting)
onNodeWithTag(CAPTURE_BUTTON)
.assertExists()
.performTouchInput {
up()

// Wait for recording to start (timer displayed)
trace("wait for ELAPSED_TIME_TAG") {
waitUntil(timeoutMillis = ELAPSED_TIME_TEXT_TIMEOUT_MILLIS) {
onAllNodesWithTag(ELAPSED_TIME_TAG).fetchSemanticsNodes().isNotEmpty()
}
}

// Wait for the desired duration outside performTouchInput
waitUntilVideoRecordingDurationAtLeast(durationMillis, checkWhileWaiting)

// Complete the gesture (release touch)
trace("up() after long click") { onNodeWithTag(CAPTURE_BUTTON).performTouchInput { up() } }
}
}

fun ComposeTestRule.longClickForVideoRecording(durationMillis: Long = VIDEO_DURATION_MILLIS) {
onNodeWithTag(CAPTURE_BUTTON)
.assertExists()
.performTouchInput {
down(center)
}
idleForVideoDuration(durationMillis)
onNodeWithTag(CAPTURE_BUTTON)
.assertExists()
.performTouchInput {
up()
trace("longClickForVideoRecording") {
onNodeWithTag(CAPTURE_BUTTON).assertExists().performTouchInput {
trace("down(center)") { down(center) }
trace("wait for long press and trigger onDragStart") {
advanceEventTime(viewConfiguration.longPressTimeoutMillis + 100)
moveBy(delta = Offset(1f, 0f))
}
trace("wait for duration") { advanceEventTime(durationMillis) }
trace("up()") { up() }
}
}
}

fun ComposeTestRule.tapStartLockedVideoRecording() {
Expand Down
3 changes: 3 additions & 0 deletions ui/components/capture/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ dependencies {
implementation(libs.camera.core)
implementation(libs.camera.compose)

// Tracing
implementation(libs.androidx.tracing)

// Compose - Testing
androidTestImplementation(libs.compose.junit)
debugImplementation(libs.compose.test.manifest)
Expand Down
Loading
Loading