Browse Source

SONAR-20254 Migrate app-level component tests to RTL

tags/10.2.0.77647
Jay 8 months ago
parent
commit
759862025d

+ 1
- 1
server/sonar-web/src/main/js/app/components/AdminContainer.tsx View File

@@ -103,7 +103,7 @@ export class AdminContainer extends React.PureComponent<AdminContainerProps, Sta
({ status }) => {
if (this.mounted) {
this.setState({ systemStatus: status });
document.location.reload();
window.location.reload();
}
},
() => {}

+ 134
- 16
server/sonar-web/src/main/js/app/components/__tests__/AdminContainer-test.tsx View File

@@ -17,34 +17,152 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
import userEvent from '@testing-library/user-event';
import * as React from 'react';
import { Route, useOutletContext } from 'react-router-dom';
import { getSystemStatus, waitSystemUPStatus } from '../../../api/system';
import { mockAppState } from '../../../helpers/testMocks';
import { renderAppRoutes } from '../../../helpers/testReactTestingUtils';
import { byLabelText, byRole, byText } from '../../../helpers/testSelector';
import { AdminPagesContext } from '../../../types/admin';
import { AdminContainer, AdminContainerProps } from '../AdminContainer';
import AdminContext from '../AdminContext';

jest.mock('../../../api/navigation', () => ({
getSettingsNavigation: jest
.fn()
.mockResolvedValue({ extensions: [{ key: 'asd', name: 'asdf' }] }),
}));

jest.mock('../../../api/plugins', () => ({
getSettingsNavigation: jest.fn().mockResolvedValue({}),
getPendingPlugins: jest.fn().mockResolvedValue({}),
getPendingPlugins: jest.fn().mockResolvedValue({
installing: [{ key: '1', name: 'installing' }],
updating: [
{ key: '2', name: 'updating' },
{ key: '2b', name: 'update this too' },
],
removing: [{ key: '3', name: 'removing' }],
}),
}));

jest.mock('../../../api/system', () => ({
getSystemStatus: jest.fn().mockResolvedValue({}),
getSystemStatus: jest.fn().mockResolvedValue({ status: 'DOWN' }),
waitSystemUPStatus: jest.fn().mockResolvedValue({ status: 'RESTARTING' }),
}));

