Skip to content

Commit eea17ae

Browse files
committed
feat(e2e_appium): async test config and onboarding fixture
1 parent fd4651c commit eea17ae

File tree

5 files changed

+57
-21
lines changed

5 files changed

+57
-21
lines changed

test/e2e_appium/fixtures/onboarding_fixture.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from models.user_model import User, UserProfile
2727
from config import get_config
2828
from config.logging_config import get_logger
29+
from services.app_initialization_manager import AppInitializationManager
2930

3031

3132
@dataclass
@@ -148,22 +149,16 @@ def execute_complete_flow(self) -> Dict[str, Any]:
148149
else:
149150
self._execute_analytics_skip_step()
150151

151-
# Step 3a: Create Profile Screen OR Step 3b: Seed Phrase Import
152152
if self.config.use_seed_phrase:
153-
# Seed phrase import flow
154153
self._execute_seed_phrase_import_step()
155154
else:
156-
# New profile creation flow
157155
if not self.config.skip_profile_creation:
158156
self._execute_create_profile_step()
159157

160-
# Step 4: Password Creation
161158
self._execute_password_step()
162159

163-
# Step 5: Loading Screen
164160
self._execute_loading_step()
165161

166-
# Step 6: Main App Verification
167162
if self.config.verify_main_app:
168163
self._execute_main_app_verification()
169164

@@ -189,14 +184,18 @@ def _execute_welcome_step(self):
189184
self.current_step = "welcome_screen"
190185
self.logger.info("Step 1: Welcome Screen")
191186

192-
# Wait for screen to be fully loaded before activating accessibility
193-
# Wait for app to be visually ready (look for any UI elements)
187+
# Wait for session to be ready before checking for UI
188+
try:
189+
init_manager = AppInitializationManager(self.driver)
190+
init_manager._wait_for_session_ready(timeout=5.0)
191+
except Exception as exc:
192+
self.logger.debug("Session readiness check skipped: %s", exc)
193+
194194
max_wait = 10
195195
for attempt in range(max_wait):
196196
try:
197-
# Check if any UI elements are present (even without accessibility)
198197
elements = self.main_app_page.driver.find_elements("xpath", "//*")
199-
if len(elements) > 5: # Basic UI structure loaded
198+
if len(elements) > 5:
200199
break
201200
time.sleep(1)
202201
except Exception:
@@ -206,10 +205,21 @@ def _execute_welcome_step(self):
206205
self.main_app_page.driver.tap([(500, 300)])
207206
time.sleep(1)
208207
except Exception:
209-
pass # Non-critical if tap fails
208+
self.logger.debug("Initial tap attempt skipped", exc_info=True)
210209

211210
if self.config.validate_each_step:
212-
assert self.welcome_page.is_screen_displayed(timeout=30), (
211+
welcome_visible = False
212+
for attempt in range(3):
213+
if self.welcome_page.is_screen_displayed(timeout=10):
214+
welcome_visible = True
215+
break
216+
if attempt < 2:
217+
self.logger.debug(
218+
f"Welcome screen not visible yet (attempt {attempt + 1}/3), waiting..."
219+
)
220+
time.sleep(2)
221+
222+
assert welcome_visible, (
213223
"Welcome screen should be displayed"
214224
)
215225

@@ -224,7 +234,6 @@ def _execute_welcome_step(self):
224234
self._take_screenshot("welcome_completed")
225235

226236
def _execute_seed_phrase_import_step(self):
227-
"""Execute seed phrase import from Create Profile screen into Password."""
228237
self.current_step = "seed_phrase_import"
229238
self.logger.info("Step 3: Seed Phrase Import")
230239

@@ -257,7 +266,6 @@ def _execute_seed_phrase_import_step(self):
257266
self._take_screenshot("seed_phrase_import_completed")
258267

259268
def _execute_analytics_step(self):
260-
"""Execute analytics screen interaction"""
261269
self.current_step = "analytics_screen"
262270
self.logger.info("Step 2: Analytics Screen (interacting)")
263271

@@ -266,7 +274,6 @@ def _execute_analytics_step(self):
266274
"Analytics screen should be displayed"
267275
)
268276

