Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts
40 changes: 40 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
## Usage

Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.

This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
be removed once you clone a template.

```bash
$ npm install # or pnpm install or yarn install
```

## Exploring the template

This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
together to parallelize data fetching tied to a route via the `.data.ts` pattern.

You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev` or `npm start`

Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.<br>

### `npm run build`

Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
build for the best performance.

The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!

## Deployment

You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
15 changes: 15 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
{
"name": "solid-static",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "vite build",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"dev": "vite",
"preview": "vite preview",
"start": "vite",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test:prod"
},
"license": "MIT",
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.33",
"solid-devtools": "^0.29.2",
"tailwindcss": "^3.4.1",
"vite": "^5.4.11",
"vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"solid-js": "^1.8.18",
"@sentry/solid": "file:../../packed/sentry-solid-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'pnpm preview --port 3030',
port: 3030,
});

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
module.exports={
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
import * as Sentry from '@sentry/solid';
import { ErrorBoundary, createSignal, onMount } from 'solid-js';

const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);

const [count, setCount] = createSignal(1);
const [caughtError, setCaughtError] = createSignal(false);

export default function App() {
return (
<SampleErrorBoundary>
{caughtError() && <Throw error={`Error ${count()} thrown from Sentry ErrorBoundary in Solid E2E test app`} />}
<section class="bg-gray-100 text-gray-700 p-8">
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="caughtErrorBtn"
onClick={() => setCaughtError(true)}
>
Throw caught error
</button>
</div>
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="errorBtn"
onClick={() => {
throw new Error('Error thrown from Solid E2E test app');
}}
>
Throw uncaught error
</button>
</div>
</section>
</SampleErrorBoundary>
);
}

function Throw(props) {
onMount(() => {
throw new Error(props.error);
});
return null;
}

function SampleErrorBoundary(props) {
return (
<SentryErrorBoundary
fallback={(error, reset) => (
<section class="bg-gray-100 text-gray-700 p-8">
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
<div class="flex items-center space-x-2 mb-4">
<code>{error.message}</code>
</div>
<button
id="errorBoundaryResetBtn"
class="border rounded-lg px-2 border-gray-900"
onClick={() => {
setCount(count() + 1);
setCaughtError(false);
reset();
}}
>
Reset
</button>
</section>
)}
>
{props.children}
</SentryErrorBoundary>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/* @refresh reload */
import * as Sentry from '@sentry/solid';
import { render } from 'solid-js/web';
import App from './app';
import './index.css';

Sentry.init({
traceLifecycle: 'static',
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
debug: true,
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
release: 'e2e-test',
tunnel: 'http://localhost:3031/', // proxy server
tracesSampleRate: 1.0,
});

render(() => <App />, document.getElementById('root'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import { A } from '@solidjs/router';

export default function PageRoot(props) {
return (
<>
<nav class="bg-gray-200 text-gray-900 px-4">
<ul class="flex items-center">
<li class="py-2 px-4">
<A href="/" class="no-underline hover:underline">
Home
</A>
</li>
<li>
<A href="/error-boundary-example" class="no-underline hover:underline">
Error Boundary Example
</A>
</li>
<li class="py-2 px-4">
<A href="/error" class="no-underline hover:underline">
Error
</A>
</li>
</ul>
</nav>
<main>{props.children}</main>
</>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { lazy } from 'solid-js';

import ErrorBoundaryExample from './pages/errorboundaryexample';
import Home from './pages/home';

export const routes = [
{
path: '/',
component: Home,
},
{
path: '/user/:id',
component: lazy(() => import('./pages/user')),
},
{
path: '/error-boundary-example',
component: ErrorBoundaryExample,
},
{
path: '**',
component: lazy(() => import('./errors/404')),
},
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'solid-static',
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
import type { Config } from 'tailwindcss';

const config: Config = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('captures an exception', async ({ page }) => {
const errorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , errorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
errorEventPromise,
]);

expect(errorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});

test('captures a second exception after resetting the boundary', async ({ page }) => {
const firstErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , firstErrorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
firstErrorEventPromise,
]);

expect(firstErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});

const secondErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , secondErrorEvent] = await Promise.all([
page.locator('#errorBoundaryResetBtn').click(),
page.locator('#caughtErrorBtn').click(),
await secondErrorEventPromise,
]);

expect(secondErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts
40 changes: 40 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
## Usage

Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.

This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
be removed once you clone a template.

```bash
$ npm install # or pnpm install or yarn install
```

## Exploring the template

This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
together to parallelize data fetching tied to a route via the `.data.ts` pattern.

You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev` or `npm start`

Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.<br>