it('should render correctly', () => {
const wrapper = shallowRender();
expect(wrapper).toMatchSnapshot();
const originalLocation = window.location;
const reload = jest.fn();

beforeAll(() => {
Object.defineProperty(window, 'location', {
writable: true,
value: { reload },
});
});

function shallowRender(props: Partial<AdminContainerProps> = {}) {
return shallow(
<AdminContainer
appState={mockAppState({
canAdmin: true,
})}
{...props}
afterAll(() => {
Object.defineProperty(window, 'location', {
writable: true,
value: originalLocation,
});
});

it('should render nav and provide context to children', async () => {
const user = userEvent.setup();
renderAdminContainer();

expect(await ui.navHeader.find()).toBeInTheDocument();

expect(ui.pagesList.byRole('listitem').getAll()).toHaveLength(1);
expect(ui.pagesList.byText('asdf').get()).toBeInTheDocument();

expect(ui.pluginsInstallingList.byRole('listitem').getAll()).toHaveLength(1);
expect(ui.pluginsInstallingList.byText('installing').get()).toBeInTheDocument();

expect(ui.pluginsUpdatingList.byRole('listitem').getAll()).toHaveLength(2);
expect(ui.pluginsUpdatingList.byText('updating').get()).toBeInTheDocument();
expect(ui.pluginsUpdatingList.byText('update this too').get()).toBeInTheDocument();

expect(ui.pluginsRemovingList.byRole('listitem').getAll()).toHaveLength(1);
expect(ui.pluginsRemovingList.byText('removing').get()).toBeInTheDocument();

expect(byText('DOWN').get()).toBeInTheDocument();

// Trigger a status update
jest.mocked(getSystemStatus).mockResolvedValueOnce({ id: '', version: '', status: 'RESTARTING' });
jest.mocked(waitSystemUPStatus).mockResolvedValueOnce({ id: '', version: '', status: 'UP' });
await user.click(ui.fetchStatusButton.get());

expect(await byText('UP').find()).toBeInTheDocument();
expect(reload).toHaveBeenCalled();
});

function renderAdminContainer(props: Partial<AdminContainerProps> = {}) {
return renderAppRoutes('admin', () => (
<Route
path="admin"
element={
<AdminContainer
appState={mockAppState({
canAdmin: true,
})}
{...props}
/>
}
>
<div />
</AdminContainer>
<Route index element={<TestChildComponent />} />
</Route>
));
}

function TestChildComponent() {
const { adminPages } = useOutletContext<AdminPagesContext>();

const { fetchPendingPlugins, fetchSystemStatus, pendingPlugins, systemStatus } =
React.useContext(AdminContext);

return (
<div>
<ul aria-label="pages">
{adminPages.map((page) => (
<li key={page.key}>{page.name}</li>
))}
</ul>

<ul aria-label="plugins - installing">
{pendingPlugins.installing.map((p) => (
<li key={p.key}>{p.name}</li>
))}
</ul>
<ul aria-label="plugins - removing">
{pendingPlugins.removing.map((p) => (
<li key={p.key}>{p.name}</li>
))}
</ul>
<ul aria-label="plugins - updating">
{pendingPlugins.updating.map((p) => (
<li key={p.key}>{p.name}</li>
))}
</ul>
<button type="button" onClick={fetchPendingPlugins}>
fetch plugins
</button>

{systemStatus}
<button type="button" onClick={fetchSystemStatus}>
fetch status
</button>
</div>
);
}

const ui = {
navHeader: byRole('heading', { name: 'layout.settings' }),
pagesList: byLabelText('pages'),
pluginsInstallingList: byLabelText('plugins - installing'),
pluginsUpdatingList: byLabelText('plugins - updating'),
pluginsRemovingList: byLabelText('plugins - removing'),

fetchPluginsButton: byRole('button', { name: 'fetch plugins' }),
fetchStatusButton: byRole('button', { name: 'fetch status' }),
};

+ 16
- 16
server/sonar-web/src/main/js/app/components/__tests__/App-test.tsx View File

@@ -17,32 +17,32 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
import * as React from 'react';
import { mockAppState } from '../../../helpers/testMocks';
import { renderComponent } from '../../../helpers/testReactTestingUtils';
import { App } from '../App';

it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot('default');
expect(
shallowRender({
appState: mockAppState({
settings: {
'sonar.lf.enableGravatar': 'true',
'sonar.lf.gravatarServerUrl': 'http://example.com',
},
}),
})
).toMatchSnapshot('with gravatar');
it('should render correctly with gravatar', () => {
renderApp({
appState: mockAppState({
settings: {
'sonar.lf.enableGravatar': 'true',
'sonar.lf.gravatarServerUrl': 'http://example.com',
},
}),
});
// eslint-disable-next-line testing-library/no-node-access
expect(document.head.querySelector('link')).toHaveAttribute('href', 'http://example.com');
});

it('should correctly set the scrollbar width as a custom property', () => {
shallowRender();
renderApp();
expect(document.body.style.getPropertyValue('--sbw')).toBe('0px');
});

function shallowRender(props: Partial<App['props']> = {}) {
return shallow<App>(
function renderApp(props: Partial<App['props']> = {}) {
return renderComponent(
<App
appState={mockAppState({
settings: {

+ 38
- 47
server/sonar-web/src/main/js/app/components/__tests__/KeyboardShortcutsModal-test.tsx View File

@@ -17,69 +17,60 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
import { act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import Modal from '../../../components/controls/Modal';
import { mockEvent } from '../../../helpers/testUtils';
import { renderComponent } from '../../../helpers/testReactTestingUtils';
import { byRole } from '../../../helpers/testSelector';
import KeyboardShortcutsModal from '../KeyboardShortcutsModal';

jest.mock('react', () => {
let close: () => void;
return {
...jest.requireActual('react'),
useEffect: jest.fn().mockImplementation((f) => {
close = f();
}),
clean: () => {
close();
},
};
});
it('should render correctly', async () => {
const user = userEvent.setup();
renderKeyboardShortcutsModal();

afterEach(() => {
if ((React as any).clean as () => void) {
(React as any).clean();
}
});
expect(ui.modalTitle.query()).not.toBeInTheDocument();

it('should render correctly', () => {
const wrapper = shallowRender();
expect(wrapper).toMatchSnapshot('hidden');
await act(() => user.keyboard('?'));

document.dispatchEvent(new KeyboardEvent('keydown', { key: '?' }));
expect(ui.modalTitle.get()).toBeInTheDocument();

expect(wrapper).toMatchSnapshot('visible');
});
await user.click(ui.closeButton.get());

it('should close correctly', () => {
const wrapper = shallowRender();
document.dispatchEvent(new KeyboardEvent('keydown', { key: '?' }));
expect(ui.modalTitle.query()).not.toBeInTheDocument();
});

wrapper.find(Modal).props().onRequestClose!(mockEvent());
it('should ignore other keydownes', async () => {
const user = userEvent.setup();
renderKeyboardShortcutsModal();

expect(wrapper.type()).toBeNull();
});
await act(() => user.keyboard('!'));

it('should ignore other keydownes', () => {
const wrapper = shallowRender();
document.dispatchEvent(new KeyboardEvent('keydown', { key: '!' }));
expect(wrapper.type()).toBeNull();
expect(ui.modalTitle.query()).not.toBeInTheDocument();
});

it.each([['input'], ['select'], ['textarea']])('should ignore events on a %s', (type) => {
const wrapper = shallowRender();

const fakeEvent = new KeyboardEvent('keydown', { key: '!' });
it('should ignore events in an input', async () => {
const user = userEvent.setup();

Object.defineProperty(fakeEvent, 'target', {
value: document.createElement(type),
});
renderKeyboardShortcutsModal();

document.dispatchEvent(fakeEvent);
await user.click(ui.textInput.get());
await act(() => user.keyboard('?'));

expect(wrapper.type()).toBeNull();
expect(ui.modalTitle.query()).not.toBeInTheDocument();
});

function shallowRender() {
return shallow(<KeyboardShortcutsModal />);
function renderKeyboardShortcutsModal() {
return renderComponent(
<>
<KeyboardShortcutsModal />
<input type="text" />
</>
);
}

const ui = {
modalTitle: byRole('heading', { name: 'keyboard_shortcuts.title' }),
closeButton: byRole('button', { name: 'close' }),

textInput: byRole('textbox'),
};

+ 19
- 5
server/sonar-web/src/main/js/app/components/__tests__/MigrationContainer-test.tsx View File

@@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
import * as React from 'react';
import { Route } from 'react-router-dom';
import { getSystemStatus } from '../../../helpers/system';
import { renderAppRoutes } from '../../../helpers/testReactTestingUtils';
import { byText } from '../../../helpers/testSelector';
import MigrationContainer from '../MigrationContainer';

jest.mock('../../../helpers/system', () => ({
@@ -49,14 +51,26 @@ afterAll(() => {

it('should render correctly if system is up', () => {
(getSystemStatus as jest.Mock).mockReturnValueOnce('UP');
expect(shallowRender()).toMatchSnapshot();

renderMigrationContainer();

expect(byText('children').get()).toBeInTheDocument();
});

it('should render correctly if system is starting', () => {
(getSystemStatus as jest.Mock).mockReturnValueOnce('STARTING');
expect(shallowRender()).toMatchSnapshot();

renderMigrationContainer();

expect(
byText('/maintenance?return_to=%2Fprojects%3Fquery%3Dtoto%23hash').get()
).toBeInTheDocument();
});

function shallowRender() {
return shallow(<MigrationContainer />);
function renderMigrationContainer() {
return renderAppRoutes('/', () => (
<Route element={<MigrationContainer />}>
<Route index element={<div>children</div>} />
</Route>
));
}

+ 31
- 15
server/sonar-web/src/main/js/app/components/__tests__/PageTracker-test.tsx View File

@@ -17,12 +17,15 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
import userEvent from '@testing-library/user-event';
import * as React from 'react';
import { Link } from 'react-router-dom';
import { installScript } from '../../../helpers/extensions';
import { getWebAnalyticsPageHandlerFromCache } from '../../../helpers/extensionsHandler';
import { mockAppState, mockLocation } from '../../../helpers/testMocks';
import { PageTracker } from '../PageTracker';
import { mockAppState } from '../../../helpers/testMocks';
import { renderComponent } from '../../../helpers/testReactTestingUtils';
import { byRole } from '../../../helpers/testSelector';
import PageTracker from '../PageTracker';

jest.mock('../../../helpers/extensions', () => ({
installScript: jest.fn().mockResolvedValue({}),
@@ -43,28 +46,41 @@ afterEach(() => {
});

it('should not trigger if no analytics system is given', () => {
const wrapper = shallowRender();
expect(wrapper).toMatchSnapshot();
renderPageTracker();
expect(installScript).not.toHaveBeenCalled();
});

it('should work for WebAnalytics plugin', () => {
it('should work for WebAnalytics plugin', async () => {
const user = userEvent.setup({ delay: null });
const pageChange = jest.fn();
const webAnalyticsJsPath = '/static/pluginKey/web_analytics.js';
const wrapper = shallowRender({ appState: mockAppState({ webAnalyticsJsPath }) });
renderPageTracker(mockAppState({ webAnalyticsJsPath }));

expect(wrapper).toMatchSnapshot();
expect(wrapper.find('Helmet').prop('onChangeClientState')).toBe(wrapper.instance().trackPage);
expect(installScript).toHaveBeenCalledWith(webAnalyticsJsPath, 'head');
(getWebAnalyticsPageHandlerFromCache as jest.Mock).mockReturnValueOnce(pageChange);

wrapper.instance().trackPage();
jest.mocked(getWebAnalyticsPageHandlerFromCache).mockClear().mockReturnValueOnce(pageChange);

// trigger trackPage
await user.click(byRole('link').get());

jest.runAllTimers();
expect(pageChange).toHaveBeenCalledWith('/path');
expect(pageChange).toHaveBeenCalledWith('/newpath');
});

function shallowRender(props: Partial<PageTracker['props']> = {}) {
return shallow<PageTracker>(
<PageTracker appState={mockAppState()} location={mockLocation()} {...props} />
function renderPageTracker(appState = mockAppState()) {
return renderComponent(<WrappingComponent />, '', { appState });
}

function WrappingComponent() {
const [metatag, setmetatag] = React.useState<React.ReactNode>(null);

return (
<>
<PageTracker>{metatag}</PageTracker>
<Link to="newpath" onClick={() => setmetatag(<meta name="toto" />)}>
trigger change
</Link>
</>
);
}

+ 23
- 18
server/sonar-web/src/main/js/app/components/__tests__/ProjectAdminContainer-test.tsx View File

@@ -17,10 +17,12 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { mount, shallow } from 'enzyme';
import * as React from 'react';
import { Route } from 'react-router-dom';
import handleRequiredAuthorization from '../../../app/utils/handleRequiredAuthorization';
import { mockComponent } from '../../../helpers/mocks/component';
import { renderAppRoutes } from '../../../helpers/testReactTestingUtils';
import { byText } from '../../../helpers/testSelector';
import { ProjectAdminContainer } from '../ProjectAdminContainer';

jest.mock('../../utils/handleRequiredAuthorization', () => {
@@ -28,30 +30,33 @@ jest.mock('../../utils/handleRequiredAuthorization', () => {
});

it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
renderProjectAdminContainer();

expect(byText('children').get()).toBeInTheDocument();
});

it('should redirect for authorization if needed', () => {
jest.useFakeTimers();
mountRender({ component: mockComponent({ configuration: { showSettings: false } }) });
renderProjectAdminContainer({
component: mockComponent({ configuration: { showSettings: false } }),
});
jest.runAllTimers();
expect(handleRequiredAuthorization).toHaveBeenCalled();
jest.useRealTimers();
});

function mountRender(props: Partial<ProjectAdminContainer['props']> = {}) {
return mount(createComponent(props));
}

function shallowRender(props: Partial<ProjectAdminContainer['props']> = {}) {
return shallow(createComponent(props));
}

function createComponent(props: Partial<ProjectAdminContainer['props']> = {}) {
return (
<ProjectAdminContainer
component={mockComponent({ configuration: { showSettings: true } })}
{...props}
/>
);
function renderProjectAdminContainer(props: Partial<ProjectAdminContainer['props']> = {}) {
return renderAppRoutes('project/settings', () => (
<Route
path="project/settings"
element={
<ProjectAdminContainer
component={mockComponent({ configuration: { showSettings: true } })}
{...props}
/>
}
>
<Route index element={<div>children</div>} />
</Route>
));
}

+ 0
- 47
server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/AdminContainer-test.tsx.snap View File

@@ -1,47 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly 1`] = `
<Fragment>
<Helmet
defer={false}
encodeSpecialCharacters={true}
prioritizeSeoTags={false}
titleTemplate="page_title.template.with_category.layout.settings"
/>
<WithLocation
extensions={[]}
fetchPendingPlugins={[Function]}
fetchSystemStatus={[Function]}
pendingPlugins={
{
"installing": [],
"removing": [],
"updating": [],
}
}
systemStatus="UP"
/>
<ContextProvider
value={
{
"fetchPendingPlugins": [Function],
"fetchSystemStatus": [Function],
"pendingPlugins": {
"installing": [],
"removing": [],
"updating": [],
},
"systemStatus": "UP",
}
}
>
<Outlet
context={
{
"adminPages": [],
}
}
/>
</ContextProvider>
</Fragment>
`;

+ 0
- 22
server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/App-test.tsx.snap View File

@@ -1,22 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly: default 1`] = `
<Fragment>
<withRouter(withAppStateContext(PageTracker)) />
<Outlet />
<KeyboardShortcutsModal />
</Fragment>
`;

exports[`should render correctly: with gravatar 1`] = `
<Fragment>
<withRouter(withAppStateContext(PageTracker))>
<link
href="http://example.com"
rel="preconnect"
/>
</withRouter(withAppStateContext(PageTracker))>
<Outlet />
<KeyboardShortcutsModal />
</Fragment>
`;

+ 0
- 583
server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/KeyboardShortcutsModal-test.tsx.snap View File

@@ -1,583 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly: hidden 1`] = `""`;

exports[`should render correctly: visible 1`] = `
<Modal
contentLabel="keyboard_shortcuts.title"
onRequestClose={[Function]}
size="medium"
>
<div
className="modal-head display-flex-space-between"
>
<h2>
keyboard_shortcuts.title
</h2>
<ForwardRef(Link)
onClick={[Function]}
to="/account"
>
keyboard_shortcuts.disable_link
</ForwardRef(Link)>
</div>
<div
className="modal-body modal-container markdown display-flex-start shortcuts-modal"
>
<div
className="flex-1"
>
<div
className="spacer-bottom"
key="global"
>
<h3
className="null-spacer-top"
>
keyboard_shortcuts.global.title
</h3>
<table>
<thead>
<tr>
<th>
keyboard_shortcuts.shortcut
</th>
<th>
keyboard_shortcuts.action
</th>
</tr>
</thead>
<tbody>
<tr
key="search"
>
<td>
<code
className="little-spacer-right"
key="s"
>
s
</code>
</td>
<td>
keyboard_shortcuts.global.search
</td>
</tr>
<tr
key="open_shortcuts"
>
<td>
<code
className="little-spacer-right"
key="?"
>
?
</code>
</td>
<td>
keyboard_shortcuts.global.open_shortcuts
</td>
</tr>
</tbody>
</table>
</div>
<div
className="spacer-bottom"
key="issues_page"
>
<h3
className="null-spacer-top"
>
keyboard_shortcuts.issues_page.title
</h3>
<table>
<thead>
<tr>
<th>
keyboard_shortcuts.shortcut
</th>
<th>
keyboard_shortcuts.action
</th>
</tr>
</thead>
<tbody>
<tr
key="navigate"
>
<td>
<code
className="little-spacer-right"
key="↑"
>
</code>
<code
className="little-spacer-right"
key="↓"
>
</code>
</td>
<td>
keyboard_shortcuts.issues_page.navigate
</td>
</tr>
<tr
key="source_code"
>
<td>
<code
className="little-spacer-right"
key="→"
>
</code>
</td>
<td>
keyboard_shortcuts.issues_page.source_code
</td>
</tr>
<tr
key="back"
>
<td>
<code
className="little-spacer-right"
key="←"
>
</code>
</td>
<td>
keyboard_shortcuts.issues_page.back
</td>
</tr>
<tr
key="navigate_locations"
>
<td>
<code
className="little-spacer-right"
key="alt"
>
alt
</code>
<span
className="little-spacer-right"
key="+"
>
+
</span>
<code
className="little-spacer-right"
key="↑"
>
</code>
<code
className="little-spacer-right"
key="↓"
>
</code>
</td>
<td>
keyboard_shortcuts.issues_page.navigate_locations
</td>
</tr>
<tr
key="switch_flows"
>
<td>
<code
className="little-spacer-right"
key="alt"
>
alt
</code>
<span
className="little-spacer-right"
key="+"
>
+
</span>
<code
className="little-spacer-right"
key="←"
>
</code>
<code
className="little-spacer-right"
key="→"
>
</code>
</td>
<td>
keyboard_shortcuts.issues_page.switch_flows
</td>
</tr>
<tr
key="transition"
>
<td>
<code
className="little-spacer-right"
key="f"
>
f
</code>
</td>
<td>
keyboard_shortcuts.issues_page.transition
</td>
</tr>
<tr
key="assign"
>
<td>
<code
className="little-spacer-right"
key="a"
>
a
</code>
</td>
<td>
keyboard_shortcuts.issues_page.assign
</td>
</tr>
<tr
key="assign_to_me"
>
<td>
<code
className="little-spacer-right"
key="m"
>
m
</code>
</td>
<td>
keyboard_shortcuts.issues_page.assign_to_me
</td>
</tr>
<tr
key="severity"
>
<td>
<code
className="little-spacer-right"
key="i"
>
i
</code>
</td>
<td>
keyboard_shortcuts.issues_page.severity
</td>
</tr>
<tr
key="comment"
>
<td>
<code
className="little-spacer-right"
key="c"
>
c
</code>
</td>
<td>
keyboard_shortcuts.issues_page.comment
</td>
</tr>
<tr
key="submit_comment"
>
<td>
<code
className="little-spacer-right"
key="ctrl"
>
ctrl
</code>
<span
className="little-spacer-right"
key="+"
>
+
</span>
<code
className="little-spacer-right"
key="enter"
>
enter
</code>
</td>
<td>
keyboard_shortcuts.issues_page.submit_comment
</td>
</tr>
<tr
key="tags"
>
<td>
<code
className="little-spacer-right"
key="t"
>
t
</code>
</td>
<td>
keyboard_shortcuts.issues_page.tags
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div
className="flex-1 huge-spacer-left"
>
<div
className="spacer-bottom"
key="code_page"
>
<h3
className="null-spacer-top"
>
keyboard_shortcuts.code_page.title
</h3>
<table>
<thead>
<tr>
<th>
keyboard_shortcuts.shortcut
</th>
<th>
keyboard_shortcuts.action
</th>
</tr>
</thead>
<tbody>
<tr
key="select_files"
>
<td>
<code
className="little-spacer-right"
key="↑"
>
</code>
<code
className="little-spacer-right"
key="↓"
>
</code>
</td>
<td>
keyboard_shortcuts.code_page.select_files
</td>
</tr>
<tr
key="open_file"
>
<td>
<code
className="little-spacer-right"
key="→"
>
</code>
</td>
<td>
keyboard_shortcuts.code_page.open_file
</td>
</tr>
<tr
key="back"
>
<td>
<code
className="little-spacer-right"
key="←"
>
</code>
</td>
<td>
keyboard_shortcuts.code_page.back
</td>
</tr>
</tbody>
</table>
</div>
<div
className="spacer-bottom"
key="measures_page"
>
<h3
className="null-spacer-top"
>
keyboard_shortcuts.measures_page.title
</h3>
<table>
<thead>
<tr>
<th>
keyboard_shortcuts.shortcut
</th>
<th>
keyboard_shortcuts.action
</th>
</tr>
</thead>
<tbody>
<tr
key="select_files"
>
<td>
<code
className="little-spacer-right"
key="↑"
>
</code>
<code
className="little-spacer-right"
key="↓"
>
</code>
</td>
<td>
keyboard_shortcuts.measures_page.select_files
</td>
</tr>
<tr
key="open_file"
>
<td>
<code
className="little-spacer-right"
key="→"
>
</code>
</td>
<td>
keyboard_shortcuts.measures_page.open_file
</td>
</tr>
<tr
key="back"
>
<td>
<code
className="little-spacer-right"
key="←"
>
</code>
</td>
<td>
keyboard_shortcuts.measures_page.back
</td>
</tr>
</tbody>
</table>
</div>
<div
className="spacer-bottom"
key="rules_page"
>
<h3
className="null-spacer-top"
>
keyboard_shortcuts.rules_page.title
</h3>
<table>
<thead>
<tr>
<th>
keyboard_shortcuts.shortcut
</th>
<th>
keyboard_shortcuts.action
</th>
</tr>
</thead>
<tbody>
<tr
key="navigate"
>
<td>
<code
className="little-spacer-right"
key="↑"
>
</code>
<code
className="little-spacer-right"
key="↓"
>
</code>
</td>
<td>
keyboard_shortcuts.rules_page.navigate
</td>
</tr>
<tr
key="rule_details"
>
<td>
<code
className="little-spacer-right"
key="→"
>
</code>
</td>
<td>
keyboard_shortcuts.rules_page.rule_details
</td>
</tr>
<tr
key="back"
>
<td>
<code
className="little-spacer-right"
key="←"
>
</code>
</td>
<td>
keyboard_shortcuts.rules_page.back
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div
className="modal-foot"
>
<Button
onClick={[Function]}
>
close
</Button>
</div>
</Modal>
`;

+ 0
- 14
server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/MigrationContainer-test.tsx.snap View File

@@ -1,14 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly if system is starting 1`] = `
<Navigate
to={
{
"pathname": "/maintenance",
"search": "return_to=%2Fprojects%3Fquery%3Dtoto%23hash",
}
}
/>
`;

exports[`should render correctly if system is up 1`] = `<Outlet />`;

+ 0
- 18
server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/PageTracker-test.tsx.snap View File

@@ -1,18 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should not trigger if no analytics system is given 1`] = `
<Helmet
defer={false}
encodeSpecialCharacters={true}
prioritizeSeoTags={false}
/>
`;

exports[`should work for WebAnalytics plugin 1`] = `
<Helmet
defer={false}
encodeSpecialCharacters={true}
onChangeClientState={[Function]}
prioritizeSeoTags={false}
/>
`;

+ 0
- 10
server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/ProjectAdminContainer-test.tsx.snap View File

@@ -1,10 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly 1`] = `
<main>
<A11ySkipTarget
anchor="admin_main"
/>
<Outlet />
</main>
`;

Loading…
Cancel
Save