import { expect, test } from "@playwright/test";
import {
goToAppMarket,
installComponent,
checkComponent,
upgradeComponent,
verifyOverviewSort,
prepareHelloWorldPackageLikeMarketplace,
} from "./utils/application";
import { cleanupAfterEach } from "./utils/application-cleanup";
import type { DeployPlan } from "./test-application.constants";
import {
totalTimeout,
upgradeTime,
serviceClusterUrl,
appName,
appNameAiaio,
appNameMonitor,
componentNameMonitor,
PLAN_APP_AIAIO,
PLAN_EXTEND_LOGGING_MONITOR,
eagleEyeApp,
initVersion,
upgradeVersion,
EAGLE_INIT_VERSION,
EAGLE_UPGRADE_VERSION,
PLAN_APP_EAGLE,
} from "./test-application.constants";
test.describe("应用管理-概览", () => {
let createdApps: DeployPlan[] = [];
test.beforeEach(async ({ page }) => {
await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
});
test.afterEach(async ({ page }) => {
await cleanupAfterEach(page, {
createdApps,
});
});
async function installComponentTracked(page: any, plan: DeployPlan) {
await installComponent(page, plan.componentName, plan.appName, plan.version, plan.source);
createdApps.push(plan);
}
async function deployComponents(page: any, plans: DeployPlan[]) {
for (const plan of plans) {
await test.step(`部署前置组件(${plan.componentName} -> ${plan.appName})`, async () => {
await goToAppMarket(page);
await installComponentTracked(page, plan);
await checkComponent(page, plan.appName, {
entry: plan.entry,
serviceClusterUrl,
});
});
}
}
test("【应用运维-应用管理概览-007】应用管理-概览-刷新-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
test.setTimeout(totalTimeout);
let oldTime = "";
await test.step("部署应用并记录更新时间", async () => {
await deployComponents(page, PLAN_APP_EAGLE);
await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
await page.getByRole("textbox", { name: /搜索.*名称/ }).fill(eagleEyeApp);
await page.getByRole("button", { name: "search" }).click();
await expect(page.getByRole("link", { name: eagleEyeApp })).toBeVisible();
const row = page
.getByRole("row")
.filter({ has: page.getByRole("link", { name: eagleEyeApp }) })
.first();
const updateTimeCell = row
.getByRole("cell")
.filter({ hasText: /\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}/ })
.last();
await expect(updateTimeCell).toBeVisible();
oldTime = ((await updateTimeCell.textContent()) ?? "").trim();
await expect(oldTime).not.toBe("");
});
await test.step("新标签页进行升级", async () => {
const pageB = await page.context().newPage();
await pageB.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
await pageB.getByRole("textbox", { name: /搜索.*名称/ }).fill(eagleEyeApp);
await pageB.getByRole("button", { name: "search" }).click();
await pageB.getByRole("link", { name: eagleEyeApp }).click();
await upgradeComponent(pageB, EAGLE_INIT_VERSION, EAGLE_UPGRADE_VERSION);
await pageB.getByRole("button", { name: /确\s*定/ }).click();
await expect(pageB.getByText("升级成功")).toBeVisible({ timeout: upgradeTime });
await pageB.close();
});
await test.step("原标签页点击平台刷新并校验更新时间", async () => {
await page.getByRole("button", { name: "sync" }).click();
const row = page
.getByRole("row")
.filter({ has: page.getByRole("link", { name: eagleEyeApp }) })
.first();
const updateTimeCell = row
.getByRole("cell")
.filter({ hasText: /\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}/ })
.last();
const newTime = ((await updateTimeCell.textContent()) ?? "").trim();
await expect(newTime).not.toBe("");
await expect(newTime >= oldTime).toBeTruthy();
});
});
test("【应用运维-扩展组件管理概览-007】扩展管理-概览-刷新-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
test.setTimeout(totalTimeout);
let oldTime = "";
await test.step("部署扩展组件并验证成功", async () => {
await deployComponents(page, [{ componentName: componentNameMonitor, appName: appNameMonitor, entry: "extendManage", version: initVersion }]);
oldTime = ((await page.locator(".container-platform-space-item").nth(5).textContent()) ?? "").trim();
await expect(oldTime).not.toBe("");
});
await test.step("创建新标签页升级", async () => {
const pageB = await page.context().newPage();
await pageB.goto(serviceClusterUrl + "/container_platform/extendManage");
await pageB.getByRole("textbox", { name: /搜索.*名称/ }).fill(appNameMonitor);
await pageB.getByRole("button", { name: "search" }).click();
await pageB.getByRole("link", { name: appNameMonitor }).click();
await upgradeComponent(pageB, initVersion, upgradeVersion);
await pageB.getByRole("button", { name: /确\s*定/ }).click();
await expect(pageB.getByText("升级成功")).toBeVisible({ timeout: upgradeTime });
await pageB.close();
});
await test.step("返回原标签页检查更新时间", async () => {
await page.getByRole("button", { name: "sync" }).click();
const nowTime = ((await page.locator(".container-platform-space-item").nth(5).textContent()) ?? "").trim();
await expect(nowTime).not.toBe("");
await expect(nowTime >= oldTime).toBeTruthy();
});
});
test("【应用运维-扩展管理概览-008】扩展管理-概览-排序-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
await deployComponents(page, PLAN_EXTEND_LOGGING_MONITOR);
await test.step("进入扩展组件管理概览页", async () => {
await page.goto(serviceClusterUrl + "/container_platform/extendManage");
await expect(page.getByRole("table")).toBeVisible();
});
await verifyOverviewSort(page, {
nameHeader: "扩展组件名称",
nameColIndex: 1,
updateTimeHeader: "更新时间",
updateTimeColIndex: 3,
});
});
test("【应用运维-应用管理概览-008】应用管理-概览-排序-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
await deployComponents(page, PLAN_APP_AIAIO);
await test.step("进入应用管理概览页", async () => {
await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
await expect(page.getByRole("table")).toBeVisible();
});
await verifyOverviewSort(page, {
nameHeader: "应用名称",
nameColIndex: 1,
updateTimeHeader: "更新时间",
updateTimeColIndex: 3,
});
});
test("【应用运维-扩展管理概览-002/009】扩展管理-概览-搜索/筛选-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
await deployComponents(page, PLAN_EXTEND_LOGGING_MONITOR);
await test.step("进入扩展组件管理概览页", async () => {
await page.goto(serviceClusterUrl + "/container_platform/extendManage");
await expect(page.getByRole("table")).toBeVisible();
});
await test.step("搜索:全称命中 test-log", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill(appName);
await search.press("Enter");
await expect(page.getByRole("link", { name: appName })).toBeVisible();
});
await test.step("搜索:部分命中 log", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill("log");
await search.press("Enter");
await expect(page.getByRole("link", { name: appName })).toBeVisible();
});
await test.step("搜索:大小写命中 MONITOR", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill("MONITOR");
await search.press("Enter");
await expect(page.getByRole("link", { name: appNameMonitor })).toBeVisible();
});
await test.step("搜索:数字 1(当前前置数据无数字名称)", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill("1");
await search.press("Enter");
await expect(page.getByRole("link", { name: appName })).toHaveCount(0);
await expect(page.getByRole("link", { name: appNameMonitor })).toHaveCount(0);
});
await test.step("按状态筛选部署成功", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill("");
await search.press("Enter");
await page.getByLabel("状态").getByRole("button", { name: "filter" }).click();
await page.getByRole("menuitem", { name: "部署成功" }).click();
await page.getByRole("button", { name: /确\s*定/ }).click();
await expect(page.getByRole("table")).toContainText("部署成功");
});
});
test("【应用运维-应用管理概览-002/009】应用管理-概览-搜索/筛选-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
await deployComponents(page, PLAN_APP_AIAIO);
await test.step("进入应用管理概览页", async () => {
await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
await expect(page.getByRole("table")).toBeVisible();
});
await test.step("搜索:全称命中 test-aiaio", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill(appNameAiaio);
await search.press("Enter");
await expect(page.getByRole("link", { name: appNameAiaio })).toBeVisible();
});
await test.step("搜索:部分命中 aiaio", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill("aiaio");
await search.press("Enter");
await expect(page.getByRole("link", { name: appNameAiaio })).toBeVisible();
});
await test.step("搜索:大小写命中 AIAIO", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill("AIAIO");
await search.press("Enter");
await expect(page.getByRole("link", { name: appNameAiaio })).toBeVisible();
});
await test.step("搜索:数字 1(当前前置数据无数字名称)", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill("1");
await search.press("Enter");
await expect(page.getByRole("link", { name: appNameAiaio })).toHaveCount(0);
});
await test.step("按状态筛选部署成功", async () => {
const search = page.getByRole("textbox", { name: /搜索.*名称/ });
await search.fill("");
await search.press("Enter");
await page.getByLabel("状态").getByRole("button", { name: "filter" }).click();
await page.getByRole("menuitem", { name: "部署成功" }).click();
await page.getByRole("button", { name: /确\s*定/ }).click();
await expect(page.getByRole("table")).toContainText("部署成功");
});
});
test("【应用运维-应用管理概览-010】应用管理-概览-页面跳转-基础功能验证 ", { tag: ["@v24.06", "@application"] }, async ({ page }) => {
test.setTimeout(totalTimeout);
const componentNameHelloWorld = "hello-world";
const appNames = Array.from({ length: 12 }, (_, i) => `test${i + 1}`);
await prepareHelloWorldPackageLikeMarketplace(page);
await deployComponents(
page,
appNames.map((appName): DeployPlan => ({
componentName: componentNameHelloWorld,
appName,
entry: "applicationManageHelm",
source: "",
})),
);
await page.goto(serviceClusterUrl + "/container_platform/applicationManageHelm");
await expect(page.getByRole("table")).toBeVisible();
const extractFirstRowAppName = async (): Promise<string> => {
const rowText = (await page.locator("table tbody tr").first().textContent()) ?? "";
const m = rowText.match(/test\d+/);
return m?.[0] ?? rowText.trim();
};
const getPaginationContainer = () =>
page
.locator("[class*='container-platform-pagination']")
.filter({ hasText: /条\/页|共\s*\d+\s*条/ })
.first();
const clickPageNumber = async (no: number) => {
const strNo = String(no);
const pagination = getPaginationContainer();
await expect(pagination).toBeVisible({ timeout: 60_000 });
const byText = pagination.getByText(strNo, { exact: true }).first();
await expect(byText).toBeVisible({ timeout: 60_000 });
await byText.click();
};
const isPageButtonVisible = async (no: number) => {
const strNo = String(no);
const pagination = getPaginationContainer();
if ((await pagination.count()) === 0) return false;
return pagination.getByText(strNo, { exact: true }).first().isVisible().catch(() => false);
};
const pickPageSize = async (size: 10 | 20) => {
const pagination = getPaginationContainer();
await expect(pagination).toBeVisible({ timeout: 30_000 });
const sizeTrigger = pagination.locator(".container-platform-select-selection-item").first();
await expect(sizeTrigger).toBeVisible({ timeout: 10_000 });
await sizeTrigger.click();
const option = page.getByText(new RegExp(`^${size}\\s*条/页$`)).first();
await expect(option).toBeVisible({ timeout: 10_000 });
await option.click();
await expect(pagination.locator(".container-platform-select-selection-item").first()).toContainText(
new RegExp(`${size}\\s*条/页`),
);
};
await expect(page.getByText(/共\s*13\s*条/)).toBeVisible();
await pickPageSize(10);
await expect.poll(async () => await isPageButtonVisible(2), { timeout: 10_000 }).toBeTruthy();
const firstRowPage1 = await extractFirstRowAppName();
await clickPageNumber(2);
await page.waitForTimeout(1000);
const firstRowPage2 = await extractFirstRowAppName();
expect(firstRowPage2).not.toBe(firstRowPage1);
await pickPageSize(20);
await page.waitForTimeout(1000);
const page2VisibleAfter20 = await isPageButtonVisible(2);
expect(page2VisibleAfter20).toBeFalsy();
});
});