Files
MeshChatX/tests/frontend/InterfacesPerformance.test.js
Sudo-Ivan e2586e9052
Some checks failed
CI / test-backend (push) Successful in 32s
CI / lint (push) Failing after 2m12s
CI / build-frontend (pull_request) Successful in 1m38s
Build and Publish Docker Image / build (pull_request) Has been skipped
CI / test-backend (pull_request) Successful in 24s
OSV-Scanner PR Scan / scan-pr (pull_request) Successful in 53s
CI / test-lang (pull_request) Successful in 1m15s
CI / lint (pull_request) Failing after 5m8s
CI / build-frontend (push) Successful in 9m46s
CI / test-lang (push) Successful in 9m48s
Tests / test (push) Successful in 13m32s
Tests / test (pull_request) Successful in 11m23s
Build Test / Build and Test (push) Successful in 15m56s
Build and Publish Docker Image / build-dev (pull_request) Successful in 13m42s
Build Test / Build and Test (pull_request) Successful in 16m9s
feat(tests): add comprehensive telemetry and interface tests
- Introduced new test files for telemetry functionality, including integration, fuzzing, and extended tests to ensure robustness and performance.
- Added tests for parsing LXMF display names and telemetry data, addressing potential bugs and ensuring correct handling of various input formats.
- Implemented performance tests for the InterfacesPage component, validating rendering efficiency with a large number of discovered interfaces.
- Enhanced existing tests for markdown rendering and link utilities to cover additional edge cases and improve stability.
2026-01-07 19:22:00 -06:00

147 lines
4.7 KiB
JavaScript

import { mount } from "@vue/test-utils";
import { describe, it, expect, vi } from "vitest";
import InterfacesPage from "../../meshchatx/src/frontend/components/interfaces/InterfacesPage.vue";
// Mock dependencies
vi.mock("../../meshchatx/src/frontend/js/GlobalState", () => ({
default: {
config: { theme: "light" },
hasPendingInterfaceChanges: false,
modifiedInterfaceNames: new Set(),
},
}));
vi.mock("../../meshchatx/src/frontend/js/Utils", () => ({
default: {
formatBytes: (b) => `${b} B`,
isInterfaceEnabled: () => true,
},
}));
vi.mock("../../meshchatx/src/frontend/js/ToastUtils", () => ({
default: {
success: vi.fn(),
error: vi.fn(),
},
}));
vi.mock("../../meshchatx/src/frontend/js/ElectronUtils", () => ({
default: {
relaunch: vi.fn(),
},
}));
// Mock axios
global.axios = {
get: vi.fn((url) => {
if (url.includes("/api/v1/reticulum/interfaces")) {
return Promise.resolve({ data: { interfaces: {} } });
}
if (url.includes("/api/v1/app/info")) {
return Promise.resolve({ data: { app_info: { is_reticulum_running: true } } });
}
if (url.includes("/api/v1/interface-stats")) {
return Promise.resolve({ data: { interface_stats: { interfaces: [] } } });
}
if (url.includes("/api/v1/reticulum/discovery")) {
return Promise.resolve({ data: { discovery: { discover_interfaces: true } } });
}
if (url.includes("/api/v1/reticulum/discovered-interfaces")) {
return Promise.resolve({ data: { interfaces: [], active: [] } });
}
return Promise.resolve({ data: {} });
}),
post: vi.fn(() => Promise.resolve({ data: {} })),
patch: vi.fn(() => Promise.resolve({ data: {} })),
};
window.axios = global.axios;
// Mock MaterialDesignIcon
const MaterialDesignIcon = {
template: '<div class="mdi"></div>',
props: ["iconName"],
};
describe("InterfacesPage Performance", () => {
it("renders InterfacesPage with 1000 disconnected discovered interfaces", async () => {
const numDiscovered = 1000;
const discoveredInterfaces = Array.from({ length: numDiscovered }, (_, i) => ({
name: `Discovered ${i}`,
type: "UDPInterface",
reachable_on: `192.168.1.${i}`,
port: 4242,
discovery_hash: `hash_${i}`,
}));
const start = performance.now();
const wrapper = mount(InterfacesPage, {
global: {
components: {
MaterialDesignIcon,
Toggle: { template: "<div></div>" },
ImportInterfacesModal: {
template: "<div></div>",
methods: { show: vi.fn() },
},
Interface: { template: "<div></div>" },
},
mocks: {
$t: (key) => key,
$router: { push: vi.fn() },
},
},
});
await wrapper.setData({
discoveredInterfaces,
activeTab: "overview", // This is where discovered interfaces are shown in the template I saw
});
const end = performance.now();
console.log(`Rendered ${numDiscovered} discovered interfaces in ${(end - start).toFixed(2)}ms`);
// Check if animations are present
const pulsingElements = wrapper.findAll(".animate-pulse");
expect(pulsingElements.length).toBe(numDiscovered);
expect(end - start).toBeLessThan(5000);
});
it("stops pulsing animations after 30 seconds", async () => {
const iface = {
name: "Discovered 1",
type: "UDPInterface",
reachable_on: "192.168.1.1",
port: 4242,
discovery_hash: "hash_1",
disconnected_at: Date.now() - 31000, // 31 seconds ago
};
const wrapper = mount(InterfacesPage, {
global: {
components: {
MaterialDesignIcon,
Toggle: { template: "<div></div>" },
ImportInterfacesModal: {
template: "<div></div>",
methods: { show: vi.fn() },
},
Interface: { template: "<div></div>" },
},
mocks: {
$t: (key) => key,
$router: { push: vi.fn() },
},
},
});
await wrapper.setData({
discoveredInterfaces: [iface],
activeTab: "overview",
});
const pulsingElements = wrapper.findAll(".animate-pulse");
expect(pulsingElements.length).toBe(0);
});
});