mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
test: migrate Compose UI tests from androidTest to commonTest (#5091)
This commit is contained in:
parent
4156acf297
commit
a11dee42a7
27 changed files with 296 additions and 597 deletions
|
|
@ -16,28 +16,46 @@
|
|||
*/
|
||||
package org.meshtastic.core.ui.component
|
||||
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.junit4.v2.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import androidx.compose.ui.test.runComposeUiTest
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.meshtastic.core.ui.util.AlertManager
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
|
||||
@OptIn(ExperimentalTestApi::class, ExperimentalCoroutinesApi::class)
|
||||
class AlertHostTest {
|
||||
|
||||
@get:Rule val composeTestRule = createComposeRule()
|
||||
private val testDispatcher = UnconfinedTestDispatcher()
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
fun tearDown() {
|
||||
Dispatchers.resetMain()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun alertHost_showsDialog_whenAlertIsTriggered() {
|
||||
fun alertHost_showsDialog_whenAlertIsTriggered() = runComposeUiTest {
|
||||
val alertManager = AlertManager()
|
||||
val title = "Alert Title"
|
||||
val message = "Alert Message"
|
||||
|
||||
composeTestRule.setContent { AlertHost(alertManager = alertManager) }
|
||||
setContent { AlertHost(alertManager = alertManager) }
|
||||
|
||||
alertManager.showAlert(title = title, message = message)
|
||||
|
||||
composeTestRule.onNodeWithText(title).assertIsDisplayed()
|
||||
composeTestRule.onNodeWithText(message).assertIsDisplayed()
|
||||
onNodeWithText(title).assertIsDisplayed()
|
||||
onNodeWithText(message).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
|
|
@ -18,27 +18,25 @@ package org.meshtastic.core.ui.component
|
|||
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.test.assertDoesNotExist
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.junit4.v2.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import androidx.compose.ui.test.runComposeUiTest
|
||||
import org.meshtastic.core.ui.util.LocalBarcodeScannerSupported
|
||||
import org.meshtastic.core.ui.util.LocalNfcScannerSupported
|
||||
import org.meshtastic.proto.SharedContact
|
||||
import org.meshtastic.proto.User
|
||||
import kotlin.test.Test
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
class ImportFabUiTest {
|
||||
|
||||
@get:Rule val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
fun importFab_expands_onButtonClick_whenSupported() {
|
||||
fun importFab_expands_onButtonClick_whenSupported() = runComposeUiTest {
|
||||
val testTag = "import_fab"
|
||||
composeTestRule.setContent {
|
||||
setContent {
|
||||
CompositionLocalProvider(
|
||||
LocalBarcodeScannerSupported provides true,
|
||||
LocalNfcScannerSupported provides true,
|
||||
|
|
@ -48,18 +46,18 @@ class ImportFabUiTest {
|
|||
}
|
||||
|
||||
// Expand the FAB
|
||||
composeTestRule.onNodeWithTag(testTag).performClick()
|
||||
onNodeWithTag(testTag).performClick()
|
||||
|
||||
// Verify menu items are visible using their tags
|
||||
composeTestRule.onNodeWithTag("nfc_import").assertIsDisplayed()
|
||||
composeTestRule.onNodeWithTag("qr_import").assertIsDisplayed()
|
||||
composeTestRule.onNodeWithTag("url_import").assertIsDisplayed()
|
||||
onNodeWithTag("nfc_import").assertIsDisplayed()
|
||||
onNodeWithTag("qr_import").assertIsDisplayed()
|
||||
onNodeWithTag("url_import").assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun importFab_hidesNfcAndQr_whenNotSupported() {
|
||||
fun importFab_hidesNfcAndQr_whenNotSupported() = runComposeUiTest {
|
||||
val testTag = "import_fab"
|
||||
composeTestRule.setContent {
|
||||
setContent {
|
||||
CompositionLocalProvider(
|
||||
LocalBarcodeScannerSupported provides false,
|
||||
LocalNfcScannerSupported provides false,
|
||||
|
|
@ -69,41 +67,41 @@ class ImportFabUiTest {
|
|||
}
|
||||
|
||||
// Expand the FAB
|
||||
composeTestRule.onNodeWithTag(testTag).performClick()
|
||||
onNodeWithTag(testTag).performClick()
|
||||
|
||||
// Verify menu items are visible using their tags
|
||||
composeTestRule.onNodeWithTag("nfc_import").assertDoesNotExist()
|
||||
composeTestRule.onNodeWithTag("qr_import").assertDoesNotExist()
|
||||
composeTestRule.onNodeWithTag("url_import").assertIsDisplayed()
|
||||
onNodeWithTag("nfc_import").assertDoesNotExist()
|
||||
onNodeWithTag("qr_import").assertDoesNotExist()
|
||||
onNodeWithTag("url_import").assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun importFab_showsUrlDialog_whenUrlItemClicked() {
|
||||
fun importFab_showsUrlDialog_whenUrlItemClicked() = runComposeUiTest {
|
||||
val testTag = "import_fab"
|
||||
composeTestRule.setContent { MeshtasticImportFAB(onImport = {}, isContactContext = true, testTag = testTag) }
|
||||
setContent { MeshtasticImportFAB(onImport = {}, isContactContext = true, testTag = testTag) }
|
||||
|
||||
composeTestRule.onNodeWithTag(testTag).performClick()
|
||||
composeTestRule.onNodeWithTag("url_import").performClick()
|
||||
onNodeWithTag(testTag).performClick()
|
||||
onNodeWithTag("url_import").performClick()
|
||||
|
||||
// The URL dialog should be shown.
|
||||
// We'll search for its title indirectly or check if an AlertDialog appeared.
|
||||
}
|
||||
|
||||
@Test
|
||||
fun importFab_showsShareChannels_whenCallbackProvided() {
|
||||
fun importFab_showsShareChannels_whenCallbackProvided() = runComposeUiTest {
|
||||
val testTag = "import_fab"
|
||||
composeTestRule.setContent {
|
||||
setContent {
|
||||
MeshtasticImportFAB(onImport = {}, onShareChannels = {}, isContactContext = false, testTag = testTag)
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithTag(testTag).performClick()
|
||||
composeTestRule.onNodeWithTag("share_channels").assertIsDisplayed()
|
||||
onNodeWithTag(testTag).performClick()
|
||||
onNodeWithTag("share_channels").assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun importFab_showsSharedContactDialog_whenProvided() {
|
||||
fun importFab_showsSharedContactDialog_whenProvided() = runComposeUiTest {
|
||||
val contact = SharedContact(user = User(long_name = "Suzume Goddess"), node_num = 1)
|
||||
composeTestRule.setContent {
|
||||
setContent {
|
||||
MeshtasticImportFAB(
|
||||
onImport = {},
|
||||
sharedContact = contact,
|
||||
|
|
@ -113,6 +111,6 @@ class ImportFabUiTest {
|
|||
}
|
||||
|
||||
// Check if goddess is here
|
||||
composeTestRule.onNodeWithText("Importing Suzume Goddess").assertIsDisplayed()
|
||||
onNodeWithText("Importing Suzume Goddess").assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
|
|
@ -18,22 +18,21 @@ package org.meshtastic.core.ui.util
|
|||
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.junit4.v2.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import androidx.compose.ui.test.runComposeUiTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
class AlertManagerUiTest {
|
||||
|
||||
@get:Rule val composeTestRule = createComposeRule()
|
||||
|
||||
private val alertManager = AlertManager()
|
||||
|
||||
@Test
|
||||
fun alertManager_showsAlert_whenRequested() {
|
||||
composeTestRule.setContent {
|
||||
fun alertManager_showsAlert_whenRequested() = runComposeUiTest {
|
||||
val alertManager = AlertManager()
|
||||
setContent {
|
||||
val alertData by alertManager.currentAlert.collectAsState()
|
||||
alertData?.let { data -> AlertPreviewRenderer(data) }
|
||||
}
|
||||
|
|
@ -43,29 +42,24 @@ class AlertManagerUiTest {
|
|||
|
||||
alertManager.showAlert(title = title, message = message)
|
||||
|
||||
composeTestRule.onNodeWithText(title).assertIsDisplayed()
|
||||
composeTestRule.onNodeWithText(message).assertIsDisplayed()
|
||||
onNodeWithText(title).assertIsDisplayed()
|
||||
onNodeWithText(message).assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun alertManager_confirmButton_triggersCallbackAndDismisses() {
|
||||
fun alertManager_confirmButton_triggersCallbackAndDismisses() = runComposeUiTest {
|
||||
val alertManager = AlertManager()
|
||||
var confirmClicked = false
|
||||
composeTestRule.setContent {
|
||||
setContent {
|
||||
val alertData by alertManager.currentAlert.collectAsState()
|
||||
alertData?.let { data -> AlertPreviewRenderer(data) }
|
||||
}
|
||||
|
||||
alertManager.showAlert(title = "Confirm Title", onConfirm = { confirmClicked = true })
|
||||
|
||||
// Default confirm text is "Okay" from resources, but AlertPreviewRenderer uses it
|
||||
// We'll search for the text "Okay" (assuming it matches the resource value)
|
||||
// Since we are in a test, we might need to use a hardcoded string or a resource
|
||||
// But for this test, let's just use the confirmText parameter to be sure
|
||||
alertManager.showAlert(title = "Confirm Title", confirmText = "Yes", onConfirm = { confirmClicked = true })
|
||||
|
||||
composeTestRule.onNodeWithText("Yes").performClick()
|
||||
onNodeWithText("Yes").performClick()
|
||||
|
||||
assert(confirmClicked)
|
||||
composeTestRule.onNodeWithText("Confirm Title").assertDoesNotExist()
|
||||
assertTrue(confirmClicked)
|
||||
onNodeWithText("Confirm Title").assertDoesNotExist()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue