]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-18423 Migrate background tasks app to RTL
author7PH <benjamin.raymond@sonarsource.com>
Fri, 14 Apr 2023 14:48:36 +0000 (16:48 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 17 Apr 2023 20:02:52 +0000 (20:02 +0000)
36 files changed:
server/sonar-web/src/main/js/api/mocks/ComputeEngineServiceMock.ts
server/sonar-web/src/main/js/apps/background-tasks/__tests__/BackgroundTasks-it.tsx
server/sonar-web/src/main/js/apps/background-tasks/__tests__/BackgroundTasks-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/__tests__/utils-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/ScannerContext.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/Stacktrace.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/StatPendingCount.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.tsx
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/BackgroundTasksApp-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/NoWorkersSupportPopup-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/ScannerContext-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/Stacktrace-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatPendingCount-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatPendingTime-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatStillFailing-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskActions-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskComponent-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskDate-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskStatus-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/Workers-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/BackgroundTasksApp-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/NoWorkersSupportPopup-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/ScannerContext-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Stacktrace-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatPendingCount-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatPendingTime-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatStillFailing-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskActions-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskComponent-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskDate-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskStatus-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.tsx.snap [deleted file]
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 531acde76b44967d5ab3fc71f05b2f434633b4a0..d892eda5901f9afcb8c5a9053808ae7a93f9eb1f 100644 (file)
@@ -28,6 +28,7 @@ import {
   cancelTask,
   getActivity,
   getStatus,
+  getTask,
   getTypes,
   getWorkers,
   setWorkerCount,
@@ -65,6 +66,7 @@ export default class ComputeEngineServiceMock {
     (getActivity as jest.Mock).mockImplementation(this.handleGetActivity);
     (getStatus as jest.Mock).mockImplementation(this.handleGetStatus);
     (getTypes as jest.Mock).mockImplementation(this.handleGetTypes);
+    (getTask as jest.Mock).mockImplementation(this.handleGetTask);
     (getWorkers as jest.Mock).mockImplementation(this.handleGetWorkers);
     (setWorkerCount as jest.Mock).mockImplementation(this.handleSetWorkerCount);
 
@@ -165,6 +167,16 @@ export default class ComputeEngineServiceMock {
 
   handleGetTypes = () => Promise.resolve([...TASK_TYPES]);
 
+  handleGetTask = (id: string) => {
+    const task = this.tasks.find((t) => t.id === id);
+
+    if (task) {
+      return Promise.resolve(task);
+    }
+
+    return Promise.reject();
+  };
+
   handleGetWorkers = () => Promise.resolve({ ...this.workers });
 
   handleSetWorkerCount = (count: number) => {
index 30da2bf09f7240b42d88a8c88d4cbb9e0cf3ff52..2db1eb701ce9e0f1dcf9e508f19f8dba716fb02f 100644 (file)
  */
 import { screen, waitFor, within } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
-import { UserEvent } from '@testing-library/user-event/dist/types/setup/setup';
+import { byLabelText, byPlaceholderText, byRole, byText } from 'testing-library-selector';
 import ComputeEngineServiceMock from '../../../api/mocks/ComputeEngineServiceMock';
 import { mockAppState } from '../../../helpers/testMocks';
-import { renderAppWithAdminContext, RenderContext } from '../../../helpers/testReactTestingUtils';
+import { RenderContext, renderAppWithAdminContext } from '../../../helpers/testReactTestingUtils';
 import { EditionKey } from '../../../types/editions';
 import { TaskStatuses, TaskTypes } from '../../../types/tasks';
 import routes from '../routes';
 
 jest.mock('../../../api/ce');
 
-jest.mock('../constants', () => {
-  const contants = jest.requireActual('../constants');
-
-  return { ...contants, PAGE_SIZE: 9 };
-});
-
-let computeEngineServiceMock: ComputeEngineServiceMock;
+const computeEngineServiceMock = new ComputeEngineServiceMock();
 
 beforeAll(() => {
-  computeEngineServiceMock = new ComputeEngineServiceMock();
+  computeEngineServiceMock.reset();
 });
 
 afterEach(() => computeEngineServiceMock.reset());
 
 describe('The Global background task page', () => {
   it('should display the list of workers and allow edit', async () => {
-    const user = userEvent.setup();
+    const { ui, user } = getPageObject();
 
     renderGlobalBackgroundTasksApp();
+    await ui.appLoaded();
 
-    expect(
-      within(await screen.findByText('background_tasks.number_of_workers')).getByText('2')
-    ).toBeInTheDocument();
+    expect(within(ui.numberOfWorkers.get()).getByText('2')).toBeInTheDocument();
 
     const editWorkersButton = screen.getByRole('button', {
       name: 'background_tasks.change_number_of_workers',
@@ -76,13 +69,11 @@ describe('The Global background task page', () => {
 
     await user.click(within(modal).getByRole('button', { name: 'save' }));
 
-    expect(
-      within(await screen.findByText('background_tasks.number_of_workers')).getByText('4')
-    ).toBeInTheDocument();
+    expect(within(ui.numberOfWorkers.get()).getByText('4')).toBeInTheDocument();
   });
 
   it('should display the list of tasks', async () => {
-    const user = userEvent.setup();
+    const { ui, user } = getPageObject();
 
     computeEngineServiceMock.clearTasks();
     computeEngineServiceMock.addTask({ status: TaskStatuses.Canceled, type: TaskTypes.AppRefresh });
@@ -102,57 +93,54 @@ describe('The Global background task page', () => {
     });
 
     renderGlobalBackgroundTasksApp();
+    await ui.appLoaded();
 
-    expect(
-      await screen.findByRole('heading', { name: 'background_tasks.page' })
-    ).toBeInTheDocument();
+    expect(ui.pageHeading.get()).toBeInTheDocument();
 
-    expect(screen.getAllByRole('row')).toHaveLength(5); // including header, excluding pending (default filter)
+    expect(ui.getAllRows()).toHaveLength(4);
 
-    await changeTaskFilter(user, 'status', 'background_task.status.IN_PROGRESS');
-    expect(await screen.findAllByRole('row')).toHaveLength(2); // including header
+    await ui.changeTaskFilter('status', 'background_task.status.IN_PROGRESS');
+    expect(ui.getAllRows()).toHaveLength(1);
 
-    await changeTaskFilter(user, 'status', 'background_task.status.ALL');
-    expect(await screen.findAllByRole('row')).toHaveLength(6); // including header
+    await ui.changeTaskFilter('status', 'background_task.status.ALL');
+    expect(ui.getAllRows()).toHaveLength(5);
 
-    await changeTaskFilter(user, 'type', `background_task.type.${TaskTypes.AppRefresh}`);
-    expect(await screen.findAllByRole('row')).toHaveLength(4); // including header
+    await ui.changeTaskFilter('type', `background_task.type.${TaskTypes.AppRefresh}`);
+    expect(ui.getAllRows()).toHaveLength(3);
 
-    await user.click(screen.getByRole('checkbox', { name: 'yes' }));
-    expect(await screen.findAllByRole('row')).toHaveLength(3); // including header
-    await user.click(screen.getByRole('checkbox', { name: 'yes' }));
+    await user.click(ui.onlyLatestAnalysis.get());
+    expect(ui.getAllRows()).toHaveLength(2);
+    await user.click(ui.onlyLatestAnalysis.get());
 
     /*
      * Must test date range filters, but it requires refactoring the DateRange component
      */
-
-    const searchBox = screen.getByPlaceholderText('background_tasks.search_by_task_or_component');
-    expect(searchBox).toBeInTheDocument();
-    await user.click(searchBox);
+    await user.click(ui.search.get());
     await user.keyboard('other');
 
-    expect(await screen.findAllByRole('row')).toHaveLength(2); // including header
+    expect(ui.getAllRows()).toHaveLength(1);
 
-    //reset filters
-    await user.click(screen.getByRole('button', { name: 'reset_verb' }));
-    expect(screen.getAllByRole('row')).toHaveLength(5);
+    // Reset filters
+    await user.click(ui.resetFilters.get());
+    expect(ui.getAllRows()).toHaveLength(4);
 
-    // reset tasks (internally) and reload:
+    // Reset tasks (internally) and reload:
     computeEngineServiceMock.reset();
-    await changeTaskFilter(user, 'status', 'background_task.status.ALL');
-    await user.click(screen.getByRole('button', { name: 'reload' }));
-    expect(await screen.findAllByRole('row')).toHaveLength(2);
+    await ui.changeTaskFilter('status', 'background_task.status.ALL');
+    await user.click(ui.reloadButton.get());
+    expect(ui.getAllRows()).toHaveLength(1);
   });
 
   it.each([[EditionKey.community], [EditionKey.developer], [EditionKey.enterprise]])(
-    'Editions %s should not display node name',
+    '%s should not display node name',
     async (editionKey: EditionKey) => {
+      const { ui } = getPageObject();
       givenOneTaskWithoutNodeNameAndOneWithNodeName();
 
       renderGlobalBackgroundTasksApp({ appState: mockAppState({ edition: editionKey }) });
 
       await waitFor(() => {
-        expect(screen.getAllByRole('row')).toHaveLength(3); // including header
+        expect(ui.getAllRows()).toHaveLength(2);
       });
 
       expect(screen.queryByText('background_tasks.table.nodeName')).not.toBeInTheDocument();
@@ -160,44 +148,126 @@ describe('The Global background task page', () => {
     }
   );
 
-  it('Node name should be shown in DCE edition', async () => {
+  it('DCE edition should display node name', async () => {
+    const { ui } = getPageObject();
     givenOneTaskWithoutNodeNameAndOneWithNodeName();
 
     renderGlobalBackgroundTasksApp({ appState: mockAppState({ edition: EditionKey.datacenter }) });
+    await ui.appLoaded();
 
-    await waitFor(async () => {
-      expect(await screen.findByText('background_tasks.table.nodeName')).toBeInTheDocument();
-    });
+    expect(screen.getByText('background_tasks.table.nodeName')).toBeInTheDocument();
 
-    expect(
-      within(await screen.getAllByRole('row')[1]).getByText('best_node_ever')
-    ).toBeInTheDocument();
+    expect(within(ui.getAllRows()[0]).getByText('best_node_ever')).toBeInTheDocument();
   });
 
   it('should handle task pagination', async () => {
-    const user = userEvent.setup();
+    const { ui, user } = getPageObject();
 
     computeEngineServiceMock.clearTasks();
-    computeEngineServiceMock.createTasks(10);
+    computeEngineServiceMock.createTasks(101);
 
     renderGlobalBackgroundTasksApp();
+    await ui.appLoaded();
 
-    expect(
-      await screen.findByRole('heading', { name: 'background_tasks.page' })
-    ).toBeInTheDocument();
+    expect(ui.pageHeading.get()).toBeInTheDocument();
 
-    expect(screen.getAllByRole('row')).toHaveLength(10); // including header
+    expect(ui.getAllRows()).toHaveLength(100);
 
-    user.click(screen.getByRole('button', { name: 'show_more' }));
+    user.click(ui.showMoreButton.get());
 
     await waitFor(() => {
-      expect(screen.getAllByRole('row')).toHaveLength(11); // including header
+      expect(ui.getAllRows()).toHaveLength(101);
+    });
+  });
+
+  it('should filter using row list', async () => {
+    const { ui, user } = getPageObject();
+
+    computeEngineServiceMock.clearTasks();
+    computeEngineServiceMock.addTask({ status: TaskStatuses.Success });
+    computeEngineServiceMock.addTask({
+      status: TaskStatuses.Failed,
+      errorMessage: 'FooError',
+      errorStacktrace: 'FooStackTrace',
+    });
+    computeEngineServiceMock.addTask({
+      status: TaskStatuses.Failed,
+      warningCount: 2,
+      warnings: ['FooWarning1', 'FooWarning2'],
+    });
+    computeEngineServiceMock.addTask({
+      status: TaskStatuses.Success,
+      hasScannerContext: true,
+      scannerContext: 'FooScannerContext',
     });
+    computeEngineServiceMock.addTask({
+      componentKey: 'otherComponent',
+      status: TaskStatuses.Success,
+    });
+
+    renderGlobalBackgroundTasksApp();
+    await ui.appLoaded();
+
+    // Filter by first task component
+    expect(ui.getAllRows()).toHaveLength(5);
+    await ui.clickOnTaskAction(0, 'background_tasks.filter_by_component_x.Foo');
+    expect(ui.getAllRows()).toHaveLength(4);
+
+    // Show second task error
+    await user.click(ui.resetFilters.get());
+    await ui.clickOnTaskAction(1, 'background_tasks.show_stacktrace');
+    expect(within(screen.getByRole('dialog')).getByText('FooStackTrace')).toBeInTheDocument();
+    await user.click(screen.getByRole('button', { name: 'close' }));
+
+    // Show third task warnings
+    await user.click(ui.resetFilters.get());
+    await ui.clickOnTaskAction(2, 'background_tasks.show_warnings');
+    expect(within(screen.getByRole('dialog')).getByText('FooWarning1')).toBeInTheDocument();
+    expect(within(screen.getByRole('dialog')).getByText('FooWarning2')).toBeInTheDocument();
+    await user.click(screen.getByRole('button', { name: 'close' }));
+
+    // Show fourth task scanner context
+    await user.click(ui.resetFilters.get());
+    await ui.clickOnTaskAction(3, 'background_tasks.show_scanner_context');
+    expect(within(screen.getByRole('dialog')).getByText('FooScannerContext')).toBeInTheDocument();
+    await user.click(screen.getByRole('button', { name: 'close' }));
   });
 
-  /*
-   * Must also test row actions
-   */
+  it('should cancel all pending tasks', async () => {
+    const { ui, user } = getPageObject();
+
+    computeEngineServiceMock.clearTasks();
+    computeEngineServiceMock.addTask({
+      status: TaskStatuses.Pending,
+    });
+    computeEngineServiceMock.addTask({
+      status: TaskStatuses.Pending,
+    });
+    computeEngineServiceMock.addTask({
+      status: TaskStatuses.Success,
+    });
+
+    renderGlobalBackgroundTasksApp({
+      appState: mockAppState({ canAdmin: true }),
+    });
+    await ui.appLoaded();
+
+    // Pending tasks should not be shown by default
+    expect(ui.getAllRows()).toHaveLength(1);
+
+    // Verify two pending tasks are shown when filtering by pending
+    await ui.changeTaskFilter('status', 'background_task.status.PENDING');
+    expect(ui.getAllRows()).toHaveLength(2);
+
+    // Cancel all tasks
+    await user.click(ui.cancelAllButton.get());
+    await user.click(ui.cancelAllButtonConfirm.get());
+    expect(ui.getAllRows()).toHaveLength(0);
+
+    // Go back to default filter, all tasks should now be shown
+    await ui.changeTaskFilter('status', 'background_task.status.ALL_EXCEPT_PENDING');
+    expect(ui.getAllRows()).toHaveLength(3);
+  });
 });
 
 function givenOneTaskWithoutNodeNameAndOneWithNodeName() {
@@ -219,9 +289,51 @@ function givenOneTaskWithoutNodeNameAndOneWithNodeName() {
   });
 }
 
-async function changeTaskFilter(user: UserEvent, fieldLabel: string, value: string) {
-  await user.click(screen.getByLabelText(fieldLabel, { selector: 'input' }));
-  await user.click(screen.getByText(value));
+function getPageObject() {
+  const user = userEvent.setup();
+
+  const selectors = {
+    loading: byLabelText('loading'),
+    pageHeading: byRole('heading', { name: 'background_tasks.page' }),
+    numberOfWorkers: byText('background_tasks.number_of_workers'),
+    onlyLatestAnalysis: byRole('checkbox', { name: 'yes' }),
+    search: byPlaceholderText('background_tasks.search_by_task_or_component'),
+    resetFilters: byRole('button', { name: 'reset_verb' }),
+    showMoreButton: byRole('button', { name: 'show_more' }),
+    reloadButton: byRole('button', { name: 'reload' }),
+    cancelAllButton: byRole('button', { description: 'background_tasks.cancel_all_tasks' }),
+    cancelAllButtonConfirm: byText('background_tasks.cancel_all_tasks.submit'),
+    row: byRole('row'),
+  };
+
+  const ui = {
+    ...selectors,
+
+    appLoaded: async () => {
+      await waitFor(() => {
+        expect(selectors.loading.query()).not.toBeInTheDocument();
+      });
+    },
+
+    getAllRows: () => screen.getAllByRole('row').slice(1), // Excludes header
+
+    changeTaskFilter: async (fieldLabel: string, value: string) => {
+      await user.click(screen.getByLabelText(fieldLabel, { selector: 'input' }));
+      await user.click(screen.getByText(value));
+    },
+
+    clickOnTaskAction: async (rowIndex: number, label: string) => {
+      const row = ui.getAllRows()[rowIndex];
+      expect(row).toBeVisible();
+      await user.click(within(row).getByRole('button', { name: 'background_tasks.show_actions' }));
+      await user.click(within(row).getByRole('button', { name: label }));
+    },
+  };
+
+  return {
+    ui,
+    user,
+  };
 }
 
 function renderGlobalBackgroundTasksApp(context: RenderContext = {}) {
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/__tests__/BackgroundTasks-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/__tests__/BackgroundTasks-test.tsx
deleted file mode 100644 (file)
index bf64405..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { click } from '../../../helpers/testUtils';
-import Search from '../components/Search';
-import { DEFAULT_FILTERS } from '../constants';
-import { formatDuration } from '../utils';
-
-describe('Search', () => {
-  const defaultProps: Search['props'] = {
-    ...DEFAULT_FILTERS,
-    loading: false,
-    types: [],
-    onFilterUpdate: () => true,
-    onReload: () => true,
-    maxExecutedAt: undefined,
-    minSubmittedAt: undefined,
-  };
-
-  it('should render search form', () => {
-    const component = shallow(<Search {...defaultProps} />);
-    expect(component.find('SearchBox').exists()).toBe(true);
-  });
-
-  it('should not render search form', () => {
-    const component = shallow(<Search {...defaultProps} component={{ id: 'ABCD' }} />);
-    expect(component.find('SearchBox').exists()).toBe(false);
-  });
-
-  it('should search', () => {
-    const searchSpy = jest.fn();
-    const component = shallow(<Search {...defaultProps} onFilterUpdate={searchSpy} />);
-    const searchInput = component.find('SearchBox');
-    searchInput.prop<Function>('onChange')('some search query');
-    expect(searchSpy).toHaveBeenCalledWith({ query: 'some search query' });
-  });
-
-  it('should reload', () => {
-    const reloadSpy = jest.fn();
-    const component = shallow(<Search {...defaultProps} onReload={reloadSpy} />);
-    const reloadButton = component.find('.js-reload');
-    expect(reloadSpy).not.toHaveBeenCalled();
-    click(reloadButton);
-    expect(reloadSpy).toHaveBeenCalled();
-  });
-});
-
-describe('Helpers', () => {
-  describe('#formatDuration()', () => {
-    it('should format 173ms', () => {
-      expect(formatDuration(173)).toBe('173ms');
-    });
-
-    it('should format 999ms', () => {
-      expect(formatDuration(999)).toBe('999ms');
-    });
-
-    it('should format 1s 0ms', () => {
-      expect(formatDuration(1000)).toBe('1.0s');
-    });
-
-    it('should format 1s 1ms', () => {
-      expect(formatDuration(1001)).toBe('1.1s');
-    });
-
-    it('should format 1s 501ms', () => {
-      expect(formatDuration(1501)).toBe('1.501s');
-    });
-
-    it('should format 59s', () => {
-      expect(formatDuration(59000)).toBe('59s');
-    });
-
-    it('should format 1min 0s', () => {
-      expect(formatDuration(60000)).toBe('1min 0s');
-    });
-
-    it('should format 1min 2s', () => {
-      expect(formatDuration(62757)).toBe('1min 2s');
-    });
-
-    it('should format 3min 44s', () => {
-      expect(formatDuration(224567)).toBe('3min 44s');
-    });
-
-    it('should format 1h 20m', () => {
-      expect(formatDuration(80 * 60 * 1000)).toBe('1h 20min');
-    });
-  });
-});
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/__tests__/utils-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/__tests__/utils-test.tsx
new file mode 100644 (file)
index 0000000..5183481
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { formatDuration } from '../utils';
+
+describe('Helpers', () => {
+  describe('#formatDuration()', () => {
+    it('should format 173ms', () => {
+      expect(formatDuration(173)).toBe('173ms');
+    });
+
+    it('should format 999ms', () => {
+      expect(formatDuration(999)).toBe('999ms');
+    });
+
+    it('should format 1s 0ms', () => {
+      expect(formatDuration(1000)).toBe('1.0s');
+    });
+
+    it('should format 1s 1ms', () => {
+      expect(formatDuration(1001)).toBe('1.1s');
+    });
+
+    it('should format 1s 501ms', () => {
+      expect(formatDuration(1501)).toBe('1.501s');
+    });
+
+    it('should format 59s', () => {
+      expect(formatDuration(59000)).toBe('59s');
+    });
+
+    it('should format 1min 0s', () => {
+      expect(formatDuration(60000)).toBe('1min 0s');
+    });
+
+    it('should format 1min 2s', () => {
+      expect(formatDuration(62757)).toBe('1min 2s');
+    });
+
+    it('should format 3min 44s', () => {
+      expect(formatDuration(224567)).toBe('3min 44s');
+    });
+
+    it('should format 1h 20m', () => {
+      expect(formatDuration(80 * 60 * 1000)).toBe('1h 20min');
+    });
+  });
+});
index 0b37e713584a620796469194bca182e5d94804ac..7d8d47d5f7ccc26e1e59f2e0e1f0f46efd5d46d2 100644 (file)
@@ -31,6 +31,7 @@ import withComponentContext from '../../../app/components/componentContext/withC
 import ListFooter from '../../../components/controls/ListFooter';
 import Suggestions from '../../../components/embed-docs-modal/Suggestions';
 import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
+import DeferredSpinner from '../../../components/ui/DeferredSpinner';
 import { toShortNotSoISOString } from '../../../helpers/dates';
 import { translate } from '../../../helpers/l10n';
 import { parseAsDate } from '../../../helpers/query';
@@ -38,7 +39,7 @@ import { Task, TaskStatuses } from '../../../types/tasks';
 import { Component, Paging, RawQuery } from '../../../types/types';
 import '../background-tasks.css';
 import { CURRENTS, DEBOUNCE_DELAY, DEFAULT_FILTERS, PAGE_SIZE } from '../constants';
-import { mapFiltersToParameters, Query, updateTask } from '../utils';
+import { Query, mapFiltersToParameters, updateTask } from '../utils';
 import Header from './Header';
 import Search from './Search';
 import Stats from './Stats';
@@ -217,7 +218,7 @@ export class BackgroundTasksApp extends React.PureComponent<Props, State> {
       return (
         <div className="page page-limited">
           <Helmet defer={false} title={translate('background_tasks.page')} />
-          <i className="spinner" />
+          <DeferredSpinner loading={true} />
         </div>
       );
     }
index d9dd53769e012464206aac3a067c35699ddca894..a63cd07032ed7df5c4033929eda2cbc4b17b6783 100644 (file)
@@ -20,6 +20,7 @@
 import * as React from 'react';
 import { getTask } from '../../../api/ce';
 import Modal from '../../../components/controls/Modal';
+import { ResetButtonLink } from '../../../components/controls/buttons';
 import { translate } from '../../../helpers/l10n';
 import { Task } from '../../../types/tasks';
 
@@ -53,11 +54,6 @@ export default class ScannerContext extends React.PureComponent<Props, State> {
     });
   }
 
-  handleCloseClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
-    event.preventDefault();
-    this.props.onClose();
-  };
-
   render() {
     const { task } = this.props;
     const { scannerContext } = this.state;
@@ -84,9 +80,7 @@ export default class ScannerContext extends React.PureComponent<Props, State> {
         </div>
 
         <div className="modal-foot">
-          <a className="js-modal-close" href="#" onClick={this.handleCloseClick}>
-            {translate('close')}
-          </a>
+          <ResetButtonLink onClick={this.props.onClose}>{translate('close')}</ResetButtonLink>
         </div>
       </Modal>
     );
index bb2d68563725a364046b4dfdc359184a00a86c9e..367ad202a300e8b611264de9466e587d83a81731 100644 (file)
@@ -20,6 +20,7 @@
 import * as React from 'react';
 import { getTask } from '../../../api/ce';
 import Modal from '../../../components/controls/Modal';
+import { ResetButtonLink } from '../../../components/controls/buttons';
 import { translate } from '../../../helpers/l10n';
 import { Task } from '../../../types/tasks';
 
@@ -61,11 +62,6 @@ export default class Stacktrace extends React.PureComponent<Props, State> {
     );
   }
 
-  handleCloseClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
-    event.preventDefault();
-    this.props.onClose();
-  };
-
   render() {
     const { task } = this.props;
     const { loading, stacktrace } = this.state;
@@ -100,9 +96,9 @@ export default class Stacktrace extends React.PureComponent<Props, State> {
         </div>
 
         <div className="modal-foot">
-          <a className="js-modal-close" href="#" onClick={this.handleCloseClick}>
+          <ResetButtonLink className="js-modal-close" onClick={this.props.onClose}>
             {translate('close')}
-          </a>
+          </ResetButtonLink>
         </div>
       </Modal>
     );
index 68e5a41c5302f4494c0cd00e14c7228c89094452..a6e9616042674882e9a8e736aba4ede5a980af7e 100644 (file)
@@ -20,9 +20,9 @@
 import * as React from 'react';
 import withAppStateContext from '../../../app/components/app-state/withAppStateContext';
 import { colors } from '../../../app/theme';
-import { ClearButton } from '../../../components/controls/buttons';
 import ConfirmButton from '../../../components/controls/ConfirmButton';
 import Tooltip from '../../../components/controls/Tooltip';
+import { ClearButton } from '../../../components/controls/buttons';
 import { translate } from '../../../helpers/l10n';
 import { AppState } from '../../../types/appstate';
 
@@ -32,7 +32,7 @@ export interface Props {
   pendingCount?: number;
 }
 
-export function StatPendingCount({ appState, onCancelAllPending, pendingCount }: Props) {
+function StatPendingCount({ appState, onCancelAllPending, pendingCount }: Props) {
   if (pendingCount === undefined) {
     return null;
   }
index d71c305bb4dcb30c708b2da478cfd5e17a0bf92b..35ade871b498f6d23b0931c240edce228b96a669 100644 (file)
@@ -104,7 +104,10 @@ export default class TaskActions extends React.PureComponent<Props, State> {
 
     return (
       <td className="thin nowrap">
-        <ActionsDropdown className="js-task-action">
+        <ActionsDropdown
+          label={translate('background_tasks.show_actions')}
+          className="js-task-action"
+        >
           {canFilter && task.componentName && (
             <ActionsDropdownItem className="js-task-filter" onClick={this.handleFilterClick}>
               {translateWithParameters(
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/BackgroundTasksApp-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/BackgroundTasksApp-test.tsx
deleted file mode 100644 (file)
index 83f5a92..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { mockComponent } from '../../../../helpers/mocks/component';
-import { mockLocation, mockRouter } from '../../../../helpers/testMocks';
-import { waitAndUpdate } from '../../../../helpers/testUtils';
-import { BackgroundTasksApp } from '../BackgroundTasksApp';
-
-jest.mock('../../../../api/ce', () => ({
-  getTypes: jest.fn().mockResolvedValue({
-    taskTypes: ['REPORT', 'PROJECT_EXPORT', 'PROJECT_IMPORT', 'VIEW_REFRESH'],
-  }),
-  getActivity: jest.fn().mockResolvedValue({
-    tasks: [
-      {
-        id: 'AWkGcOThOiAPiP5AE-kM',
-        type: 'VIEW_REFRESH',
-        nodeName: 'node_CE_server_1',
-        componentId: 'AWBLZYhGOUrjxRA-u6ex',
-        componentKey: 'sonar-csharp',
-        componentName: 'SonarC#',
-        componentQualifier: 'APP',
-        status: 'FAILED',
-        submittedAt: '2019-02-19T16:47:35+0100',
-        startedAt: '2019-02-19T16:47:36+0100',
-        executedAt: '2019-02-19T16:47:36+0100',
-        executionTimeMs: 16,
-        logs: false,
-        errorMessage:
-          'Analyses suspended. Please set a valid license for the Edition you installed.',
-        hasScannerContext: false,
-        errorType: 'LICENSING',
-        warningCount: 0,
-        warnings: [],
-      },
-      {
-        id: 'AWkGcOThOiAPiP5AE-kL',
-        type: 'VIEW_REFRESH',
-        componentId: 'AV2ZaHs1Wa2znA6pDz1l',
-        componentKey: 'c-cpp-build-wrapper',
-        componentName: 'C/C++ Build Wrapper',
-        componentQualifier: 'APP',
-        status: 'SUCCESS',
-        submittedAt: '2019-02-19T16:47:35+0100',
-        startedAt: '2019-02-19T16:47:36+0100',
-        executedAt: '2019-02-19T16:47:36+0100',
-        executionTimeMs: 19,
-        logs: false,
-        hasScannerContext: false,
-        warningCount: 0,
-        warnings: [],
-      },
-    ],
-    paging: { total: 2, pageIndex: 1 },
-  }),
-  getStatus: jest.fn().mockResolvedValue({ pending: 0, failing: 15, inProgress: 0 }),
-  cancelAllTasks: jest.fn().mockResolvedValue({}),
-  cancelTask: jest.fn().mockResolvedValue({}),
-}));
-
-beforeEach(() => {
-  jest.clearAllMocks();
-});
-
-it('should render correctly', async () => {
-  const wrapper = shallowRender();
-  expect(wrapper).toMatchSnapshot('initial');
-
-  await waitAndUpdate(wrapper);
-  expect(wrapper).toMatchSnapshot('loaded');
-});
-
-function shallowRender(props: Partial<BackgroundTasksApp['props']> = {}) {
-  return shallow(
-    <BackgroundTasksApp
-      component={mockComponent({ key: 'foo' })}
-      location={mockLocation()}
-      router={mockRouter()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/NoWorkersSupportPopup-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/NoWorkersSupportPopup-test.tsx
deleted file mode 100644 (file)
index 091a1bc..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 NoWorkersSupportPopup from '../NoWorkersSupportPopup';
-
-it('should render correctly', () => {
-  expect(shallow(<NoWorkersSupportPopup />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/ScannerContext-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/ScannerContext-test.tsx
deleted file mode 100644 (file)
index 3cbfa29..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { mockTask } from '../../../../helpers/mocks/tasks';
-import { click } from '../../../../helpers/testUtils';
-import { TaskTypes } from '../../../../types/tasks';
-import ScannerContext from '../ScannerContext';
-
-jest.mock('../../../../api/ce', () => ({
-  getTask: jest.fn(() => Promise.resolve({ scannerContext: 'context' })),
-}));
-
-const getTask = require('../../../../api/ce').getTask as jest.Mock<any>;
-
-const task = mockTask({
-  componentName: 'foo',
-  id: '123',
-  type: TaskTypes.Report,
-});
-
-beforeEach(() => {
-  getTask.mockClear();
-});
-
-it('renders', () => {
-  const wrapper = shallow(<ScannerContext onClose={jest.fn()} task={task} />);
-  wrapper.setState({ scannerContext: 'context' });
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('closes', () => {
-  const onClose = jest.fn();
-  const wrapper = shallow(<ScannerContext onClose={onClose} task={task} />);
-  click(wrapper.find('.js-modal-close'));
-  expect(onClose).toHaveBeenCalled();
-});
-
-it('fetches scanner context on mount', async () => {
-  const wrapper = shallow(<ScannerContext onClose={jest.fn()} task={task} />);
-  expect(wrapper.state()).toEqual({});
-  expect(getTask).toHaveBeenCalledWith('123', ['scannerContext']);
-  await new Promise(setImmediate);
-  expect(wrapper.state()).toEqual({ scannerContext: 'context' });
-});
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/Stacktrace-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/Stacktrace-test.tsx
deleted file mode 100644 (file)
index 82a32cf..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { mockTask } from '../../../../helpers/mocks/tasks';
-import { click } from '../../../../helpers/testUtils';
-import { TaskTypes } from '../../../../types/tasks';
-import Stacktrace from '../Stacktrace';
-
-jest.mock('../../../../api/ce', () => ({
-  getTask: jest.fn(() => Promise.resolve({ errorStacktrace: 'stacktrace' })),
-}));
-
-const getTask = require('../../../../api/ce').getTask as jest.Mock<any>;
-
-const task = mockTask({
-  componentName: 'foo',
-  id: '123',
-  type: TaskTypes.Report,
-});
-
-beforeEach(() => {
-  getTask.mockClear();
-});
-
-it('renders', () => {
-  const wrapper = shallow(<Stacktrace onClose={jest.fn()} task={task} />);
-  wrapper.setState({ loading: false, stacktrace: 'stacktrace' });
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('closes', () => {
-  const onClose = jest.fn();
-  const wrapper = shallow(<Stacktrace onClose={onClose} task={task} />);
-  click(wrapper.find('.js-modal-close'));
-  expect(onClose).toHaveBeenCalled();
-});
-
-it('fetches scanner context on mount', async () => {
-  const wrapper = shallow(<Stacktrace onClose={jest.fn()} task={task} />);
-  expect(wrapper.state()).toEqual({ loading: true });
-  expect(getTask).toHaveBeenCalledWith('123', ['stacktrace']);
-  await new Promise(setImmediate);
-  expect(wrapper.state()).toEqual({ loading: false, stacktrace: 'stacktrace' });
-});
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatPendingCount-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatPendingCount-test.tsx
deleted file mode 100644 (file)
index c096b24..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { Props, StatPendingCount } from '../StatPendingCount';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should not render', () => {
-  expect(shallowRender({ pendingCount: undefined }).type()).toBeNull();
-});
-
-it('should not show cancel pending button', () => {
-  expect(shallowRender({ pendingCount: 0 }).find('ConfirmButton').exists()).toBe(false);
-  expect(
-    shallowRender({ appState: mockAppState({ canAdmin: false }) })
-      .find('ConfirmButton')
-      .exists()
-  ).toBe(false);
-});
-
-it('should trigger cancelling pending', () => {
-  const onCancelAllPending = jest.fn();
-  const result = shallowRender({ onCancelAllPending });
-  expect(onCancelAllPending).not.toHaveBeenCalled();
-  result.find('ConfirmButton').prop<Function>('onConfirm')();
-  expect(onCancelAllPending).toHaveBeenCalled();
-});
-
-function shallowRender(props: Partial<Props> = {}) {
-  return shallow(
-    <StatPendingCount
-      appState={mockAppState({ canAdmin: true })}
-      onCancelAllPending={jest.fn()}
-      pendingCount={5}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatPendingTime-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatPendingTime-test.tsx
deleted file mode 100644 (file)
index 1610f4c..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 StatPendingTime, { Props } from '../StatPendingTime';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should not render', () => {
-  expect(shallowRender({ pendingCount: undefined }).type()).toBeNull();
-  expect(shallowRender({ pendingCount: 0 }).type()).toBeNull();
-  expect(shallowRender({ pendingTime: undefined }).type()).toBeNull();
-});
-
-it('should not render when pending time is too small', () => {
-  expect(shallowRender({ pendingTime: 0 }).find('.emphasised-measure').exists()).toBe(false);
-  expect(shallowRender({ pendingTime: 900 }).find('.emphasised-measure').exists()).toBe(false);
-});
-
-function shallowRender(props: Partial<Props> = {}) {
-  return shallow(<StatPendingTime pendingCount={5} pendingTime={15420} {...props} />);
-}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatStillFailing-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/StatStillFailing-test.tsx
deleted file mode 100644 (file)
index 9566c7e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { click } from '../../../../helpers/testUtils';
-import StatStillFailing, { Props } from '../StatStillFailing';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should not render', () => {
-  expect(shallowRender({ failingCount: undefined }).type()).toBeNull();
-});
-
-it('should render without the filter link', () => {
-  expect(shallowRender({ failingCount: 0 })).toMatchSnapshot();
-});
-
-it('should trigger filtering failures', () => {
-  const onShowFailing = jest.fn();
-  const result = shallowRender({ onShowFailing });
-  expect(onShowFailing).not.toHaveBeenCalled();
-  click(result.find('ButtonLink'));
-  expect(onShowFailing).toHaveBeenCalled();
-});
-
-function shallowRender(props: Partial<Props> = {}) {
-  return shallow(<StatStillFailing failingCount={5} onShowFailing={jest.fn()} {...props} />);
-}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskActions-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskActions-test.tsx
deleted file mode 100644 (file)
index a214e6f..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { mockTask } from '../../../../helpers/mocks/tasks';
-import { click } from '../../../../helpers/testUtils';
-import { Task, TaskStatuses } from '../../../../types/tasks';
-import TaskActions from '../TaskActions';
-
-it('renders', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ status: TaskStatuses.Success })).toMatchSnapshot();
-  expect(shallowRender({ hasScannerContext: true })).toMatchSnapshot();
-  expect(shallowRender({ errorMessage: 'error!' })).toMatchSnapshot();
-  expect(shallowRender({}, { component: { key: 'foo' } })).toMatchSnapshot();
-});
-
-it('shows stack trace', () => {
-  const wrapper = shallowRender({ errorMessage: 'error!' });
-  click(wrapper.find('.js-task-show-stacktrace'));
-  expect(wrapper.find('Stacktrace')).toMatchSnapshot();
-  wrapper.find('Stacktrace').prop<Function>('onClose')();
-  wrapper.update();
-  expect(wrapper.find('Stacktrace').exists()).toBe(false);
-});
-
-it('shows scanner context', () => {
-  const wrapper = shallowRender({ hasScannerContext: true });
-  click(wrapper.find('.js-task-show-scanner-context'));
-  expect(wrapper.find('ScannerContext')).toMatchSnapshot();
-  wrapper.find('ScannerContext').prop<Function>('onClose')();
-  wrapper.update();
-  expect(wrapper.find('ScannerContext').exists()).toBe(false);
-});
-
-it('shows warnings', () => {
-  const wrapper = shallowRender({ warningCount: 2 });
-  click(wrapper.find('.js-task-show-warnings'));
-  expect(wrapper.find('withCurrentUserContext(AnalysisWarningsModal)')).toMatchSnapshot();
-  wrapper.find('withCurrentUserContext(AnalysisWarningsModal)').prop<Function>('onClose')();
-  wrapper.update();
-  expect(wrapper.find('withCurrentUserContext(AnalysisWarningsModal)').exists()).toBe(false);
-});
-
-function shallowRender(fields?: Partial<Task>, props?: Partial<TaskActions['props']>) {
-  return shallow(
-    <TaskActions
-      onCancelTask={jest.fn()}
-      onFilterTask={jest.fn()}
-      task={mockTask({ ...fields })}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskComponent-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskComponent-test.tsx
deleted file mode 100644 (file)
index a79b2c0..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { mockTask } from '../../../../helpers/mocks/tasks';
-import { ComponentQualifier } from '../../../../types/component';
-import { Task } from '../../../../types/tasks';
-import TaskComponent from '../TaskComponent';
-
-it('renders correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ componentKey: undefined })).toMatchSnapshot('undefined key');
-  expect(shallowRender({ componentQualifier: ComponentQualifier.Portfolio })).toMatchSnapshot(
-    'portfolio'
-  );
-  expect(shallowRender({ branch: 'feature' })).toMatchSnapshot('branch');
-  expect(shallowRender({ branch: 'branch-6.7' })).toMatchSnapshot('branch');
-  expect(shallowRender({ pullRequest: 'pr-89' })).toMatchSnapshot('pull request');
-});
-
-function shallowRender(taskOverrides: Partial<Task> = {}) {
-  return shallow(<TaskComponent task={mockTask({ ...taskOverrides })} />);
-}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskDate-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskDate-test.tsx
deleted file mode 100644 (file)
index ea581de..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 TaskDate from '../TaskDate';
-
-it('renders', () => {
-  expect(shallow(<TaskDate />)).toMatchSnapshot();
-  expect(shallow(<TaskDate date="2017-01-01T00:00:00.000Z" />)).toMatchSnapshot();
-  expect(
-    shallow(<TaskDate baseDate="2017-01-01T00:00:00.000Z" date="2017-01-01T00:00:00.000Z" />)
-  ).toMatchSnapshot();
-  expect(
-    shallow(<TaskDate baseDate="2017-01-01T00:00:00.000Z" date="2017-01-05T00:00:00.000Z" />)
-  ).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskStatus-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskStatus-test.tsx
deleted file mode 100644 (file)
index 9990c57..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 TaskStatus from '../TaskStatus';
-
-it('renders', () => {
-  expect.assertions(5);
-  const statuses = ['PENDING', 'IN_PROGRESS', 'SUCCESS', 'FAILED', 'CANCELED'];
-  statuses.forEach((status) => {
-    expect(shallow(<TaskStatus status={status} />)).toMatchSnapshot();
-  });
-});
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/Workers-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/Workers-test.tsx
deleted file mode 100644 (file)
index 8a0537b..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * 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 { click } from '../../../../helpers/testUtils';
-import Workers from '../Workers';
-
-it('renders', () => {
-  const wrapper = shallow(<Workers />);
-  expect(wrapper).toMatchSnapshot();
-
-  wrapper.setState({
-    canSetWorkerCount: true,
-    loading: false,
-    workerCount: 1,
-  });
-  expect(wrapper).toMatchSnapshot();
-
-  wrapper.setState({ workerCount: 2 });
-  expect(wrapper).toMatchSnapshot();
-
-  wrapper.setState({ canSetWorkerCount: false });
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('opens form', () => {
-  const wrapper = shallow(<Workers />);
-
-  wrapper.setState({
-    canSetWorkerCount: true,
-    loading: false,
-    workerCount: 1,
-  });
-  expect(wrapper).toMatchSnapshot();
-
-  click(wrapper.find('.js-edit'));
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('updates worker count', () => {
-  const wrapper = shallow(<Workers />);
-
-  wrapper.setState({
-    canSetWorkerCount: true,
-    formOpen: true,
-    loading: false,
-    workerCount: 1,
-  });
-  expect(wrapper).toMatchSnapshot();
-
-  wrapper.find('WorkersForm').prop<Function>('onClose')(7);
-  wrapper.update();
-  expect(wrapper).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.tsx
deleted file mode 100644 (file)
index 43b537a..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-/* eslint-disable import/first */
-jest.mock('../../../../api/ce', () => ({
-  setWorkerCount: () => Promise.resolve(),
-}));
-
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import Select from '../../../../components/controls/Select';
-import { submit } from '../../../../helpers/testUtils';
-import WorkersForm from '../WorkersForm';
-
-it('changes select', () => {
-  const wrapper = shallow(<WorkersForm onClose={jest.fn()} workerCount={1} />);
-  expect(wrapper).toMatchSnapshot();
-
-  wrapper.find(Select).prop<Function>('onChange')({ value: 7 });
-  wrapper.update();
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('returns new worker count', async () => {
-  const onClose = jest.fn();
-  const wrapper = shallow(<WorkersForm onClose={onClose} workerCount={1} />);
-  (wrapper.instance() as WorkersForm).mounted = true;
-  wrapper.find(Select).prop<Function>('onChange')({ value: 7 });
-
-  wrapper.update();
-  submit(wrapper.find('form'));
-
-  await new Promise(setImmediate);
-  expect(onClose).toHaveBeenCalled();
-});
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/BackgroundTasksApp-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/BackgroundTasksApp-test.tsx.snap
deleted file mode 100644 (file)
index f3363ad..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: initial 1`] = `
-<div
-  className="page page-limited"
->
-  <Helmet
-    defer={false}
-    encodeSpecialCharacters={true}
-    prioritizeSeoTags={false}
-    title="background_tasks.page"
-  />
-  <i
-    className="spinner"
-  />
-</div>
-`;
-
-exports[`should render correctly: loaded 1`] = `
-<main
-  className="page page-limited"
->
-  <Suggestions
-    suggestions="background_tasks"
-  />
-  <Helmet
-    defer={false}
-    encodeSpecialCharacters={true}
-    prioritizeSeoTags={false}
-    title="background_tasks.page"
-  />
-  <Header
-    component={
-      {
-        "breadcrumbs": [],
-        "key": "foo",
-        "name": "MyProject",
-        "qualifier": "TRK",
-        "qualityGate": {
-          "isDefault": true,
-          "key": "30",
-          "name": "Sonar way",
-        },
-        "qualityProfiles": [
-          {
-            "deleted": false,
-            "key": "my-qp",
-            "language": "ts",
-            "name": "Sonar way",
-          },
-        ],
-        "tags": [],
-      }
-    }
-  />
-  <Stats
-    component={
-      {
-        "breadcrumbs": [],
-        "key": "foo",
-        "name": "MyProject",
-        "qualifier": "TRK",
-        "qualityGate": {
-          "isDefault": true,
-          "key": "30",
-          "name": "Sonar way",
-        },
-        "qualityProfiles": [
-          {
-            "deleted": false,
-            "key": "my-qp",
-            "language": "ts",
-            "name": "Sonar way",
-          },
-        ],
-        "tags": [],
-      }
-    }
-    failingCount={15}
-    onCancelAllPending={[Function]}
-    onShowFailing={[Function]}
-    pendingCount={0}
-  />
-  <Search
-    component={
-      {
-        "breadcrumbs": [],
-        "key": "foo",
-        "name": "MyProject",
-        "qualifier": "TRK",
-        "qualityGate": {
-          "isDefault": true,
-          "key": "30",
-          "name": "Sonar way",
-        },
-        "qualityProfiles": [
-          {
-            "deleted": false,
-            "key": "my-qp",
-            "language": "ts",
-            "name": "Sonar way",
-          },
-        ],
-        "tags": [],
-      }
-    }
-    currents="__ALL__"
-    loading={false}
-    onFilterUpdate={[Function]}
-    onReload={[Function]}
-    query=""
-    status="__ALL_EXCEPT_PENDING__"
-    taskType="ALL_TYPES"
-    types={
-      {
-        "taskTypes": [
-          "REPORT",
-          "PROJECT_EXPORT",
-          "PROJECT_IMPORT",
-          "VIEW_REFRESH",
-        ],
-      }
-    }
-  />
-  <withAppStateContext(Tasks)
-    component={
-      {
-        "breadcrumbs": [],
-        "key": "foo",
-        "name": "MyProject",
-        "qualifier": "TRK",
-        "qualityGate": {
-          "isDefault": true,
-          "key": "30",
-          "name": "Sonar way",
-        },
-        "qualityProfiles": [
-          {
-            "deleted": false,
-            "key": "my-qp",
-            "language": "ts",
-            "name": "Sonar way",
-          },
-        ],
-        "tags": [],
-      }
-    }
-    loading={false}
-    onCancelTask={[Function]}
-    onFilterTask={[Function]}
-    tasks={
-      [
-        {
-          "componentId": "AWBLZYhGOUrjxRA-u6ex",
-          "componentKey": "sonar-csharp",
-          "componentName": "SonarC#",
-          "componentQualifier": "APP",
-          "errorMessage": "Analyses suspended. Please set a valid license for the Edition you installed.",
-          "errorType": "LICENSING",
-          "executedAt": "2019-02-19T16:47:36+0100",
-          "executionTimeMs": 16,
-          "hasScannerContext": false,
-          "id": "AWkGcOThOiAPiP5AE-kM",
-          "logs": false,
-          "nodeName": "node_CE_server_1",
-          "startedAt": "2019-02-19T16:47:36+0100",
-          "status": "FAILED",
-          "submittedAt": "2019-02-19T16:47:35+0100",
-          "type": "VIEW_REFRESH",
-          "warningCount": 0,
-          "warnings": [],
-        },
-        {
-          "componentId": "AV2ZaHs1Wa2znA6pDz1l",
-          "componentKey": "c-cpp-build-wrapper",
-          "componentName": "C/C++ Build Wrapper",
-          "componentQualifier": "APP",
-          "executedAt": "2019-02-19T16:47:36+0100",
-          "executionTimeMs": 19,
-          "hasScannerContext": false,
-          "id": "AWkGcOThOiAPiP5AE-kL",
-          "logs": false,
-          "startedAt": "2019-02-19T16:47:36+0100",
-          "status": "SUCCESS",
-          "submittedAt": "2019-02-19T16:47:35+0100",
-          "type": "VIEW_REFRESH",
-          "warningCount": 0,
-          "warnings": [],
-        },
-      ]
-    }
-  />
-  <ListFooter
-    count={2}
-    loadMore={[Function]}
-    loading={false}
-    total={2}
-  />
-</main>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/NoWorkersSupportPopup-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/NoWorkersSupportPopup-test.tsx.snap
deleted file mode 100644 (file)
index ad292a7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
-  <p
-    className="spacer-bottom"
-  >
-    <strong>
-      background_tasks.add_more_workers
-    </strong>
-  </p>
-  <p
-    className="big-spacer-bottom markdown"
-  >
-    background_tasks.add_more_workers.text
-  </p>
-  <p>
-    <ForwardRef(Link)
-      target="_blank"
-      to="https://www.sonarqube.org/trial-request/enterprise-edition/?referrer=sonarqube-background-tasks"
-    >
-      learn_more
-    </ForwardRef(Link)>
-  </p>
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/ScannerContext-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/ScannerContext-test.tsx.snap
deleted file mode 100644 (file)
index 4515f08..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<Modal
-  contentLabel="scanner context"
-  onRequestClose={[MockFunction]}
-  size="large"
->
-  <div
-    className="modal-head"
-  >
-    <h2>
-      background_tasks.scanner_context
-      : 
-      foo
-       [
-      background_task.type.REPORT
-      ]
-    </h2>
-  </div>
-  <div
-    className="modal-body modal-container"
-  >
-    <pre
-      className="js-task-scanner-context"
-    >
-      context
-    </pre>
-  </div>
-  <div
-    className="modal-foot"
-  >
-    <a
-      className="js-modal-close"
-      href="#"
-      onClick={[Function]}
-    >
-      close
-    </a>
-  </div>
-</Modal>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Stacktrace-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Stacktrace-test.tsx.snap
deleted file mode 100644 (file)
index aaf5962..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<Modal
-  contentLabel="stacktrace"
-  onRequestClose={[MockFunction]}
-  size="large"
->
-  <div
-    className="modal-head"
-  >
-    <h2>
-      background_tasks.error_stacktrace
-      : 
-      foo
-       [
-      background_task.type.REPORT
-      ]
-    </h2>
-  </div>
-  <div
-    className="modal-body modal-container"
-  >
-    <div>
-      <h4
-        className="spacer-bottom"
-      >
-        background_tasks.error_stacktrace
-      </h4>
-      <pre
-        className="js-task-stacktrace"
-      >
-        stacktrace
-      </pre>
-    </div>
-  </div>
-  <div
-    className="modal-foot"
-  >
-    <a
-      className="js-modal-close"
-      href="#"
-      onClick={[Function]}
-    >
-      close
-    </a>
-  </div>
-</Modal>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatPendingCount-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatPendingCount-test.tsx.snap
deleted file mode 100644 (file)
index c68b390..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<span>
-  <span
-    className="emphasised-measure"
-  >
-    5
-  </span>
-  <span
-    className="little-spacer-left display-inline-flex-center"
-  >
-    background_tasks.pending
-    <ConfirmButton
-      cancelButtonText="close"
-      confirmButtonText="background_tasks.cancel_all_tasks.submit"
-      isDestructive={true}
-      modalBody="background_tasks.cancel_all_tasks.text"
-      modalHeader="background_tasks.cancel_all_tasks"
-      onConfirm={[MockFunction]}
-    >
-      <Component />
-    </ConfirmButton>
-  </span>
-</span>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatPendingTime-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatPendingTime-test.tsx.snap
deleted file mode 100644 (file)
index 85a3555..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<span>
-  <span
-    className="emphasised-measure"
-  >
-    15s
-  </span>
-  <span
-    className="little-spacer-left"
-  >
-    background_tasks.pending_time
-  </span>
-  <HelpTooltip
-    className="little-spacer-left"
-    overlay="background_tasks.pending_time.description"
-  />
-</span>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatStillFailing-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/StatStillFailing-test.tsx.snap
deleted file mode 100644 (file)
index 98ba7bb..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<span>
-  <ButtonLink
-    className="emphasised-measure text-baseline"
-    onClick={[MockFunction]}
-  >
-    5
-  </ButtonLink>
-  <span
-    className="little-spacer-left"
-  >
-    background_tasks.failures
-  </span>
-  <HelpTooltip
-    className="little-spacer-left"
-    overlay="background_tasks.failing_count"
-  />
-</span>
-`;
-
-exports[`should render without the filter link 1`] = `
-<span>
-  <span
-    className="emphasised-measure"
-  >
-    0
-  </span>
-  <span
-    className="little-spacer-left"
-  >
-    background_tasks.failures
-  </span>
-  <HelpTooltip
-    className="little-spacer-left"
-    overlay="background_tasks.failing_count"
-  />
-</span>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskActions-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskActions-test.tsx.snap
deleted file mode 100644 (file)
index f0b52ad..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<td
-  className="thin nowrap"
->
-  <ActionsDropdown
-    className="js-task-action"
-  >
-    <ActionsDropdownItem
-      className="js-task-filter"
-      onClick={[Function]}
-    >
-      background_tasks.filter_by_component_x.Foo
-    </ActionsDropdownItem>
-    <ActionsDropdownItem
-      className="js-task-cancel"
-      destructive={true}
-      onClick={[Function]}
-    >
-      background_tasks.cancel_task
-    </ActionsDropdownItem>
-  </ActionsDropdown>
-</td>
-`;
-
-exports[`renders 2`] = `
-<td
-  className="thin nowrap"
->
-  <ActionsDropdown
-    className="js-task-action"
-  >
-    <ActionsDropdownItem
-      className="js-task-filter"
-      onClick={[Function]}
-    >
-      background_tasks.filter_by_component_x.Foo
-    </ActionsDropdownItem>
-  </ActionsDropdown>
-</td>
-`;
-
-exports[`renders 3`] = `
-<td
-  className="thin nowrap"
->
-  <ActionsDropdown
-    className="js-task-action"
-  >
-    <ActionsDropdownItem
-      className="js-task-filter"
-      onClick={[Function]}
-    >
-      background_tasks.filter_by_component_x.Foo
-    </ActionsDropdownItem>
-    <ActionsDropdownItem
-      className="js-task-cancel"
-      destructive={true}
-      onClick={[Function]}
-    >
-      background_tasks.cancel_task
-    </ActionsDropdownItem>
-    <ActionsDropdownItem
-      className="js-task-show-scanner-context"
-      onClick={[Function]}
-    >
-      background_tasks.show_scanner_context
-    </ActionsDropdownItem>
-  </ActionsDropdown>
-</td>
-`;
-
-exports[`renders 4`] = `
-<td
-  className="thin nowrap"
->
-  <ActionsDropdown
-    className="js-task-action"
-  >
-    <ActionsDropdownItem
-      className="js-task-filter"
-      onClick={[Function]}
-    >
-      background_tasks.filter_by_component_x.Foo
-    </ActionsDropdownItem>
-    <ActionsDropdownItem
-      className="js-task-cancel"
-      destructive={true}
-      onClick={[Function]}
-    >
-      background_tasks.cancel_task
-    </ActionsDropdownItem>
-    <ActionsDropdownItem
-      className="js-task-show-stacktrace"
-      onClick={[Function]}
-    >
-      background_tasks.show_stacktrace
-    </ActionsDropdownItem>
-  </ActionsDropdown>
-</td>
-`;
-
-exports[`renders 5`] = `
-<td
-  className="thin nowrap"
->
-  <ActionsDropdown
-    className="js-task-action"
-  >
-    <ActionsDropdownItem
-      className="js-task-cancel"
-      destructive={true}
-      onClick={[Function]}
-    >
-      background_tasks.cancel_task
-    </ActionsDropdownItem>
-  </ActionsDropdown>
-</td>
-`;
-
-exports[`shows scanner context 1`] = `
-<ScannerContext
-  onClose={[Function]}
-  task={
-    {
-      "analysisId": "x123",
-      "componentKey": "foo",
-      "componentName": "Foo",
-      "componentQualifier": "TRK",
-      "hasScannerContext": true,
-      "id": "AXR8jg_0mF2ZsYr8Wzs2",
-      "status": "PENDING",
-      "submittedAt": "2020-09-11T11:45:35+0200",
-      "type": "REPORT",
-    }
-  }
-/>
-`;
-
-exports[`shows stack trace 1`] = `
-<Stacktrace
-  onClose={[Function]}
-  task={
-    {
-      "analysisId": "x123",
-      "componentKey": "foo",
-      "componentName": "Foo",
-      "componentQualifier": "TRK",
-      "errorMessage": "error!",
-      "id": "AXR8jg_0mF2ZsYr8Wzs2",
-      "status": "PENDING",
-      "submittedAt": "2020-09-11T11:45:35+0200",
-      "type": "REPORT",
-    }
-  }
-/>
-`;
-
-exports[`shows warnings 1`] = `
-<withCurrentUserContext(AnalysisWarningsModal)
-  componentKey="foo"
-  onClose={[Function]}
-  taskId="AXR8jg_0mF2ZsYr8Wzs2"
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskComponent-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskComponent-test.tsx.snap
deleted file mode 100644 (file)
index 6b9c12a..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<td>
-  <span
-    className="little-spacer-right"
-  >
-    <QualifierIcon
-      qualifier="TRK"
-    />
-  </span>
-  <ForwardRef(Link)
-    className="spacer-right"
-    to={
-      {
-        "pathname": "/dashboard",
-        "search": "?id=foo",
-      }
-    }
-  >
-    Foo
-  </ForwardRef(Link)>
-  <TaskType
-    type="REPORT"
-  />
-</td>
-`;
-
-exports[`renders correctly: branch 1`] = `
-<td>
-  <BranchIcon
-    className="little-spacer-right"
-  />
-  <ForwardRef(Link)
-    className="spacer-right"
-    to={
-      {
-        "pathname": "/dashboard",
-        "search": "?branch=feature&id=foo",
-      }
-    }
-  >
-    Foo
-    <span
-      className="text-limited text-text-top"
-      title="feature"
-    >
-      <span
-        style={
-          {
-            "marginLeft": 5,
-            "marginRight": 5,
-          }
-        }
-      >
-        /
-      </span>
-      feature
-    </span>
-  </ForwardRef(Link)>
-  <TaskType
-    type="REPORT"
-  />
-</td>
-`;
-
-exports[`renders correctly: branch 2`] = `
-<td>
-  <BranchIcon
-    className="little-spacer-right"
-  />
-  <ForwardRef(Link)
-    className="spacer-right"
-    to={
-      {
-        "pathname": "/dashboard",
-        "search": "?branch=branch-6.7&id=foo",
-      }
-    }
-  >
-    Foo
-    <span
-      className="text-limited text-text-top"
-      title="branch-6.7"
-    >
-      <span
-        style={
-          {
-            "marginLeft": 5,
-            "marginRight": 5,
-          }
-        }
-      >
-        /
-      </span>
-      branch-6.7
-    </span>
-  </ForwardRef(Link)>
-  <TaskType
-    type="REPORT"
-  />
-</td>
-`;
-
-exports[`renders correctly: portfolio 1`] = `
-<td>
-  <span
-    className="little-spacer-right"
-  >
-    <QualifierIcon
-      qualifier="VW"
-    />
-  </span>
-  <ForwardRef(Link)
-    className="spacer-right"
-    to={
-      {
-        "pathname": "/portfolio",
-        "search": "?id=foo",
-      }
-    }
-  >
-    Foo
-  </ForwardRef(Link)>
-  <TaskType
-    type="REPORT"
-  />
-</td>
-`;
-
-exports[`renders correctly: pull request 1`] = `
-<td>
-  <PullRequestIcon
-    className="little-spacer-right"
-  />
-  <ForwardRef(Link)
-    className="spacer-right"
-    to={
-      {
-        "pathname": "/dashboard",
-        "search": "?id=foo&pullRequest=pr-89",
-      }
-    }
-  >
-    Foo
-    <span
-      className="text-limited text-text-top"
-    >
-      <span
-        style={
-          {
-            "marginLeft": 5,
-            "marginRight": 5,
-          }
-        }
-      >
-        /
-      </span>
-      pr-89
-    </span>
-  </ForwardRef(Link)>
-  <TaskType
-    type="REPORT"
-  />
-</td>
-`;
-
-exports[`renders correctly: undefined key 1`] = `
-<td>
-  <span
-    className="note"
-  >
-    AXR8jg_0mF2ZsYr8Wzs2
-  </span>
-  <TaskType
-    type="REPORT"
-  />
-</td>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskDate-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskDate-test.tsx.snap
deleted file mode 100644 (file)
index 7a5dbb2..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<td
-  className="thin nowrap text-right"
-/>
-`;
-
-exports[`renders 2`] = `
-<td
-  className="thin nowrap text-right"
->
-  <TimeFormatter
-    date={2017-01-01T00:00:00.000Z}
-    long={true}
-  />
-</td>
-`;
-
-exports[`renders 3`] = `
-<td
-  className="thin nowrap text-right"
->
-  <TimeFormatter
-    date={2017-01-01T00:00:00.000Z}
-    long={true}
-  />
-</td>
-`;
-
-exports[`renders 4`] = `
-<td
-  className="thin nowrap text-right"
->
-  <span
-    className="text-warning little-spacer-right"
-  >
-    (+4d)
-  </span>
-  <TimeFormatter
-    date={2017-01-05T00:00:00.000Z}
-    long={true}
-  />
-</td>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskStatus-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskStatus-test.tsx.snap
deleted file mode 100644 (file)
index d4df3ea..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<td
-  className="thin spacer-right"
->
-  <PendingIcon />
-</td>
-`;
-
-exports[`renders 2`] = `
-<td
-  className="thin spacer-right"
->
-  <i
-    className="spinner"
-  />
-</td>
-`;
-
-exports[`renders 3`] = `
-<td
-  className="thin spacer-right"
->
-  <span
-    className="badge badge-success"
-  >
-    background_task.status.SUCCESS
-  </span>
-</td>
-`;
-
-exports[`renders 4`] = `
-<td
-  className="thin spacer-right"
->
-  <span
-    className="badge badge-error"
-  >
-    background_task.status.FAILED
-  </span>
-</td>
-`;
-
-exports[`renders 5`] = `
-<td
-  className="thin spacer-right"
->
-  <span
-    className="badge"
-  >
-    background_task.status.CANCELED
-  </span>
-</td>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap
deleted file mode 100644 (file)
index 6cefea0..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`opens form 1`] = `
-<div
-  className="display-flex-center"
->
-  <span
-    className="text-middle"
-  >
-    background_tasks.number_of_workers
-    <strong
-      className="little-spacer-left"
-    >
-      1
-    </strong>
-  </span>
-  <Tooltip
-    overlay="background_tasks.change_number_of_workers"
-  >
-    <EditButton
-      aria-label="background_tasks.change_number_of_workers"
-      className="js-edit button-small spacer-left"
-      onClick={[Function]}
-      title="edit"
-    />
-  </Tooltip>
-</div>
-`;
-
-exports[`opens form 2`] = `
-<div
-  className="display-flex-center"
->
-  <span
-    className="text-middle"
-  >
-    background_tasks.number_of_workers
-    <strong
-      className="little-spacer-left"
-    >
-      1
-    </strong>
-  </span>
-  <Tooltip
-    overlay="background_tasks.change_number_of_workers"
-  >
-    <EditButton
-      aria-label="background_tasks.change_number_of_workers"
-      className="js-edit button-small spacer-left"
-      onClick={[Function]}
-      title="edit"
-    />
-  </Tooltip>
-  <WorkersForm
-    onClose={[Function]}
-    workerCount={1}
-  />
-</div>
-`;
-
-exports[`renders 1`] = `
-<div
-  className="display-flex-center"
->
-  <span
-    className="text-middle"
-  >
-    background_tasks.number_of_workers
-    <i
-      className="spinner little-spacer-left"
-    />
-  </span>
-</div>
-`;
-
-exports[`renders 2`] = `
-<div
-  className="display-flex-center"
->
-  <span
-    className="text-middle"
-  >
-    background_tasks.number_of_workers
-    <strong
-      className="little-spacer-left"
-    >
-      1
-    </strong>
-  </span>
-  <Tooltip
-    overlay="background_tasks.change_number_of_workers"
-  >
-    <EditButton
-      aria-label="background_tasks.change_number_of_workers"
-      className="js-edit button-small spacer-left"
-      onClick={[Function]}
-      title="edit"
-    />
-  </Tooltip>
-</div>
-`;
-
-exports[`renders 3`] = `
-<div
-  className="display-flex-center"
->
-  <Tooltip
-    overlay="background_tasks.number_of_workers.warning"
-  >
-    <span
-      className="display-inline-flex-center little-spacer-right"
-    >
-      <AlertWarnIcon
-        fill="#d3d3d3"
-      />
-    </span>
-  </Tooltip>
-  <span
-    className="text-middle"
-  >
-    background_tasks.number_of_workers
-    <strong
-      className="little-spacer-left"
-    >
-      2
-    </strong>
-  </span>
-  <Tooltip
-    overlay="background_tasks.change_number_of_workers"
-  >
-    <EditButton
-      aria-label="background_tasks.change_number_of_workers"
-      className="js-edit button-small spacer-left"
-      onClick={[Function]}
-      title="edit"
-    />
-  </Tooltip>
-</div>
-`;
-
-exports[`renders 4`] = `
-<div
-  className="display-flex-center"
->
-  <Tooltip
-    overlay="background_tasks.number_of_workers.warning"
-  >
-    <span
-      className="display-inline-flex-center little-spacer-right"
-    >
-      <AlertWarnIcon
-        fill="#d3d3d3"
-      />
-    </span>
-  </Tooltip>
-  <span
-    className="text-middle"
-  >
-    background_tasks.number_of_workers
-    <strong
-      className="little-spacer-left"
-    >
-      2
-    </strong>
-  </span>
-  <HelpTooltip
-    className="spacer-left"
-    overlay={<NoWorkersSupportPopup />}
-  >
-    <PlusCircleIcon
-      fill="#4b9fd5"
-      size={12}
-    />
-  </HelpTooltip>
-</div>
-`;
-
-exports[`updates worker count 1`] = `
-<div
-  className="display-flex-center"
->
-  <span
-    className="text-middle"
-  >
-    background_tasks.number_of_workers
-    <strong
-      className="little-spacer-left"
-    >
-      1
-    </strong>
-  </span>
-  <Tooltip
-    overlay="background_tasks.change_number_of_workers"
-  >
-    <EditButton
-      aria-label="background_tasks.change_number_of_workers"
-      className="js-edit button-small spacer-left"
-      onClick={[Function]}
-      title="edit"
-    />
-  </Tooltip>
-  <WorkersForm
-    onClose={[Function]}
-    workerCount={1}
-  />
-</div>
-`;
-
-exports[`updates worker count 2`] = `
-<div
-  className="display-flex-center"
->
-  <Tooltip
-    overlay="background_tasks.number_of_workers.warning"
-  >
-    <span
-      className="display-inline-flex-center little-spacer-right"
-    >
-      <AlertWarnIcon
-        fill="#d3d3d3"
-      />
-    </span>
-  </Tooltip>
-  <span
-    className="text-middle"
-  >
-    background_tasks.number_of_workers
-    <strong
-      className="little-spacer-left"
-    >
-      7
-    </strong>
-  </span>
-  <Tooltip
-    overlay="background_tasks.change_number_of_workers"
-  >
-    <EditButton
-      aria-label="background_tasks.change_number_of_workers"
-      className="js-edit button-small spacer-left"
-      onClick={[Function]}
-      title="edit"
-    />
-  </Tooltip>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.tsx.snap
deleted file mode 100644 (file)
index aa434b1..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`changes select 1`] = `
-<Modal
-  contentLabel="background_tasks.change_number_of_workers"
-  onRequestClose={[Function]}
->
-  <header
-    className="modal-head"
-  >
-    <h2
-      id="background-task-workers-label"
-    >
-      background_tasks.change_number_of_workers
-    </h2>
-  </header>
-  <form
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-body"
-    >
-      <Select
-        aria-labelledby="background-task-workers-label"
-        className="input-tiny spacer-top"
-        isSearchable={false}
-        onChange={[Function]}
-        options={
-          [
-            {
-              "label": "1",
-              "value": 1,
-            },
-            {
-              "label": "2",
-              "value": 2,
-            },
-            {
-              "label": "3",
-              "value": 3,
-            },
-            {
-              "label": "4",
-              "value": 4,
-            },
-            {
-              "label": "5",
-              "value": 5,
-            },
-            {
-              "label": "6",
-              "value": 6,
-            },
-            {
-              "label": "7",
-              "value": 7,
-            },
-            {
-              "label": "8",
-              "value": 8,
-            },
-            {
-              "label": "9",
-              "value": 9,
-            },
-            {
-              "label": "10",
-              "value": 10,
-            },
-          ]
-        }
-        value={
-          {
-            "label": "1",
-            "value": 1,
-          }
-        }
-      />
-      <Alert
-        className="big-spacer-top"
-        variant="info"
-      >
-        background_tasks.change_number_of_workers.hint
-      </Alert>
-    </div>
-    <footer
-      className="modal-foot"
-    >
-      <div>
-        <SubmitButton
-          disabled={false}
-        >
-          save
-        </SubmitButton>
-        <ResetButtonLink
-          onClick={[Function]}
-        >
-          cancel
-        </ResetButtonLink>
-      </div>
-    </footer>
-  </form>
-</Modal>
-`;
-
-exports[`changes select 2`] = `
-<Modal
-  contentLabel="background_tasks.change_number_of_workers"
-  onRequestClose={[Function]}
->
-  <header
-    className="modal-head"
-  >
-    <h2
-      id="background-task-workers-label"
-    >
-      background_tasks.change_number_of_workers
-    </h2>
-  </header>
-  <form
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-body"
-    >
-      <Select
-        aria-labelledby="background-task-workers-label"
-        className="input-tiny spacer-top"
-        isSearchable={false}
-        onChange={[Function]}
-        options={
-          [
-            {
-              "label": "1",
-              "value": 1,
-            },
-            {
-              "label": "2",
-              "value": 2,
-            },
-            {
-              "label": "3",
-              "value": 3,
-            },
-            {
-              "label": "4",
-              "value": 4,
-            },
-            {
-              "label": "5",
-              "value": 5,
-            },
-            {
-              "label": "6",
-              "value": 6,
-            },
-            {
-              "label": "7",
-              "value": 7,
-            },
-            {
-              "label": "8",
-              "value": 8,
-            },
-            {
-              "label": "9",
-              "value": 9,
-            },
-            {
-              "label": "10",
-              "value": 10,
-            },
-          ]
-        }
-        value={
-          {
-            "label": "7",
-            "value": 7,
-          }
-        }
-      />
-      <Alert
-        className="big-spacer-top"
-        variant="info"
-      >
-        background_tasks.change_number_of_workers.hint
-      </Alert>
-    </div>
-    <footer
-      className="modal-foot"
-    >
-      <div>
-        <SubmitButton
-          disabled={false}
-        >
-          save
-        </SubmitButton>
-        <ResetButtonLink
-          onClick={[Function]}
-        >
-          cancel
-        </ResetButtonLink>
-      </div>
-    </footer>
-  </form>
-</Modal>
-`;
index 1e77d9d9ca1deeaeecc6512f1811a675a425e2b2..00a380dd05aa81caa86639e40b35bf8c759ae2ac 100644 (file)
@@ -3243,6 +3243,7 @@ background_tasks.cancel_all_tasks.text=Are you sure you want to cancel all pendi
 background_tasks.cancel_all_tasks.submit=Cancel All
 background_tasks.scanner_context=Scanner Context
 background_tasks.show_scanner_context=Show Scanner Context
+background_tasks.show_actions=Show actions
 background_tasks.show_stacktrace=Show Error Details
 background_tasks.show_warnings=Show Warnings
 background_tasks.error_message=Error Message