Skip to content

Commit da59f96

Browse files
authored
feat(solidjs): Add solid router unit tests (#12374)
1 parent 5229217 commit da59f96

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

packages/solidjs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
},
5353
"devDependencies": {
5454
"@solidjs/testing-library": "0.8.5",
55+
"@solidjs/router": "^0.13.5",
5556
"solid-js": "^1.8.11",
5657
"vite-plugin-solid": "^2.8.2"
5758
},
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import { spanToJSON } from '@sentry/browser';
2+
import {
3+
SEMANTIC_ATTRIBUTE_SENTRY_OP,
4+
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
5+
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
6+
createTransport,
7+
getCurrentScope,
8+
setCurrentClient,
9+
} from '@sentry/core';
10+
import { MemoryRouter, Navigate, Route, createMemoryHistory, useBeforeLeave, useLocation } from '@solidjs/router';
11+
import { render } from '@solidjs/testing-library';
12+
import { vi } from 'vitest';
13+
14+
import { BrowserClient } from '../src';
15+
import { solidRouterBrowserTracingIntegration, withSentryRouterRouting } from '../src/solidrouter';
16+
17+
// solid router uses `window.scrollTo` when navigating
18+
vi.spyOn(global, 'scrollTo').mockImplementation(() => {});
19+
20+
const renderRouter = (SentryRouter, history) =>
21+
render(() => (
22+
<SentryRouter history={history}>
23+
<Route path="/" component={() => <div>Home</div>} />
24+
<Route path="/about">
25+
<Route path="/" component={() => <div>About</div>} />
26+
<Route path="/us" component={() => <div>us</div>} />
27+
</Route>
28+
<Route path="/user">
29+
<Route path="/:id" component={() => <div>User</div>} />
30+
<Route path="/:id/post/:postId" component={() => <div>Post</div>} />
31+
</Route>
32+
<Route path="/navigate-to-about" component={() => <Navigate href="/about" />} />
33+
<Route path="/navigate-to-about-us" component={() => <Navigate href="/about/us" />} />
34+
<Route path="/navigate-to-user" component={() => <Navigate href="/user/5" />} />
35+
<Route path="/navigate-to-user-post" component={() => <Navigate href="/user/5/post/12" />} />
36+
</SentryRouter>
37+
));
38+
39+
describe('solidRouterBrowserTracingIntegration', () => {
40+
function createMockBrowserClient(): BrowserClient {
41+
return new BrowserClient({
42+
integrations: [],
43+
tracesSampleRate: 1,
44+
transport: () => createTransport({ recordDroppedEvent: () => undefined }, _ => Promise.resolve({})),
45+
stackParser: () => [],
46+
});
47+
}
48+
49+
beforeEach(() => {
50+
vi.clearAllMocks();
51+
getCurrentScope().setClient(undefined);
52+
});
53+
54+
it('starts a pageload span', () => {
55+
const spanStartMock = vi.fn();
56+
57+
const client = createMockBrowserClient();
58+
setCurrentClient(client);
59+
60+
client.on('spanStart', span => spanStartMock(spanToJSON(span)));
61+
client.addIntegration(solidRouterBrowserTracingIntegration({ useBeforeLeave, useLocation }));
62+
63+
const history = createMemoryHistory();
64+
history.set({ value: '/' });
65+
66+
expect(spanStartMock).toHaveBeenCalledWith(
67+
expect.objectContaining({
68+
op: 'pageload',
69+
description: '/',
70+
data: expect.objectContaining({
71+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
72+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
73+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',
74+
}),
75+
}),
76+
);
77+
});
78+
79+
it('skips pageload span, with `instrumentPageLoad: false`', () => {
80+
const spanStartMock = vi.fn();
81+
82+
const client = createMockBrowserClient();
83+
setCurrentClient(client);
84+
85+
client.on('spanStart', span => spanStartMock(spanToJSON(span)));
86+
client.addIntegration(
87+
solidRouterBrowserTracingIntegration({
88+
instrumentPageLoad: false,
89+
useBeforeLeave,
90+
useLocation,
91+
}),
92+
);
93+
const SentryRouter = withSentryRouterRouting(MemoryRouter);
94+
95+
const history = createMemoryHistory();
96+
history.set({ value: '/' });
97+
98+
renderRouter(SentryRouter, history);
99+
100+
expect(spanStartMock).not.toHaveBeenCalledWith(
101+
expect.objectContaining({
102+
op: 'pageload',
103+
description: '/',
104+
data: expect.objectContaining({
105+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
106+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
107+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',
108+
}),
109+
}),
110+
);
111+
});
112+
113+
it.each([
114+
['', '/navigate-to-about', '/about'],
115+
['for nested navigation', '/navigate-to-about-us', '/about/us'],
116+
['for navigation with param', '/navigate-to-user', '/user/5'],
117+
['for nested navigation with params', '/navigate-to-user-post', '/user/5/post/12'],
118+
])('starts a navigation span %s', (_itDescription, navigationPath, path) => {
119+
const spanStartMock = vi.fn();
120+
121+
const client = createMockBrowserClient();
122+
setCurrentClient(client);
123+
124+
client.on('spanStart', span => {
125+
spanStartMock(spanToJSON(span));
126+
});
127+
client.addIntegration(solidRouterBrowserTracingIntegration({ useBeforeLeave, useLocation }));
128+
const SentryRouter = withSentryRouterRouting(MemoryRouter);
129+
130+
const history = createMemoryHistory();
131+
history.set({ value: navigationPath });
132+
133+
renderRouter(SentryRouter, history);
134+
135+
expect(spanStartMock).toHaveBeenCalledWith(
136+
expect.objectContaining({
137+
op: 'navigation',
138+
description: path,
139+
data: expect.objectContaining({
140+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
141+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
142+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.solidjs.solidrouter',
143+
}),
144+
}),
145+
);
146+
});
147+
148+
it('skips navigation span, with `instrumentNavigation: false`', () => {
149+
const spanStartMock = vi.fn();
150+
151+
const client = createMockBrowserClient();
152+
setCurrentClient(client);
153+
154+
client.on('spanStart', span => spanStartMock(spanToJSON(span)));
155+
client.addIntegration(
156+
solidRouterBrowserTracingIntegration({
157+
instrumentNavigation: false,
158+
useBeforeLeave,
159+
useLocation,
160+
}),
161+
);
162+
const SentryRouter = withSentryRouterRouting(MemoryRouter);
163+
164+
const history = createMemoryHistory();
165+
history.set({ value: '/navigate-to-about' });
166+
167+
renderRouter(SentryRouter, history);
168+
169+
expect(spanStartMock).not.toHaveBeenCalledWith(
170+
expect.objectContaining({
171+
op: 'navigation',
172+
description: '/about',
173+
data: expect.objectContaining({
174+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
175+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
176+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.solidjs.solidrouter',
177+
}),
178+
}),
179+
);
180+
});
181+
182+
it("updates the scope's `transactionName` on a navigation", () => {
183+
const spanStartMock = vi.fn();
184+
185+
const client = createMockBrowserClient();
186+
setCurrentClient(client);
187+
188+
client.on('spanStart', span => {
189+
spanStartMock(spanToJSON(span));
190+
});
191+
client.addIntegration(solidRouterBrowserTracingIntegration({ useBeforeLeave, useLocation }));
192+
const SentryRouter = withSentryRouterRouting(MemoryRouter);
193+
194+
const history = createMemoryHistory();
195+
history.set({ value: '/navigate-to-about' });
196+
197+
renderRouter(SentryRouter, history);
198+
199+
expect(getCurrentScope().getScopeData()?.transactionName).toBe('/about');
200+
});
201+
});

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7768,6 +7768,11 @@
77687768
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
77697769
integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
77707770

7771+
"@solidjs/router@^0.13.5":
7772+
version "0.13.5"
7773+
resolved "https://registry.yarnpkg.com/@solidjs/router/-/router-0.13.5.tgz#62ee37f63d2b5f74937903d64d04ec9a2b4223cf"
7774+
integrity sha512-I/bR5ZHCz2Dx80qL+6uGwSdclqXRqoT49SJ5cvLbOuT3HnYysSIxSfULCTWUMLFVcgPh5GrdHV6KwEoyrbPZZA==
7775+
77717776
"@solidjs/[email protected]":
77727777
version "0.8.5"
77737778
resolved "https://registry.yarnpkg.com/@solidjs/testing-library/-/testing-library-0.8.5.tgz#97061b2286d8641bd43bf474e624c3bb47e486a6"

0 commit comments

Comments
 (0)