@file:OptIn(ExperimentalTestApi::class) package ru.myitschool.work import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.test.espresso.Espresso.pressBack import androidx.test.ext.junit.runners.AndroidJUnit4 import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen import org.junit.FixMethodOrder import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import ru.myitschool.work.screens.AuthScreen import ru.myitschool.work.screens.BookScreen import ru.myitschool.work.screens.MainScreen import ru.myitschool.work.screens.getDateText import ru.myitschool.work.screens.getPlaceText import ru.myitschool.work.ui.root.RootActivity import ru.myitschool.work.utils.MockWebServerRule import ru.myitschool.work.utils.Response import ru.samsung.test.core.core.BaseTest import ru.samsung.test.core.utils.warmUpCompose @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) class Tests : BaseTest( clazz = RootActivity::class.java, isEnabledCompose = true, ) { @get:Rule val composeTestRule = createAndroidComposeRule() @get:Rule val serverRule = MockWebServerRule(8090) @Test fun aПроверка_экрана_авторизации_валидация() = runWithInit(1) { onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { errorText.assertIsNotDisplayed() signButton.assertIsDisplayed() codeInput.assertIsDisplayed() codeInput.assertTextEquals("Код", includeEditableText = false) } step("Проверка состояния при пустом поле ввода") { signButton.assertIsNotEnabled() } step("Проверка состояния при вводе неверной комбинации 1") { codeInput.performTextReplacement("1234567890") signButton.assertIsNotEnabled() } step("Проверка состояния при вводе верной комбинации 1") { codeInput.performTextReplacement("1230") signButton.assertIsEnabled() } step("Проверка состояния при вводе неверной комбинации 2") { codeInput.performTextReplacement("прив") signButton.assertIsNotEnabled() } step("Проверка состояния при вводе верной комбинации 2") { codeInput.performTextReplacement("aAzZ") signButton.assertIsEnabled() } step("Проверка состояния при вводе неверной комбинации 3") { codeInput.performTextReplacement("1пLK") signButton.assertIsNotEnabled() } } } @Test fun bПроверка_экрана_авторизации_статусы() = runWithInit(1) { serverRule.mockResponses( "/api/abcd/auth" to Response(statusCode = 401), "/api/1234/auth" to Response(statusCode = 400), "/api/4321/auth" to Response(statusCode = 500), "/api/abc1/auth" to Response(statusCode = 200), "/api/abc1/info" to Response(statusCode = 400), ) onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { errorText.assertIsNotDisplayed() signButton.assertIsDisplayed() codeInput.assertIsDisplayed() } listOf( "abcd", "1234", "4321" ).forEachIndexed { index, code -> warmUpCompose(composeTestRule) step("Проверка статуса ошибки $index") { codeInput.performTextReplacement(code) flakySafely(timeoutMs = 500L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() } signButton.performClick() flakySafely(timeoutMs = 500L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsDisplayed() } } } step("Проверка верного статуса") { codeInput.performTextReplacement("abc1") errorText.assertIsNotDisplayed() signButton.assertIsEnabled() signButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверка перехода на главный экран") { errorText.assertIsDisplayed() refreshButton.assertIsDisplayed() } } } @Test fun cПроверка_главного_экрана() = runWithInit(1) { serverRule.mockResponses( "/api/abc1/info" to Response(assetFile = "profile.json"), "/api/abc1/info" to Response(assetFile = "profile2.json"), ) onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() addButton.assertIsDisplayed() refreshButton.assertIsDisplayed() logoutButton.assertIsDisplayed() profileNameText.assertIsDisplayed() } } step("Проверка контента на экране") { profileNameText.assertTextEquals("Иван А") getItemByPosition(0).invoke { getDateText().assertTextEquals("05.01.2025") getPlaceText().assertTextEquals("102") } getItemByPosition(1).invoke { getDateText().assertTextEquals("06.01.2025") getPlaceText().assertTextEquals("209.13") } getItemByPosition(2).invoke { getDateText().assertTextEquals("09.01.2025") getPlaceText().assertTextEquals("Зона 51. 50") } } step("Обновляем контент и проверяем повторно") { refreshButton.performClick() flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) profileNameText.assertTextEquals("Вова Б") } getItemByPosition(0).invoke { getDateText().assertTextEquals("01.01.2001") getPlaceText().assertTextEquals("1") } getItemByPosition(1).invoke { getDateText().assertTextEquals("01.01.2002") getPlaceText().assertTextEquals("2") } getItemByPosition(2).invoke { getDateText().assertTextEquals("01.01.2003") getPlaceText().assertTextEquals("3") } getItemByPosition(3).assertIsNotDisplayed() } } } @Test fun dПроверка_кнопки_выхода() = runWithInit(1) { serverRule.mockResponses( "/api/abc1/info" to Response(assetFile = "profile.json"), ) onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() addButton.assertIsDisplayed() refreshButton.assertIsDisplayed() logoutButton.assertIsDisplayed() profileNameText.assertIsDisplayed() } } step("Нажимаем на кнопку выхода") { logoutButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { errorText.assertIsNotDisplayed() signButton.assertIsDisplayed() codeInput.assertIsDisplayed() codeInput.assertTextEquals("Код", includeEditableText = false) } } } @Test fun eПроверка_навигации_брони() = runWithInit(1) { serverRule.mockResponses( "/api/abc1/auth" to Response(statusCode = 200), "/api/abc1/info" to Response(assetFile = "profile.json"), "/api/abc1/booking" to Response(statusCode = 400), ) onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { errorText.assertIsNotDisplayed() signButton.assertIsDisplayed() codeInput.assertIsDisplayed() } step("Вход") { codeInput.performTextReplacement("abc1") errorText.assertIsNotDisplayed() signButton.assertIsEnabled() signButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() addButton.assertIsDisplayed() refreshButton.assertIsDisplayed() logoutButton.assertIsDisplayed() profileNameText.assertIsDisplayed() } } step("Нажимаем на кнопку добавления") { addButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() refreshButton.assertIsDisplayed() } pressBack() } } onComposeScreen(composeTestRule) { step("Проверка контента на экране (обратная навигация)") { profileNameText.assertTextEquals("Иван А") getItemByPosition(0).invoke { getDateText().assertTextEquals("05.01.2025") getPlaceText().assertTextEquals("102") } getItemByPosition(1).invoke { getDateText().assertTextEquals("06.01.2025") getPlaceText().assertTextEquals("209.13") } getItemByPosition(2).invoke { getDateText().assertTextEquals("09.01.2025") getPlaceText().assertTextEquals("Зона 51. 50") } } } } @Test fun fПроверка_контента_брони() = runWithInit(1) { serverRule.mockResponses( "/api/abc1/info" to Response(assetFile = "profile.json"), "/api/abc1/booking" to Response(statusCode = 400), "/api/abc1/booking" to Response(assetFile = "booking.json"), ) onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() addButton.assertIsDisplayed() refreshButton.assertIsDisplayed() logoutButton.assertIsDisplayed() profileNameText.assertIsDisplayed() } } step("Нажимаем на кнопку добавления") { addButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() refreshButton.assertIsDisplayed() } refreshButton.performClick() } step("Проверка контента") { getNodeDateByPosition(0).invoke { assertTextEquals("05.01") assertIsSelected() } getNodeDateByPosition(1).assertTextEquals("06.01") getNodeDateByPosition(2).assertTextEquals("07.02") getNodeDateByPosition(3).assertTextEquals("08.03") getNodePlaceByPosition(0).invoke { assertTextEquals("102") assertIsSelected() } getNodePlaceByPosition(1).assertTextEquals("666") getNodePlaceByPosition(2).assertIsNotDisplayed() } step("Проверка выбора переговорок") { getNodePlaceByPosition(1).invoke { performClick() assertIsSelected() } getNodePlaceByPosition(0).assertIsNotSelected() } step("Проверка переключения дат") { getNodeDateByPosition(2).invoke { performClick() assertIsSelected() } getNodePlaceByPosition(0).invoke { assertTextEquals("102") assertIsSelected() } getNodePlaceByPosition(1).assertTextEquals("209.13") getNodePlaceByPosition(2).assertIsNotDisplayed() } } } @Test fun gПроверка_возможности_брони() = runWithInit(1) { serverRule.mockResponses( "/api/abc1/info" to Response(assetFile = "profile.json"), "/api/abc1/booking" to Response(assetFile = "booking.json"), "/api/abc1/book" to Response(statusCode = 201), "/api/abc1/info" to Response(assetFile = "profile2.json"), ) onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() addButton.assertIsDisplayed() refreshButton.assertIsDisplayed() logoutButton.assertIsDisplayed() profileNameText.assertIsDisplayed() } } step("Нажимаем на кнопку добавления") { addButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) backButton.assertIsDisplayed() bookButton.assertIsDisplayed() } } step("Оформление брони") { bookButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверяем данные с главного экрана") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) profileNameText.assertTextEquals("Вова Б") } getItemByPosition(0).invoke { getDateText().assertTextEquals("01.01.2001") getPlaceText().assertTextEquals("1") } getItemByPosition(1).invoke { getDateText().assertTextEquals("01.01.2002") getPlaceText().assertTextEquals("2") } getItemByPosition(2).invoke { getDateText().assertTextEquals("01.01.2003") getPlaceText().assertTextEquals("3") } getItemByPosition(3).assertIsNotDisplayed() } } } @Test fun hПроверка_пустых_слотов() = runWithInit(1) { serverRule.mockResponses( "/api/abc1/info" to Response(assetFile = "profile.json"), "/api/abc1/booking" to Response(assetFile = "booking2.json"), "/api/abc1/booking" to Response(assetFile = "booking3.json") ) onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) errorText.assertIsNotDisplayed() addButton.assertIsDisplayed() refreshButton.assertIsDisplayed() logoutButton.assertIsDisplayed() profileNameText.assertIsDisplayed() } } step("Нажимаем на кнопку добавления") { addButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) backButton.assertIsDisplayed() bookButton.assertIsDisplayed() } } step("Проверка пустого состояния") { emptyText.assertIsNotDisplayed() getNodeDateByPosition(0).assertIsDisplayed() getNodeDateByPosition(1).assertIsDisplayed() getNodeDateByPosition(2).assertIsDisplayed() getNodeDateByPosition(3).assertIsNotDisplayed() } step("Возврат на главную") { backButton.performClick() } } onComposeScreen(composeTestRule) { step("Нажимаем на кнопку добавления") { addButton.performClick() } } onComposeScreen(composeTestRule) { step("Проверка наличия всех элементов на экране") { flakySafely(timeoutMs = 5000L, intervalMs = 100L) { warmUpCompose(composeTestRule) backButton.assertIsDisplayed() bookButton.assertIsNotDisplayed() } } step("Проверка пустого состояния") { emptyText.assertIsDisplayed() } } } }