Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions tda/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,11 +498,11 @@ def android_emu_driver(request, selenium_endpoint, se_prefix):

options = UiAutomator2Options().load_capabilities({
'deviceName': 'Android GoogleAPI Emulator',
'platformVersion': '10.0',
'platformVersion': '14.0',
'platformName': 'Android',
'app': f'https://github.com/sentry-demos/android/releases/download/{release_version}/app-release.apk',
'sauce:options': {
'appiumVersion': '1.20.2',
'appiumVersion': '2.0.0',
'build': 'RDC-Android-Python-Best-Practice',
'name': request.node.name
},
Expand Down Expand Up @@ -577,7 +577,7 @@ def ios_sim_driver(request, selenium_endpoint, se_prefix):
'appium:platformVersion': '15.5',

'sauce:options': {
'appiumVersion': '1.22.3',
'appiumVersion': '2.0.0',
'build': 'RDC-iOS-Mobile-Native',
'name': request.node.name,
},
Expand Down
45 changes: 38 additions & 7 deletions tda/mobile_native/android/test_anr_android.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,55 @@
import time
import pytest
import subprocess
import sentry_sdk
from appium.webdriver.common.appiumby import AppiumBy

# Application Not Responding button
@pytest.mark.skip(reason="not working")
def test_anr_android(android_emu_driver):

try:
# navigate to list app
android_emu_driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'More').click()
android_emu_driver.find_element(AppiumBy.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.ListView/android.widget.LinearLayout/android.widget.LinearLayout').click()
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/content').click()

# trigger error
btn = android_emu_driver.find_element(AppiumBy.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.ScrollView/android.widget.LinearLayout/android.widget.Button[4]')
btn.click()
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/anr').click()

# TODO get the event to send to Sentry.io
time.sleep(10)
android_emu_driver.launch_app()
# keep clicking on the button for a while so the ANR is thrown with "Input dispatching timeout"
# we can't use Appium's driver here as it's also locked together with the ANR, so we send taps directly via adb
try:
time.sleep(1)
android_emu_driver.execute_script('mobile: shell', {
'command': 'input',
'args': ['tap', '200', '200'],
'timeout': 5000
})
except Exception:
pass # it's expected to fail but it's still gonna click and cause an ANR

try:
time.sleep(1)
android_emu_driver.execute_script('mobile: shell', {
'command': 'input',
'args': ['tap', '200', '200'],
'timeout': 5000
})
except Exception:
pass # it's expected to fail but it's still gonna click and cause an ANR

# Click "Close app" in the ANR dialog
android_emu_driver.find_element(AppiumBy.ID, 'android:id/aerr_close').click()

# Give system some time to recover
time.sleep(3)

android_emu_driver.execute_script('mobile: startActivity', {
'component': 'com.example.vu.android/.empowerplant.EmpowerPlantActivity',
'action': 'android.intent.action.MAIN',
'extras': [['z', 'relaunch_for_send', 'true']]
})

# sleep after relaunch to make sure error (+ traces + replays) makes it to the server
time.sleep(8)
except Exception as err:
sentry_sdk.capture_exception(err)
4 changes: 2 additions & 2 deletions tda/mobile_native/android/test_checkout_android.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def test_checkout_android(android_emu_driver):
# Checkout button
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/checkout_btn').click()

# Sleep in seconds to allow time for error to send to Sentry (minimum 3, tested 4/8/2025 sz)
time.sleep(3)
# Sleep in seconds to allow time for error to send to Sentry (minimum 4, tested 6/4/2025 romtsn)
time.sleep(4)

except Exception as err:
sentry_sdk.capture_exception(err)
4 changes: 3 additions & 1 deletion tda/mobile_native/android/test_handlederror_android.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
import sentry_sdk
from appium.webdriver.common.appiumby import AppiumBy

Expand All @@ -11,6 +12,7 @@ def test_handlederror_android(android_emu_driver):

# trigger error
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/handled_exception').click()


time.sleep(4)
except Exception as err:
sentry_sdk.capture_exception(err)
5 changes: 4 additions & 1 deletion tda/mobile_native/android/test_httperror_android.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ def test_httperror_android(android_emu_driver):
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/content').click()

# swipe down to have the HTTP Error button in the frame
android_emu_driver.swipe(start_x=0, start_y=1100, end_x=0, end_y=500, duration=800)
android_emu_driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().resourceId(\"com.example.vu.android:id/error_404\"))'
)
# HTTP Error button
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/error_404').click()

time.sleep(4)
except Exception as err:
sentry_sdk.capture_exception(err)
27 changes: 18 additions & 9 deletions tda/mobile_native/android/test_nativecrash_android.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
import time
import pytest
import sentry_sdk
from appium.webdriver.common.appiumby import AppiumBy

# NDK/C++ Native Crash SIGSEGV button
@pytest.mark.skip(reason="not working")
def test_nativecrash_android(android_emu_driver):

try:
# navigate to list app
android_emu_driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'More').click()
android_emu_driver.find_element(AppiumBy.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.ListView/android.widget.LinearLayout/android.widget.LinearLayout').click()
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/content').click()

# trigger error
btn = android_emu_driver.find_element(AppiumBy.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.ScrollView/android.widget.LinearLayout/android.widget.Button[4]')
btn.click()
# swipe down to have the Native Crash button in the frame
android_emu_driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().resourceId(\"com.example.vu.android:id/native_crash\"))'
)

# TODO get the event to send to Sentry.io
time.sleep(5)
android_emu_driver.launch_app()
# nativecrash button
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/native_crash').click()

time.sleep(2)

android_emu_driver.execute_script('mobile: startActivity', {
'component': 'com.example.vu.android/.empowerplant.EmpowerPlantActivity',
'action': 'android.intent.action.MAIN',
'extras': [['z', 'relaunch_for_send', 'true']]
})

# sleep after relaunch to make sure error (+ traces + replays) makes it to the server
time.sleep(10)

except Exception as err:
sentry_sdk.capture_exception(err)
6 changes: 5 additions & 1 deletion tda/mobile_native/android/test_nativemessage_android.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
import sentry_sdk
from appium.webdriver.common.appiumby import AppiumBy

Expand All @@ -10,10 +11,13 @@ def test_nativemessage_android(android_emu_driver):
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/content').click()

# swipe down to have the Native Message button in the frame
android_emu_driver.swipe(start_x=0, start_y=1100, end_x=0, end_y=500, duration=800)
android_emu_driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().resourceId(\"com.example.vu.android:id/native_message\"))'
)

# nativemessage button
android_emu_driver.find_element(AppiumBy.ID, 'com.example.vu.android:id/native_message').click()

time.sleep(4)
except Exception as err:
sentry_sdk.capture_exception(err)
12 changes: 11 additions & 1 deletion tda/mobile_native/android/test_unhandlederror2_android.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
import sentry_sdk
from appium.webdriver.common.appiumby import AppiumBy

Expand All @@ -24,7 +25,16 @@ def test_unhandlederror2_android(android_emu_driver):
level='info',
)

android_emu_driver.launch_app()
time.sleep(2)

android_emu_driver.execute_script('mobile: startActivity', {
'component': 'com.example.vu.android/.empowerplant.EmpowerPlantActivity',
'action': 'android.intent.action.MAIN',
'extras': [['z', 'relaunch_for_send', 'true']]
})

# sleep after relaunch to make sure error (+ traces + replays) makes it to the server
time.sleep(10)

except Exception as err:
sentry_sdk.capture_exception(err)
12 changes: 11 additions & 1 deletion tda/mobile_native/android/test_unhandlederror_android.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
import sentry_sdk
from appium.webdriver.common.appiumby import AppiumBy

Expand All @@ -24,7 +25,16 @@ def test_unhandlederror_android(android_emu_driver):
level='info',
)

android_emu_driver.launch_app()
time.sleep(2)

android_emu_driver.execute_script('mobile: startActivity', {
'component': 'com.example.vu.android/.empowerplant.EmpowerPlantActivity',
'action': 'android.intent.action.MAIN',
'extras': [['z', 'relaunch_for_send', 'true']]
})

# sleep after relaunch to make sure error (+ traces + replays) makes it to the server
time.sleep(10)

except Exception as err:
sentry_sdk.capture_exception(err)
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_nativecrash_react_native_android(android_react_native_emu_driver):
btn.click()

# launch app again or the error does not get sent to Sentry
android_react_native_emu_driver.launch_app()
android_react_native_emu_driver.activate_app("com.sentry_react_native")

time.sleep(5) # success rate is ~ 46% regardless of sleep duration (must be at least 2 seconds)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def test_uncaughtthrownerror_react_native_android(android_react_native_emu_drive

# launch app again or the error does not get sent to Sentry
# still ~ 83% success rate
android_react_native_emu_driver.launch_app()
android_react_native_emu_driver.activate_app("com.sentry_react_native")

time.sleep(10) # replay success rate is ~ 75% for sleep >= 10 seconds and ~ 50% for sleep = 5 seconds

Expand Down
17 changes: 5 additions & 12 deletions tda/mobile_native/ios/test_error_list_ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,17 @@ def test_error_list_ios(ios_sim_driver):
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="Error"]').click()
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="NSException"]').click()
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="Fatal Error"]').click()
ios_sim_driver.launch_app()

