Skip to content

Commit 90c2889

Browse files
feat(onboarding): Bulletproof critical back actions with new tests (#88532)
Add more acceptance tests to ensure critical workflows in the onboarding don't break
1 parent 54b7cc3 commit 90c2889

File tree

3 files changed

+100
-59
lines changed

3 files changed

+100
-59
lines changed

src/sentry/testutils/asserts.py

+20
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
from django.http import StreamingHttpResponse
44

5+
from sentry.constants import ObjectStatus
56
from sentry.integrations.types import EventLifecycleOutcome
67
from sentry.models.auditlogentry import AuditLogEntry
78
from sentry.models.commitfilechange import CommitFileChange
9+
from sentry.models.organization import Organization
10+
from sentry.models.project import Project
811
from sentry.silo.base import SiloMode
912
from sentry.testutils.silo import assume_test_silo_mode
1013

@@ -45,6 +48,23 @@ def assert_status_code(response, minimum: int, maximum: int | None = None):
4548
)
4649

4750

51+
def assert_existing_projects_status(
52+
org: Organization, active_project_ids: list[int], deleted_project_ids: list[int]
53+
):
54+
all_projects = Project.objects.filter(organization=org).values_list("id", "status")
55+
active_ids = []
56+
deleted_or_to_be_deleted_ids = []
57+
58+
for project_id, status in all_projects:
59+
if status == ObjectStatus.ACTIVE:
60+
active_ids.append(project_id)
61+
else:
62+
deleted_or_to_be_deleted_ids.append(project_id)
63+
64+
assert active_ids == active_project_ids
65+
assert deleted_or_to_be_deleted_ids == deleted_project_ids
66+
67+
4868
@assume_test_silo_mode(SiloMode.CONTROL)
4969
def org_audit_log_exists(**kwargs):
5070
assert kwargs
+25-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from selenium.webdriver.common.by import By
2-
1+
from sentry.models.project import Project
2+
from sentry.testutils.asserts import assert_existing_projects_status
33
from sentry.testutils.cases import AcceptanceTestCase
44
from sentry.testutils.silo import no_silo_test
55

@@ -11,37 +11,42 @@ def setUp(self):
1111
self.user = self.create_user("[email protected]")
1212
self.org = self.create_organization(name="Rowdy Tiger", owner=self.user)
1313
self.login_as(self.user)
14-
1514
self.path = f"/organizations/{self.org.slug}/projects/new/"
1615

17-
def test_no_teams(self):
16+
def load_project_creation_page(self):
1817
self.browser.get(self.path)
19-
self.browser.wait_until_not(".loading")
18+
self.browser.wait_until('[aria-label="Create Project"]')
2019

20+
def test_no_teams(self):
21+
self.load_project_creation_page()
2122
self.browser.click(None, "//*[text()='Select a Team']")
2223
self.browser.click('[data-test-id="create-team-option"]')
2324
self.browser.wait_until("[role='dialog']")
2425
input = self.browser.element('input[name="slug"]')
2526
input.send_keys("new-team")
26-
2727
self.browser.element("[role='dialog'] form").submit()
28-
29-
# After creating team, should end up in onboarding screen
3028
self.browser.wait_until(xpath='//div[text()="#new-team"]')
3129

3230
def test_select_correct_platform(self):
3331
self.create_team(organization=self.org, name="team three")
34-
35-
self.browser.get(self.path)
36-
self.browser.wait_until_not(".loading")
37-
38-
self.browser.click('[data-test-id="platform-javascript-react"]')
39-
self.browser.wait_until_not(".loading")
32+
self.load_project_creation_page()
33+
self.browser.click("[data-test-id='platform-javascript-react']")
4034
self.browser.click('[data-test-id="create-project"]')
35+
self.browser.wait_until(xpath="//h2[text()='Configure React SDK']")
4136

42-
self.browser.wait_until_not(".loading")
43-
self.browser.wait_until("h2")
44-
45-
title = self.browser.find_element(by=By.CSS_SELECTOR, value="h2")
46-
47-
assert "React" in title.text
37+
def test_project_deletion_on_going_back(self):
38+
self.create_team(organization=self.org, name="team three")
39+
self.load_project_creation_page()
40+
self.browser.click("[data-test-id='platform-php-laravel']")
41+
self.browser.click('[data-test-id="create-project"]')
42+
self.browser.wait_until(xpath="//h2[text()='Configure Laravel SDK']")
43+
project1 = Project.objects.get(organization=self.org, slug="php-laravel")
44+
self.browser.click('[aria-label="Back to Platform Selection"]')
45+
self.browser.click("[data-test-id='platform-javascript-nextjs']")
46+
self.browser.click('[data-test-id="create-project"]')
47+
self.browser.wait_until(xpath="//h2[text()='Configure Next.js SDK']")
48+
project2 = Project.objects.get(organization=self.org, slug="javascript-nextjs")
49+
self.browser.back()
50+
self.browser.get("/organizations/%s/projects/" % self.org.slug)
51+
self.browser.wait_until(xpath='//h1[text()="Remain Calm"]')
52+
assert_existing_projects_status(self.org, [], [project1.id, project2.id])

tests/acceptance/test_onboarding.py

+55-39
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
from selenium.common.exceptions import TimeoutException
1+
import pytest
22

33
from sentry.models.project import Project
4+
from sentry.testutils.asserts import assert_existing_projects_status
45
from sentry.testutils.cases import AcceptanceTestCase
56
from sentry.testutils.silo import no_silo_test
6-
from sentry.utils.retries import TimedRetryPolicy
7+
8+
pytestmark = pytest.mark.sentry_metrics
79

