Fix failing UI tests
Some checks failed
Build & Test / Validate (pull_request) Successful in 25s
Build & Test / Run Unit Tests (pull_request) Successful in 9m19s
Build & Test / Run UI Tests (pull_request) Failing after 17m13s

This commit is contained in:
William Brawner 2024-08-01 18:47:12 -06:00
parent 262b63cfa0
commit b0e8ebbf71
Signed by: wbrawner
GPG key ID: 8FF12381C6C90D35
4 changed files with 34 additions and 16 deletions

View file

@ -6,13 +6,10 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.webkit.WebView import android.webkit.WebView
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.input.key.NativeKeyEvent
import androidx.compose.ui.semantics.SemanticsProperties import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.semantics.getOrNull import androidx.compose.ui.semantics.getOrNull
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.SemanticsMatcher import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.assert import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed import androidx.compose.ui.test.assertIsNotDisplayed
@ -27,13 +24,8 @@ import androidx.compose.ui.test.junit4.createEmptyComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performKeyInput
import androidx.compose.ui.test.performKeyPress
import androidx.compose.ui.test.performTextInput
import androidx.compose.ui.test.performTextInputSelection
import androidx.compose.ui.test.performTextReplacement import androidx.compose.ui.test.performTextReplacement
import androidx.compose.ui.test.printToLog import androidx.compose.ui.test.printToLog
import androidx.compose.ui.text.TextRange
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider.getApplicationContext import androidx.test.core.app.ApplicationProvider.getApplicationContext
@ -233,7 +225,7 @@ class MarkdownTests {
private fun ComposeTestRule.checkTitleEquals(title: String) = private fun ComposeTestRule.checkTitleEquals(title: String) =
onNode(hasAnySibling(hasContentDescription("Main Menu")).and(hasText(title))) onNode(hasAnySibling(hasContentDescription("Main Menu")).and(hasText(title)))
.assertIsDisplayed() .waitUntilIsDisplayed()
private fun ComposeTestRule.typeMarkdown(markdown: String) = private fun ComposeTestRule.typeMarkdown(markdown: String) =
onNode(hasSetTextAction()).performTextReplacement(markdown) onNode(hasSetTextAction()).performTextReplacement(markdown)
@ -258,12 +250,38 @@ class MarkdownTests {
private fun ComposeTestRule.clickSaveMenuItem() = onNodeWithText("Save").performClick() private fun ComposeTestRule.clickSaveMenuItem() = onNodeWithText("Save").performClick()
private fun ComposeTestRule.verifyDialogIsShown(text: String) = private fun ComposeTestRule.verifyDialogIsShown(text: String) =
onNode(isDialog().and(hasAnyDescendant(hasText(text)))).assertIsDisplayed() onNode(isDialog().and(hasAnyDescendant(hasText(text)))).waitUntilIsDisplayed()
private fun ComposeTestRule.verifyDialogIsNotShown() = onNode(isDialog()).assertIsNotDisplayed() private fun ComposeTestRule.verifyDialogIsNotShown() =
onNode(isDialog()).waitUntilIsNotDisplayed()
private fun ComposeTestRule.discardChanges() = onNodeWithText("No").performClick() private fun ComposeTestRule.discardChanges() = onNodeWithText("No").performClick()
private fun ComposeTestRule.verifyTextIsShown(text: String) = private fun ComposeTestRule.verifyTextIsShown(text: String) =
onNodeWithText(text).assertIsDisplayed() onNodeWithText(text).waitUntilIsDisplayed()
private val ASSERTION_TIMEOUT = 5_000L
private fun SemanticsNodeInteraction.waitUntil(assertion: SemanticsNodeInteraction.() -> Unit) {
val start = System.currentTimeMillis()
lateinit var assertionError: AssertionError
while (System.currentTimeMillis() - start < ASSERTION_TIMEOUT) {
try {
assertion()
return
} catch (e: AssertionError) {
assertionError = e
Thread.sleep(10)
}
}
throw assertionError
}
private fun SemanticsNodeInteraction.waitUntilIsDisplayed() = waitUntil {
assertIsDisplayed()
}
private fun SemanticsNodeInteraction.waitUntilIsNotDisplayed() = waitUntil {
assertIsNotDisplayed()
}
} }

View file

@ -96,7 +96,7 @@ class MarkdownViewModel(
markdown = content, markdown = content,
initialMarkdown = content, initialMarkdown = content,
reloadToggle = currentState.reloadToggle.inv(), reloadToggle = currentState.reloadToggle.inv(),
toast = ParameterizedText(R.string.file_loaded) toast = ParameterizedText(R.string.file_loaded, arrayOf(name))
) )
preferenceHelper[Preference.AUTOSAVE_URI] = actualLoadPath preferenceHelper[Preference.AUTOSAVE_URI] = actualLoadPath
} ?: throw IllegalStateException("Opened file was null") } ?: throw IllegalStateException("Opened file was null")

View file

@ -380,4 +380,4 @@ fun <P> MarkdownViewModel.collectAsState(prop: KProperty1<EditorState, P>, initi
remember(prop) { state.map { prop.get(it) }.distinctUntilChanged() }.collectAsState(initial) remember(prop) { state.map { prop.get(it) }.distinctUntilChanged() }.collectAsState(initial)
@Composable @Composable
fun ParameterizedText.stringRes() = stringResource(text, params) fun ParameterizedText.stringRes() = stringResource(text, *params)

View file

@ -16,7 +16,7 @@
<string name="share_file">Share file to…</string> <string name="share_file">Share file to…</string>
<string name="file_saved">Successfully saved %1$s</string> <string name="file_saved">Successfully saved %1$s</string>
<string name="file_save_error">An error occurred while saving the file</string> <string name="file_save_error">An error occurred while saving the file</string>
<string name="file_loaded">File successfully loaded</string> <string name="file_loaded">Successfully loaded %1$s</string>
<string name="file_load_error">An error occurred while opening the file</string> <string name="file_load_error">An error occurred while opening the file</string>
<string name="action_back">Back</string> <string name="action_back">Back</string>
<string name="action_menu">Main Menu</string> <string name="action_menu">Main Menu</string>