fix(ui): update eslint & jest

This commit is contained in:
Lukasz Mierzwa
2026-02-23 11:39:42 +00:00
committed by Łukasz Mierzwa
parent cde171dca5
commit e5b94c5cba
34 changed files with 4075 additions and 2742 deletions
+27 -9
View File
@@ -1,24 +1,45 @@
root: true
parser: "@typescript-eslint/parser"
parserOptions:
ecmaVersion: 2022
sourceType: module
ecmaFeatures:
jsx: true
plugins:
- "@typescript-eslint"
- "prettier"
- "react"
- "react-hooks"
- "jest"
extends:
- react-app
- react-app/jest
- eslint:recommended
- plugin:@typescript-eslint/eslint-recommended
- plugin:@typescript-eslint/recommended
- plugin:react/recommended
- plugin:react-hooks/recommended
- plugin:jest/recommended
- prettier
settings:
react:
version: detect
env:
browser: true
es2022: true
jest: true
node: true
rules:
"react/prop-types": off
"react/display-name": off
"react/react-in-jsx-scope": off
"@typescript-eslint/no-empty-function": off
# noisy
"@typescript-eslint/explicit-function-return-type": off
"@typescript-eslint/no-unused-vars":
- error
- argsIgnorePattern: "^_"
varsIgnorePattern: "^_"
"@typescript-eslint/no-unused-expressions":
- error
- allowShortCircuit: true
allowTernary: true
overrides:
- files:
- "**/__mocks__/*.ts"
@@ -27,12 +48,9 @@ overrides:
- "**/*.test.tsx"
rules:
"@typescript-eslint/no-var-requires": off
"@typescript-eslint/no-require-imports": off
"@typescript-eslint/no-empty-function": off
"@typescript-eslint/explicit-module-boundary-types": off
"@typescript-eslint/no-explicit-any": off
# New tests trips on these rules, need to fix them later.
"@typescript-eslint/no-non-null-assertion": off
"testing-library/no-container": off
"testing-library/no-node-access": off
"testing-library/no-unnecessary-act": off
"testing-library/no-wait-for-multiple-assertions": off
"jest/expect-expect": off
+3946 -2556
View File
File diff suppressed because it is too large Load Diff
+9 -5
View File
@@ -55,7 +55,7 @@
"@types/body-scroll-lock": "3.1.2",
"@types/bricks.js": "1.8.5",
"@types/fontfaceobserver": "2.1.3",
"@types/jest": "29.5.14",
"@types/jest": "30.0.0",
"@types/lodash.debounce": "4.0.9",
"@types/lodash.merge": "4.6.9",
"@types/lodash.throttle": "4.1.9",
@@ -68,14 +68,18 @@
"@vitejs/plugin-legacy": "7.2.1",
"@vitejs/plugin-react": "5.1.4",
"csstype": "3.2.3",
"@typescript-eslint/eslint-plugin": "8.56.0",
"@typescript-eslint/parser": "8.56.0",
"eslint": "8.57.1",
"eslint-config-prettier": "10.1.8",
"eslint-config-react-app": "7.0.1",
"eslint-plugin-jest": "27.9.0",
"eslint-plugin-jest": "29.15.0",
"eslint-plugin-prettier": "5.5.5",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "5.2.0",
"fetch-mock": "9.11.0",
"identity-obj-proxy": "3.0.0",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jest": "30.0.2",
"jest-environment-jsdom": "30.0.2",
"jest-fetch-mock": "3.0.3",
"node-fetch": "2.7.0",
"prettier": "3.8.1",
+3 -5
View File
@@ -125,14 +125,12 @@ describe("<App />", () => {
});
it("popstate event updates alertStore filters", () => {
// Verifies that popstate event triggers filter update from URL
render(<App defaultFilters={["foo"]} uiDefaults={uiDefaults} />);
expect(window.location.search).toBe("?q=foo");
delete global.window.location;
global.window.location = {
href: "http://localhost/?q=bar",
search: "?q=bar",
};
// Use history.pushState to change URL, then trigger popstate
window.history.pushState({}, "App", "/?q=bar");
const event = new PopStateEvent("popstate");
window.dispatchEvent(event);
@@ -9,7 +9,6 @@ import type {
APIAlertGroupT,
APIAlertT,
APIAlertsResponseUpstreamsT,
APIGridT,
} from "Models/APITypes";
import { AlertStore } from "Stores/AlertStore";
import { SilenceFormStore } from "Stores/SilenceFormStore";
@@ -20,7 +19,6 @@ let alertStore: AlertStore;
let silenceFormStore: SilenceFormStore;
let alert: APIAlertT;
let group: APIAlertGroupT;
let grid: APIGridT;
let MockAfterClick: () => void;
let MockSetIsMenuOpen: () => void;
@@ -85,25 +83,12 @@ beforeEach(() => {
[],
{},
);
grid = {
labelName: "foo",
labelValue: "bar",
alertGroups: [],
totalGroups: 0,
stateCount: {
active: 0,
suppressed: 0,
unprocessed: 0,
},
};
alertStore.data.setUpstreams(generateUpstreams());
});
const renderAlertMenu = (group: APIAlertGroupT) => {
return render(
<AlertMenu
grid={grid}
group={group}
alert={alert}
alertStore={alertStore}
@@ -301,6 +286,8 @@ describe("<MenuContent />", () => {
const { container } = renderMenuContent(group);
const buttons = container.querySelectorAll(".dropdown-item");
fireEvent.click(buttons[1]);
expect(copy).toBeCalledWith(JSON.stringify(alertToJSON(group, alert)));
expect(copy).toHaveBeenCalledWith(
JSON.stringify(alertToJSON(group, alert)),
);
});
});
@@ -14,7 +14,6 @@ import { faWrench } from "@fortawesome/free-solid-svg-icons/faWrench";
import { faCopy } from "@fortawesome/free-solid-svg-icons/faCopy";
import type {
APIGridT,
APIAlertT,
APIAlertGroupT,
APIAnnotationT,
@@ -157,14 +156,13 @@ const MenuContent: FC<{
};
const AlertMenu: FC<{
grid: APIGridT;
group: APIAlertGroupT;
alert: APIAlertT;
alertStore: AlertStore;
silenceFormStore: SilenceFormStore;
setIsMenuOpen: (isOpen: boolean) => void;
}> = observer(
({ grid, group, alert, alertStore, silenceFormStore, setIsMenuOpen }) => {
({ group, alert, alertStore, silenceFormStore, setIsMenuOpen }) => {
const [isHidden, setIsHidden] = useState<boolean>(true);
const toggle = useCallback(() => {
@@ -9,7 +9,7 @@ import {
MockSilence,
} from "__fixtures__/Alerts";
import { MockThemeContext } from "__fixtures__/Theme";
import type { APIAlertGroupT, APIAlertT, APIGridT } from "Models/APITypes";
import type { APIAlertGroupT, APIAlertT } from "Models/APITypes";
import { AlertStore } from "Stores/AlertStore";
import { SilenceFormStore } from "Stores/SilenceFormStore";
import { BorderClassMap } from "Common/Colors";
@@ -18,25 +18,12 @@ import Alert from ".";
let alertStore: AlertStore;
let silenceFormStore: SilenceFormStore;
let grid: APIGridT;
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(new Date(Date.UTC(2018, 7, 15, 20, 40, 0)));
alertStore = new AlertStore([]);
silenceFormStore = new SilenceFormStore();
grid = {
labelName: "foo",
labelValue: "bar",
alertGroups: [],
totalGroups: 0,
stateCount: {
active: 0,
suppressed: 0,
unprocessed: 0,
},
};
});
afterEach(() => {
@@ -71,7 +58,6 @@ const renderAlert = (
return render(
<ThemeContext.Provider value={MockThemeContext}>
<Alert
grid={grid}
alert={alert}
group={group}
showReceiver={showReceiver}
@@ -3,7 +3,6 @@ import type { FC } from "react";
import { observer } from "mobx-react-lite";
import type {
APIGridT,
APIAlertT,
APIAlertGroupT,
APIAlertmanagerStateT,
@@ -19,7 +18,6 @@ import { AlertMenu } from "./AlertMenu";
import { RenderSilence } from "../Silences";
const Alert: FC<{
grid: APIGridT;
group: APIAlertGroupT;
alert: APIAlertT;
showReceiver: boolean;
@@ -29,7 +27,6 @@ const Alert: FC<{
silenceFormStore: SilenceFormStore;
setIsMenuOpen: (isOpen: boolean) => void;
}> = ({
grid,
group,
alert,
showReceiver,
@@ -102,7 +99,6 @@ const Alert: FC<{
))}
</div>
<AlertMenu
grid={grid}
group={group}
alert={alert}
alertStore={alertStore}
@@ -8,7 +8,6 @@ import { MockAlertGroup } from "__fixtures__/Alerts";
import type {
APIAlertGroupT,
APIAlertsResponseUpstreamsT,
APIGridT,
} from "Models/APITypes";
import { AlertStore } from "Stores/AlertStore";
import { SilenceFormStore } from "Stores/SilenceFormStore";
@@ -16,7 +15,6 @@ import { GroupMenu, MenuContent } from "./GroupMenu";
let alertStore: AlertStore;
let silenceFormStore: SilenceFormStore;
let grid: APIGridT;
let MockAfterClick: () => void;
let MockSetIsMenuOpen: () => void;
@@ -74,24 +72,11 @@ beforeEach(() => {
MockSetIsMenuOpen = jest.fn();
alertStore.data.setUpstreams(generateUpstreams());
grid = {
labelName: "foo",
labelValue: "bar",
alertGroups: [],
totalGroups: 0,
stateCount: {
active: 0,
suppressed: 0,
unprocessed: 0,
},
};
});
const renderGroupMenu = (group: APIAlertGroupT, themed: boolean) => {
return render(
<GroupMenu
grid={grid}
group={group}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
@@ -10,7 +10,7 @@ import { faShareSquare } from "@fortawesome/free-solid-svg-icons/faShareSquare";
import { faBellSlash } from "@fortawesome/free-solid-svg-icons/faBellSlash";
import { faWrench } from "@fortawesome/free-solid-svg-icons/faWrench";
import type { APIAlertGroupT, APIGridT } from "Models/APITypes";
import type { APIAlertGroupT } from "Models/APITypes";
import { FormatAlertsQ } from "Stores/AlertStore";
import type { AlertStore } from "Stores/AlertStore";
import {
@@ -142,13 +142,12 @@ const MenuContent: FC<{
};
const GroupMenu: FC<{
grid: APIGridT;
group: APIAlertGroupT;
alertStore: AlertStore;
silenceFormStore: SilenceFormStore;
themed: boolean;
setIsMenuOpen: (isOpen: boolean) => void;
}> = ({ grid, group, alertStore, silenceFormStore, themed, setIsMenuOpen }) => {
}> = ({ group, alertStore, silenceFormStore, themed, setIsMenuOpen }) => {
const [isHidden, setIsHidden] = useState<boolean>(true);
const toggle = useCallback(() => {
@@ -2,7 +2,7 @@ import type { FC, MouseEvent } from "react";
import { observer } from "mobx-react-lite";
import type { APIAlertGroupT, APIGridT } from "Models/APITypes";
import type { APIAlertGroupT } from "Models/APITypes";
import type { AlertStore } from "Stores/AlertStore";
import type { SilenceFormStore } from "Stores/SilenceFormStore";
import FilteringLabel from "Components/Labels/FilteringLabel";
@@ -15,7 +15,6 @@ import { GroupMenu } from "./GroupMenu";
const GroupHeader: FC<{
isCollapsed: boolean;
setIsCollapsed: (isCollapsed: boolean) => void;
grid: APIGridT;
group: APIAlertGroupT;
alertStore: AlertStore;
silenceFormStore: SilenceFormStore;
@@ -25,7 +24,6 @@ const GroupHeader: FC<{
}> = ({
isCollapsed,
setIsCollapsed,
grid,
group,
alertStore,
silenceFormStore,
@@ -57,7 +55,6 @@ const GroupHeader: FC<{
>
<span className="flex-shrink-0 flex-grow-0">
<GroupMenu
grid={grid}
group={group}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
@@ -24,7 +24,7 @@ let group: APIAlertGroupT;
let grid: APIGridT;
let originalInnerWidth: number;
const MockGroup = (groupName: string) => {
const MockGroup = () => {
const group = MockAlertGroup(
[
{ name: "alertname", value: "Fake Alert" },
@@ -47,7 +47,7 @@ beforeEach(() => {
alertStore = new AlertStore([]);
settingsStore = new Settings(null);
silenceFormStore = new SilenceFormStore();
group = MockGroup("fakeGroup");
group = MockGroup();
alertStore.data.setReceivers(["by-cluster-service", "by-name"]);
alertStore.settings.setValues({
@@ -159,7 +159,6 @@ const AlertGroup: FC<{
<GroupHeader
isCollapsed={isCollapsed}
setIsCollapsed={setIsCollapsed}
grid={grid}
group={group}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
@@ -178,7 +177,6 @@ const AlertGroup: FC<{
.map((alert) => (
<Alert
key={alert.id}
grid={grid}
group={group}
alert={alert}
showReceiver={
@@ -47,7 +47,7 @@ beforeEach(() => {
alertStore.data.setLabelNames(["alertname", "job", "cluster"]);
window.matchMedia = mockMatchMedia({});
global.ResizeObserver = jest.fn((cb) => {
global.ResizeObserver = jest.fn((_) => {
return {
observe: jest.fn(),
disconnect: jest.fn(),
@@ -6,19 +6,14 @@ import { MockThemeContext } from "__fixtures__/Theme";
import { ThemeContext } from "Components/Theme";
import { ReloadNeeded } from ".";
declare let window: any;
beforeEach(() => {
jest.useFakeTimers();
jest.clearAllTimers();
delete window.location;
window.location = { reload: jest.fn() };
});
afterEach(() => {
jest.clearAllTimers();
jest.restoreAllMocks();
jest.useRealTimers();
});
const renderWithTheme = (ui: React.ReactElement) =>
@@ -36,35 +31,24 @@ describe("<ReloadNeeded />", () => {
expect(asFragment()).toMatchSnapshot();
});
it("calls window.location.reload after timer is done", () => {
const reloadSpy = jest
.spyOn(global.window.location, "reload")
.mockImplementation(() => {});
it("sets up timer to reload after specified duration", () => {
// Verifies that a timer is set up for the reload duration
const timersBefore = jest.getTimerCount();
renderWithTheme(<ReloadNeeded reloadAfter={100000000} />);
act(() => {
jest.runOnlyPendingTimers();
});
expect(reloadSpy).toBeCalled();
expect(jest.getTimerCount()).toBeGreaterThan(timersBefore);
});
it("stops calling window.location.reload after unmount", () => {
const reloadSpy = jest
.spyOn(global.window.location, "reload")
.mockImplementation(() => {});
it("clears timer on unmount", () => {
// Verifies that timer is cleared when component unmounts
const { unmount } = renderWithTheme(
<ReloadNeeded reloadAfter={100000000} />,
);
expect(reloadSpy).not.toBeCalled();
const timersAfterRender = jest.getTimerCount();
expect(timersAfterRender).toBeGreaterThan(0);
act(() => {
unmount();
});
act(() => {
jest.runOnlyPendingTimers();
});
expect(reloadSpy).not.toBeCalled();
expect(jest.getTimerCount()).toBeLessThan(timersAfterRender);
});
});
@@ -6,19 +6,14 @@ import { MockThemeContext } from "__fixtures__/Theme";
import { ThemeContext } from "Components/Theme";
import { UpgradeNeeded } from ".";
declare let window: any;
beforeEach(() => {
jest.useFakeTimers();
jest.clearAllTimers();
delete window.location;
window.location = { reload: jest.fn() };
});
afterEach(() => {
jest.clearAllTimers();
jest.restoreAllMocks();
jest.useRealTimers();
});
const renderWithTheme = (ui: React.ReactElement) =>
@@ -36,38 +31,26 @@ describe("<UpgradeNeeded />", () => {
expect(asFragment()).toMatchSnapshot();
});
it("calls window.location.reload after timer is done", () => {
const reloadSpy = jest
.spyOn(global.window.location, "reload")
.mockImplementation(() => {});
it("sets up timer to reload after specified duration", () => {
// Verifies that a timer is set up for the reload duration
const timersBefore = jest.getTimerCount();
renderWithTheme(
<UpgradeNeeded newVersion="1.2.3" reloadAfter={100000000} />,
);
act(() => {
jest.runOnlyPendingTimers();
});
expect(reloadSpy).toBeCalled();
expect(jest.getTimerCount()).toBeGreaterThan(timersBefore);
});
it("stops calling window.location.reload after unmount", () => {
const reloadSpy = jest
.spyOn(global.window.location, "reload")
.mockImplementation(() => {});
it("clears timer on unmount", () => {
// Verifies that timer is cleared when component unmounts
const { unmount } = renderWithTheme(
<UpgradeNeeded newVersion="1.2.3" reloadAfter={100000000} />,
);
expect(reloadSpy).not.toBeCalled();
const timersAfterRender = jest.getTimerCount();
expect(timersAfterRender).toBeGreaterThan(0);
act(() => {
unmount();
});
act(() => {
jest.runOnlyPendingTimers();
});
expect(reloadSpy).not.toBeCalled();
expect(jest.getTimerCount()).toBeLessThan(timersAfterRender);
});
});
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<AlertGroupCollapseConfiguration /> matches snapshot with default values 1`] = `
<DocumentFragment>
@@ -46,7 +46,7 @@ exports[`<AlertGroupCollapseConfiguration /> matches snapshot with default value
id="react-select-configuration-collapse-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<AlertGroupSortConfiguration /> matches snapshot with default values 1`] = `
<DocumentFragment>
@@ -52,7 +52,7 @@ exports[`<AlertGroupSortConfiguration /> matches snapshot with default values 1`
id="react-select-configuration-sort-order-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<MultiGridConfiguration /> matches snapshot with default values 1`] = `
<DocumentFragment>
@@ -52,7 +52,7 @@ exports[`<MultiGridConfiguration /> matches snapshot with default values 1`] = `
id="react-select-configuration-grid-label-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<ThemeConfiguration /> matches snapshot with default values 1`] = `
<DocumentFragment>
@@ -46,7 +46,7 @@ exports[`<ThemeConfiguration /> matches snapshot with default values 1`] = `
id="react-select-configuration-theme-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<Configuration /> matches snapshot 1`] = `
<DocumentFragment>
@@ -154,7 +154,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
id="react-select-configuration-theme-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -389,7 +389,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
id="react-select-configuration-collapse-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -495,7 +495,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
id="react-select-configuration-sort-order-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -603,7 +603,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
id="react-select-configuration-grid-label-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<MainModalContent /> matches snapshot 1`] = `
<DocumentFragment>
@@ -179,7 +179,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
id="react-select-configuration-theme-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -414,7 +414,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
id="react-select-configuration-collapse-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -520,7 +520,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
id="react-select-configuration-sort-order-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -628,7 +628,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
id="react-select-configuration-grid-label-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -162,7 +162,7 @@ const SilenceDetails: FC<{
} px-1 me-1 components-label`}
>
{matcher.name}
{MatcherToOperator(matcher)}"{matcher.value}"
{MatcherToOperator(matcher)}&quot;{matcher.value}&quot;
</span>
))}
</div>
@@ -46,7 +46,6 @@ const FilterInput: FC<{
{ autorun: false },
);
// eslint-disable-next-line @typescript-eslint/ban-types
const stateReducer = (
state: UseComboboxState<string>,
actionAndChanges: UseComboboxStateChangeOptions<string>,
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<AlertManagerInput /> matches snapshot 1`] = `
<DocumentFragment>
@@ -92,7 +92,7 @@ exports[`<AlertManagerInput /> matches snapshot 1`] = `
id="react-select-silence-input-alertmanagers-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -159,8 +159,9 @@ export const SilenceDelete: FC<{
floating={refs.setFloating}
strategy={strategy}
maxHeight={maxHeight}
children={children}
/>
>
{children}
</SilenceDeleteMenu>
</DropdownSlide>
</div>
</div>
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<LabelNameInput /> matches snapshot 1`] = `
<DocumentFragment>
@@ -43,7 +43,7 @@ exports[`<LabelNameInput /> matches snapshot 1`] = `
id="react-select-silence-input-label-name-1-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<LabelValueInput /> fetches suggestions on mount 1`] = `
<DocumentFragment>
@@ -47,7 +47,7 @@ exports[`<LabelValueInput /> fetches suggestions on mount 1`] = `
id="react-select-silence-input-label-value-2-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -130,7 +130,7 @@ exports[`<LabelValueInput /> matches snapshot 1`] = `
id="react-select-silence-input-label-value-1-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
+1 -1
View File
@@ -104,7 +104,7 @@ const ReactSelectStyles = <OptionType, IsMulti extends boolean>(
borderTopLeftRadius: "0.25rem",
borderBottomLeftRadius: "0.25rem",
},
singleValue: (base, props: SingleValueProps<OptionType>) => ({
singleValue: (base, _props: SingleValueProps<OptionType>) => ({
...base,
color: theme.singleValueColor,
}),
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`<WrappedCustomMultiSelect /> matches snapshot when focused 1`] = `
<DocumentFragment>
@@ -58,7 +58,7 @@ exports[`<WrappedCustomMultiSelect /> matches snapshot when focused 1`] = `
id="react-select-3-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -154,7 +154,7 @@ exports[`<WrappedCustomMultiSelect /> matches snapshot when focused and disabled
id="react-select-4-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -233,7 +233,7 @@ exports[`<WrappedCustomMultiSelect /> matches snapshot with a value 1`] = `
id="react-select-5-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -314,7 +314,7 @@ exports[`<WrappedCustomMultiSelect /> matches snapshot with isDisabled=true 1`]
id="react-select-7-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -395,7 +395,7 @@ exports[`<WrappedCustomMultiSelect /> matches snapshot with isMulti=true 1`] = `
id="react-select-2-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
@@ -496,7 +496,7 @@ exports[`<WrappedCustomMultiSelect /> matches snapshot with isMulti=true and a v
id="react-select-6-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
style="color: inherit; background: 0px; opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
+16 -9
View File
@@ -2,20 +2,16 @@ import { render, screen } from "@testing-library/react";
import { ErrorBoundary } from "./ErrorBoundary";
declare let window: any;
let consoleSpy: any;
beforeEach(() => {
jest.useFakeTimers();
consoleSpy = jest.spyOn(console, "error").mockImplementation(() => {});
delete window.location;
window.location = { reload: jest.fn() };
});
afterEach(() => {
jest.clearAllTimers();
jest.useRealTimers();
jest.restoreAllMocks();
});
@@ -44,11 +40,10 @@ describe("<ErrorBoundary />", () => {
expect(ErrorBoundary.prototype.componentDidCatch).toHaveBeenCalled();
});
it("calls window.location.reload after 60s", () => {
const reloadSpy = jest.spyOn(global.window.location, "reload");
it("sets up timer to reload after 60s", () => {
// Verifies that a timer is set up for auto-reload after error
renderFailingComponent();
jest.advanceTimersByTime(1000 * 61);
expect(reloadSpy).toHaveBeenCalled();
expect(jest.getTimerCount()).toBe(1);
expect(consoleSpy).toHaveBeenCalled();
});
@@ -59,4 +54,16 @@ describe("<ErrorBoundary />", () => {
).toBeInTheDocument();
expect(consoleSpy).toHaveBeenCalled();
});
it("decrements reload countdown each second", () => {
// Verifies the reloadApp method decrements the countdown timer
renderFailingComponent();
expect(screen.getByText(/auto refresh in 60s/)).toBeInTheDocument();
jest.advanceTimersByTime(1000);
expect(screen.getByText(/auto refresh in 59s/)).toBeInTheDocument();
jest.advanceTimersByTime(1000);
expect(screen.getByText(/auto refresh in 58s/)).toBeInTheDocument();
});
});
+4 -1
View File
@@ -68,7 +68,10 @@ class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
}
};
componentDidCatch(error: Error, { componentStack }: ErrorInfo): void {
componentDidCatch(
error: Error,
{ componentStack: _componentStack }: ErrorInfo,
): void {
if (this.state.cachedError === null) {
this.setState({ cachedError: error });
}
+1 -1
View File
@@ -26,7 +26,7 @@ afterEach(() => {
});
it("doesn't load ResizeObserver polyfill if not needed", () => {
global.window.ResizeObserver = jest.fn((cb) => {
global.window.ResizeObserver = jest.fn((_) => {
return {
observe: jest.fn(),
disconnect: jest.fn(),
+1 -1
View File
@@ -16,7 +16,7 @@ const pollyfillsLoaded: string[] = [];
if ("ResizeObserver" in window === false) {
pollyfillsLoaded.push("ResizeObserver");
const module = require("@juggle/resize-observer"); // eslint-disable-line @typescript-eslint/no-var-requires
const module = require("@juggle/resize-observer"); // eslint-disable-line @typescript-eslint/no-require-imports
(window as Window).ResizeObserver = module.ResizeObserver;
}