269-
# Interact with analytics consent (accept sharing)
270277
self.analytics_page.accept_analytics_sharing()
271278

272279
self.step_results["analytics_screen"] = {
@@ -276,7 +283,6 @@ def _execute_analytics_step(self):
276283
}
277284

278285
def _execute_analytics_skip_step(self):
279-
"""Execute analytics screen skip action"""
280286
self.current_step = "analytics_screen_skip"
281287
self.logger.info("Step 2: Analytics Screen (skipping)")
282288

@@ -297,7 +303,6 @@ def _execute_analytics_skip_step(self):
297303
self._take_screenshot("analytics_skipped")
298304

299305
def _execute_create_profile_step(self):
300-
"""Execute create profile screen interaction"""
301306
self.current_step = "create_profile_screen"
302307
self.logger.info("Step 3: Create Profile Screen")
303308

@@ -317,7 +322,6 @@ def _execute_create_profile_step(self):
317322
self._take_screenshot("profile_created")
318323

319324
def _execute_password_step(self):
320-
"""Execute password creation step"""
321325
self.current_step = "password_screen"
322326
self.logger.info("Step 4: Password Screen")
323327

test/e2e_appium/pages/base_page.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import time
22
import logging
3+
import os
34
from datetime import datetime
45
from pathlib import Path
56
from typing import Optional, List

test/e2e_appium/pages/onboarding/loading_page.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66

77
from selenium.webdriver.support.ui import WebDriverWait
88
from selenium.webdriver.support import expected_conditions as EC
9-
from selenium.common.exceptions import TimeoutException
9+
from selenium.common.exceptions import (
10+
TimeoutException,
11+
WebDriverException,
12+
NoSuchWindowException,
13+
InvalidSessionIdException,
14+
)
1015

1116
from ..base_page import BasePage
1217
from locators.onboarding.loading_screen_locators import LoadingScreenLocators
@@ -34,6 +39,21 @@ def wait_for_loading_completion(self, timeout: int = 60) -> bool:
3439
)
3540
self.logger.info("Loading completed - screen disappeared")
3641
return True
42+
except (NoSuchWindowException, InvalidSessionIdException) as e:
43+
self.logger.error(
44+
f"WebDriver session ended during loading wait: {type(e).__name__}: {e}"
45+
)
46+
return False
47+
except WebDriverException as e:
48+
self.logger.warning(
49+
f"WebDriver error during loading wait: {type(e).__name__}: {e}"
50+
)
51+
try:
52+
_ = self.driver.current_url
53+
except (WebDriverException, InvalidSessionIdException, NoSuchWindowException):
54+
self.logger.error("WebDriver session appears to be dead")
55+
return False
56+
return False
3757
except TimeoutException:
3858
self.logger.warning(
3959
f"Loading did not complete within {timeout} seconds; checking main app state"

test/e2e_appium/pytest.ini

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
[pytest]
2-
addopts = -v --tb=short --strict-markers
2+
addopts = -v --tb=short --strict-markers --timeout=600
3+
asyncio_mode = strict
4+
timeout = 600
35
markers =
46
smoke: Quick critical tests for PR validation
57
onboarding: User onboarding flow tests
@@ -12,4 +14,7 @@ markers =
1214
onboarding_config: Custom configuration for onboarding fixture
1315
messaging: Messaging tests
1416
wallet: Wallet tests
15-
saved_addresses: Saved addresses tests
17+
saved_addresses: Saved addresses tests
18+
no_autouse_onboarded: Skip automatic onboarding fixture for tests that manage their own onboarding
19+
single_device: Tests that only require a single device (use device_count(1) marker)
20+
asyncio: Async test marker (managed by pytest-asyncio)

test/e2e_appium/utils/exceptions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ class SessionManagementError(Exception):
3232
pass
3333

3434

35+
class BrowserStackQueueError(SessionManagementError):
36+
"""Exception for BrowserStack queue exhaustion errors."""
37+
38+
pass
39+
40+
3541
class ElementInteractionError(Exception):
3642
"""Exception for element interaction failures (clicks, input, etc.)."""
3743

0 commit comments

Comments
 (0)