mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-07 14:20:58 -04:00
Refactored the ZimHostFragmentTest according to compose.
This commit is contained in:
parent
6e370a1e74
commit
a72d021e95
@ -53,12 +53,14 @@ class ErrorActivityRobot : BaseRobot() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun assertCheckBoxesDisplayed(composeTestRule: ComposeContentTestRule) {
|
fun assertCheckBoxesDisplayed(composeTestRule: ComposeContentTestRule) {
|
||||||
composeTestRule.onNodeWithText(context.getString(R.string.crash_checkbox_language))
|
composeTestRule.apply {
|
||||||
.assertIsDisplayed()
|
onNodeWithText(context.getString(R.string.crash_checkbox_language))
|
||||||
composeTestRule.onNodeWithText(context.getString(R.string.crash_checkbox_logs))
|
.assertIsDisplayed()
|
||||||
.assertIsDisplayed()
|
onNodeWithText(context.getString(R.string.crash_checkbox_logs))
|
||||||
composeTestRule.onNodeWithText(context.getString(R.string.crash_checkbox_zimfiles))
|
.assertIsDisplayed()
|
||||||
.assertIsDisplayed()
|
onNodeWithText(context.getString(R.string.crash_checkbox_zimfiles))
|
||||||
|
.assertIsDisplayed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clickOnSendDetailsButton(composeTestRule: ComposeContentTestRule) {
|
fun clickOnSendDetailsButton(composeTestRule: ComposeContentTestRule) {
|
||||||
|
@ -21,6 +21,7 @@ package org.kiwix.kiwixmobile.webserver
|
|||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.test.core.app.ActivityScenario
|
import androidx.test.core.app.ActivityScenario
|
||||||
import androidx.test.espresso.accessibility.AccessibilityChecks
|
import androidx.test.espresso.accessibility.AccessibilityChecks
|
||||||
@ -31,7 +32,6 @@ import androidx.test.uiautomator.UiDevice
|
|||||||
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesCheck
|
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesCheck
|
||||||
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews
|
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews
|
||||||
import com.google.android.apps.common.testing.accessibility.framework.checks.DuplicateClickableBoundsCheck
|
import com.google.android.apps.common.testing.accessibility.framework.checks.DuplicateClickableBoundsCheck
|
||||||
import leakcanary.LeakAssertions
|
|
||||||
import org.hamcrest.Matchers.allOf
|
import org.hamcrest.Matchers.allOf
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -54,6 +54,9 @@ class ZimHostFragmentTest {
|
|||||||
@JvmField
|
@JvmField
|
||||||
var retryRule = RetryRule()
|
var retryRule = RetryRule()
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val composeTestRule = createComposeRule()
|
||||||
|
|
||||||
private lateinit var sharedPreferenceUtil: SharedPreferenceUtil
|
private lateinit var sharedPreferenceUtil: SharedPreferenceUtil
|
||||||
|
|
||||||
private lateinit var activityScenario: ActivityScenario<KiwixMainActivity>
|
private lateinit var activityScenario: ActivityScenario<KiwixMainActivity>
|
||||||
@ -150,53 +153,52 @@ class ZimHostFragmentTest {
|
|||||||
openZimHostFragment()
|
openZimHostFragment()
|
||||||
|
|
||||||
// Check if server is already started
|
// Check if server is already started
|
||||||
stopServerIfAlreadyStarted()
|
stopServerIfAlreadyStarted(composeTestRule)
|
||||||
|
|
||||||
// Check if both zim file are selected or not to properly run our test case
|
// Check if both zim file are selected or not to properly run our test case
|
||||||
selectZimFileIfNotAlreadySelected()
|
selectZimFileIfNotAlreadySelected(composeTestRule)
|
||||||
|
|
||||||
clickOnTestZim()
|
clickOnTestZim(composeTestRule)
|
||||||
|
|
||||||
// Start the server with one ZIM file
|
// Start the server with one ZIM file
|
||||||
startServer()
|
startServer(composeTestRule)
|
||||||
assertServerStarted()
|
assertServerStarted(composeTestRule)
|
||||||
|
|
||||||
// Check that only one ZIM file is hosted on the server
|
// Check that only one ZIM file is hosted on the server
|
||||||
assertItemHostedOnServer(1)
|
assertItemHostedOnServer(1, composeTestRule)
|
||||||
|
|
||||||
// Check QR code shown
|
// Check QR code shown
|
||||||
assertQrShown()
|
assertQrShown(composeTestRule)
|
||||||
|
|
||||||
// Stop the server
|
// Stop the server
|
||||||
stopServer()
|
stopServer(composeTestRule)
|
||||||
assertServerStopped()
|
assertServerStopped(composeTestRule)
|
||||||
|
|
||||||
// Check QR code not shown after stopping the server
|
// Check QR code not shown after stopping the server
|
||||||
assertQrNotShown()
|
assertQrNotShown(composeTestRule)
|
||||||
|
|
||||||
// Select the test ZIM file to host on the server
|
// Select the test ZIM file to host on the server
|
||||||
clickOnTestZim()
|
clickOnTestZim(composeTestRule)
|
||||||
|
|
||||||
// Start the server with two ZIM files
|
// Start the server with two ZIM files
|
||||||
startServer()
|
startServer(composeTestRule)
|
||||||
assertServerStarted()
|
assertServerStarted(composeTestRule)
|
||||||
|
|
||||||
// Check that both ZIM files are hosted on the server
|
// Check that both ZIM files are hosted on the server
|
||||||
assertItemHostedOnServer(2)
|
assertItemHostedOnServer(2, composeTestRule)
|
||||||
|
|
||||||
// Unselect the test ZIM to test restarting server functionality
|
// Unselect the test ZIM to test restarting server functionality
|
||||||
clickOnTestZim()
|
clickOnTestZim(composeTestRule)
|
||||||
|
|
||||||
// Check if the server is running
|
// Check if the server is running
|
||||||
assertServerStarted()
|
assertServerStarted(composeTestRule)
|
||||||
|
|
||||||
// Check that only one ZIM file is hosted on the server after unselecting
|
// Check that only one ZIM file is hosted on the server after unselecting
|
||||||
assertItemHostedOnServer(1)
|
assertItemHostedOnServer(1, composeTestRule)
|
||||||
|
|
||||||
// finally close the server at the end of test case
|
// finally close the server at the end of test case
|
||||||
stopServer()
|
stopServer(composeTestRule)
|
||||||
}
|
}
|
||||||
LeakAssertions.assertNoLeaks()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,30 +18,28 @@
|
|||||||
|
|
||||||
package org.kiwix.kiwixmobile.webserver
|
package org.kiwix.kiwixmobile.webserver
|
||||||
|
|
||||||
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
|
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||||
|
import androidx.compose.ui.test.assertIsOn
|
||||||
|
import androidx.compose.ui.test.assertTextEquals
|
||||||
|
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||||
|
import androidx.compose.ui.test.onNodeWithTag
|
||||||
|
import androidx.compose.ui.test.performClick
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
|
||||||
import androidx.test.espresso.matcher.ViewMatchers
|
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.assertThat
|
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||||
import applyWithViewHierarchyPrinting
|
import applyWithViewHierarchyPrinting
|
||||||
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
|
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
|
||||||
import com.adevinta.android.barista.interaction.BaristaSwipeRefreshInteractions.refresh
|
import com.adevinta.android.barista.interaction.BaristaSwipeRefreshInteractions.refresh
|
||||||
import junit.framework.AssertionFailedError
|
import junit.framework.AssertionFailedError
|
||||||
import org.hamcrest.CoreMatchers
|
|
||||||
import org.kiwix.kiwixmobile.BaseRobot
|
import org.kiwix.kiwixmobile.BaseRobot
|
||||||
import org.kiwix.kiwixmobile.Findable.StringId.TextId
|
import org.kiwix.kiwixmobile.Findable.StringId.TextId
|
||||||
import org.kiwix.kiwixmobile.Findable.Text
|
import org.kiwix.kiwixmobile.Findable.Text
|
||||||
import org.kiwix.kiwixmobile.Findable.ViewId
|
|
||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
import org.kiwix.kiwixmobile.R.id
|
|
||||||
import org.kiwix.kiwixmobile.core.utils.files.Log
|
import org.kiwix.kiwixmobile.core.utils.files.Log
|
||||||
import org.kiwix.kiwixmobile.testutils.TestUtils
|
import org.kiwix.kiwixmobile.testutils.TestUtils
|
||||||
import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView
|
import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView
|
||||||
import org.kiwix.kiwixmobile.utils.RecyclerViewItemCount
|
import org.kiwix.kiwixmobile.ui.BOOK_ITEM_CHECKBOX_TESTING_TAG
|
||||||
import org.kiwix.kiwixmobile.utils.RecyclerViewMatcher
|
|
||||||
import org.kiwix.kiwixmobile.utils.RecyclerViewSelectedCheckBoxCountAssertion
|
|
||||||
import org.kiwix.kiwixmobile.utils.StandardActions.openDrawer
|
import org.kiwix.kiwixmobile.utils.StandardActions.openDrawer
|
||||||
|
|
||||||
fun zimHost(func: ZimHostRobot.() -> Unit) = ZimHostRobot().applyWithViewHierarchyPrinting(func)
|
fun zimHost(func: ZimHostRobot.() -> Unit) = ZimHostRobot().applyWithViewHierarchyPrinting(func)
|
||||||
@ -66,15 +64,20 @@ class ZimHostRobot : BaseRobot() {
|
|||||||
clickOn(TextId(R.string.menu_wifi_hotspot))
|
clickOn(TextId(R.string.menu_wifi_hotspot))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clickOnTestZim() {
|
fun clickOnTestZim(composeTestRule: ComposeContentTestRule) {
|
||||||
pauseForBetterTestPerformance()
|
testFlakyView({
|
||||||
clickOn(Text("Test_Zim"))
|
composeTestRule.apply {
|
||||||
|
waitForIdle()
|
||||||
|
onNodeWithTag("${BOOK_ITEM_CHECKBOX_TESTING_TAG}2").performClick()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startServer() {
|
fun startServer(composeTestRule: ComposeContentTestRule) {
|
||||||
// stop the server if it is already running.
|
// stop the server if it is already running.
|
||||||
stopServerIfAlreadyStarted()
|
stopServerIfAlreadyStarted(composeTestRule)
|
||||||
clickOn(ViewId(id.startServerButton))
|
composeTestRule.onNodeWithTag(START_SERVER_BUTTON_TESTING_TAG)
|
||||||
|
.performClick()
|
||||||
assetWifiDialogDisplayed()
|
assetWifiDialogDisplayed()
|
||||||
testFlakyView({ onView(withText("PROCEED")).perform(click()) })
|
testFlakyView({ onView(withText("PROCEED")).perform(click()) })
|
||||||
}
|
}
|
||||||
@ -83,24 +86,30 @@ class ZimHostRobot : BaseRobot() {
|
|||||||
testFlakyView({ isVisible(Text("WiFi connection detected")) })
|
testFlakyView({ isVisible(Text("WiFi connection detected")) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertServerStarted() {
|
fun assertServerStarted(composeTestRule: ComposeContentTestRule) {
|
||||||
pauseForBetterTestPerformance()
|
pauseForBetterTestPerformance()
|
||||||
// starting server takes a bit so sometimes it fails to find this view.
|
// starting server takes a bit so sometimes it fails to find this view.
|
||||||
// which makes this view flaky so we are testing this with FlakyView.
|
// which makes this view flaky so we are testing this with FlakyView.
|
||||||
testFlakyView({ isVisible(Text("STOP SERVER")) })
|
testFlakyView({
|
||||||
|
composeTestRule.apply {
|
||||||
|
waitForIdle()
|
||||||
|
onNodeWithTag(START_SERVER_BUTTON_TESTING_TAG)
|
||||||
|
.assertTextEquals(context.getString(R.string.stop_server_label).uppercase())
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopServerIfAlreadyStarted() {
|
fun stopServerIfAlreadyStarted(composeTestRule: ComposeContentTestRule) {
|
||||||
try {
|
try {
|
||||||
// Check if the "START SERVER" button is visible because, in most scenarios,
|
// Check if the "START SERVER" button is visible because, in most scenarios,
|
||||||
// this button will appear when the server is already stopped.
|
// this button will appear when the server is already stopped.
|
||||||
// This will expedite our test case, as verifying the visibility of
|
// This will expedite our test case, as verifying the visibility of
|
||||||
// non-visible views takes more time due to the try mechanism needed
|
// non-visible views takes more time due to the try mechanism needed
|
||||||
// to properly retrieve the view.
|
// to properly retrieve the view.
|
||||||
assertServerStopped()
|
assertServerStopped(composeTestRule)
|
||||||
} catch (exception: Exception) {
|
} catch (_: Exception) {
|
||||||
// if "START SERVER" button is not visible it means server is started so close it.
|
// if "START SERVER" button is not visible it means server is started so close it.
|
||||||
stopServer()
|
stopServer(composeTestRule)
|
||||||
Log.i(
|
Log.i(
|
||||||
"ZIM_HOST_FRAGMENT",
|
"ZIM_HOST_FRAGMENT",
|
||||||
"Stopped the server to perform our test case since it was already running"
|
"Stopped the server to perform our test case since it was already running"
|
||||||
@ -108,66 +117,76 @@ class ZimHostRobot : BaseRobot() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun selectZimFileIfNotAlreadySelected() {
|
fun selectZimFileIfNotAlreadySelected(composeTestRule: ComposeContentTestRule) {
|
||||||
try {
|
try {
|
||||||
// check both files are selected.
|
// check both files are selected.
|
||||||
assertItemHostedOnServer(2)
|
assertItemHostedOnServer(2, composeTestRule)
|
||||||
} catch (assertionFailedError: AssertionFailedError) {
|
} catch (_: AssertionFailedError) {
|
||||||
try {
|
try {
|
||||||
val recyclerViewItemsCount =
|
selectZimFile(1, composeTestRule)
|
||||||
RecyclerViewItemCount(id.recyclerViewZimHost).checkRecyclerViewCount()
|
selectZimFile(2, composeTestRule)
|
||||||
(0 until recyclerViewItemsCount)
|
} catch (_: AssertionFailedError) {
|
||||||
.asSequence()
|
|
||||||
.filter { it != 0 }
|
|
||||||
.forEach(::selectZimFile)
|
|
||||||
} catch (assertionFailedError: AssertionFailedError) {
|
|
||||||
Log.i("ZIM_HOST_FRAGMENT", "Failed to select the zim file, probably it is already selected")
|
Log.i("ZIM_HOST_FRAGMENT", "Failed to select the zim file, probably it is already selected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun selectZimFile(position: Int) {
|
private fun selectZimFile(position: Int, composeTestRule: ComposeContentTestRule) {
|
||||||
try {
|
try {
|
||||||
onView(
|
composeTestRule.onNodeWithTag("$BOOK_ITEM_CHECKBOX_TESTING_TAG$position")
|
||||||
RecyclerViewMatcher(id.recyclerViewZimHost).atPositionOnView(
|
.assertIsOn()
|
||||||
position,
|
} catch (_: AssertionFailedError) {
|
||||||
R.id.itemBookCheckbox
|
composeTestRule.onNodeWithTag("$BOOK_ITEM_CHECKBOX_TESTING_TAG$position")
|
||||||
)
|
.performClick()
|
||||||
).check(matches(ViewMatchers.isChecked()))
|
|
||||||
} catch (assertionError: AssertionFailedError) {
|
|
||||||
onView(
|
|
||||||
RecyclerViewMatcher(id.recyclerViewZimHost).atPositionOnView(
|
|
||||||
position,
|
|
||||||
R.id.itemBookCheckbox
|
|
||||||
)
|
|
||||||
).perform(click())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertItemHostedOnServer(itemCount: Int) {
|
fun assertItemHostedOnServer(itemCount: Int, composeTestRule: ComposeContentTestRule) {
|
||||||
val checkedCheckboxCount =
|
for (i in 0 until itemCount) {
|
||||||
RecyclerViewSelectedCheckBoxCountAssertion(
|
composeTestRule.onNodeWithTag("$BOOK_ITEM_CHECKBOX_TESTING_TAG${i + 1}")
|
||||||
id.recyclerViewZimHost,
|
.assertIsOn()
|
||||||
R.id.itemBookCheckbox
|
}
|
||||||
).countCheckedCheckboxes()
|
|
||||||
assertThat(checkedCheckboxCount, CoreMatchers.`is`(itemCount))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopServer() {
|
fun stopServer(composeTestRule: ComposeContentTestRule) {
|
||||||
testFlakyView({ onView(withId(id.startServerButton)).perform(click()) })
|
testFlakyView(
|
||||||
|
{
|
||||||
|
composeTestRule.apply {
|
||||||
|
waitForIdle()
|
||||||
|
onNodeWithTag(START_SERVER_BUTTON_TESTING_TAG).performClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertServerStopped() {
|
fun assertServerStopped(composeTestRule: ComposeContentTestRule) {
|
||||||
pauseForBetterTestPerformance()
|
testFlakyView({
|
||||||
isVisible(Text("START SERVER"))
|
composeTestRule.apply {
|
||||||
|
waitForIdle()
|
||||||
|
onNodeWithTag(START_SERVER_BUTTON_TESTING_TAG)
|
||||||
|
.assertTextEquals(context.getString(R.string.start_server_label).uppercase())
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertQrShown() {
|
fun assertQrShown(composeTestRule: ComposeContentTestRule) {
|
||||||
isVisible(ViewId(id.serverQrCode))
|
testFlakyView({
|
||||||
|
composeTestRule.apply {
|
||||||
|
waitForIdle()
|
||||||
|
onNodeWithTag(QR_IMAGE_TESTING_TAG)
|
||||||
|
.assertIsDisplayed()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertQrNotShown() {
|
fun assertQrNotShown(composeTestRule: ComposeContentTestRule) {
|
||||||
isNotVisible(ViewId(id.serverQrCode))
|
testFlakyView({
|
||||||
|
composeTestRule.apply {
|
||||||
|
waitForIdle()
|
||||||
|
onNodeWithTag(QR_IMAGE_TESTING_TAG)
|
||||||
|
.assertIsNotDisplayed()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pauseForBetterTestPerformance() {
|
private fun pauseForBetterTestPerformance() {
|
||||||
|
@ -40,6 +40,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
@ -56,9 +57,12 @@ import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.ArticleCount
|
|||||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode
|
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
||||||
|
|
||||||
|
const val BOOK_ITEM_CHECKBOX_TESTING_TAG = "bookItemCheckboxTestingTag"
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun BookItem(
|
fun BookItem(
|
||||||
|
index: Int,
|
||||||
bookOnDisk: BookOnDisk,
|
bookOnDisk: BookOnDisk,
|
||||||
onClick: ((BookOnDisk) -> Unit)? = null,
|
onClick: ((BookOnDisk) -> Unit)? = null,
|
||||||
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
onLongClick: ((BookOnDisk) -> Unit)? = null,
|
||||||
@ -87,7 +91,7 @@ fun BookItem(
|
|||||||
elevation = CardDefaults.elevatedCardElevation(),
|
elevation = CardDefaults.elevatedCardElevation(),
|
||||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainer)
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainer)
|
||||||
) {
|
) {
|
||||||
BookContent(bookOnDisk, selectionMode, onMultiSelect, onClick)
|
BookContent(bookOnDisk, selectionMode, onMultiSelect, onClick, index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,6 +102,7 @@ private fun BookContent(
|
|||||||
selectionMode: SelectionMode,
|
selectionMode: SelectionMode,
|
||||||
onMultiSelect: ((BookOnDisk) -> Unit)?,
|
onMultiSelect: ((BookOnDisk) -> Unit)?,
|
||||||
onClick: ((BookOnDisk) -> Unit)?,
|
onClick: ((BookOnDisk) -> Unit)?,
|
||||||
|
index: Int,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -106,7 +111,7 @@ private fun BookContent(
|
|||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
if (selectionMode == SelectionMode.MULTI) {
|
if (selectionMode == SelectionMode.MULTI) {
|
||||||
BookCheckbox(bookOnDisk, selectionMode, onMultiSelect, onClick)
|
BookCheckbox(bookOnDisk, selectionMode, onMultiSelect, onClick, index)
|
||||||
}
|
}
|
||||||
BookIcon(bookOnDisk.book.faviconToPainter())
|
BookIcon(bookOnDisk.book.faviconToPainter())
|
||||||
BookDetails(Modifier.weight(1f), bookOnDisk)
|
BookDetails(Modifier.weight(1f), bookOnDisk)
|
||||||
@ -118,7 +123,8 @@ private fun BookCheckbox(
|
|||||||
bookOnDisk: BookOnDisk,
|
bookOnDisk: BookOnDisk,
|
||||||
selectionMode: SelectionMode,
|
selectionMode: SelectionMode,
|
||||||
onMultiSelect: ((BookOnDisk) -> Unit)?,
|
onMultiSelect: ((BookOnDisk) -> Unit)?,
|
||||||
onClick: ((BookOnDisk) -> Unit)?
|
onClick: ((BookOnDisk) -> Unit)?,
|
||||||
|
index: Int
|
||||||
) {
|
) {
|
||||||
Checkbox(
|
Checkbox(
|
||||||
checked = bookOnDisk.isSelected,
|
checked = bookOnDisk.isSelected,
|
||||||
@ -127,7 +133,8 @@ private fun BookCheckbox(
|
|||||||
SelectionMode.MULTI -> onMultiSelect?.invoke(bookOnDisk)
|
SelectionMode.MULTI -> onMultiSelect?.invoke(bookOnDisk)
|
||||||
SelectionMode.NORMAL -> onClick?.invoke(bookOnDisk)
|
SelectionMode.NORMAL -> onClick?.invoke(bookOnDisk)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.testTag("$BOOK_ITEM_CHECKBOX_TESTING_TAG$index")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
@ -65,6 +66,9 @@ import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDis
|
|||||||
import org.kiwix.kiwixmobile.ui.BookItem
|
import org.kiwix.kiwixmobile.ui.BookItem
|
||||||
import org.kiwix.kiwixmobile.ui.ZimFilesLanguageHeader
|
import org.kiwix.kiwixmobile.ui.ZimFilesLanguageHeader
|
||||||
|
|
||||||
|
const val START_SERVER_BUTTON_TESTING_TAG = "startServerButtonTestingTag"
|
||||||
|
const val QR_IMAGE_TESTING_TAG = "qrImageTestingTag"
|
||||||
|
|
||||||
@Suppress("ComposableLambdaParameterNaming", "LongParameterList")
|
@Suppress("ComposableLambdaParameterNaming", "LongParameterList")
|
||||||
@Composable
|
@Composable
|
||||||
fun ZimHostScreen(
|
fun ZimHostScreen(
|
||||||
@ -104,7 +108,10 @@ fun ZimHostScreen(
|
|||||||
KiwixButton(
|
KiwixButton(
|
||||||
startServerButtonItem.first,
|
startServerButtonItem.first,
|
||||||
startServerButtonItem.third,
|
startServerButtonItem.third,
|
||||||
modifier = Modifier.fillMaxWidth().padding(FOUR_DP),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(FOUR_DP)
|
||||||
|
.testTag(START_SERVER_BUTTON_TESTING_TAG),
|
||||||
buttonBackgroundColor = startServerButtonItem.second
|
buttonBackgroundColor = startServerButtonItem.second
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -157,7 +164,8 @@ private fun QRImage(qrImageItem: Pair<Boolean, IconItem>) {
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.heightIn(min = MINIMUM_HEIGHT_OF_QR_CODE, max = MAXIMUM_HEIGHT_OF_QR_CODE)
|
.heightIn(min = MINIMUM_HEIGHT_OF_QR_CODE, max = MAXIMUM_HEIGHT_OF_QR_CODE)
|
||||||
.padding(horizontal = SIXTEEN_DP),
|
.padding(horizontal = SIXTEEN_DP)
|
||||||
|
.testTag(QR_IMAGE_TESTING_TAG),
|
||||||
contentScale = ContentScale.Fit
|
contentScale = ContentScale.Fit
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -181,7 +189,7 @@ private fun BookItemList(
|
|||||||
item {
|
item {
|
||||||
QRImage(qrImageItem)
|
QRImage(qrImageItem)
|
||||||
}
|
}
|
||||||
itemsIndexed(booksList) { _, bookItem ->
|
itemsIndexed(booksList) { index, bookItem ->
|
||||||
when (bookItem) {
|
when (bookItem) {
|
||||||
is BooksOnDiskListItem.LanguageItem -> {
|
is BooksOnDiskListItem.LanguageItem -> {
|
||||||
ZimFilesLanguageHeader(bookItem)
|
ZimFilesLanguageHeader(bookItem)
|
||||||
@ -189,6 +197,7 @@ private fun BookItemList(
|
|||||||
|
|
||||||
is BookOnDisk -> {
|
is BookOnDisk -> {
|
||||||
BookItem(
|
BookItem(
|
||||||
|
index = index,
|
||||||
bookOnDisk = bookItem,
|
bookOnDisk = bookItem,
|
||||||
selectionMode = selectionMode,
|
selectionMode = selectionMode,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user