Skip to content
Merged
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
14 changes: 14 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -298,23 +298,37 @@ dependencies {

// Testing
testImplementation(libs.junit5)
testImplementation(libs.junit)
testRuntimeOnly(libs.junit5.launcher)
testRuntimeOnly(libs.junit5.vintage)
testImplementation(libs.coroutines.test)
testImplementation(libs.mockk)
testImplementation(libs.robolectric)
testImplementation(libs.ktor.client.mock)
testImplementation(libs.mockwebserver3)
testImplementation(project(":player-test-fixtures"))

detektPlugins(libs.detekt.compose.rules)

androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
androidTestImplementation(libs.mockwebserver3)
androidTestImplementation(libs.kaspresso)
androidTestImplementation(libs.kaspresso.compose)
androidTestImplementation(libs.kakao.compose)
add("instrumentationImplementation", project(":player-test-fixtures"))
add("instrumentationImplementation", libs.mockwebserver3)
add("instrumentationImplementation", libs.androidx.drawerlayout)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)

implementation(libs.androidx.profileinstaller)
}

android.testOptions {
unitTests.isIncludeAndroidResources = true
}

baselineProfile {
saveInSrc = true
automaticGenerationDuringBuild = false
Expand Down
4 changes: 4 additions & 0 deletions app/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.kino.puber.ui.feature.player

import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.kaspersky.components.composesupport.config.withComposeSupport
import com.kaspersky.kaspresso.kaspresso.Kaspresso
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
import com.kino.puber.ui.feature.player.component.PlayerComposeScreen
import io.github.kakaocup.compose.node.element.ComposeScreen

internal abstract class PlayerInstrumentationTestCase : TestCase(
kaspressoBuilder = Kaspresso.Builder.simple(),
)

internal abstract class PlayerComposeInstrumentationTestCase : TestCase(
kaspressoBuilder = Kaspresso.Builder.withComposeSupport(),
) {
protected fun onPlayerScreen(
semanticsProvider: SemanticsNodeInteractionsProvider,
actions: PlayerComposeScreen.() -> Unit,
) {
ComposeScreen.onComposeScreen<PlayerComposeScreen>(
semanticsProvider = semanticsProvider,
function = actions,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.kino.puber.ui.feature.player.component

import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import androidx.compose.ui.test.hasAnyDescendant
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isFocused
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.KNode

internal class PlayerComposeScreen(
semanticsProvider: SemanticsNodeInteractionsProvider,
) : ComposeScreen<PlayerComposeScreen>(
semanticsProvider = semanticsProvider,
viewBuilderAction = {
useUnmergedTree = true
hasTestTag(PlayerScreenTestTags.Root)
},
) {

val playerSurface: KNode = child {
useUnmergedTree = true
hasTestTag(PlayerScreenTestTags.Surface)
}

val playPauseButton: KNode = child {
useUnmergedTree = true
hasTestTag(PlayerScreenTestTags.PlayPause)
}

val seekBar: KNode = child {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тут тоже tagged можно использовать. tagged вынести как экстеншн в утильный класс и переиспользовать в будущем

useUnmergedTree = true
hasTestTag(PlayerScreenTestTags.SeekBar)
}

val markWatchedButton: KNode = tagged(PlayerScreenTestTags.MarkWatched)
val episodesButton: KNode = tagged(PlayerScreenTestTags.Episodes)
val audioSubtitlesButton: KNode = tagged(PlayerScreenTestTags.AudioSubtitles)
val videoSettingsButton: KNode = tagged(PlayerScreenTestTags.VideoSettings)
val resumeButton: KNode = tagged(PlayerScreenTestTags.ResumeContinue)
val retryButton: KNode = tagged(PlayerScreenTestTags.Retry)
val nextEpisodeButton: KNode = tagged(PlayerScreenTestTags.NextEpisode)

val focusedMarkWatchedButton: KNode = focusedTag(PlayerScreenTestTags.MarkWatched)
val focusedEpisodesButton: KNode = focusedTag(PlayerScreenTestTags.Episodes)
val focusedAudioSubtitlesButton: KNode = focusedTag(PlayerScreenTestTags.AudioSubtitles)
val focusedVideoSettingsButton: KNode = focusedTag(PlayerScreenTestTags.VideoSettings)
val focusedResumeButton: KNode = focusedTag(PlayerScreenTestTags.ResumeContinue)
val focusedRetryButton: KNode = focusedTag(PlayerScreenTestTags.Retry)
val focusedNextEpisodeButton: KNode = focusedTag(PlayerScreenTestTags.NextEpisode)

fun panelItem(group: String, index: Int): KNode =
tagged(PlayerScreenTestTags.panelItem(group, index))

fun focusedPanelItem(group: String, index: Int): KNode =
focusedTag(PlayerScreenTestTags.panelItem(group, index))

fun tagged(tag: String): KNode = child {
useUnmergedTree = true
hasTestTag(tag)
}

fun focusedTag(tag: String): KNode {
val tagMatcher = hasTestTag(tag)
val matcher = isFocused() and (
tagMatcher or
hasAnyDescendant(tagMatcher)
)
return child {
useUnmergedTree = true
addSemanticsMatcher(matcher)
}
}

fun text(text: String, substring: Boolean = false): KNode = child {
useUnmergedTree = true
hasText(text, substring = substring)
}

fun focusedText(text: String, substring: Boolean = false): KNode {
val textMatcher = hasText(text, substring = substring)
val matcher = isFocused() and (textMatcher or hasAnyDescendant(textMatcher))
return child {
useUnmergedTree = true
addSemanticsMatcher(matcher)
}
}
}
Loading
Loading