ios_sim_driver.find_element(AppiumBy.ACCESSIBILITY_ID, "more").click()
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="DiskWriteException (!)"]').click()
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="HighCPULoad"]').click()
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="Permissions (!)"]').click()
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="Async Crash (!)"]').click()
ios_sim_driver.launch_app()
ios_sim_driver.activate_app('sentrydemos.ios.EmpowerPlant')

ios_sim_driver.find_element(AppiumBy.ACCESSIBILITY_ID, "more").click()
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="ANR Fully Blocking"]').click()
ios_sim_driver.launch_app()
ios_sim_driver.activate_app('sentrydemos.ios.EmpowerPlant')

ios_sim_driver.find_element(AppiumBy.ACCESSIBILITY_ID, "more").click()
ios_sim_driver.find_element(AppiumBy.XPATH, '//XCUIElementTypeStaticText[@name="ANR Filling Run Loop"]').click()

ios_sim_driver.launch_app()

ios_sim_driver.activate_app('sentrydemos.ios.EmpowerPlant')

time.sleep(5)
# wait for confirmation of purchase? (currently nothing happens)

except Exception as err:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sentry_sdk
import time
from appium.webdriver.common.appiumby import AppiumBy

def test_captureexception_react_native_ios(ios_react_native_sim_driver):
Expand All @@ -11,5 +12,6 @@ def test_captureexception_react_native_ios(ios_react_native_sim_driver):
btn = ios_react_native_sim_driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Capture Exception")
btn.click()