### `npm run build`

Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
build for the best performance.

The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!

## Deployment

You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
15 changes: 15 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
{
"name": "solid-static",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "vite build",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"dev": "vite",
"preview": "vite preview",
"start": "vite",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test:prod"
},
"license": "MIT",
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.33",
"solid-devtools": "^0.29.2",
"tailwindcss": "^3.4.1",
"vite": "^5.4.11",
"vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"solid-js": "^1.8.18",
"@sentry/solid": "file:../../packed/sentry-solid-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'pnpm preview --port 3030',
port: 3030,
});

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
module.exports={
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
import * as Sentry from '@sentry/solid';
import { ErrorBoundary, createSignal, onMount } from 'solid-js';

const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);

const [count, setCount] = createSignal(1);
const [caughtError, setCaughtError] = createSignal(false);

export default function App() {
return (
<SampleErrorBoundary>
{caughtError() && <Throw error={`Error ${count()} thrown from Sentry ErrorBoundary in Solid E2E test app`} />}
<section class="bg-gray-100 text-gray-700 p-8">
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="caughtErrorBtn"
onClick={() => setCaughtError(true)}
>
Throw caught error
</button>
</div>
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="errorBtn"
onClick={() => {
throw new Error('Error thrown from Solid E2E test app');
}}
>
Throw uncaught error
</button>
</div>
</section>
</SampleErrorBoundary>
);
}

function Throw(props) {
onMount(() => {
throw new Error(props.error);
});
return null;
}

