diff --git a/frontend-modern/src/pages/Docker.tsx b/frontend-modern/src/pages/Docker.tsx
index c66819f17..47f4919b6 100644
--- a/frontend-modern/src/pages/Docker.tsx
+++ b/frontend-modern/src/pages/Docker.tsx
@@ -1,4 +1,5 @@
import { Navigate, useLocation } from '@solidjs/router';
+import { Show } from 'solid-js';
import { DockerPageSurface } from '@/features/docker/DockerPageSurface';
import { buildDockerPath, DOCKER_PATH } from '@/routing/resourceLinks';
@@ -6,11 +7,14 @@ export function Docker() {
const location = useLocation();
const pathname = () => location.pathname.replace(/\/+$/, '');
- if (pathname() === `${DOCKER_PATH}/workloads`) {
- return ;
- }
-
- return ;
+ return (
+ }
+ >
+
+
+ );
}
export default Docker;
diff --git a/tests/integration/tests/01-core-e2e.spec.ts b/tests/integration/tests/01-core-e2e.spec.ts
index 293cb6e5a..37a80bbc6 100644
--- a/tests/integration/tests/01-core-e2e.spec.ts
+++ b/tests/integration/tests/01-core-e2e.spec.ts
@@ -1,6 +1,7 @@
import { test, expect, type Locator } from '@playwright/test';
import {
E2E_CREDENTIALS,
+ apiRequest,
ensureAuthenticated,
getMockMode,
login,
@@ -81,7 +82,7 @@ test.describe.serial('Core E2E flows', () => {
test.skip(true, `Unable to read CPU default threshold (value="${cpuDefaultValueRaw}")`);
}
- const configResBeforeCreate = await page.request.get('/api/alerts/config');
+ const configResBeforeCreate = await apiRequest(page, '/api/alerts/config');
expect(configResBeforeCreate.ok()).toBeTruthy();
const configBeforeCreate = (await configResBeforeCreate.json()) as {
overrides?: Record;
@@ -166,7 +167,7 @@ test.describe.serial('Core E2E flows', () => {
});
await expect(revertOverride).toBeVisible();
- const configResAfterCreate = await page.request.get('/api/alerts/config');
+ const configResAfterCreate = await apiRequest(page, '/api/alerts/config');
expect(configResAfterCreate.ok()).toBeTruthy();
const configAfterCreate = (await configResAfterCreate.json()) as { overrides?: Record };
const previousOverrideIds = new Set(Object.keys(configBeforeCreate.overrides ?? {}));
@@ -181,7 +182,7 @@ test.describe.serial('Core E2E flows', () => {
await page.getByRole('button', { name: 'Save Changes' }).click();
await expect(unsaved).not.toBeVisible();
- const configResAfterDelete = await page.request.get('/api/alerts/config');
+ const configResAfterDelete = await apiRequest(page, '/api/alerts/config');
expect(configResAfterDelete.ok()).toBeTruthy();
const configAfterDelete = (await configResAfterDelete.json()) as { overrides?: Record };
expect(
diff --git a/tests/integration/tests/11-first-session.spec.ts b/tests/integration/tests/11-first-session.spec.ts
index 78f0df8a7..4a2ef3100 100644
--- a/tests/integration/tests/11-first-session.spec.ts
+++ b/tests/integration/tests/11-first-session.spec.ts
@@ -279,21 +279,29 @@ test.describe.serial("First-session experience", () => {
route: "/settings/support/reporting",
expectedURL: /\/settings\/support\/reporting/,
feature: "advanced_reporting",
+ paywallIndicator: /Advanced Reporting/i,
},
{
route: "/settings/security-webhooks",
expectedURL: /\/settings\/security-webhooks/,
feature: "audit_logging",
+ paywallIndicator: /Audit (Logging|Webhooks)/i,
},
{
route: "/settings/system-relay",
expectedURL: /\/settings\/system-relay/,
feature: "relay",
+ paywallIndicator: /Remote Access \(Relay\)/i,
},
] as const;
try {
- for (const { route, expectedURL, feature } of gatedRoutes) {
+ for (const {
+ route,
+ expectedURL,
+ feature,
+ paywallIndicator: paywallPattern,
+ } of gatedRoutes) {
const hasFeature = features.has(feature);
if (!hasFeature) {
@@ -346,9 +354,8 @@ test.describe.serial("First-session experience", () => {
// Paywall indicator should be visible.
const paywallIndicator = page
- .locator(
- "text=/Upgrade|Pro Feature|Requires Pro|Requires Relay|Start.*Trial|Advanced Reporting|Audit Logging|Audit Webhooks|Pulse Relay/i",
- )
+ .getByRole("main")
+ .getByText(paywallPattern)
.first();
const isPaywallVisible = await paywallIndicator
.isVisible({ timeout: 5_000 })
diff --git a/tests/integration/tests/38-vmware-ai-chat-mentions.spec.ts b/tests/integration/tests/38-vmware-ai-chat-mentions.spec.ts
index 0aabe6350..7f848e3b1 100644
--- a/tests/integration/tests/38-vmware-ai-chat-mentions.spec.ts
+++ b/tests/integration/tests/38-vmware-ai-chat-mentions.spec.ts
@@ -78,7 +78,7 @@ test.describe('VMware AI chat mentions', () => {
.filter({ hasText: /esxi-01\.lab\.local/ })
.first();
await expect(hostOption).toBeVisible({ timeout: 30_000 });
- await hostOption.click();
+ await textarea.press('Enter');
await expect(textarea).toHaveValue('@esxi-01.lab.local ');
// API-backed vSphere VMs use the same shared mention contract, carrying
@@ -91,7 +91,7 @@ test.describe('VMware AI chat mentions', () => {
.filter({ hasText: /warehouse-api-01/ })
.first();
await expect(vmOption).toBeVisible({ timeout: 30_000 });
- await vmOption.click();
+ await textarea.press('Enter');
await expect(textarea).toHaveValue('@warehouse-api-01 ');
expect(unexpectedVMwareRequests).toEqual([]);
diff --git a/tests/integration/tests/42-vmware-ai-chat-read-recovery.spec.ts b/tests/integration/tests/42-vmware-ai-chat-read-recovery.spec.ts
index 3c1e5efd8..e80d99f6c 100644
--- a/tests/integration/tests/42-vmware-ai-chat-read-recovery.spec.ts
+++ b/tests/integration/tests/42-vmware-ai-chat-read-recovery.spec.ts
@@ -65,15 +65,16 @@ test.describe('VMware AI chat read recovery', () => {
await expect(textarea).toBeVisible();
// First websocket state frame can lag on a freshly booted backend.
- await textarea.click();
- await textarea.pressSequentially('@warehouse');
+ await textarea.focus();
+ await textarea.fill('@warehouse');
const mentionListbox = page.getByRole('listbox', { name: 'Assistant resources' });
await expect(mentionListbox).toBeVisible({ timeout: 30_000 });
- await mentionListbox
+ const vmOption = mentionListbox
.getByRole('option')
.filter({ hasText: /warehouse-api-01/ })
- .first()
- .click();
+ .first();
+ await expect(vmOption).toBeVisible({ timeout: 30_000 });
+ await textarea.press('Enter');
await expect(textarea).toHaveValue('@warehouse-api-01 ');
await textarea.fill('@warehouse-api-01 show me recent status');
diff --git a/tests/integration/tests/helpers.ts b/tests/integration/tests/helpers.ts
index a8e5422cf..d96c3baed 100644
--- a/tests/integration/tests/helpers.ts
+++ b/tests/integration/tests/helpers.ts
@@ -1161,7 +1161,7 @@ async function waitForDefaultMockRuntimeReady(page: Page): Promise {
await expect
.poll(
async () => {
- const response = await page.request.get("/api/state").catch(() => null);
+ const response = await apiRequest(page, "/api/state").catch(() => null);
if (!response?.ok()) {
return false;
}
@@ -1272,7 +1272,11 @@ export async function setMockMode(page: Page, enabled: boolean) {
}
if (res.ok()) {
- return (await res.json()) as { enabled: boolean };
+ const result = (await res.json()) as { enabled: boolean };
+ if (enabled) {
+ await waitForDefaultMockRuntimeReady(page);
+ }
+ return result;
}
lastError = new Error(`HTTP ${res.status()}: ${await res.text()}`);