✨(frontend) add sentry
In order to monitor the frontend, we are adding sentry.
This commit is contained in:
@@ -17,6 +17,7 @@ and this project adheres to
|
|||||||
- ✨(backend) whitelist pod's IP address #443
|
- ✨(backend) whitelist pod's IP address #443
|
||||||
- ✨(backend) config endpoint #425
|
- ✨(backend) config endpoint #425
|
||||||
- ✨(frontend) config endpoint #424
|
- ✨(frontend) config endpoint #424
|
||||||
|
- ✨(frontend) add sentry #424
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
COLLABORATION_SERVER_URL: 'ws://localhost:4444',
|
||||||
|
ENVIRONMENT: 'development',
|
||||||
|
FRONTEND_THEME: 'dsfr',
|
||||||
|
MEDIA_BASE_URL: 'http://localhost:8083',
|
||||||
|
LANGUAGES: [
|
||||||
|
['en-us', 'English'],
|
||||||
|
['fr-fr', 'French'],
|
||||||
|
['de-de', 'German'],
|
||||||
|
],
|
||||||
|
LANGUAGE_CODE: 'en-us',
|
||||||
|
SENTRY_DSN: null,
|
||||||
|
};
|
||||||
|
|
||||||
test.describe('Config', () => {
|
test.describe('Config', () => {
|
||||||
test('it checks the config api is called', async ({ page }) => {
|
test('it checks the config api is called', async ({ page }) => {
|
||||||
const responsePromise = page.waitForResponse(
|
const responsePromise = page.waitForResponse(
|
||||||
@@ -12,18 +26,34 @@ test.describe('Config', () => {
|
|||||||
const response = await responsePromise;
|
const response = await responsePromise;
|
||||||
expect(response.ok()).toBeTruthy();
|
expect(response.ok()).toBeTruthy();
|
||||||
|
|
||||||
expect(await response.json()).toStrictEqual({
|
expect(await response.json()).toStrictEqual(config);
|
||||||
COLLABORATION_SERVER_URL: 'ws://localhost:4444',
|
});
|
||||||
ENVIRONMENT: 'development',
|
|
||||||
FRONTEND_THEME: 'dsfr',
|
test('it checks that sentry is trying to init from config endpoint', async ({
|
||||||
MEDIA_BASE_URL: 'http://localhost:8083',
|
page,
|
||||||
LANGUAGES: [
|
}) => {
|
||||||
['en-us', 'English'],
|
await page.route('**/api/v1.0/config/', async (route) => {
|
||||||
['fr-fr', 'French'],
|
const request = route.request();
|
||||||
['de-de', 'German'],
|
if (request.method().includes('GET')) {
|
||||||
],
|
await route.fulfill({
|
||||||
LANGUAGE_CODE: 'en-us',
|
json: {
|
||||||
SENTRY_DSN: null,
|
...config,
|
||||||
|
SENTRY_DSN: 'https://sentry.io/123',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await route.continue();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const invalidMsg = 'Invalid Sentry Dsn: https://sentry.io/123';
|
||||||
|
const consoleMessage = page.waitForEvent('console', {
|
||||||
|
timeout: 5000,
|
||||||
|
predicate: (msg) => msg.text().includes(invalidMsg),
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.goto('/');
|
||||||
|
|
||||||
|
expect((await consoleMessage).text()).toContain(invalidMsg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"@gouvfr-lasuite/integration": "1.0.2",
|
"@gouvfr-lasuite/integration": "1.0.2",
|
||||||
"@hocuspocus/provider": "2.13.7",
|
"@hocuspocus/provider": "2.13.7",
|
||||||
"@openfun/cunningham-react": "2.9.4",
|
"@openfun/cunningham-react": "2.9.4",
|
||||||
|
"@sentry/nextjs": "8.39.0",
|
||||||
"@tanstack/react-query": "5.60.5",
|
"@tanstack/react-query": "5.60.5",
|
||||||
"i18next": "23.16.5",
|
"i18next": "23.16.5",
|
||||||
"i18next-browser-languagedetector": "8.0.0",
|
"i18next-browser-languagedetector": "8.0.0",
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ jest.mock('next/router', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('@sentry/nextjs', () => ({
|
||||||
|
captureException: jest.fn(),
|
||||||
|
captureMessage: jest.fn(),
|
||||||
|
setUser: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('Page', () => {
|
describe('Page', () => {
|
||||||
it('checks Page rendering', () => {
|
it('checks Page rendering', () => {
|
||||||
render(<Page />, { wrapper: AppWrapper });
|
render(<Page />, { wrapper: AppWrapper });
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
import { PropsWithChildren } from 'react';
|
import { PropsWithChildren, useEffect } from 'react';
|
||||||
|
|
||||||
|
import { useSentryStore } from '@/stores/useSentryStore';
|
||||||
|
|
||||||
import { useConfig } from './api/useConfig';
|
import { useConfig } from './api/useConfig';
|
||||||
|
|
||||||
export const ConfigProvider = ({ children }: PropsWithChildren) => {
|
export const ConfigProvider = ({ children }: PropsWithChildren) => {
|
||||||
useConfig();
|
const { data: conf } = useConfig();
|
||||||
|
const { setSentry } = useSentryStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!conf?.SENTRY_DSN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSentry(conf.SENTRY_DSN, conf.ENVIRONMENT);
|
||||||
|
}, [conf?.SENTRY_DSN, conf?.ENVIRONMENT, setSentry]);
|
||||||
|
|
||||||
return children;
|
return children;
|
||||||
};
|
};
|
||||||
|
|||||||
32
src/frontend/apps/impress/src/stores/useSentryStore.tsx
Normal file
32
src/frontend/apps/impress/src/stores/useSentryStore.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import * as Sentry from '@sentry/nextjs';
|
||||||
|
import type { Client } from '@sentry/types';
|
||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
import packageJson from '../../package.json';
|
||||||
|
|
||||||
|
interface SentryState {
|
||||||
|
sentry?: Client;
|
||||||
|
setSentry: (dsn?: string, environment?: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useSentryStore = create<SentryState>((set, get) => ({
|
||||||
|
sentry: undefined,
|
||||||
|
setSentry: (dsn, environment) => {
|
||||||
|
const sentry = get().sentry;
|
||||||
|
if (sentry) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set({
|
||||||
|
sentry: Sentry.init({
|
||||||
|
dsn,
|
||||||
|
environment,
|
||||||
|
integrations: [Sentry.replayIntegration()],
|
||||||
|
release: packageJson.version,
|
||||||
|
replaysSessionSampleRate: 0.1,
|
||||||
|
replaysOnErrorSampleRate: 1.0,
|
||||||
|
tracesSampleRate: 1.0,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}));
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user