test: expand API and GUI test coverage across all tools

Add ~500 new E2E tests and ~300 new integration tests covering:

- 24 new GUI E2E specs: navigation, responsive layout, keyboard shortcuts,
  tool UI for all 35 non-AI tools, batch/pipeline workflows, settings/RBAC,
  visual regression, accessibility, and performance budgets
- 3 new E2E-Docker specs: batch workflows, advanced pipelines, cross-format
- 1 new adversarial integration test: memory pressure, corrupted files,
  unicode filenames, extreme dimensions, pipeline/batch edge cases
- 29 expanded integration test files: HEIC/HEIF input, large files, parameter
  boundaries, batch processing, format edge cases across all tools
- Cross-format matrix expanded: 641 tests covering every tool x 18 formats
- AI bridge unit tests expanded: lifecycle, tool modules, error propagation
- Unit test gaps filled: analytics, tool-registry, web stores

Also fixes:
- vitest.config.ts: exclude e2e-docs and e2e-landing from Vitest runner
- AI E2E specs: add sidecar health check to skip gracefully when Python
  AI backend is not running instead of timing out
This commit is contained in:
SnapOtter
2026-04-29 01:39:25 +08:00
parent 4acec0846c
commit 03f82567d0
74 changed files with 15893 additions and 14 deletions
+73
View File
@@ -361,3 +361,76 @@ describe("getToolRegistryEntry", () => {
expect(entry?.ResultsPanel).toBeDefined();
});
});
// ==========================================================================
// Wrapper components (lines 305-324)
// ==========================================================================
import { render } from "@testing-library/react";
import React from "react";
function renderSettings(Settings: React.ComponentType<Record<string, unknown>>, props = {}) {
return render(
React.createElement(React.Suspense, { fallback: null }, React.createElement(Settings, props)),
);
}
describe("CropSettingsWrapper", () => {
it("renders null when cropProps is undefined", () => {
const entry = getToolRegistryEntry("crop");
expect(entry).toBeDefined();
const { container } = renderSettings(entry!.Settings as never);
expect(container.innerHTML).toBe("");
});
it("renders CropSettings when cropProps is provided", () => {
const entry = getToolRegistryEntry("crop");
expect(entry).toBeDefined();
const cropProps = {
cropState: {
crop: { x: 0, y: 0, width: 50, height: 50, unit: "%" },
aspect: undefined,
showGrid: true,
imgDimensions: { width: 200, height: 150 },
},
onCropChange: vi.fn(),
onAspectChange: vi.fn(),
onGridToggle: vi.fn(),
};
const { container } = renderSettings(entry!.Settings as never, { cropProps });
expect(container).toBeDefined();
});
});
describe("EraseObjectSettingsWrapper", () => {
it("renders null when eraserProps is undefined", () => {
const entry = getToolRegistryEntry("erase-object");
expect(entry).toBeDefined();
const { container } = renderSettings(entry!.Settings as never);
expect(container.innerHTML).toBe("");
});
it("renders EraseObjectSettings when eraserProps is provided", () => {
const entry = getToolRegistryEntry("erase-object");
expect(entry).toBeDefined();
const eraserProps = {
eraserRef: React.createRef(),
hasStrokes: false,
brushSize: 20,
onBrushSizeChange: vi.fn(),
};
const { container } = renderSettings(entry!.Settings as never, { eraserProps });
expect(container).toBeDefined();
});
});
describe("makeColorSettingsComponent", () => {
it("adjust-colors Settings renders without throwing", () => {
const entry = getToolRegistryEntry("adjust-colors");
expect(entry).toBeDefined();
const { container } = renderSettings(entry!.Settings as never, {
onPreviewFilter: vi.fn(),
});
expect(container).toBeDefined();
});
});