import {ProjectFixture} from 'sentry-fixture/project';
import {ProjectKeysFixture} from 'sentry-fixture/projectKeys';
import {initializeOrg} from 'sentry-test/initializeOrg';
import {
render,
renderGlobalModal,
screen,
userEvent,
} from 'sentry-test/reactTestingLibrary';
import {OnboardingContextProvider} from 'sentry/components/onboarding/onboardingContext';
import * as useRecentCreatedProjectHook from 'sentry/components/onboarding/useRecentCreatedProject';
import type {PlatformKey, Project} from 'sentry/types';
import {OnboardingProjectStatus} from 'sentry/types';
import Onboarding from 'sentry/views/onboarding/onboarding';
describe('Onboarding', function () {
afterEach(function () {
MockApiClient.clearMockResponses();
});
it('renders the welcome page', function () {
const routeParams = {
step: 'welcome',
};
const {routerProps, routerContext, organization} = initializeOrg({
router: {
params: routeParams,
},
});
render(
,
{
context: routerContext,
organization,
}
);
expect(screen.getByLabelText('Start')).toBeInTheDocument();
expect(screen.getByLabelText('Invite Team')).toBeInTheDocument();
});
it('renders the select platform step', async function () {
const routeParams = {
step: 'select-platform',
};
const {routerProps, routerContext, organization} = initializeOrg({
router: {
params: routeParams,
},
});
render(
,
{
context: routerContext,
organization,
}
);
expect(
await screen.findByText('Select the platform you want to monitor')
).toBeInTheDocument();
});
it('renders the setup docs step', async function () {
const nextJsProject: Project = ProjectFixture({
platform: 'javascript-nextjs',
id: '2',
slug: 'javascript-nextjs-slug',
});
const routeParams = {
step: 'setup-docs',
};
const {routerProps, routerContext, organization} = initializeOrg({
router: {
params: routeParams,
},
});
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/sdks/`,
body: {},
});
MockApiClient.addMockResponse({
url: `/projects/${organization.slug}/${nextJsProject.slug}/docs/javascript-nextjs-with-error-monitoring/`,
body: null,
});
MockApiClient.addMockResponse({
url: `/projects/org-slug/${nextJsProject.slug}/`,
body: [nextJsProject],
});
MockApiClient.addMockResponse({
url: `/projects/${organization.slug}/${nextJsProject.slug}/issues/`,
body: [],
});
MockApiClient.addMockResponse({
url: `/projects/org-slug/${nextJsProject.slug}/keys/`,
method: 'GET',
body: [ProjectKeysFixture()[0]],
});
jest
.spyOn(useRecentCreatedProjectHook, 'useRecentCreatedProject')
.mockImplementation(() => {
return {
...nextJsProject,
firstError: false,
firstTransaction: false,
hasReplays: false,
hasSessions: false,
olderThanOneHour: false,
firstIssue: undefined,
};
});
render(
,
{
context: routerContext,
organization,
}
);
expect(await screen.findByText('Configure Next.js SDK')).toBeInTheDocument();
});
it('renders SDK data removal modal when going back', async function () {
const reactProject: Project = ProjectFixture({
platform: 'javascript-react',
id: '2',
slug: 'javascript-react-slug',
firstTransactionEvent: false,
firstEvent: null,
hasReplays: false,
hasSessions: false,
});
const routeParams = {
step: 'setup-docs',
};
const {routerProps, routerContext, organization} = initializeOrg({
router: {
params: routeParams,
},
});
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/sdks/`,
body: {},
});
MockApiClient.addMockResponse({
url: `/projects/org-slug/${reactProject.slug}/`,
body: [reactProject],
});
MockApiClient.addMockResponse({
url: `/projects/org-slug/${reactProject.slug}/keys/`,
method: 'GET',
body: [ProjectKeysFixture()[0]],
});
MockApiClient.addMockResponse({
url: `/projects/${organization.slug}/${reactProject.slug}/issues/`,
body: [],
});
jest
.spyOn(useRecentCreatedProjectHook, 'useRecentCreatedProject')
.mockImplementation(() => {
return {
...reactProject,
firstError: false,
firstTransaction: false,
hasReplays: false,
hasSessions: false,
olderThanOneHour: false,
firstIssue: undefined,
};
});
render(
,
{
context: routerContext,
organization,
}
);
// Await for the docs to be loaded
await screen.findByText('Configure React SDK');
renderGlobalModal();
// Click on back button
await userEvent.click(screen.getByRole('button', {name: 'Back'}));
// Await for the modal to be open
expect(
await screen.findByText(/Are you sure you want to head back?/)
).toBeInTheDocument();
// Close modal
await userEvent.click(screen.getByRole('button', {name: 'Cancel'}));
});
it('does not render SDK data removal modal when going back', async function () {
const reactProject: Project = ProjectFixture({
platform: 'javascript-react',
id: '2',
slug: 'javascript-react-slug',
});
const routeParams = {
step: 'setup-docs',
};
const {routerProps, routerContext, organization} = initializeOrg({
router: {
params: routeParams,
},
});
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/sdks/`,
body: {},
});
MockApiClient.addMockResponse({
url: `/projects/org-slug/${reactProject.slug}/`,
body: [reactProject],
});
MockApiClient.addMockResponse({
url: `/projects/org-slug/${reactProject.slug}/keys/`,
method: 'GET',
body: [ProjectKeysFixture()[0]],
});
MockApiClient.addMockResponse({
url: `/projects/${organization.slug}/${reactProject.slug}/issues/`,
body: [],
});
jest
.spyOn(useRecentCreatedProjectHook, 'useRecentCreatedProject')
.mockImplementation(() => {
return {
...reactProject,
firstError: false,
firstTransaction: false,
hasReplays: false,
hasSessions: true,
olderThanOneHour: false,
firstIssue: undefined,
};
});
render(
,
{
context: routerContext,
organization,
}
);
// Await for the docs to be loaded
await screen.findByText('Configure React SDK');
renderGlobalModal();
// Click on back button
await userEvent.click(screen.getByRole('button', {name: 'Back'}));
// Await for the modal to be open
expect(
screen.queryByText(/Are you sure you want to head back?/)
).not.toBeInTheDocument();
});
it('renders framework selection modal if vanilla js is selected', async function () {
const routeParams = {
step: 'select-platform',
};
const {routerProps, routerContext, organization} = initializeOrg({
organization: {
features: ['onboarding-sdk-selection'],
},
router: {
params: routeParams,
},
});
render(
,
{
context: routerContext,
organization,
}
);
renderGlobalModal();
// Select the JavaScript platform
await userEvent.click(screen.getByTestId('platform-javascript'));
// Click on 'configure SDK' button
await userEvent.click(screen.getByRole('button', {name: 'Configure SDK'}));
// Modal is open
await screen.findByText('Do you use a framework?');
// Close modal
await userEvent.click(screen.getByRole('button', {name: 'Skip'}));
});
it('does not render framework selection modal if vanilla js is NOT selected', async function () {
const routeParams = {
step: 'select-platform',
};
const {routerProps, routerContext, organization} = initializeOrg({
organization: {
features: ['onboarding-sdk-selection'],
},
router: {
params: routeParams,
},
});
render(
,
{
context: routerContext,
organization,
}
);
// Select the React platform
await userEvent.click(screen.getByTestId('platform-javascript-vue'));
// Click on 'configure SDK' button
await userEvent.click(screen.getByRole('button', {name: 'Configure SDK'}));
// Modal shall not be open
expect(screen.queryByText('Do you use a framework?')).not.toBeInTheDocument();
});
});