test: make tests less fragile

This commit is contained in:
2026-02-09 09:57:39 +05:00
parent 2bbe59107c
commit c4103e937d
12 changed files with 49 additions and 55 deletions
@@ -1,6 +1,6 @@
import AppHeader from "$components/layout/AppHeader.svelte"; import AppHeader from "$components/layout/AppHeader.svelte";
import { themeState } from "$states/theme.svelte"; import { themeState } from "$states/theme.svelte";
import { fireEvent, render } from "@testing-library/svelte"; import { fireEvent, render, screen } from "@testing-library/svelte";
import { beforeEach, describe, expect, it } from "vitest"; import { beforeEach, describe, expect, it } from "vitest";
describe("AppHeader.svelte", () => { describe("AppHeader.svelte", () => {
@@ -9,10 +9,9 @@ describe("AppHeader.svelte", () => {
}); });
it("should toggle theme on button click", async () => { it("should toggle theme on button click", async () => {
const { container } = render(AppHeader); render(AppHeader);
const toggleButton = container.querySelector("button"); const toggleButton = screen.getByRole("button", { name: /toggle theme/i });
if (!toggleButton) throw new Error("Toggle button not found");
themeState.theme = "dark"; themeState.theme = "dark";
await fireEvent.click(toggleButton); await fireEvent.click(toggleButton);
+3 -3
View File
@@ -1,11 +1,11 @@
import { render } from "@testing-library/svelte"; import { render, screen } from "@testing-library/svelte";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import CardTest from "./CardTest.svelte"; import CardTest from "./CardTest.svelte";
describe("Card.svelte", () => { describe("Card.svelte", () => {
it("should render without crashing", () => { it("should render without crashing", () => {
render(CardTest); render(CardTest);
const card = document.querySelector(".card"); expect(screen.getByText("Test Title")).toBeInTheDocument();
expect(card).toBeInTheDocument(); expect(screen.getByTestId("card-content")).toBeInTheDocument();
}); });
}); });
@@ -1,11 +1,12 @@
import { render } from "@testing-library/svelte"; import { render, screen } from "@testing-library/svelte";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import InputGroupTest from "./InputGroupTest.svelte"; import InputGroupTest from "./InputGroupTest.svelte";
describe("InputGroup.svelte", () => { describe("InputGroup.svelte", () => {
it("should render without crashing", () => { it("should render without crashing", () => {
render(InputGroupTest); render(InputGroupTest);
const inputGroup = document.querySelector(".input-group"); expect(screen.getByTestId("input1")).toBeInTheDocument();
expect(inputGroup).toBeInTheDocument(); expect(screen.getByTestId("input2")).toBeInTheDocument();
expect(screen.getByTestId("button")).toBeInTheDocument();
}); });
}); });
@@ -1,11 +1,12 @@
import { render } from "@testing-library/svelte"; import { render, screen } from "@testing-library/svelte";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import SettingsGridTest from "./SettingsGridTest.svelte"; import SettingsGridTest from "./SettingsGridTest.svelte";
describe("SettingsGrid.svelte", () => { describe("SettingsGrid.svelte", () => {
it("should render without crashing", () => { it("should render without crashing", () => {
render(SettingsGridTest); render(SettingsGridTest);
const settingsGrid = document.querySelector(".settings-grid"); expect(screen.getByTestId("item1")).toBeInTheDocument();
expect(settingsGrid).toBeInTheDocument(); expect(screen.getByTestId("item2")).toBeInTheDocument();
expect(screen.getByTestId("item3")).toBeInTheDocument();
}); });
}); });
@@ -1,11 +1,11 @@
import { render } from "@testing-library/svelte"; import { render, screen } from "@testing-library/svelte";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import SettingsRowTest from "./SettingsRowTest.svelte"; import SettingsRowTest from "./SettingsRowTest.svelte";
describe("SettingsRow.svelte", () => { describe("SettingsRow.svelte", () => {
it("should render without crashing", () => { it("should render without crashing", () => {
render(SettingsRowTest); render(SettingsRowTest);
const settingRow = document.querySelector(".setting-row"); expect(screen.getByText("Test Label")).toBeInTheDocument();
expect(settingRow).toBeInTheDocument(); expect(screen.getByTestId("test-input")).toBeInTheDocument();
}); });
}); });
@@ -1,5 +1,5 @@
import PreviewControls from "$components/panel/PreviewControls.svelte"; import PreviewControls from "$components/panel/PreviewControls.svelte";
import { cleanup, render } from "@testing-library/svelte"; import { cleanup, render, screen } from "@testing-library/svelte";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
afterEach(() => { afterEach(() => {
@@ -16,7 +16,7 @@ describe("PreviewControls.svelte", () => {
}, },
}); });
const buttons = document.querySelectorAll("button"); const buttons = screen.getAllByRole("button");
expect(buttons.length).toBeGreaterThan(0); expect(buttons.length).toBeGreaterThan(0);
}); });
}); });
@@ -1,5 +1,5 @@
import TextInlineEdit from "$components/text/TextInlineEdit.svelte"; import TextInlineEdit from "$components/text/TextInlineEdit.svelte";
import { cleanup, render } from "@testing-library/svelte"; import { cleanup, render, screen } from "@testing-library/svelte";
import { afterEach, describe, expect, it } from "vitest"; import { afterEach, describe, expect, it } from "vitest";
afterEach(() => { afterEach(() => {
@@ -16,7 +16,7 @@ describe("TextInlineEdit.svelte", () => {
}, },
}); });
const input = document.querySelector("input[type='text']"); const input = screen.getByRole("textbox");
expect(input).toBeInTheDocument(); expect(input).toBeInTheDocument();
expect(input).toHaveValue("Test text"); expect(input).toHaveValue("Test text");
}); });
@@ -30,7 +30,7 @@ describe("TextInlineEdit.svelte", () => {
}, },
}); });
const input = document.querySelector("input[type='text']"); const input = screen.getByRole("textbox");
expect(input).toHaveValue(""); expect(input).toHaveValue("");
}); });
}); });
+9 -12
View File
@@ -1,10 +1,10 @@
import TextInput from "$components/text/TextInput.svelte"; import TextInput from "$components/text/TextInput.svelte";
import { fireEvent, render } from "@testing-library/svelte"; import { fireEvent, render, screen } from "@testing-library/svelte";
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it, vi } from "vitest";
describe("TextInput.svelte", () => { describe("TextInput.svelte", () => {
it("should render with initial value", () => { it("should render with initial value", () => {
const { container } = render(TextInput, { render(TextInput, {
props: { props: {
text: "Test text", text: "Test text",
onenter: vi.fn(), onenter: vi.fn(),
@@ -12,13 +12,13 @@ describe("TextInput.svelte", () => {
}, },
}); });
const input = container.querySelector("input"); const input = screen.getByRole("textbox", { name: /test input/i });
expect(input).toBeInTheDocument(); expect(input).toBeInTheDocument();
expect(input).toHaveValue("Test text"); expect(input).toHaveValue("Test text");
}); });
it("should update value on input", async () => { it("should update value on input", async () => {
const { container } = render(TextInput, { render(TextInput, {
props: { props: {
text: "Initial", text: "Initial",
onenter: vi.fn(), onenter: vi.fn(),
@@ -26,8 +26,7 @@ describe("TextInput.svelte", () => {
}, },
}); });
const input = container.querySelector("input"); const input = screen.getByRole("textbox", { name: /test input/i });
if (!input) throw new Error("Input element not found");
await fireEvent.input(input, { target: { value: "Updated text" } }); await fireEvent.input(input, { target: { value: "Updated text" } });
expect(input).toHaveValue("Updated text"); expect(input).toHaveValue("Updated text");
@@ -35,7 +34,7 @@ describe("TextInput.svelte", () => {
it("should call onenter when Enter key is pressed", async () => { it("should call onenter when Enter key is pressed", async () => {
const onenter = vi.fn(); const onenter = vi.fn();
const { container } = render(TextInput, { render(TextInput, {
props: { props: {
text: "Test", text: "Test",
onenter, onenter,
@@ -43,8 +42,7 @@ describe("TextInput.svelte", () => {
}, },
}); });
const input = container.querySelector("input"); const input = screen.getByRole("textbox", { name: /test input/i });
if (!input) throw new Error("Input element not found");
await fireEvent.keyDown(input, { key: "Enter" }); await fireEvent.keyDown(input, { key: "Enter" });
expect(onenter).toHaveBeenCalledTimes(1); expect(onenter).toHaveBeenCalledTimes(1);
@@ -52,7 +50,7 @@ describe("TextInput.svelte", () => {
it("should not call onenter when other keys are pressed", async () => { it("should not call onenter when other keys are pressed", async () => {
const onenter = vi.fn(); const onenter = vi.fn();
const { container } = render(TextInput, { render(TextInput, {
props: { props: {
text: "Test", text: "Test",
onenter, onenter,
@@ -60,8 +58,7 @@ describe("TextInput.svelte", () => {
}, },
}); });
const input = container.querySelector("input"); const input = screen.getByRole("textbox", { name: /test input/i });
if (!input) throw new Error("Input element not found");
await fireEvent.keyDown(input, { key: "Escape" }); await fireEvent.keyDown(input, { key: "Escape" });
await fireEvent.keyDown(input, { key: "Tab" }); await fireEvent.keyDown(input, { key: "Tab" });
@@ -1,6 +1,6 @@
import TextManager from "$components/text/TextManager.svelte"; import TextManager from "$components/text/TextManager.svelte";
import { textsState } from "$states/texts.svelte"; import { textsState } from "$states/texts.svelte";
import { fireEvent, render, screen, waitFor } from "@testing-library/svelte"; import { fireEvent, render, screen, waitFor, within } from "@testing-library/svelte";
import { beforeEach, describe, expect, it, vi } from "vitest"; import { beforeEach, describe, expect, it, vi } from "vitest";
describe("TextManager.svelte", () => { describe("TextManager.svelte", () => {
@@ -98,9 +98,8 @@ describe("TextManager.svelte", () => {
const textItems = screen.queryAllByRole("listitem"); const textItems = screen.queryAllByRole("listitem");
expect(textItems).toHaveLength(1); expect(textItems).toHaveLength(1);
const inputs = textItems[0].querySelectorAll('input[type="text"]'); const input = within(textItems[0]).getByRole("textbox");
expect(inputs).toHaveLength(1); expect(input).toHaveValue("Test text");
expect(inputs[0]).toHaveValue("Test text");
}); });
it("should call textsState.removeText when delete button is clicked", () => { it("should call textsState.removeText when delete button is clicked", () => {
+10 -11
View File
@@ -5,7 +5,7 @@ import MockIcon from "./MockIcon.svelte";
describe("Button.svelte", () => { describe("Button.svelte", () => {
it("should render with icon and label", () => { it("should render with icon and label", () => {
const { container } = render(Button, { render(Button, {
props: { props: {
icon: MockIcon, icon: MockIcon,
label: "Test Button", label: "Test Button",
@@ -14,23 +14,23 @@ describe("Button.svelte", () => {
}); });
expect(screen.getByText("Test Button")).toBeInTheDocument(); expect(screen.getByText("Test Button")).toBeInTheDocument();
expect(container.querySelector("svg")).toBeInTheDocument(); expect(screen.getByRole("button", { name: /test button/i })).toBeInTheDocument();
}); });
it("should render with icon only", () => { it("should render with icon only", () => {
const { container } = render(Button, { render(Button, {
props: { props: {
icon: MockIcon, icon: MockIcon,
ariaLabel: "Test button", ariaLabel: "Test button",
}, },
}); });
expect(container.querySelector("svg")).toBeInTheDocument(); expect(screen.getByRole("button", { name: /test button/i })).toBeInTheDocument();
}); });
it("should call onclick handler", async () => { it("should call onclick handler", async () => {
const onclick = vi.fn(); const onclick = vi.fn();
const { container } = render(Button, { render(Button, {
props: { props: {
icon: MockIcon, icon: MockIcon,
label: "Click me", label: "Click me",
@@ -39,15 +39,14 @@ describe("Button.svelte", () => {
}, },
}); });
const button = container.querySelector("button"); const button = screen.getByRole("button", { name: /test button/i });
if (!button) throw new Error("Button element not found");
await fireEvent.click(button); await fireEvent.click(button);
expect(onclick).toHaveBeenCalledTimes(1); expect(onclick).toHaveBeenCalledTimes(1);
}); });
it("should be disabled when disabled prop is true", () => { it("should be disabled when disabled prop is true", () => {
const { container } = render(Button, { render(Button, {
props: { props: {
icon: MockIcon, icon: MockIcon,
label: "Disabled", label: "Disabled",
@@ -56,12 +55,12 @@ describe("Button.svelte", () => {
}, },
}); });
const button = container.querySelector("button"); const button = screen.getByRole("button", { name: /test button/i });
expect(button).toBeDisabled(); expect(button).toBeDisabled();
}); });
it("should not be disabled by default", () => { it("should not be disabled by default", () => {
const { container } = render(Button, { render(Button, {
props: { props: {
icon: MockIcon, icon: MockIcon,
label: "Enabled", label: "Enabled",
@@ -69,7 +68,7 @@ describe("Button.svelte", () => {
}, },
}); });
const button = container.querySelector("button"); const button = screen.getByRole("button", { name: /test button/i });
expect(button).not.toBeDisabled(); expect(button).not.toBeDisabled();
}); });
}); });
+3 -4
View File
@@ -1,19 +1,18 @@
import RangeSlider from "$components/ui/RangeSlider.svelte"; import RangeSlider from "$components/ui/RangeSlider.svelte";
import { fireEvent, render } from "@testing-library/svelte"; import { fireEvent, render, screen } from "@testing-library/svelte";
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it, vi } from "vitest";
describe("RangeSlider.svelte", () => { describe("RangeSlider.svelte", () => {
it("should call onchange handler", async () => { it("should call onchange handler", async () => {
const onchange = vi.fn(); const onchange = vi.fn();
const { container } = render(RangeSlider, { render(RangeSlider, {
props: { props: {
value: 50, value: 50,
onchange, onchange,
}, },
}); });
const slider = container.querySelector("input[type='range']"); const slider = screen.getByRole("slider");
if (!slider) throw new Error("Slider element not found");
await fireEvent.change(slider, { target: { value: "75" } }); await fireEvent.change(slider, { target: { value: "75" } });
expect(onchange).toHaveBeenCalledTimes(1); expect(onchange).toHaveBeenCalledTimes(1);
+2 -3
View File
@@ -1,11 +1,10 @@
import { render } from "@testing-library/svelte"; import { render, screen } from "@testing-library/svelte";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import PageTest from "./PageTest.svelte"; import PageTest from "./PageTest.svelte";
describe("+page.svelte", () => { describe("+page.svelte", () => {
it("should render without crashing", () => { it("should render without crashing", () => {
render(PageTest); render(PageTest);
const mainGrid = document.querySelector(".main-grid"); expect(screen.getByText("Тексты панелей")).toBeInTheDocument();
expect(mainGrid).toBeInTheDocument();
}); });
}); });