diff --git a/ci/Jenkinsfile.test-e2e.android b/ci/Jenkinsfile.test-e2e.android index 1dd634b283..36f856a830 100644 --- a/ci/Jenkinsfile.test-e2e.android +++ b/ci/Jenkinsfile.test-e2e.android @@ -39,8 +39,8 @@ pipeline { ) string( name: 'PYTEST_ARGS', - description: 'Pytest flags (e.g. "-m smoke" or "-m critical") and other args.', - defaultValue: '-n=5 -m smoke tests' + description: 'Pytest flags. Default runs gate tests for PRs. Use "-n=5 -m smoke tests" for nightly/full runs.', + defaultValue: '-n=5 -m gate tests' ) } @@ -167,6 +167,7 @@ pipeline { junit allowEmptyResults: true, testResults: "test/e2e_appium/reports/${env.BUILD_TAG}/pytest_results_*.xml" archiveArtifacts artifacts: "test/e2e_appium/reports/${env.BUILD_TAG}/**/*", allowEmptyArchive: true env.PKG_URL = "${env.BUILD_URL}testReport/" + updateGitHubStatus() } } success { script { github.notifyPR(true) } } failure { script { github.notifyPR(false) } } diff --git a/test/e2e_appium/pytest.ini b/test/e2e_appium/pytest.ini index dff7b91d46..9261e64964 100644 --- a/test/e2e_appium/pytest.ini +++ b/test/e2e_appium/pytest.ini @@ -4,6 +4,7 @@ addopts = -v --tb=short --strict-markers --timeout=1200 --reruns 0 --reruns-dela asyncio_mode = auto timeout = 600 markers = + gate: Stable tests that must pass to merge a PR smoke: Quick critical tests for PR validation onboarding: User onboarding flow tests raw_devices: Skip onboarding - get raw devices for testing onboarding flows diff --git a/test/e2e_appium/scripts/run_tests.py b/test/e2e_appium/scripts/run_tests.py index 51d9d88a8a..8c91137e07 100755 --- a/test/e2e_appium/scripts/run_tests.py +++ b/test/e2e_appium/scripts/run_tests.py @@ -73,9 +73,9 @@ def main(): parser.add_argument( "--category", "-c", - choices=["smoke", "tablet", "critical", "all"], - default="smoke", - help="Test category to run (default: smoke)", + choices=["gate", "smoke", "tablet", "critical", "all"], + default="gate", + help="Test category to run (default: gate). Use 'smoke' for full nightly set.", ) parser.add_argument( "--parallel", diff --git a/test/e2e_appium/tests/messaging/test_message_context_menu.py b/test/e2e_appium/tests/messaging/test_message_context_menu.py index ec6c76c09a..befd578fb1 100644 --- a/test/e2e_appium/tests/messaging/test_message_context_menu.py +++ b/test/e2e_appium/tests/messaging/test_message_context_menu.py @@ -157,6 +157,7 @@ class TestMessageContextMenu: return secondary_chat + @pytest.mark.gate @pytest.mark.smoke async def test_context_menu_own_message_actions(self) -> None: """Verify context menu shows correct actions for own message. @@ -185,6 +186,7 @@ class TestMessageContextMenu: async with self.step("Dismiss context menu"): assert context_menu.dismiss(), "Failed to dismiss context menu" + @pytest.mark.gate @pytest.mark.smoke async def test_add_reaction_to_message(self) -> None: """Verify adding a quick reaction to a message.""" @@ -206,6 +208,7 @@ class TestMessageContextMenu: "Context menu should close after adding reaction" ) + @pytest.mark.gate @pytest.mark.smoke async def test_copy_message_action(self) -> None: """Verify copy message action works.""" @@ -228,6 +231,7 @@ class TestMessageContextMenu: # Note: Clipboard verification would require platform-specific APIs @pytest.mark.smoke + @pytest.mark.flaky(reruns=1, reruns_delay=5) async def test_delete_own_message(self) -> None: """Verify deleting own message removes it from both devices. @@ -273,6 +277,7 @@ class TestMessageContextMenu: ) @pytest.mark.smoke + @pytest.mark.flaky(reruns=1, reruns_delay=5) async def test_reply_to_message(self) -> None: """Verify replying to a message activates reply mode. @@ -304,6 +309,7 @@ class TestMessageContextMenu: chat_page.cancel_reply(timeout=3) @pytest.mark.smoke + @pytest.mark.flaky(reruns=1, reruns_delay=5) async def test_pin_message(self) -> None: """Verify pinning a message via context menu syncs to both devices. @@ -359,6 +365,7 @@ class TestMessageContextMenu: "Secondary: Message should show 'Pinned by' indicator (sync)" ) + @pytest.mark.gate @pytest.mark.smoke async def test_verify_reaction_on_message(self) -> None: """Verify that a reaction appears on the message and syncs to both devices. diff --git a/test/e2e_appium/tests/test_onboarding_import_seed.py b/test/e2e_appium/tests/test_onboarding_import_seed.py index 2d53d06640..dc367c1945 100644 --- a/test/e2e_appium/tests/test_onboarding_import_seed.py +++ b/test/e2e_appium/tests/test_onboarding_import_seed.py @@ -20,6 +20,7 @@ from utils.multi_device_helpers import StepMixin class TestOnboardingImportSeed(StepMixin): + @pytest.mark.gate @pytest.mark.smoke @pytest.mark.onboarding @pytest.mark.raw_devices diff --git a/test/e2e_appium/tests/test_saved_addresses.py b/test/e2e_appium/tests/test_saved_addresses.py index ac925a3797..e9156ba219 100644 --- a/test/e2e_appium/tests/test_saved_addresses.py +++ b/test/e2e_appium/tests/test_saved_addresses.py @@ -13,6 +13,7 @@ class TestSavedAddresses(StepMixin): @pytest.mark.wallet @pytest.mark.saved_addresses @pytest.mark.smoke + @pytest.mark.flaky(reruns=1, reruns_delay=5) async def test_add_and_remove_saved_address(self): async with self.step(self.device, "Navigate to Saved Addresses"): app = App(self.device.driver) diff --git a/test/e2e_appium/tests/test_settings_password_change_password.py b/test/e2e_appium/tests/test_settings_password_change_password.py index f576366cd6..b49d71013b 100644 --- a/test/e2e_appium/tests/test_settings_password_change_password.py +++ b/test/e2e_appium/tests/test_settings_password_change_password.py @@ -10,6 +10,7 @@ from utils.multi_device_helpers import StepMixin class TestSettingsPasswordChange(StepMixin): + @pytest.mark.gate @pytest.mark.critical @pytest.mark.smoke @pytest.mark.flaky(reruns=2, reruns_delay=2) diff --git a/test/e2e_appium/tests/test_wallet_accounts_basic.py b/test/e2e_appium/tests/test_wallet_accounts_basic.py index ae3d91f80f..2ca06cac2e 100644 --- a/test/e2e_appium/tests/test_wallet_accounts_basic.py +++ b/test/e2e_appium/tests/test_wallet_accounts_basic.py @@ -8,6 +8,7 @@ from utils.multi_device_helpers import StepMixin class TestWalletAccountsBasic(StepMixin): + @pytest.mark.gate @pytest.mark.wallet @pytest.mark.smoke async def test_add_and_delete_generated_account(self):