Skip to content

Commit 1092d77

Browse files
authored
chore(solid): Add e2e test app for solid sdk without solidrouter (#12661)
Moved the existing app to `solid-solidrouter` and created a new for `solid` without using any of the solid router integration.
1 parent 8c94548 commit 1092d77

28 files changed

+556
-94
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
25+
/test-results/
26+
/playwright-report/
27+
/playwright/.cache/
28+
29+
!*.d.ts
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@sentry:registry=http://127.0.0.1:4873
2+
@sentry-internal:registry=http://127.0.0.1:4873
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## Usage
2+
3+
Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.
4+
5+
This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
6+
be removed once you clone a template.
7+
8+
```bash
9+
$ npm install # or pnpm install or yarn install
10+
```
11+
12+
## Exploring the template
13+
14+
This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
15+
together to parallelize data fetching tied to a route via the `.data.ts` pattern.
16+
17+
You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)
18+
19+
### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)
20+
21+
## Available Scripts
22+
23+
In the project directory, you can run:
24+
25+
### `npm run dev` or `npm start`
26+
27+
Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
28+
29+
The page will reload if you make edits.<br>
30+
31+
### `npm run build`
32+
33+
Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
34+
build for the best performance.
35+
36+
The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!
37+
38+
## Deployment
39+
40+
You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<meta name="theme-color" content="#000000" />
7+
<title>Solid App</title>
8+
</head>
9+
<body>
10+
<noscript>You need to enable JavaScript to run this app.</noscript>
11+
<div id="root"></div>
12+
13+
<script src="/src/index.tsx" type="module"></script>
14+
</body>
15+
</html>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "solid-solidrouter",
3+
"version": "0.0.0",
4+
"description": "",
5+
"scripts": {
6+
"build": "vite build",
7+
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
8+
"dev": "vite",
9+
"preview": "vite preview",
10+
"start": "vite",
11+
"test:prod": "TEST_ENV=production playwright test",
12+
"test:build": "pnpm install && npx playwright install && pnpm build",
13+
"test:assert": "pnpm test:prod"
14+
},
15+
"license": "MIT",
16+
"devDependencies": {
17+
"@playwright/test": "^1.44.1",
18+
"@sentry-internal/test-utils": "link:../../../test-utils",
19+
"@sentry/types": "latest || *",
20+
"@sentry/utils": "latest || *",
21+
"autoprefixer": "^10.4.17",
22+
"postcss": "^8.4.33",
23+
"solid-devtools": "^0.29.2",
24+
"tailwindcss": "^3.4.1",
25+
"vite": "^5.0.11",
26+
"vite-plugin-solid": "^2.8.2"
27+
},
28+
"dependencies": {
29+
"@solidjs/router": "^0.13.5",
30+
"solid-js": "^1.8.11",
31+
"@sentry/solid": "latest || *"
32+
}
33+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { getPlaywrightConfig } from '@sentry-internal/test-utils';
2+
3+
const config = getPlaywrightConfig({
4+
startCommand: 'pnpm preview --port 3030',
5+
port: 3030,
6+
});
7+
8+
export default config;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* @refresh reload */
2+
import * as Sentry from '@sentry/solid';
3+
import { solidRouterBrowserTracingIntegration, withSentryRouterRouting } from '@sentry/solid/solidrouter';
4+
import { Router } from '@solidjs/router';
5+
import { render } from 'solid-js/web';
6+
import './index.css';
7+
import PageRoot from './pageroot';
8+
import { routes } from './routes';
9+
10+
Sentry.init({
11+
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
12+
debug: true,
13+
environment: 'qa', // dynamic sampling bias to keep transactions
14+
integrations: [solidRouterBrowserTracingIntegration()],
15+
release: 'e2e-test',
16+
tunnel: 'http://localhost:3031/', // proxy server
17+
tracesSampleRate: 1.0,
18+
});
19+
20+
const SentryRouter = withSentryRouterRouting(Router);
21+
22+
render(() => <SentryRouter root={PageRoot}>{routes}</SentryRouter>, document.getElementById('root'));
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { A } from '@solidjs/router';
2+
3+
export default function PageRoot(props) {
4+
return (
5+
<>
6+
<nav class="bg-gray-200 text-gray-900 px-4">
7+
<ul class="flex items-center">
8+
<li class="py-2 px-4">
9+
<A href="/" class="no-underline hover:underline">
10+
Home
11+
</A>
12+
</li>
13+
<li>
14+
<A href="/error-boundary-example" class="no-underline hover:underline">
15+
Error Boundary Example
16+
</A>
17+
</li>
18+
<li class="py-2 px-4">
19+
<A href="/error" class="no-underline hover:underline">
20+
Error
21+
</A>
22+
</li>
23+
</ul>
24+
</nav>
25+
<main>{props.children}</main>
26+
</>
27+
);
28+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { lazy } from 'solid-js';
2+
3+
import ErrorBoundaryExample from './pages/errorboundaryexample';
4+
import Home from './pages/home';
5+
6+
export const routes = [
7+
{
8+
path: '/',
9+
component: Home,
10+
},
11+
{
12+
path: '/user/:id',
13+
component: lazy(() => import('./pages/user')),
14+
},
15+
{
16+
path: '/error-boundary-example',
17+
component: ErrorBoundaryExample,
18+
},
19+
{
20+
path: '**',
21+
component: lazy(() => import('./errors/404')),
22+
},
23+
];
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { startEventProxyServer } from '@sentry-internal/test-utils';
2+
3+
startEventProxyServer({
4+
port: 3031,
5+
proxyServerName: 'solid',
6+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { Config } from 'tailwindcss';
2+
3+
const config: Config = {
4+
content: ['./src/**/*.{js,jsx,ts,tsx}'],
5+
theme: {
6+
extend: {},
7+
},
8+
plugins: [],
9+
};
10+
11+
export default config;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { expect, test } from '@playwright/test';
2+
import { waitForError } from '@sentry-internal/test-utils';
3+
4+
test('captures an exception', async ({ page }) => {
5+
const errorEventPromise = waitForError('solid', errorEvent => {
6+
return !errorEvent.type && errorEvent.transaction === '/error-boundary-example';
7+
});
8+
9+
const [, errorEvent] = await Promise.all([page.goto('/error-boundary-example'), errorEventPromise]);
10+
11+
expect(errorEvent).toMatchObject({
12+
exception: {
13+
values: [
14+
{
15+
type: 'ReferenceError',
16+
value: 'NonExistentComponent is not defined',
17+
mechanism: {
18+
type: 'generic',
19+
handled: true,
20+
},
21+
},
22+
],
23+
},
24+
transaction: '/error-boundary-example',
25+
});
26+
});
27+
28+
test('captures a second exception after resetting the boundary', async ({ page }) => {
29+
const firstErrorEventPromise = waitForError('solid', errorEvent => {
30+
return !errorEvent.type && errorEvent.transaction === '/error-boundary-example';
31+
});
32+
33+
const [, firstErrorEvent] = await Promise.all([page.goto('/error-boundary-example'), firstErrorEventPromise]);
34+
35+
expect(firstErrorEvent).toMatchObject({
36+
exception: {
37+
values: [
38+
{
39+
type: 'ReferenceError',
40+
value: 'NonExistentComponent is not defined',
41+
mechanism: {
42+
type: 'generic',
43+
handled: true,
44+
},
45+
},
46+
],
47+
},
48+
transaction: '/error-boundary-example',
49+
});
50+
51+
const secondErrorEventPromise = waitForError('solid', errorEvent => {
52+
return !errorEvent.type && errorEvent.transaction === '/error-boundary-example';
53+
});
54+
55+
const [, secondErrorEvent] = await Promise.all([
56+
page.locator('#errorBoundaryResetBtn').click(),
57+
await secondErrorEventPromise,
58+
]);
59+
60+
expect(secondErrorEvent).toMatchObject({
61+
exception: {
62+
values: [
63+
{
64+
type: 'ReferenceError',
65+
value: 'NonExistentComponent is not defined',
66+
mechanism: {
67+
type: 'generic',
68+
handled: true,
69+
},
70+
},
71+
],
72+
},
73+
transaction: '/error-boundary-example',
74+
});
75+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { expect, test } from '@playwright/test';
2+
import { waitForError } from '@sentry-internal/test-utils';
3+
4+
test('sends an error', async ({ page }) => {
5+
const errorPromise = waitForError('solid', async errorEvent => {
6+
return !errorEvent.type && errorEvent.exception?.values?.[0]?.value === 'Error thrown from Solid E2E test app';
7+
});
8+
9+
await Promise.all([page.goto(`/`), page.locator('#errorBtn').click()]);
10+
11+
const error = await errorPromise;
12+
13+
expect(error).toMatchObject({
14+
exception: {
15+
values: [
16+
{
17+
type: 'Error',
18+
value: 'Error thrown from Solid E2E test app',
19+
mechanism: {
20+
type: 'onerror',
21+
handled: false,
22+
},
23+
},
24+
],
25+
},
26+
transaction: '/',
27+
});
28+
});

0 commit comments

Comments
 (0)