810

911
@no_silo_test
@@ -18,55 +20,69 @@ def setUp(self):
1820
)
1921
self.login_as(self.user)
2022

21-
def test_onboarding(self):
23+
def start_onboarding(self):
2224
self.browser.get("/onboarding/%s/" % self.org.slug)
23-
24-
# Welcome step
2525
self.browser.wait_until('[data-test-id="onboarding-step-welcome"]')
2626
self.browser.click('[aria-label="Start"]')
27-
28-
# Platform selection step
2927
self.browser.wait_until('[data-test-id="onboarding-step-select-platform"]')
3028

31-
@TimedRetryPolicy.wrap(timeout=5, exceptions=((TimeoutException,)))
32-
def click_platform_select_name(browser):
33-
# Select and create React project
34-
browser.click('[data-test-id="platform-javascript-react"]')
35-
36-
# Project getting started loads
37-
browser.wait_until(xpath='//h2[text()="Configure React SDK"]')
38-
39-
click_platform_select_name(self.browser)
40-
41-
# Verify project was created for org
42-
project = Project.objects.get(organization=self.org)
29+
def test_onboarding_happy_path(self):
30+
self.start_onboarding()
31+
self.browser.click('[data-test-id="platform-javascript-react"]')
32+
self.browser.wait_until(xpath='//h2[text()="Configure React SDK"]')
33+
project = Project.objects.get(organization=self.org, slug="javascript-react")
4334
assert project.name == "javascript-react"
4435
assert project.platform == "javascript-react"
45-
46-
# Click on back button
36+
assert_existing_projects_status(self.org, [project.id], [])
37+
38+
def test_project_deletion_on_going_back(self):
39+
self.start_onboarding()
40+
self.browser.click('[data-test-id="platform-javascript-nextjs"]')
41+
self.browser.wait_until(xpath='//h2[text()="Configure Next.js SDK"]')
42+
project1 = Project.objects.get(organization=self.org, slug="javascript-nextjs")
43+
assert project1.name == "javascript-nextjs"
44+
assert project1.platform == "javascript-nextjs"
4745
self.browser.click('[aria-label="Back"]')
48-
49-
# Assert no deletion confirm dialog is shown
50-
assert not self.browser.element_exists("[role='dialog']")
51-
52-
# Platform selection step
53-
self.browser.wait_until('[data-test-id="onboarding-step-select-platform"]')
54-
55-
# Select generic platform
46+
self.browser.click('[data-test-id="platform-javascript-react"]')
47+
self.browser.wait_until(xpath='//h2[text()="Configure React SDK"]')
48+
project2 = Project.objects.get(organization=self.org, slug="javascript-react")
49+
assert project2.name == "javascript-react"
50+
assert project2.platform == "javascript-react"
51+
self.browser.back()
52+
self.browser.click(xpath='//a[text()="Skip Onboarding"]')
53+
self.browser.get("/organizations/%s/projects/" % self.org.slug)
54+
self.browser.wait_until(xpath='//h1[text()="Remain Calm"]')
55+
assert_existing_projects_status(self.org, [], [project1.id, project2.id])
56+
57+
def test_framework_modal_open_by_selecting_vanilla_platform(self):
58+
self.start_onboarding()
5659
self.browser.click('[data-test-id="platform-javascript"]')
57-
58-
# Modal is shown prompting to select a framework
5960
self.browser.wait_until(xpath='//h6[text()="Do you use a framework?"]')
60-
61-
# Close modal
6261
self.browser.click('[aria-label="Close Modal"]')
63-
64-
# Platform is not selected
6562
assert not self.browser.element_exists('[aria-label="Clear"]')
66-
67-
# Click again on the modal and continue with the vanilla project
6863
self.browser.click('[data-test-id="platform-javascript"]')
6964
self.browser.click('[aria-label="Configure SDK"]')
70-
71-
# Project getting started loads
7265
self.browser.wait_until(xpath='//h2[text()="Configure Browser JavaScript SDK"]')
66+
project = Project.objects.get(organization=self.org, slug="javascript")
67+
assert project.name == "javascript"
68+
assert project.platform == "javascript"
69+
assert_existing_projects_status(self.org, [project.id], [])
70+
71+
def test_create_delete_create_same_platform(self):
72+
"This test ensures that the regression fixed in PR https://github.com/getsentry/sentry/pull/87869 no longer occurs."
73+
self.start_onboarding()
74+
self.browser.click('[data-test-id="platform-javascript-nextjs"]')
75+
self.browser.wait_until(xpath='//h2[text()="Configure Next.js SDK"]')
76+
project1 = Project.objects.get(organization=self.org, slug="javascript-nextjs")
77+
assert project1.name == "javascript-nextjs"
78+
assert project1.platform == "javascript-nextjs"
79+
self.browser.click('[aria-label="Back"]')
80+
self.browser.click('[data-test-id="platform-javascript-nextjs"]')
81+
self.browser.wait_until(xpath='//h2[text()="Configure Next.js SDK"]')
82+
project2 = Project.objects.get(organization=self.org, slug="javascript-nextjs")
83+
assert project2.name == "javascript-nextjs"
84+
assert project2.platform == "javascript-nextjs"
85+
self.browser.click(xpath='//a[text()="Skip Onboarding"]')
86+
self.browser.get("/organizations/%s/projects/" % self.org.slug)
87+
self.browser.wait_until("[data-test-id='javascript-nextjs']")
88+
assert_existing_projects_status(self.org, [project2.id], [project1.id])

0 commit comments

Comments
 (0)