Skip to content

Commit 0857a22

Browse files
committed
test(e2e): Add standard frontend test app specification
1 parent c09cab8 commit 0857a22

File tree

12 files changed

+9426
-0
lines changed

12 files changed

+9426
-0
lines changed

packages/e2e-tests/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,27 @@ add Sentry dependencies to your test application, you should set the dependency
9797
```
9898

9999
All that is left for you to do now is to create a test app and run `yarn test:e2e`.
100+
101+
## Standardized Test Apps
102+
103+
For some of our integration tests we define a standard for test applications as to how they should look and behave.
104+
Standardized test apps enables us to reuse the same test suite over a number of different frameworks/SDKs.
105+
106+
### Standardized Frontend Test Apps
107+
108+
A standardized frontend test application has the following features:
109+
110+
- Just for the sake of consistency we prefix the standardized frontend tests with `standard-frontend-`. For example
111+
`standard-frontend-nextjs`.
112+
- A page at path `/`
113+
- Having a `<input type="button" id="exception-button">` that captures an Exception when clicked. The returned
114+
`eventId` from the `Sentry.captureException()` call must be written to `window.capturedExceptionId`. It doesn not
115+
matter what the captured error looks like.
116+
- Having an link with `id="navigation"` that navigates to `/user/5`. It doesn't have to be an `<a>` tag, for example
117+
if a framework has another way of doing routing, the important part is that the element to click for navigation has
118+
the correct `id`. Text of the link doesn't matter.
119+
- An empty page at `/user/5`
120+
121+
### Standardized Backend Test Apps
122+
123+
TBD
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
25+
!*.d.ts
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@sentry:registry=http://localhost:4873
2+
@sentry-internal:registry=http://localhost:4873
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "standard-frontend-react-test",
3+
"version": "0.1.0",
4+
"private": true,
5+
"dependencies": {
6+
"@sentry/react": "*",
7+
"@sentry/tracing": "*",
8+
"@testing-library/jest-dom": "5.14.1",
9+
"@testing-library/react": "13.0.0",
10+
"@testing-library/user-event": "13.2.1",
11+
"@types/jest": "27.0.1",
12+
"@types/node": "16.7.13",
13+
"@types/react": "18.0.0",
14+
"@types/react-dom": "18.0.0",
15+
"react": "18.2.0",
16+
"react-dom": "18.2.0",
17+
"react-router-dom": "^6.4.1",
18+
"react-scripts": "5.0.1",
19+
"typescript": "4.4.2",
20+
"web-vitals": "2.1.0"
21+
},
22+
"scripts": {
23+
"start": "react-scripts start",
24+
"build": "react-scripts build"
25+
},
26+
"eslintConfig": {
27+
"extends": [
28+
"react-app",
29+
"react-app/jest"
30+
]
31+
},
32+
"browserslist": {
33+
"production": [
34+
">0.2%",
35+
"not dead",
36+
"not op_mini all"
37+
],
38+
"development": [
39+
"last 1 chrome version",
40+
"last 1 firefox version",
41+
"last 1 safari version"
42+
]
43+
}
44+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1" />
7+
<meta name="theme-color" content="#000000" />
8+
<meta name="description" content="Web site created using create-react-app" />
9+
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
10+
<!--
11+
manifest.json provides metadata used when your web app is installed on a
12+
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
13+
-->
14+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
15+
<!--
16+
Notice the use of %PUBLIC_URL% in the tags above.
17+
It will be replaced with the URL of the `public` folder during the build.
18+
Only files inside the `public` folder can be referenced from the HTML.
19+
20+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
21+
work correctly both with client-side routing and a non-root public URL.
22+
Learn how to configure a non-root public URL by running `npm run build`.
23+
-->
24+
<title>React App</title>
25+
</head>
26+
<body>
27+
<noscript>You need to enable JavaScript to run this app.</noscript>
28+
<div id="root"></div>
29+
<!--
30+
This HTML file is a template.
31+
If you open it directly in the browser, you will see an empty page.
32+
33+
You can add webfonts, meta tags, or analytics to this file.
34+
The build step will place the bundled scripts into the <body> tag.
35+
36+
To begin the development, run `npm start` or `yarn start`.
37+
To create a production bundle, use `npm run build` or `yarn build`.
38+
-->
39+
</body>
40+
</html>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom/client';
3+
import * as Sentry from '@sentry/react';
4+
import { BrowserTracing } from '@sentry/tracing';
5+
import {
6+
Routes,
7+
BrowserRouter,
8+
useLocation,
9+
useNavigationType,
10+
createRoutesFromChildren,
11+
matchRoutes,
12+
Route,
13+
} from 'react-router-dom';
14+
import Index from './pages/Index';
15+
import User from './pages/User';
16+
17+
Sentry.init({
18+
dsn: 'https://[email protected]/1337',
19+
integrations: [
20+
new BrowserTracing({
21+
routingInstrumentation: Sentry.reactRouterV6Instrumentation(
22+
React.useEffect,
23+
useLocation,
24+
useNavigationType,
25+
createRoutesFromChildren,
26+
matchRoutes,
27+
),
28+
}),
29+
],
30+
// We recommend adjusting this value in production, or using tracesSampler
31+
// for finer control
32+
tracesSampleRate: 1.0,
33+
});
34+
35+
const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes);
36+
37+
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
38+
root.render(
39+
<BrowserRouter>
40+
<SentryRoutes>
41+
<Route path="/" element={<Index />} />
42+
<Route path="/user/:id" element={<User />} />
43+
</SentryRoutes>
44+
</BrowserRouter>,
45+
);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as React from 'react';
2+
import * as Sentry from '@sentry/react';
3+
import { Link } from 'react-router-dom';
4+
5+
const Index = () => {
6+
return (
7+
<>
8+
<input
9+
type="button"
10+
value="Capture Exception"
11+
id="exception-button"
12+
onClick={() => {
13+
Sentry.captureException(new Error('I am an error!'));
14+
}}
15+
/>
16+
<Link to="/user/5" id="navigation">
17+
navigate
18+
</Link>
19+
</>
20+
);
21+
};
22+
23+
export default Index;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as React from 'react';
2+
3+
const User = () => {
4+
return <p>I am a blank page :)</p>;
5+
};
6+
7+
export default User;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="react-scripts" />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"$schema": "../../test-recipe-schema.json",
3+
"testApplicationName": "standard-frontend-react",
4+
"buildCommand": "yarn install && yarn build",
5+
"tests": []
6+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"lib": ["dom", "dom.iterable", "esnext"],
5+
"allowJs": true,
6+
"skipLibCheck": true,
7+
"esModuleInterop": true,
8+
"allowSyntheticDefaultImports": true,
9+
"strict": true,
10+
"forceConsistentCasingInFileNames": true,
11+
"noFallthroughCasesInSwitch": true,
12+
"module": "esnext",
13+
"moduleResolution": "node",
14+
"resolveJsonModule": true,
15+
"isolatedModules": true,
16+
"noEmit": true,
17+
"jsx": "react"
18+
},
19+
"include": ["src"]
20+
}

0 commit comments

Comments
 (0)