test_issue_details.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. from datetime import datetime, timedelta
  2. from unittest.mock import patch
  3. import pytz
  4. from django.utils import timezone
  5. from sentry.testutils import AcceptanceTestCase, SnubaTestCase
  6. from sentry.utils.samples import load_data
  7. from tests.acceptance.page_objects.issue_details import IssueDetailsPage
  8. now = datetime.utcnow().replace(tzinfo=pytz.utc)
  9. class IssueDetailsTest(AcceptanceTestCase, SnubaTestCase):
  10. def setUp(self):
  11. super().setUp()
  12. patcher = patch("django.utils.timezone.now", return_value=now)
  13. patcher.start()
  14. self.addCleanup(patcher.stop)
  15. self.user = self.create_user("foo@example.com")
  16. self.org = self.create_organization(owner=self.user, name="Rowdy Tiger")
  17. self.team = self.create_team(organization=self.org, name="Mariachi Band")
  18. self.project = self.create_project(organization=self.org, teams=[self.team], name="Bengal")
  19. self.login_as(self.user)
  20. self.page = IssueDetailsPage(self.browser, self.client)
  21. self.dismiss_assistant()
  22. def create_sample_event(self, platform, default=None, sample_name=None, time=None):
  23. event_data = load_data(platform, default=default, sample_name=sample_name)
  24. event_data["event_id"] = "d964fdbd649a4cf8bfc35d18082b6b0e"
  25. # Only set these properties if we were given a time.
  26. # event processing will mark old time values as processing errors.
  27. if time:
  28. event_data["received"] = time.isoformat()
  29. # We need a fallback datetime for the event
  30. if time is None:
  31. time = now - timedelta(days=2)
  32. time = time.replace(hour=0, minute=0, second=0, microsecond=0)
  33. event_data["timestamp"] = time.isoformat()
  34. event = self.store_event(
  35. data=event_data, project_id=self.project.id, assert_no_errors=False
  36. )
  37. event.group.update(
  38. first_seen=datetime(2015, 8, 13, 3, 8, 25, tzinfo=timezone.utc), last_seen=time
  39. )
  40. return event
  41. def test_python_event(self):
  42. self.create_sample_event(platform="python")
  43. self.create_sample_event(platform="python")
  44. event = self.create_sample_event(platform="python")
  45. self.page.visit_issue(self.org.slug, event.group.id)
  46. # Wait for tag bars to load
  47. self.browser.wait_until_test_id("loaded-device-name")
  48. self.browser.snapshot("issue details python")
  49. def test_python_rawbody_event(self):
  50. event = self.create_sample_event(platform="python-rawbody")
  51. self.page.visit_issue(self.org.slug, event.group.id)
  52. self.browser.move_to('[data-test-id="rich-http-content-body-section-pre"]')
  53. self.browser.snapshot("issue details python raw body")
  54. def test_python_formdata_event(self):
  55. event = self.create_sample_event(platform="python-formdata")
  56. self.page.visit_issue(self.org.slug, event.group.id)
  57. self.browser.snapshot("issue details python formdata")
  58. def test_pii_tooltips(self):
  59. event = self.create_sample_event(platform="pii-tooltips")
  60. self.page.visit_issue(self.org.slug, event.group.id)
  61. self.browser.snapshot("issue details pii tooltips")
  62. def test_cocoa_event(self):
  63. event = self.create_sample_event(platform="cocoa")
  64. self.page.visit_issue(self.org.slug, event.group.id)
  65. self.browser.snapshot("issue details cocoa")
  66. def test_cocoa_event_frame_line_hover(self):
  67. event = self.create_sample_event(platform="cocoa")
  68. self.page.visit_issue(self.org.slug, event.group.id)
  69. self.browser.wait_until_not(".loading")
  70. self.browser.move_to(".traceback li:nth-child(2)")
  71. self.browser.snapshot("issue details cocoa frame line hover")
  72. def test_unity_event(self):
  73. event = self.create_sample_event(default="unity", platform="csharp")
  74. self.page.visit_issue(self.org.slug, event.group.id)
  75. self.browser.snapshot("issue details unity")
  76. def test_android_event(self):
  77. event = self.create_sample_event(platform="android")
  78. self.page.visit_issue(self.org.slug, event.group.id)
  79. self.browser.snapshot("issue details android")
  80. def test_android_ndk_event(self):
  81. event = self.create_sample_event(default="android-ndk", platform="android-ndk")
  82. self.page.visit_issue(self.org.slug, event.group.id)
  83. self.browser.snapshot("issue details android-ndk")
  84. def test_aspnetcore_event(self):
  85. event = self.create_sample_event(default="aspnetcore", platform="csharp")
  86. self.page.visit_issue(self.org.slug, event.group.id)
  87. self.browser.snapshot("issue details aspnetcore")
  88. def test_javascript_specific_event(self):
  89. event = self.create_sample_event(platform="javascript")
  90. self.page.visit_issue(self.org.slug, event.group.id)
  91. self.browser.snapshot("issue details javascript - event details")
  92. self.browser.click('[aria-label="curl"]')
  93. self.browser.snapshot("issue details javascript - event details - curl command")
  94. def test_rust_event(self):
  95. # TODO: This should become its own "rust" platform type
  96. event = self.create_sample_event(platform="native", sample_name="Rust")
  97. self.page.visit_issue(self.org.slug, event.group.id)
  98. self.browser.snapshot("issue details rust")
  99. def test_cordova_event(self):
  100. event = self.create_sample_event(platform="cordova")
  101. self.page.visit_issue(self.org.slug, event.group.id)
  102. self.browser.snapshot("issue details cordova")
  103. def test_stripped_event(self):
  104. event = self.create_sample_event(platform="pii")
  105. self.page.visit_issue(self.org.slug, event.group.id)
  106. self.browser.snapshot("issue details pii stripped")
  107. def test_empty_exception(self):
  108. event = self.create_sample_event(platform="empty-exception")
  109. self.page.visit_issue(self.org.slug, event.group.id)
  110. self.browser.snapshot("issue details empty exception")
  111. def test_empty_stacktrace(self):
  112. event = self.create_sample_event(platform="empty-stacktrace")
  113. self.page.visit_issue(self.org.slug, event.group.id)
  114. self.browser.snapshot("issue details empty stacktrace")
  115. def test_invalid_interfaces(self):
  116. event = self.create_sample_event(platform="invalid-interfaces")
  117. self.page.visit_issue(self.org.slug, event.group.id)
  118. self.browser.click('[data-test-id="event-error-toggle"]')
  119. self.browser.wait_until_test_id("event-error-details")
  120. self.browser.snapshot("issue details invalid interfaces")
  121. def test_activity_page(self):
  122. event = self.create_sample_event(platform="python")
  123. self.page.visit_issue(self.org.slug, event.group.id)
  124. self.page.go_to_subtab("Activity")
  125. self.browser.wait_until_test_id("activity-item")
  126. self.browser.blur()
  127. self.browser.snapshot("issue activity python")
  128. def test_resolved(self):
  129. event = self.create_sample_event(platform="python")
  130. self.page.visit_issue(self.org.slug, event.group.id)
  131. self.page.resolve_issue()
  132. self.browser.snapshot("issue details resolved")
  133. def test_ignored(self):
  134. event = self.create_sample_event(platform="python")
  135. self.page.visit_issue(self.org.slug, event.group.id)
  136. self.page.ignore_issue()
  137. self.browser.snapshot("issue details ignored")
  138. def test_exception_and_no_threads_event(self):
  139. event = self.create_sample_event(platform="exceptions-and-no-threads")
  140. self.page.visit_issue(self.org.slug, event.group.id)
  141. self.browser.snapshot("issue details exceptions and no threads")
  142. def test_exception_with_stack_trace_and_crashed_thread_without_stack_trace_event(self):
  143. event = self.create_sample_event(
  144. platform="exception-with-stack-trace-and-crashed-thread-without-stack-trace"
  145. )
  146. self.page.visit_issue(self.org.slug, event.group.id)
  147. self.browser.snapshot(
  148. "issue details exception with stack trace and crashed thread without stack trace"
  149. )
  150. def test_exception_without_stack_trace_and_crashed_thread_with_stack_trace_event(self):
  151. event = self.create_sample_event(
  152. platform="exception-without-stack-trace-and-crashed-thread-with-stack-trace"
  153. )
  154. self.page.visit_issue(self.org.slug, event.group.id)
  155. self.browser.snapshot(
  156. "issue details exception without stack trace and crashed thread with stack trace"
  157. )
  158. def test_exception_with_stack_trace_and_crashed_thread_with_stack_trace_event(self):
  159. event = self.create_sample_event(
  160. platform="exception-with-stack-trace-and-crashed-thread-with-stack-trace"
  161. )
  162. self.page.visit_issue(self.org.slug, event.group.id)
  163. self.browser.snapshot(
  164. "issue details exception with stack trace and crashed thread with stack trace"
  165. )
  166. def test_python_invalid_json_error(self):
  167. event = self.create_sample_event(default="python-invalid-json-error", platform="native")
  168. self.page.visit_issue(self.org.slug, event.group.id)
  169. self.browser.snapshot("issue details invalid json error exception")
  170. def test_exception_with_address_instruction(self):
  171. event = self.create_sample_event(
  172. default="exception-with-address-instruction", platform="cocoa"
  173. )
  174. self.page.visit_issue(self.org.slug, event.group.id)
  175. self.browser.snapshot("issue details exception with address instruction")