function SampleErrorBoundary(props) {
return (
<SentryErrorBoundary
fallback={(error, reset) => (
<section class="bg-gray-100 text-gray-700 p-8">
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
<div class="flex items-center space-x-2 mb-4">
<code>{error.message}</code>
</div>
<button
id="errorBoundaryResetBtn"
class="border rounded-lg px-2 border-gray-900"
onClick={() => {
setCount(count() + 1);
setCaughtError(false);
reset();
}}
>
Reset
</button>
</section>
)}
>
{props.children}
</SentryErrorBoundary>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/* @refresh reload */
import * as Sentry from '@sentry/solid';
import { render } from 'solid-js/web';
import App from './app';
import './index.css';

Sentry.init({
traceLifecycle: 'static',
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
debug: true,
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
release: 'e2e-test',
tunnel: 'http://localhost:3031/', // proxy server
tracesSampleRate: 1.0,
});

render(() => <App />, document.getElementById('root'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import { A } from '@solidjs/router';

export default function PageRoot(props) {
return (
<>
<nav class="bg-gray-200 text-gray-900 px-4">
<ul class="flex items-center">
<li class="py-2 px-4">
<A href="/" class="no-underline hover:underline">
Home
</A>
</li>
<li>
<A href="/error-boundary-example" class="no-underline hover:underline">
Error Boundary Example
</A>
</li>
<li class="py-2 px-4">
<A href="/error" class="no-underline hover:underline">
Error
</A>
</li>
</ul>
</nav>
<main>{props.children}</main>
</>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { lazy } from 'solid-js';

import ErrorBoundaryExample from './pages/errorboundaryexample';
import Home from './pages/home';

export const routes = [
{
path: '/',
component: Home,
},
{
path: '/user/:id',
component: lazy(() => import('./pages/user')),
},
{
path: '/error-boundary-example',
component: ErrorBoundaryExample,
},
{
path: '**',
component: lazy(() => import('./errors/404')),
},
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'solid-static',
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
import type { Config } from 'tailwindcss';

const config: Config = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('captures an exception', async ({ page }) => {
const errorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , errorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
errorEventPromise,
]);

expect(errorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});

test('captures a second exception after resetting the boundary', async ({ page }) => {
const firstErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , firstErrorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
firstErrorEventPromise,
]);

expect(firstErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});

const secondErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , secondErrorEvent] = await Promise.all([
page.locator('#errorBoundaryResetBtn').click(),
page.locator('#caughtErrorBtn').click(),
await secondErrorEventPromise,
]);

expect(secondErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts
40 changes: 40 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
## Usage

Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.

This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
be removed once you clone a template.

```bash
$ npm install # or pnpm install or yarn install
```

## Exploring the template

This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
together to parallelize data fetching tied to a route via the `.data.ts` pattern.

You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev` or `npm start`

Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.<br>

### `npm run build`

Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
build for the best performance.

The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!

## Deployment

You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
15 changes: 15 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
{
"name": "solid-static",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "vite build",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"dev": "vite",
"preview": "vite preview",
"start": "vite",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test:prod"
},
"license": "MIT",
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.33",
"solid-devtools": "^0.29.2",
"tailwindcss": "^3.4.1",
"vite": "^5.4.11",
"vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"solid-js": "^1.8.18",
"@sentry/solid": "file:../../packed/sentry-solid-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'pnpm preview --port 3030',
port: 3030,
});

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
module.exports={
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
import * as Sentry from '@sentry/solid';
import { ErrorBoundary, createSignal, onMount } from 'solid-js';

const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);

const [count, setCount] = createSignal(1);
const [caughtError, setCaughtError] = createSignal(false);

export default function App() {
return (
<SampleErrorBoundary>
{caughtError() && <Throw error={`Error ${count()} thrown from Sentry ErrorBoundary in Solid E2E test app`} />}
<section class="bg-gray-100 text-gray-700 p-8">
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="caughtErrorBtn"
onClick={() => setCaughtError(true)}
>
Throw caught error
</button>
</div>
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="errorBtn"
onClick={() => {
throw new Error('Error thrown from Solid E2E test app');
}}
>
Throw uncaught error
</button>
</div>
</section>
</SampleErrorBoundary>
);
}

function Throw(props) {
onMount(() => {
throw new Error(props.error);
});
return null;
}

function SampleErrorBoundary(props) {
return (
<SentryErrorBoundary
fallback={(error, reset) => (
<section class="bg-gray-100 text-gray-700 p-8">
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
<div class="flex items-center space-x-2 mb-4">
<code>{error.message}</code>
</div>
<button
id="errorBoundaryResetBtn"
class="border rounded-lg px-2 border-gray-900"
onClick={() => {
setCount(count() + 1);
setCaughtError(false);
reset();
}}
>
Reset
</button>
</section>
)}
>
{props.children}
</SentryErrorBoundary>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/* @refresh reload */
import * as Sentry from '@sentry/solid';
import { render } from 'solid-js/web';
import App from './app';
import './index.css';

Sentry.init({
traceLifecycle: 'static',
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
debug: true,
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
release: 'e2e-test',
tunnel: 'http://localhost:3031/', // proxy server
tracesSampleRate: 1.0,
});

render(() => <App />, document.getElementById('root'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import { A } from '@solidjs/router';

export default function PageRoot(props) {
return (
<>
<nav class="bg-gray-200 text-gray-900 px-4">
<ul class="flex items-center">
<li class="py-2 px-4">
<A href="/" class="no-underline hover:underline">
Home
</A>
</li>
<li>
<A href="/error-boundary-example" class="no-underline hover:underline">
Error Boundary Example
</A>
</li>
<li class="py-2 px-4">
<A href="/error" class="no-underline hover:underline">
Error
</A>
</li>
</ul>
</nav>
<main>{props.children}</main>
</>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { lazy } from 'solid-js';

import ErrorBoundaryExample from './pages/errorboundaryexample';
import Home from './pages/home';

export const routes = [
{
path: '/',
component: Home,
},
{
path: '/user/:id',
component: lazy(() => import('./pages/user')),
},
{
path: '/error-boundary-example',
component: ErrorBoundaryExample,
},
{
path: '**',
component: lazy(() => import('./errors/404')),
},
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'solid-static',
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
import type { Config } from 'tailwindcss';

const config: Config = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('captures an exception', async ({ page }) => {
const errorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , errorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
errorEventPromise,
]);

expect(errorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});

test('captures a second exception after resetting the boundary', async ({ page }) => {
const firstErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , firstErrorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
firstErrorEventPromise,
]);

expect(firstErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});

const secondErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , secondErrorEvent] = await Promise.all([
page.locator('#errorBoundaryResetBtn').click(),
page.locator('#caughtErrorBtn').click(),
await secondErrorEventPromise,
]);

expect(secondErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts
40 changes: 40 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
## Usage

Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.

This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
be removed once you clone a template.

```bash
$ npm install # or pnpm install or yarn install
```

## Exploring the template

This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
together to parallelize data fetching tied to a route via the `.data.ts` pattern.

You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev` or `npm start`

Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.<br>

### `npm run build`

Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
build for the best performance.

The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!

## Deployment

You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
15 changes: 15 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
{
"name": "solid-static",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "vite build",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"dev": "vite",
"preview": "vite preview",
"start": "vite",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test:prod"
},
"license": "MIT",
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.33",
"solid-devtools": "^0.29.2",
"tailwindcss": "^3.4.1",
"vite": "^5.4.11",
"vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"solid-js": "^1.8.18",
"@sentry/solid": "file:../../packed/sentry-solid-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'pnpm preview --port 3030',
port: 3030,
});

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
module.exports={
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
import * as Sentry from '@sentry/solid';
import { ErrorBoundary, createSignal, onMount } from 'solid-js';

const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);

const [count, setCount] = createSignal(1);
const [caughtError, setCaughtError] = createSignal(false);

export default function App() {
return (
<SampleErrorBoundary>
{caughtError() && <Throw error={`Error ${count()} thrown from Sentry ErrorBoundary in Solid E2E test app`} />}
<section class="bg-gray-100 text-gray-700 p-8">
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="caughtErrorBtn"
onClick={() => setCaughtError(true)}
>
Throw caught error
</button>
</div>
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="errorBtn"
onClick={() => {
throw new Error('Error thrown from Solid E2E test app');
}}
>
Throw uncaught error
</button>
</div>
</section>
</SampleErrorBoundary>
);
}

function Throw(props) {
onMount(() => {
throw new Error(props.error);
});
return null;
}

function SampleErrorBoundary(props) {
return (
<SentryErrorBoundary
fallback={(error, reset) => (
<section class="bg-gray-100 text-gray-700 p-8">
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
<div class="flex items-center space-x-2 mb-4">
<code>{error.message}</code>
</div>
<button
id="errorBoundaryResetBtn"
class="border rounded-lg px-2 border-gray-900"
onClick={() => {
setCount(count() + 1);
setCaughtError(false);
reset();
}}
>
Reset
</button>
</section>
)}
>
{props.children}
</SentryErrorBoundary>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/* @refresh reload */
import * as Sentry from '@sentry/solid';
import { render } from 'solid-js/web';
import App from './app';
import './index.css';

Sentry.init({
traceLifecycle: 'static',
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
debug: true,
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
release: 'e2e-test',
tunnel: 'http://localhost:3031/', // proxy server
tracesSampleRate: 1.0,
});

render(() => <App />, document.getElementById('root'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import { A } from '@solidjs/router';

export default function PageRoot(props) {
return (
<>
<nav class="bg-gray-200 text-gray-900 px-4">
<ul class="flex items-center">
<li class="py-2 px-4">
<A href="/" class="no-underline hover:underline">
Home
</A>
</li>
<li>
<A href="/error-boundary-example" class="no-underline hover:underline">
Error Boundary Example
</A>
</li>
<li class="py-2 px-4">
<A href="/error" class="no-underline hover:underline">
Error
</A>
</li>
</ul>
</nav>
<main>{props.children}</main>
</>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { lazy } from 'solid-js';

import ErrorBoundaryExample from './pages/errorboundaryexample';
import Home from './pages/home';

export const routes = [
{
path: '/',
component: Home,
},
{
path: '/user/:id',
component: lazy(() => import('./pages/user')),
},
{
path: '/error-boundary-example',
component: ErrorBoundaryExample,
},
{
path: '**',
component: lazy(() => import('./errors/404')),
},
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'solid-static',
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
import type { Config } from 'tailwindcss';

const config: Config = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('captures an exception', async ({ page }) => {
const errorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , errorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
errorEventPromise,
]);

expect(errorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});

test('captures a second exception after resetting the boundary', async ({ page }) => {
const firstErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , firstErrorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
firstErrorEventPromise,
]);

expect(firstErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});

const secondErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , secondErrorEvent] = await Promise.all([
page.locator('#errorBoundaryResetBtn').click(),
page.locator('#caughtErrorBtn').click(),
await secondErrorEventPromise,
]);

expect(secondErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts
40 changes: 40 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
## Usage

Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.

This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
be removed once you clone a template.

```bash
$ npm install # or pnpm install or yarn install
```

## Exploring the template

This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
together to parallelize data fetching tied to a route via the `.data.ts` pattern.

You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev` or `npm start`

Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.<br>

### `npm run build`

Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
build for the best performance.

The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!

## Deployment

You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
15 changes: 15 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
{
"name": "solid-static",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "vite build",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"dev": "vite",
"preview": "vite preview",
"start": "vite",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test:prod"
},
"license": "MIT",
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.33",
"solid-devtools": "^0.29.2",
"tailwindcss": "^3.4.1",
"vite": "^5.4.11",
"vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"solid-js": "^1.8.18",
"@sentry/solid": "file:../../packed/sentry-solid-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'pnpm preview --port 3030',
port: 3030,
});

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
module.exports={
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
import * as Sentry from '@sentry/solid';
import { ErrorBoundary, createSignal, onMount } from 'solid-js';

const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);

const [count, setCount] = createSignal(1);
const [caughtError, setCaughtError] = createSignal(false);

export default function App() {
return (
<SampleErrorBoundary>
{caughtError() && <Throw error={`Error ${count()} thrown from Sentry ErrorBoundary in Solid E2E test app`} />}
<section class="bg-gray-100 text-gray-700 p-8">
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="caughtErrorBtn"
onClick={() => setCaughtError(true)}
>
Throw caught error
</button>
</div>
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="errorBtn"
onClick={() => {
throw new Error('Error thrown from Solid E2E test app');
}}
>
Throw uncaught error
</button>
</div>
</section>
</SampleErrorBoundary>
);
}

function Throw(props) {
onMount(() => {
throw new Error(props.error);
});
return null;
}

function SampleErrorBoundary(props) {
return (
<SentryErrorBoundary
fallback={(error, reset) => (
<section class="bg-gray-100 text-gray-700 p-8">
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
<div class="flex items-center space-x-2 mb-4">
<code>{error.message}</code>
</div>
<button
id="errorBoundaryResetBtn"
class="border rounded-lg px-2 border-gray-900"
onClick={() => {
setCount(count() + 1);
setCaughtError(false);
reset();
}}
>
Reset
</button>
</section>
)}
>
{props.children}
</SentryErrorBoundary>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/* @refresh reload */
import * as Sentry from '@sentry/solid';
import { render } from 'solid-js/web';
import App from './app';
import './index.css';

Sentry.init({
traceLifecycle: 'static',
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
debug: true,
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
release: 'e2e-test',
tunnel: 'http://localhost:3031/', // proxy server
tracesSampleRate: 1.0,
});

render(() => <App />, document.getElementById('root'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import { A } from '@solidjs/router';

export default function PageRoot(props) {
return (
<>
<nav class="bg-gray-200 text-gray-900 px-4">
<ul class="flex items-center">
<li class="py-2 px-4">
<A href="/" class="no-underline hover:underline">
Home
</A>
</li>
<li>
<A href="/error-boundary-example" class="no-underline hover:underline">
Error Boundary Example
</A>
</li>
<li class="py-2 px-4">
<A href="/error" class="no-underline hover:underline">
Error
</A>
</li>
</ul>
</nav>
<main>{props.children}</main>
</>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { lazy } from 'solid-js';

import ErrorBoundaryExample from './pages/errorboundaryexample';
import Home from './pages/home';

export const routes = [
{
path: '/',
component: Home,
},
{
path: '/user/:id',
component: lazy(() => import('./pages/user')),
},
{
path: '/error-boundary-example',
component: ErrorBoundaryExample,
},
{
path: '**',
component: lazy(() => import('./errors/404')),
},
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'solid-static',
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
import type { Config } from 'tailwindcss';

const config: Config = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('captures an exception', async ({ page }) => {
const errorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , errorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
errorEventPromise,
]);

expect(errorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});

test('captures a second exception after resetting the boundary', async ({ page }) => {
const firstErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , firstErrorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
firstErrorEventPromise,
]);

expect(firstErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});

const secondErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , secondErrorEvent] = await Promise.all([
page.locator('#errorBoundaryResetBtn').click(),
page.locator('#caughtErrorBtn').click(),
await secondErrorEventPromise,
]);

expect(secondErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts
40 changes: 40 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
## Usage

Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.

This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
be removed once you clone a template.

```bash
$ npm install # or pnpm install or yarn install
```

## Exploring the template

This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
together to parallelize data fetching tied to a route via the `.data.ts` pattern.

You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev` or `npm start`

Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.<br>

### `npm run build`

Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
build for the best performance.

The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!

## Deployment

You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
15 changes: 15 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
{
"name": "solid-static",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "vite build",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"dev": "vite",
"preview": "vite preview",
"start": "vite",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test:prod"
},
"license": "MIT",
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.33",
"solid-devtools": "^0.29.2",
"tailwindcss": "^3.4.1",
"vite": "^5.4.11",
"vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"solid-js": "^1.8.18",
"@sentry/solid": "file:../../packed/sentry-solid-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'pnpm preview --port 3030',
port: 3030,
});

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
module.exports={
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
import * as Sentry from '@sentry/solid';
import { ErrorBoundary, createSignal, onMount } from 'solid-js';

const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);

const [count, setCount] = createSignal(1);
const [caughtError, setCaughtError] = createSignal(false);

export default function App() {
return (
<SampleErrorBoundary>
{caughtError() && <Throw error={`Error ${count()} thrown from Sentry ErrorBoundary in Solid E2E test app`} />}
<section class="bg-gray-100 text-gray-700 p-8">
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="caughtErrorBtn"
onClick={() => setCaughtError(true)}
>
Throw caught error
</button>
</div>
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="errorBtn"
onClick={() => {
throw new Error('Error thrown from Solid E2E test app');
}}
>
Throw uncaught error
</button>
</div>
</section>
</SampleErrorBoundary>
);
}

function Throw(props) {
onMount(() => {
throw new Error(props.error);
});
return null;
}

function SampleErrorBoundary(props) {
return (
<SentryErrorBoundary
fallback={(error, reset) => (
<section class="bg-gray-100 text-gray-700 p-8">
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
<div class="flex items-center space-x-2 mb-4">
<code>{error.message}</code>
</div>
<button
id="errorBoundaryResetBtn"
class="border rounded-lg px-2 border-gray-900"
onClick={() => {
setCount(count() + 1);
setCaughtError(false);
reset();
}}
>
Reset
</button>
</section>
)}
>
{props.children}
</SentryErrorBoundary>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/* @refresh reload */
import * as Sentry from '@sentry/solid';
import { render } from 'solid-js/web';
import App from './app';
import './index.css';

Sentry.init({
traceLifecycle: 'static',
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
debug: true,
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
release: 'e2e-test',
tunnel: 'http://localhost:3031/', // proxy server
tracesSampleRate: 1.0,
});

render(() => <App />, document.getElementById('root'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import { A } from '@solidjs/router';

export default function PageRoot(props) {
return (
<>
<nav class="bg-gray-200 text-gray-900 px-4">
<ul class="flex items-center">
<li class="py-2 px-4">
<A href="/" class="no-underline hover:underline">
Home
</A>
</li>
<li>
<A href="/error-boundary-example" class="no-underline hover:underline">
Error Boundary Example
</A>
</li>
<li class="py-2 px-4">
<A href="/error" class="no-underline hover:underline">
Error
</A>
</li>
</ul>
</nav>
<main>{props.children}</main>
</>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { lazy } from 'solid-js';

import ErrorBoundaryExample from './pages/errorboundaryexample';
import Home from './pages/home';

export const routes = [
{
path: '/',
component: Home,
},
{
path: '/user/:id',
component: lazy(() => import('./pages/user')),
},
{
path: '/error-boundary-example',
component: ErrorBoundaryExample,
},
{
path: '**',
component: lazy(() => import('./errors/404')),
},
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'solid-static',
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
import type { Config } from 'tailwindcss';

const config: Config = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('captures an exception', async ({ page }) => {
const errorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , errorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
errorEventPromise,
]);

expect(errorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});

test('captures a second exception after resetting the boundary', async ({ page }) => {
const firstErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , firstErrorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
firstErrorEventPromise,
]);

expect(firstErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});

const secondErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , secondErrorEvent] = await Promise.all([
page.locator('#errorBoundaryResetBtn').click(),
page.locator('#caughtErrorBtn').click(),
await secondErrorEventPromise,
]);

expect(secondErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts
40 changes: 40 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
## Usage

Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.

This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
be removed once you clone a template.

```bash
$ npm install # or pnpm install or yarn install
```

## Exploring the template

This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
together to parallelize data fetching tied to a route via the `.data.ts` pattern.

You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev` or `npm start`

Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.<br>

### `npm run build`

Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
build for the best performance.

The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!

## Deployment

You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
15 changes: 15 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
{
"name": "solid-static",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "vite build",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"dev": "vite",
"preview": "vite preview",
"start": "vite",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test:prod"
},
"license": "MIT",
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.33",
"solid-devtools": "^0.29.2",
"tailwindcss": "^3.4.1",
"vite": "^5.4.11",
"vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"solid-js": "^1.8.18",
"@sentry/solid": "file:../../packed/sentry-solid-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'pnpm preview --port 3030',
port: 3030,
});

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
module.exports={
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
import * as Sentry from '@sentry/solid';
import { ErrorBoundary, createSignal, onMount } from 'solid-js';

const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);

const [count, setCount] = createSignal(1);
const [caughtError, setCaughtError] = createSignal(false);

export default function App() {
return (
<SampleErrorBoundary>
{caughtError() && <Throw error={`Error ${count()} thrown from Sentry ErrorBoundary in Solid E2E test app`} />}
<section class="bg-gray-100 text-gray-700 p-8">
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="caughtErrorBtn"
onClick={() => setCaughtError(true)}
>
Throw caught error
</button>
</div>
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="errorBtn"
onClick={() => {
throw new Error('Error thrown from Solid E2E test app');
}}
>
Throw uncaught error
</button>
</div>
</section>
</SampleErrorBoundary>
);
}

function Throw(props) {
onMount(() => {
throw new Error(props.error);
});
return null;
}

function SampleErrorBoundary(props) {
return (
<SentryErrorBoundary
fallback={(error, reset) => (
<section class="bg-gray-100 text-gray-700 p-8">
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
<div class="flex items-center space-x-2 mb-4">
<code>{error.message}</code>
</div>
<button
id="errorBoundaryResetBtn"
class="border rounded-lg px-2 border-gray-900"
onClick={() => {
setCount(count() + 1);
setCaughtError(false);
reset();
}}
>
Reset
</button>
</section>
)}
>
{props.children}
</SentryErrorBoundary>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/* @refresh reload */
import * as Sentry from '@sentry/solid';
import { render } from 'solid-js/web';
import App from './app';
import './index.css';

Sentry.init({
traceLifecycle: 'static',
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
debug: true,
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
release: 'e2e-test',
tunnel: 'http://localhost:3031/', // proxy server
tracesSampleRate: 1.0,
});

render(() => <App />, document.getElementById('root'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import { A } from '@solidjs/router';

export default function PageRoot(props) {
return (
<>
<nav class="bg-gray-200 text-gray-900 px-4">
<ul class="flex items-center">
<li class="py-2 px-4">
<A href="/" class="no-underline hover:underline">
Home
</A>
</li>
<li>
<A href="/error-boundary-example" class="no-underline hover:underline">
Error Boundary Example
</A>
</li>
<li class="py-2 px-4">
<A href="/error" class="no-underline hover:underline">
Error
</A>
</li>
</ul>
</nav>
<main>{props.children}</main>
</>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { lazy } from 'solid-js';

import ErrorBoundaryExample from './pages/errorboundaryexample';
import Home from './pages/home';

export const routes = [
{
path: '/',
component: Home,
},
{
path: '/user/:id',
component: lazy(() => import('./pages/user')),
},
{
path: '/error-boundary-example',
component: ErrorBoundaryExample,
},
{
path: '**',
component: lazy(() => import('./errors/404')),
},
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'solid-static',
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
import type { Config } from 'tailwindcss';

const config: Config = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('captures an exception', async ({ page }) => {
const errorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , errorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
errorEventPromise,
]);

expect(errorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});

test('captures a second exception after resetting the boundary', async ({ page }) => {
const firstErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , firstErrorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
firstErrorEventPromise,
]);

expect(firstErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});

const secondErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , secondErrorEvent] = await Promise.all([
page.locator('#errorBoundaryResetBtn').click(),
page.locator('#caughtErrorBtn').click(),
await secondErrorEventPromise,
]);

expect(secondErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts
40 changes: 40 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
## Usage

Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.

This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely
be removed once you clone a template.

```bash
$ npm install # or pnpm install or yarn install
```

## Exploring the template

This template's goal is to showcase the routing features of Solid. It also showcase how the router and Suspense work
together to parallelize data fetching tied to a route via the `.data.ts` pattern.

You can learn more about it on the [`@solidjs/router` repository](https://github.com/solidjs/solid-router)

### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)

## Available Scripts

In the project directory, you can run:

### `npm run dev` or `npm start`

Runs the app in the development mode.<br> Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.<br>

### `npm run build`

Builds the app for production to the `dist` folder.<br> It correctly bundles Solid in production mode and optimizes the
build for the best performance.

The build is minified and the filenames include the hashes.<br> Your app is ready to be deployed!

## Deployment

You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
15 changes: 15 additions & 0 deletions dev-packages/e2e-tests/test-applications/solid-static/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
{
"name": "solid-static",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "vite build",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"dev": "vite",
"preview": "vite preview",
"start": "vite",
"test:prod": "TEST_ENV=production playwright test",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test:prod"
},
"license": "MIT",
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.33",
"solid-devtools": "^0.29.2",
"tailwindcss": "^3.4.1",
"vite": "^5.4.11",
"vite-plugin-solid": "^2.11.6"
},
"dependencies": {
"solid-js": "^1.8.18",
"@sentry/solid": "file:../../packed/sentry-solid-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'pnpm preview --port 3030',
port: 3030,
});

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
module.exports={
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
import * as Sentry from '@sentry/solid';
import { ErrorBoundary, createSignal, onMount } from 'solid-js';

const SentryErrorBoundary = Sentry.withSentryErrorBoundary(ErrorBoundary);

const [count, setCount] = createSignal(1);
const [caughtError, setCaughtError] = createSignal(false);

export default function App() {
return (
<SampleErrorBoundary>
{caughtError() && <Throw error={`Error ${count()} thrown from Sentry ErrorBoundary in Solid E2E test app`} />}
<section class="bg-gray-100 text-gray-700 p-8">
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="caughtErrorBtn"
onClick={() => setCaughtError(true)}
>
Throw caught error
</button>
</div>
<div class="flex flex-col items-start space-x-2">
<button
class="border rounded-lg px-2 mb-2 border-red-500 text-red-500 cursor-pointer"
id="errorBtn"
onClick={() => {
throw new Error('Error thrown from Solid E2E test app');
}}
>
Throw uncaught error
</button>
</div>
</section>
</SampleErrorBoundary>
);
}

function Throw(props) {
onMount(() => {
throw new Error(props.error);
});
return null;
}

function SampleErrorBoundary(props) {
return (
<SentryErrorBoundary
fallback={(error, reset) => (
<section class="bg-gray-100 text-gray-700 p-8">
<h1 class="text-2xl font-bold">Error Boundary Fallback</h1>
<div class="flex items-center space-x-2 mb-4">
<code>{error.message}</code>
</div>
<button
id="errorBoundaryResetBtn"
class="border rounded-lg px-2 border-gray-900"
onClick={() => {
setCount(count() + 1);
setCaughtError(false);
reset();
}}
>
Reset
</button>
</section>
)}
>
{props.children}
</SentryErrorBoundary>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
/* @refresh reload */
import * as Sentry from '@sentry/solid';
import { render } from 'solid-js/web';
import App from './app';
import './index.css';

Sentry.init({
traceLifecycle: 'static',
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
debug: true,
environment: 'qa', // dynamic sampling bias to keep transactions
integrations: [Sentry.browserTracingIntegration()],
release: 'e2e-test',
tunnel: 'http://localhost:3031/', // proxy server
tracesSampleRate: 1.0,
});

render(() => <App />, document.getElementById('root'));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import { A } from '@solidjs/router';

export default function PageRoot(props) {
return (
<>
<nav class="bg-gray-200 text-gray-900 px-4">
<ul class="flex items-center">
<li class="py-2 px-4">
<A href="/" class="no-underline hover:underline">
Home
</A>
</li>
<li>
<A href="/error-boundary-example" class="no-underline hover:underline">
Error Boundary Example
</A>
</li>
<li class="py-2 px-4">
<A href="/error" class="no-underline hover:underline">
Error
</A>
</li>
</ul>
</nav>
<main>{props.children}</main>
</>
);
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { lazy } from 'solid-js';

import ErrorBoundaryExample from './pages/errorboundaryexample';
import Home from './pages/home';

export const routes = [
{
path: '/',
component: Home,
},
{
path: '/user/:id',
component: lazy(() => import('./pages/user')),
},
{
path: '/error-boundary-example',
component: ErrorBoundaryExample,
},
{
path: '**',
component: lazy(() => import('./errors/404')),
},
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'solid-static',
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
import type { Config } from 'tailwindcss';

const config: Config = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};

export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('captures an exception', async ({ page }) => {
const errorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , errorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
errorEventPromise,
]);

expect(errorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});

test('captures a second exception after resetting the boundary', async ({ page }) => {
const firstErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , firstErrorEvent] = await Promise.all([
page.goto('/'),
page.locator('#caughtErrorBtn').click(),
firstErrorEventPromise,
]);

expect(firstErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 1 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});

const secondErrorEventPromise = waitForError('solid-static', errorEvent => {
return (
!errorEvent.type &&
errorEvent.exception?.values?.[0]?.value === 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app'
);
});

const [, , secondErrorEvent] = await Promise.all([
page.locator('#errorBoundaryResetBtn').click(),
page.locator('#caughtErrorBtn').click(),
await secondErrorEventPromise,
]);

expect(secondErrorEvent).toMatchObject({
exception: {
values: [
{
type: 'Error',
value: 'Error 2 thrown from Sentry ErrorBoundary in Solid E2E test app',
mechanism: {
type: 'auto.function.solid.error_boundary',
handled: true,
},
},
],
},
transaction: '/',
});
});
Loading
Loading