diff --git a/app/src/androidTest/java/com/projectsacrifice/game/AccessibilityPersistenceTest.java b/app/src/androidTest/java/com/projectsacrifice/game/AccessibilityPersistenceTest.java index d5635dc..0ea1dde 100644 --- a/app/src/androidTest/java/com/projectsacrifice/game/AccessibilityPersistenceTest.java +++ b/app/src/androidTest/java/com/projectsacrifice/game/AccessibilityPersistenceTest.java @@ -100,6 +100,8 @@ public final class AccessibilityPersistenceTest { try (ActivityScenario activity = ActivityScenario.launch(MainActivity.class)) { activity.onActivity(current -> { GameView view = current.gameViewForAutomation(); + view.resetControlSettingsForAutomation(); + view.toggleHapticsForAutomation(); view.resetAccessibilitySettingsForAutomation(); view.openSettingsForAutomation(); }); @@ -113,6 +115,7 @@ public final class AccessibilityPersistenceTest { assertTrue(view.highContrastForAutomation()); assertTrue(view.screenDescriptionForAutomation().contains("Text size Large")); assertTrue(view.screenDescriptionForAutomation().contains("High contrast On")); + view.resetControlSettingsForAutomation(); view.resetAccessibilitySettingsForAutomation(); }); } diff --git a/app/src/androidTest/java/com/projectsacrifice/game/ControlSettingsPersistenceTest.java b/app/src/androidTest/java/com/projectsacrifice/game/ControlSettingsPersistenceTest.java index d22f237..c94b5e0 100644 --- a/app/src/androidTest/java/com/projectsacrifice/game/ControlSettingsPersistenceTest.java +++ b/app/src/androidTest/java/com/projectsacrifice/game/ControlSettingsPersistenceTest.java @@ -22,13 +22,13 @@ public final class ControlSettingsPersistenceTest { try (ActivityScenario activity = ActivityScenario.launch(MainActivity.class)) { activity.onActivity(current -> current.gameViewForAutomation() .resetControlSettingsForAutomation()); - - tap(activity, 1_700f, 115f); + activity.onActivity(current -> current.gameViewForAutomation() + .openSettingsForAutomation()); activity.onActivity(current -> assertTrue(current.gameViewForAutomation() .settingsVisibleForAutomation())); + tap(activity, 1_250f, 685f); tap(activity, 1_250f, 345f); tap(activity, 1_250f, 515f); - tap(activity, 1_250f, 685f); activity.recreate(); diff --git a/app/src/androidTest/java/com/projectsacrifice/game/StageThreeAcceptanceTest.java b/app/src/androidTest/java/com/projectsacrifice/game/StageThreeAcceptanceTest.java new file mode 100644 index 0000000..2852997 --- /dev/null +++ b/app/src/androidTest/java/com/projectsacrifice/game/StageThreeAcceptanceTest.java @@ -0,0 +1,146 @@ +package com.projectsacrifice.game; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.os.SystemClock; +import android.view.MotionEvent; + +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.List; + +@RunWith(AndroidJUnit4.class) +public final class StageThreeAcceptanceTest { + @Test + public void localizedAccessibleSettingsSurviveRecreationWithoutChangingProgress() { + try (ActivityScenario activity = ActivityScenario.launch(MainActivity.class)) { + int[] unlocked = new int[1]; + int[] bestDeaths = new int[1]; + long[] bestTime = new long[1]; + + activity.onActivity(owner -> { + GameView view = owner.gameViewForAutomation(); + view.resetLanguageForAutomation(); + view.resetControlSettingsForAutomation(); + view.toggleHapticsForAutomation(); + view.resetAccessibilitySettingsForAutomation(); + ProgressStore progress = new ProgressStore(owner); + unlocked[0] = progress.unlockedCount(); + bestDeaths[0] = progress.bestDeaths(1); + bestTime[0] = progress.bestTimeMs(1); + }); + + tap(activity, 1_700f, 115f); // Settings. + tap(activity, 1_700f, 115f); // RU. + tap(activity, 220f, 345f); // Large text. + tap(activity, 220f, 515f); // High contrast. + tap(activity, 1_250f, 345f); // Large controls. + tap(activity, 1_250f, 515f); // High control opacity. + + activity.onActivity(owner -> { + GameView view = owner.gameViewForAutomation(); + assertEquals(GameLanguage.RU, view.languageForAutomation()); + assertEquals(1.25f, view.textScaleForAutomation(), 0f); + assertTrue(view.highContrastForAutomation()); + assertTrue(view.visibleLocalizedTextForAutomation().contains("ДОСТУПНОСТЬ")); + assertTrue(view.visibleLocalizedTextForAutomation().contains("Крупный")); + assertTrue(view.screenDescriptionForAutomation().contains("Настройки")); + }); + + activity.recreate(); + + activity.onActivity(owner -> { + GameView view = owner.gameViewForAutomation(); + assertEquals(GameLanguage.RU, view.languageForAutomation()); + assertEquals(1.25f, view.textScaleForAutomation(), 0f); + assertTrue(view.highContrastForAutomation()); + assertEquals("Large", view.controlSettingsForAutomation().controlSizeLabel()); + assertEquals("High", view.controlSettingsForAutomation().controlOpacityLabel()); + assertFalse(view.controlSettingsForAutomation().hapticsEnabled()); + + ProgressStore progress = new ProgressStore(owner); + assertEquals(unlocked[0], progress.unlockedCount()); + assertEquals(bestDeaths[0], progress.bestDeaths(1)); + assertEquals(bestTime[0], progress.bestTimeMs(1)); + + view.resetLanguageForAutomation(); + view.resetControlSettingsForAutomation(); + view.resetAccessibilitySettingsForAutomation(); + }); + } + } + + @Test + public void russianTutorialAndResultRemainNonBlockingAndExposeEveryOutcome() { + try (ActivityScenario activity = ActivityScenario.launch(MainActivity.class)) { + activity.onActivity(owner -> { + GameView view = owner.gameViewForAutomation(); + view.setLanguageForAutomation(GameLanguage.RU); + view.resetOnboardingForAutomation(); + view.startLevelForAutomation(1); + + assertTrue(view.onboardingVisibleForAutomation()); + assertContainsPrefix(view.visibleLocalizedTextForAutomation(), "ДВИЖЕНИЕ"); + view.setAutomationInput(false, true, false); + assertTrue(view.automationSnapshot().inputActive()); + + view.advanceOnboardingForAutomation(); + assertContainsPrefix(view.visibleLocalizedTextForAutomation(), + "ДВИЖЕНИЕ + ПРЫЖОК"); + view.advanceOnboardingForAutomation(); + assertContainsPrefix(view.visibleLocalizedTextForAutomation(), + "СМЕРТЬ ОСТАВЛЯЕТ ИНСТРУМЕНТ"); + view.advanceOnboardingForAutomation(); + assertFalse(view.onboardingVisibleForAutomation()); + + view.finishLevelForAutomation(2, 42_000L); + List result = view.visibleLocalizedTextForAutomation(); + assertContainsPrefix(result, "Текущий результат"); + assertContainsPrefix(result, "Лучший результат"); + assertContainsPrefix(result, "Цели"); + assertContainsPrefix(result, "Следующая цель"); + assertTrue(view.screenDescriptionForAutomation().contains("Уровень завершён")); + view.setLanguageForAutomation(GameLanguage.EN); + }); + + activity.recreate(); + + activity.onActivity(owner -> { + GameView view = owner.gameViewForAutomation(); + view.startLevelForAutomation(1); + assertFalse(view.onboardingVisibleForAutomation()); + assertEquals(GameLanguage.EN, view.languageForAutomation()); + view.setAutomationInput(false, false, false); + }); + } + } + + private static void assertContainsPrefix(List values, String prefix) { + for (String value : values) { + if (value.startsWith(prefix)) return; + } + throw new AssertionError("Missing prefix '" + prefix + "' in " + values); + } + + private static void tap(ActivityScenario activity, float canvasX, float canvasY) { + activity.onActivity(owner -> { + GameView view = owner.gameViewForAutomation(); + float scale = Math.min(view.getWidth() / 1_920f, view.getHeight() / 1_080f); + float x = (view.getWidth() - 1_920f * scale) * 0.5f + canvasX * scale; + float y = (view.getHeight() - 1_080f * scale) * 0.5f + canvasY * scale; + long now = SystemClock.uptimeMillis(); + MotionEvent down = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, 0); + view.dispatchTouchEvent(down); + down.recycle(); + MotionEvent up = MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x, y, 0); + view.dispatchTouchEvent(up); + up.recycle(); + }); + } +}