time.sleep(2)
except Exception as err:
sentry_sdk.capture_exception(err)
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sentry_sdk
import time
from appium.webdriver.common.appiumby import AppiumBy

def test_capturemessage_react_native_ios(ios_react_native_sim_driver):
Expand All @@ -11,5 +12,6 @@ def test_capturemessage_react_native_ios(ios_react_native_sim_driver):
btn = ios_react_native_sim_driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Capture Message")
btn.click()

time.sleep(2)
except Exception as err:
sentry_sdk.capture_exception(err)
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ def test_checkout_react_native_ios(ios_react_native_sim_driver):

ios_react_native_sim_driver.find_element(AppiumBy.XPATH, '(//XCUIElementTypeOther[@name="Place your order"])').click()

time.sleep(10)
except Exception as err:
sentry_sdk.capture_exception(err)
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sentry_sdk
import time
from appium.webdriver.common.appiumby import AppiumBy

def test_nativecrash_react_native_ios(ios_react_native_sim_driver):
Expand All @@ -11,7 +12,8 @@ def test_nativecrash_react_native_ios(ios_react_native_sim_driver):
btn = ios_react_native_sim_driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Native Crash")
btn.click()
# launch app again or the error does not get sent to Sentry
ios_react_native_sim_driver.launch_app()
ios_react_native_sim_driver.activate_app('org.reactjs.native.example.sentry-react-native')

time.sleep(5)
except Exception as err:
sentry_sdk.capture_exception(err)
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sentry_sdk
import time
from appium.webdriver.common.appiumby import AppiumBy

def test_uncaughtthrownerror_react_native_ios(ios_react_native_sim_driver):
Expand All @@ -11,7 +12,8 @@ def test_uncaughtthrownerror_react_native_ios(ios_react_native_sim_driver):
btn = ios_react_native_sim_driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Uncaught Thrown Error")
btn.click()
# launch app again or the error does not get sent to Sentry
ios_react_native_sim_driver.launch_app()
ios_react_native_sim_driver.activate_app('org.reactjs.native.example.sentry-react-native')

time.sleep(5)
except Exception as err:
sentry_sdk.capture_exception(err)
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ def test_unhandledpromiserejection_react_native_ios(ios_react_native_sim_driver)
btn = ios_react_native_sim_driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Unhandled Promise Rejection")
btn.click()

time.sleep(2)
except Exception as err:
sentry_sdk.capture_exception(err)