119 lines
4.4 KiB
TypeScript
119 lines
4.4 KiB
TypeScript
import { expect, test } from "../../fixtures/test-base";
|
|
import { KanbanPage } from "../../pages/kanban-page";
|
|
import { SessionPage } from "../../pages/session-page";
|
|
import { createWipQueueScenario } from "../../helpers/queue-limit-navigation";
|
|
import {
|
|
createQueuedSessionOwnershipScenario,
|
|
waitForLaunchQueue,
|
|
} from "./queued-session-ownership-helpers";
|
|
|
|
test.describe("Queue limit navigation", () => {
|
|
test("labels the global capacity queue and returns without changing the task", async ({
|
|
testPage,
|
|
apiClient,
|
|
backend,
|
|
seedData,
|
|
}) => {
|
|
test.setTimeout(240_000);
|
|
const releaseCeiling = await backend.useEnv({ KANDEV_MAX_CONCURRENT_SESSIONS: "1" });
|
|
let fillerSessionId: string | undefined;
|
|
|
|
try {
|
|
const scenario = await createQueuedSessionOwnershipScenario(
|
|
apiClient,
|
|
seedData,
|
|
"Global queue navigation",
|
|
);
|
|
fillerSessionId = scenario.fillerSessionId;
|
|
|
|
await testPage.goto(`/t/${scenario.taskId}`);
|
|
await new SessionPage(testPage).waitForLoad();
|
|
const queueStatus = testPage.locator('[data-testid="task-launch-queue-status"]:visible');
|
|
await expect(queueStatus).toContainText("Global session limit");
|
|
await expect(queueStatus).toContainText("All workspaces");
|
|
|
|
const settingsLink = queueStatus.getByTestId("launch-queue-session-capacity-link");
|
|
await expect(settingsLink).toHaveAttribute(
|
|
"href",
|
|
"/settings/preferences/task-behavior#setting-session-capacity",
|
|
);
|
|
await settingsLink.click();
|
|
await expect(testPage).toHaveURL(
|
|
/\/settings\/preferences\/task-behavior#setting-session-capacity$/,
|
|
);
|
|
await expect(
|
|
testPage.locator('[data-settings-target="setting-session-capacity"]'),
|
|
).toHaveAttribute("data-settings-target-highlight", "true");
|
|
|
|
await testPage.goBack();
|
|
await new SessionPage(testPage).waitForLoad();
|
|
await expect(
|
|
testPage.locator('[data-testid="task-launch-queue-status"]:visible'),
|
|
).toBeVisible();
|
|
await expect(
|
|
waitForLaunchQueue(apiClient, seedData.workspaceId, scenario.taskId, 5_000),
|
|
).resolves.toMatchObject({ reason: "session_capacity" });
|
|
} finally {
|
|
if (fillerSessionId) {
|
|
await apiClient
|
|
.stopSession({
|
|
session_id: fillerSessionId,
|
|
reason: "queue-limit-navigation e2e cleanup",
|
|
force: true,
|
|
})
|
|
.catch(() => undefined);
|
|
}
|
|
await releaseCeiling();
|
|
}
|
|
});
|
|
|
|
test("links a WIP queue to its workflow and promotes after a saved limit change", async ({
|
|
testPage,
|
|
apiClient,
|
|
seedData,
|
|
}) => {
|
|
const scenario = await createWipQueueScenario(apiClient, seedData, "WIP queue navigation");
|
|
const kanban = new KanbanPage(testPage);
|
|
await kanban.goto();
|
|
await expect(kanban.taskCard(scenario.queuedTaskId)).toBeVisible();
|
|
await kanban.taskCard(scenario.queuedTaskId).click();
|
|
|
|
const sessionPage = new SessionPage(testPage);
|
|
await sessionPage.waitForLoad();
|
|
const wipStatus = testPage.getByTestId("task-wip-queue-status");
|
|
await expect(wipStatus).toBeVisible();
|
|
await expect(wipStatus).toContainText("Workflow WIP limit");
|
|
await expect(wipStatus).toContainText("WIP queue navigation workflow / Review");
|
|
await expect(wipStatus).toContainText("1 of 1 task admitted");
|
|
|
|
const settingsLink = wipStatus.getByTestId("wip-queue-settings-link");
|
|
await expect(settingsLink).toHaveAttribute(
|
|
"href",
|
|
`/settings/workspaces/${seedData.workspaceId}/workflows#workflow-card-${scenario.workflowId}`,
|
|
);
|
|
await settingsLink.click();
|
|
await expect(testPage).toHaveURL(
|
|
new RegExp(
|
|
`/settings/workspaces/${seedData.workspaceId}/workflows#workflow-card-${scenario.workflowId}$`,
|
|
),
|
|
);
|
|
await expect(testPage.getByTestId(`workflow-card-${scenario.workflowId}`)).toHaveAttribute(
|
|
"data-settings-target-highlight",
|
|
"true",
|
|
);
|
|
|
|
await testPage.goBack();
|
|
await sessionPage.waitForLoad();
|
|
await expect(wipStatus).toBeVisible();
|
|
|
|
await apiClient.updateWorkflowStep(scenario.reviewStepId, { wip_limit: 2 });
|
|
await expect
|
|
.poll(async () => (await apiClient.getTask(scenario.queuedTaskId)).wip_admitted)
|
|
.toBe(true);
|
|
await expect(wipStatus).toHaveCount(0);
|
|
await expect(apiClient.getTask(scenario.admittedTaskId)).resolves.toMatchObject({
|
|
wip_admitted: true,
|
|
});
|
|
});
|
|
});
|