mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-09 16:00:59 +00:00
Converge UI primitives and readiness guards
This commit is contained in:
parent
241ac9feaf
commit
09ed857869
28 changed files with 538 additions and 166 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
import net from 'node:net';
|
||||
|
||||
import { withExclusiveLock } from '../../../scripts/exclusive-lock.mjs';
|
||||
|
|
@ -155,6 +156,9 @@ export function buildManagedLocalBackendEnv(state, env = process.env) {
|
|||
PULSE_PUBLIC_URL: state.baseURL,
|
||||
PULSE_DATA_DIR: state.dataDir,
|
||||
PULSE_AUDIT_DIR: state.dataDir,
|
||||
PULSE_AUDIT_SIGNING_KEY: trim(env.PULSE_AUDIT_SIGNING_KEY)
|
||||
|| trim(env.PULSE_E2E_AUDIT_SIGNING_KEY)
|
||||
|| randomBytes(32).toString('hex'),
|
||||
PULSE_METRICS_PORT: state.metricsPort,
|
||||
PULSE_DEV: 'true',
|
||||
PULSE_E2E_BILLING_STATE_PATH: state.billingStatePath,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ test('buildManagedLocalBackendEnv seeds auth, bootstrap token, and billing path'
|
|||
assert.equal(env.PULSE_DEV, 'true');
|
||||
assert.equal(env.PULSE_DATA_DIR, state.dataDir);
|
||||
assert.equal(env.PULSE_E2E_BILLING_STATE_PATH, state.billingStatePath);
|
||||
assert.match(env.PULSE_AUDIT_SIGNING_KEY, /^[0-9a-f]{64}$/);
|
||||
assert.equal(env.PULSE_E2E_BOOTSTRAP_TOKEN.length > 0, true);
|
||||
assert.equal(env.PULSE_E2E_PRIMARY_API_TOKEN.length > 0, true);
|
||||
assert.equal(env.PULSE_METRICS_PORT, '0');
|
||||
|
|
@ -79,6 +80,28 @@ test('buildManagedLocalBackendEnv seeds auth, bootstrap token, and billing path'
|
|||
assert.match(env.ALLOWED_ORIGINS, /5173/);
|
||||
});
|
||||
|
||||
test('buildManagedLocalBackendEnv preserves explicit audit signing key', () => {
|
||||
const state = buildManagedLocalBackendState({
|
||||
PULSE_E2E_LOCAL_BACKEND_PORT: '9002',
|
||||
});
|
||||
const env = buildManagedLocalBackendEnv(state, {
|
||||
PULSE_AUDIT_SIGNING_KEY: 'explicit-audit-key',
|
||||
});
|
||||
|
||||
assert.equal(env.PULSE_AUDIT_SIGNING_KEY, 'explicit-audit-key');
|
||||
});
|
||||
|
||||
test('buildManagedLocalBackendEnv accepts deterministic e2e audit signing key', () => {
|
||||
const state = buildManagedLocalBackendState({
|
||||
PULSE_E2E_LOCAL_BACKEND_PORT: '9002',
|
||||
});
|
||||
const env = buildManagedLocalBackendEnv(state, {
|
||||
PULSE_E2E_AUDIT_SIGNING_KEY: 'e2e-audit-key',
|
||||
});
|
||||
|
||||
assert.equal(env.PULSE_AUDIT_SIGNING_KEY, 'e2e-audit-key');
|
||||
});
|
||||
|
||||
test('buildManagedLocalBackendEnv seeds deterministic auth in hosted mode', () => {
|
||||
const state = buildManagedLocalBackendState({
|
||||
PULSE_E2E_LOCAL_BACKEND_PORT: '9002',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { apiRequest, ensureAuthenticated } from "./helpers";
|
||||
import { PATROL_ROUTE } from "./routes";
|
||||
|
||||
/**
|
||||
* V6 License Activation E2E Test
|
||||
|
|
@ -298,7 +299,7 @@ test.describe.serial("V6 license activation flow", () => {
|
|||
).toBeVisible();
|
||||
await expect(page.getByText(/Patrol quickstart/i)).toHaveCount(0);
|
||||
|
||||
await page.goto("/ai");
|
||||
await page.goto(PATROL_ROUTE);
|
||||
await expect(
|
||||
page.getByRole("heading", { name: "Patrol" }).first(),
|
||||
).toBeVisible();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { fileURLToPath } from "node:url";
|
|||
import { test as base, expect } from "@playwright/test";
|
||||
|
||||
import { createAuthenticatedStorageState } from "./helpers";
|
||||
import { PATROL_ROUTE } from "./routes";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
|
|
@ -321,7 +322,7 @@ test.describe("TrueNAS patrol finding links", () => {
|
|||
});
|
||||
});
|
||||
|
||||
await page.goto("/ai", { waitUntil: "domcontentloaded" });
|
||||
await page.goto(PATROL_ROUTE, { waitUntil: "domcontentloaded" });
|
||||
|
||||
await expect(page.getByRole("button", { name: "Findings" })).toBeVisible();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { fileURLToPath } from "node:url";
|
|||
import { test as base, expect } from "@playwright/test";
|
||||
|
||||
import { createAuthenticatedStorageState } from "./helpers";
|
||||
import { PATROL_ROUTE } from "./routes";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
|
|
@ -252,7 +253,7 @@ test.describe("TrueNAS patrol run history", () => {
|
|||
});
|
||||
});
|
||||
|
||||
await page.goto("/ai", { waitUntil: "domcontentloaded" });
|
||||
await page.goto(PATROL_ROUTE, { waitUntil: "domcontentloaded" });
|
||||
|
||||
await expect(page.getByRole("button", { name: "Findings" })).toBeVisible();
|
||||
await page.getByRole("button", { name: "Runs" }).click();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { expect, test, type Page } from "@playwright/test";
|
||||
|
||||
import { ensureAuthenticated } from "./helpers";
|
||||
import { PATROL_ROUTE } from "./routes";
|
||||
|
||||
type AISettingsPayload = {
|
||||
enabled: boolean;
|
||||
|
|
@ -379,7 +380,7 @@ test.describe("Retired quickstart browser contract", () => {
|
|||
},
|
||||
});
|
||||
|
||||
await page.goto("/ai", { waitUntil: "domcontentloaded" });
|
||||
await page.goto(PATROL_ROUTE, { waitUntil: "domcontentloaded" });
|
||||
|
||||
await expect(page.getByText("Patrol Paused").first()).toBeVisible();
|
||||
await expect(
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ test.describe("Assistant & Patrol settings provider setup", () => {
|
|||
expect(updateRequests[0]).not.toHaveProperty("model");
|
||||
|
||||
await expect(
|
||||
page.getByText("Assistant & Patrol Model Overrides"),
|
||||
page.getByRole("button", { name: "Model Overrides" }),
|
||||
).toBeVisible();
|
||||
const workloadDiscoveryToggle = page.getByRole("button", {
|
||||
name: /workload discovery/i,
|
||||
|
|
@ -179,10 +179,7 @@ test.describe("Assistant & Patrol settings provider setup", () => {
|
|||
await workloadDiscoveryToggle.click();
|
||||
await expect(page.getByText("Enable workload discovery")).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(
|
||||
"Workload discovery gives Pulse Assistant and Patrol concrete service context, so chat responses and verification findings can reference real services and commands instead of generic advice.",
|
||||
{ exact: true },
|
||||
),
|
||||
page.getByRole("button", { name: "Run discovery now" }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("button", { name: /enable assistant and patrol/i }),
|
||||
|
|
|
|||
|
|
@ -86,9 +86,7 @@ test.describe.serial('Self-hosted paid prompt visibility', () => {
|
|||
|
||||
await page.goto('/settings/security-roles');
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Infrastructure', exact: true }),
|
||||
).toBeVisible();
|
||||
await expect(page.getByRole('heading', { level: 1, name: 'Roles' })).toBeVisible();
|
||||
await expect(page.getByText('Custom Roles (Pro)')).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: 'Remote Access' })).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: 'Roles' })).toHaveCount(0);
|
||||
|
|
|
|||
1
tests/integration/tests/routes.ts
Normal file
1
tests/integration/tests/routes.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const PATROL_ROUTE = "/patrol";
|
||||
Loading…
Add table
Add a link
Reference in a new issue