test_issue_details.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. from datetime import datetime, timedelta, timezone
  2. from unittest.mock import patch
  3. from fixtures.page_objects.issue_details import IssueDetailsPage
  4. from sentry.testutils.cases import AcceptanceTestCase, SnubaTestCase
  5. from sentry.testutils.silo import no_silo_test
  6. from sentry.utils.samples import load_data
  7. now = datetime.utcnow().replace(tzinfo=timezone.utc)
  8. @no_silo_test(stable=True)
  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, tags=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. if tags:
  30. event_data["tags"] = tags
  31. # We need a fallback datetime for the event
  32. if time is None:
  33. time = now - timedelta(days=2)
  34. time = time.replace(hour=0, minute=0, second=0, microsecond=0)
  35. event_data["timestamp"] = time.isoformat()
  36. event = self.store_event(
  37. data=event_data, project_id=self.project.id, assert_no_errors=False
  38. )
  39. event.group.update(
  40. first_seen=datetime(2015, 8, 13, 3, 8, 25, tzinfo=timezone.utc), last_seen=time
  41. )
  42. return event
  43. def test_python_event(self):
  44. tags = [
  45. ["server_name", "web02.example.org"],
  46. ["environment", "staging"],
  47. ]
  48. self.create_sample_event(platform="python", tags=tags)
  49. event = self.create_sample_event(platform="python")
  50. self.page.visit_issue(self.org.slug, event.group.id)
  51. # Wait for tag bars to load
  52. self.browser.wait_until_test_id("loaded-device-name")
  53. self.browser.snapshot("issue details python")
  54. def test_python_rawbody_event(self):
  55. event = self.create_sample_event(platform="python-rawbody")
  56. self.page.visit_issue(self.org.slug, event.group.id)
  57. self.browser.move_to('[data-test-id="rich-http-content-body-section-pre"]')
  58. self.browser.snapshot("issue details python raw body", desktop_only=True)
  59. def test_python_formdata_event(self):
  60. event = self.create_sample_event(platform="python-formdata")
  61. self.page.visit_issue(self.org.slug, event.group.id)
  62. self.browser.snapshot("issue details python formdata", desktop_only=True)
  63. def test_pii_tooltips(self):
  64. event = self.create_sample_event(platform="pii-tooltips")
  65. self.page.visit_issue(self.org.slug, event.group.id)
  66. self.browser.snapshot("issue details pii tooltips", desktop_only=True)
  67. def test_cocoa_event(self):
  68. event = self.create_sample_event(platform="cocoa")
  69. self.page.visit_issue(self.org.slug, event.group.id)
  70. self.browser.snapshot("issue details cocoa", desktop_only=True)
  71. def test_cocoa_event_frame_line_hover(self):
  72. event = self.create_sample_event(platform="cocoa")
  73. self.page.visit_issue(self.org.slug, event.group.id)
  74. self.browser.wait_until_not(".loading")
  75. self.browser.move_to(".traceback li:nth-child(2)")
  76. self.browser.snapshot("issue details cocoa frame line hover", desktop_only=True)
  77. def test_unity_event(self):
  78. event = self.create_sample_event(default="unity", platform="csharp")
  79. self.page.visit_issue(self.org.slug, event.group.id)
  80. self.browser.snapshot("issue details unity", desktop_only=True)
  81. def test_android_event(self):
  82. event = self.create_sample_event(platform="android")
  83. self.page.visit_issue(self.org.slug, event.group.id)
  84. self.browser.snapshot("issue details android", desktop_only=True)
  85. def test_android_ndk_event(self):
  86. event = self.create_sample_event(default="android-ndk", platform="android-ndk")
  87. self.page.visit_issue(self.org.slug, event.group.id)
  88. self.browser.snapshot("issue details android-ndk", desktop_only=True)
  89. def test_aspnetcore_event(self):
  90. event = self.create_sample_event(default="aspnetcore", platform="csharp")
  91. self.page.visit_issue(self.org.slug, event.group.id)
  92. self.browser.snapshot("issue details aspnetcore", desktop_only=True)
  93. def test_javascript_specific_event(self):
  94. event = self.create_sample_event(platform="javascript")
  95. self.page.visit_issue(self.org.slug, event.group.id)
  96. self.browser.snapshot("issue details javascript - event details", desktop_only=True)
  97. self.browser.click('label[data-test-id="curl"]')
  98. self.browser.snapshot(
  99. "issue details javascript - event details - curl command", desktop_only=True
  100. )
  101. def test_rust_event(self):
  102. # TODO: This should become its own "rust" platform type
  103. event = self.create_sample_event(platform="native", sample_name="Rust")
  104. self.page.visit_issue(self.org.slug, event.group.id)
  105. self.browser.snapshot("issue details rust", desktop_only=True)
  106. def test_cordova_event(self):
  107. event = self.create_sample_event(platform="cordova")
  108. self.page.visit_issue(self.org.slug, event.group.id)
  109. self.browser.snapshot("issue details cordova", desktop_only=True)
  110. def test_stripped_event(self):
  111. event = self.create_sample_event(platform="pii")
  112. self.page.visit_issue(self.org.slug, event.group.id)
  113. self.browser.snapshot("issue details pii stripped", desktop_only=True)
  114. def test_empty_exception(self):
  115. event = self.create_sample_event(platform="empty-exception")
  116. self.page.visit_issue(self.org.slug, event.group.id)
  117. self.browser.snapshot("issue details empty exception", desktop_only=True)
  118. def test_empty_stacktrace(self):
  119. event = self.create_sample_event(platform="empty-stacktrace")
  120. self.page.visit_issue(self.org.slug, event.group.id)
  121. self.browser.snapshot("issue details empty stacktrace", desktop_only=True)
  122. def test_invalid_interfaces(self):
  123. event = self.create_sample_event(platform="invalid-interfaces")
  124. self.page.visit_issue(self.org.slug, event.group.id)
  125. self.browser.click('[data-test-id="event-error-alert"]')
  126. self.browser.wait_until_test_id("event-error-details")
  127. self.browser.snapshot("issue details invalid interfaces", desktop_only=True)
  128. def test_activity_page(self):
  129. event = self.create_sample_event(platform="python")
  130. self.page.visit_issue(self.org.slug, event.group.id)
  131. self.page.go_to_subtab("activity")
  132. self.browser.wait_until_test_id("activity-item")
  133. self.browser.blur()
  134. self.browser.snapshot("issue activity python", desktop_only=True)
  135. def test_resolved(self):
  136. event = self.create_sample_event(platform="python")
  137. self.page.visit_issue(self.org.slug, event.group.id)
  138. self.page.resolve_issue()
  139. self.browser.snapshot("issue details resolved", desktop_only=True)
  140. def test_ignored(self):
  141. event = self.create_sample_event(platform="python")
  142. self.page.visit_issue(self.org.slug, event.group.id)
  143. self.page.ignore_issue()
  144. self.browser.snapshot("issue details ignored", desktop_only=True)
  145. def test_exception_and_no_threads_event(self):
  146. event = self.create_sample_event(platform="exceptions-and-no-threads")
  147. self.page.visit_issue(self.org.slug, event.group.id)
  148. self.browser.snapshot("issue details exceptions and no threads", desktop_only=True)
  149. def test_exception_with_stack_trace_and_crashed_thread_without_stack_trace_event(self):
  150. event = self.create_sample_event(
  151. platform="exception-with-stack-trace-and-crashed-thread-without-stack-trace"
  152. )
  153. self.page.visit_issue(self.org.slug, event.group.id)
  154. self.browser.snapshot(
  155. "issue details exception with stack trace and crashed thread without stack trace",
  156. desktop_only=True,
  157. )
  158. def test_exception_without_stack_trace_and_crashed_thread_with_stack_trace_event(self):
  159. event = self.create_sample_event(
  160. platform="exception-without-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 without stack trace and crashed thread with stack trace",
  165. desktop_only=True,
  166. )
  167. def test_exception_with_stack_trace_and_crashed_thread_with_stack_trace_event(self):
  168. event = self.create_sample_event(
  169. platform="exception-with-stack-trace-and-crashed-thread-with-stack-trace"
  170. )
  171. self.page.visit_issue(self.org.slug, event.group.id)
  172. self.browser.snapshot(
  173. "issue details exception with stack trace and crashed thread with stack trace",
  174. desktop_only=True,
  175. )
  176. def test_python_invalid_json_error(self):
  177. event = self.create_sample_event(default="python-invalid-json-error", platform="native")
  178. self.page.visit_issue(self.org.slug, event.group.id)
  179. self.browser.snapshot("issue details invalid json error exception", desktop_only=True)
  180. def test_exception_with_address_instruction(self):
  181. event = self.create_sample_event(
  182. default="exception-with-address-instruction", platform="cocoa"
  183. )
  184. self.page.visit_issue(self.org.slug, event.group.id)
  185. self.browser.snapshot("issue details exception with address instruction", desktop_only=True)