diff --git a/package.json b/package.json index e5683d34c..15b234120 100644 --- a/package.json +++ b/package.json @@ -46,8 +46,8 @@ "scripts:update-bug-report-template": "tsx ./scripts/update-bug-report-template.mts", "scripts:update-readme-integrations": "tsx ./scripts/update-integration-list.mts", "start": "pnpm -F nextjs start", - "test": "cross-env NODE_ENV=development CI=true vitest run --project \"!e2e\" --coverage.enabled ", - "test:e2e": "cross-env NODE_ENV=development CI=true vitest e2e", + "test": "cross-env NODE_ENV=development CI=true vitest run --project \"!e2e\" --retry 2 --coverage.enabled ", + "test:e2e": "cross-env NODE_ENV=development CI=true vitest e2e --retry 2 --maxWorkers 2", "test:workshop": "sh apps/workshop/test.sh", "test:workshop-image": "sh apps/workshop/test-image.sh", "test:ui": "cross-env NODE_ENV=development CI=true vitest --project \"!e2e\" --ui --coverage.enabled", diff --git a/packages/integrations/test/home-assistant.spec.ts b/packages/integrations/test/home-assistant.spec.ts index 5dc2be90e..91952b37e 100644 --- a/packages/integrations/test/home-assistant.spec.ts +++ b/packages/integrations/test/home-assistant.spec.ts @@ -41,35 +41,37 @@ describe("Home Assistant integration", () => { test("Test connection should work", async () => { // Arrange const startedContainer = await prepareHomeAssistantContainerAsync(); - const homeAssistantIntegration = createHomeAssistantIntegration(startedContainer); + try { + const homeAssistantIntegration = createHomeAssistantIntegration(startedContainer); - // Act - const result = await homeAssistantIntegration.testConnectionAsync(); + // Act + const result = await homeAssistantIntegration.testConnectionAsync(); - // Assert - expect(result.success).toBe(true); - - // Cleanup - await startedContainer.stop(); - }, 30_000); // Timeout of 30 seconds + // Assert + expect(result.success).toBe(true); + } finally { + await startedContainer.stop(); + } + }, 60_000); test("Test connection should fail with wrong credentials", async () => { // Arrange const startedContainer = await prepareHomeAssistantContainerAsync(); - const homeAssistantIntegration = createHomeAssistantIntegration(startedContainer, "wrong-api-key"); + try { + const homeAssistantIntegration = createHomeAssistantIntegration(startedContainer, "wrong-api-key"); - // Act - const result = await homeAssistantIntegration.testConnectionAsync(); + // Act + const result = await homeAssistantIntegration.testConnectionAsync(); - // Assert - expect(result.success).toBe(false); - if (result.success) return; + // Assert + expect(result.success).toBe(false); + if (result.success) return; - expect(result.error).toBeInstanceOf(TestConnectionError); - expect(result.error.type).toBe("authorization"); - - // Cleanup - await startedContainer.stop(); - }, 30_000); // Timeout of 30 seconds + expect(result.error).toBeInstanceOf(TestConnectionError); + expect(result.error.type).toBe("authorization"); + } finally { + await startedContainer.stop(); + } + }, 60_000); }); const prepareHomeAssistantContainerAsync = async () => { @@ -77,27 +79,29 @@ const prepareHomeAssistantContainerAsync = async () => { const startedContainer = await homeAssistantContainer.start(); await startedContainer.exec(["unzip", "-o", "/tmp/config.zip", "-d", "/config"]); await startedContainer.restart(); - await waitForHomeAssistantAsync(startedContainer); + await waitForHomeAssistantApiAsync(startedContainer); return startedContainer; }; -const waitForHomeAssistantAsync = async (container: StartedTestContainer) => { +const waitForHomeAssistantApiAsync = async (container: StartedTestContainer) => { const url = `http://${container.getHost()}:${container.getMappedPort(8123)}/api/config`; + const deadline = Date.now() + 45_000; - for (let attempt = 0; attempt < 40; attempt++) { + while (Date.now() < deadline) { try { const response = await fetch(url, { headers: { Authorization: `Bearer ${DEFAULT_API_KEY}` }, + signal: AbortSignal.timeout(1_000), }); if (response.ok) return; } catch { - // Home Assistant is still restarting. + // Home Assistant closes connections while restarting. Retry until the deadline. } - - await new Promise((resolve) => setTimeout(resolve, 500)); + await new Promise((resolve) => setTimeout(resolve, 250)); } - throw new Error("Home Assistant did not become ready after restart"); + await container.stop(); + throw new Error("Home Assistant API did not become ready after restart"); }; const createHomeAssistantContainer = () => {