Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions apps/deploy-web/tests/ui/pages/BuildTemplatePage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,66 @@
import { testEnvConfig } from "../fixture/test-env.config";
import { DeployBasePage } from "./DeployBasePage";

export class BuildTemplatePage extends DeployBasePage {
async gotoInteractive() {
await this.page.goto(testEnvConfig.BASE_URL);
await this.page.getByTestId("sidebar-sdl-builder-link").first().click();
}

async fillImageName(imageName: string) {
await this.page.getByTestId("image-name-input").fill(imageName);
}

async addService() {
await this.page.getByRole("button", { name: /add service/i }).click();
}

async clickDeploy() {
await this.page.getByRole("button", { name: /^deploy$/i }).click();
}

async clickPreview() {
await this.page.getByRole("button", { name: /preview/i }).click();
}

async clickReset() {
await this.page.getByRole("button", { name: /reset/i }).click();
}

getPreviewTextLocator(text: string) {
return this.page.getByText(text).first();
}

async closePreview() {
await this.page.getByRole("button", { name: /close/i }).first().click();
}

getImageNameInput() {
return this.page.getByTestId("image-name-input");
}

getDeployButton() {
return this.page.getByRole("button", { name: /^deploy$/i });
}

getPreviewButton() {
return this.page.getByRole("button", { name: /preview/i });
}

getAddServiceButton() {
return this.page.getByRole("button", { name: /add service/i });
}

getServiceLocator(serviceName: string) {
const escapedName = serviceName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
return this.page.getByText(new RegExp(`${escapedName}:`)).first();
}

getServiceNameInput(serviceName: string) {
return this.page.getByRole("textbox").filter({ hasText: serviceName });
}

async waitForServiceAdded(serviceName: string, timeout = 10000) {
await this.page.locator(`input[type="text"][value="${serviceName}"]`).first().waitFor({ state: "visible", timeout });
}
}
107 changes: 107 additions & 0 deletions apps/deploy-web/tests/ui/sdl-builder-deployment.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import type { BrowserContext, Page } from "@playwright/test";

import { expect, test } from "./fixture/base-test";
import { BuildTemplatePage } from "./pages/BuildTemplatePage";

test.describe("SDL Builder Deployment Flow", () => {
test("navigate to SDL builder page", async ({ page, context }) => {
const { sdlBuilderPage } = await setup({ page, context });

await expect(sdlBuilderPage.getDeployButton()).toBeVisible();
await expect(sdlBuilderPage.getPreviewButton()).toBeVisible();
await expect(sdlBuilderPage.getAddServiceButton()).toBeVisible();
});

test("fill image name and preview SDL", async ({ page, context }) => {
const { sdlBuilderPage } = await setup({ page, context, imageName: "nginx:latest" });

await sdlBuilderPage.clickPreview();

await expect(sdlBuilderPage.getPreviewTextLocator("nginx:latest")).toBeVisible();
await expect(sdlBuilderPage.getPreviewTextLocator("version:")).toBeVisible();
await expect(sdlBuilderPage.getPreviewTextLocator("services:")).toBeVisible();

await sdlBuilderPage.closePreview();
});

test("create deployment from SDL builder", async ({ page, context }) => {
const { sdlBuilderPage } = await setup({ page, context, imageName: "nginx:alpine" });

await sdlBuilderPage.clickDeploy();

await expect(page.getByTestId("connect-wallet-btn").first()).toBeVisible({ timeout: 10000 });
});

test("add multiple services", async ({ page, context }) => {
const { sdlBuilderPage } = await setup({ page, context, imageName: "nginx:latest" });

await sdlBuilderPage.addService();

await sdlBuilderPage.waitForServiceAdded("service-2");

await sdlBuilderPage.clickPreview();
await expect(sdlBuilderPage.getPreviewTextLocator("service-1")).toBeVisible();
await expect(sdlBuilderPage.getPreviewTextLocator("service-2")).toBeVisible();
await sdlBuilderPage.closePreview();
});

test("preview SDL with different images", async ({ page, context }) => {
const { sdlBuilderPage } = await setup({ page, context });

const images = ["postgres:15", "redis:7", "node:18-alpine"];

for (const image of images) {
await sdlBuilderPage.fillImageName(image);
await sdlBuilderPage.clickPreview();
await expect(sdlBuilderPage.getPreviewTextLocator(image)).toBeVisible();
await sdlBuilderPage.closePreview();
}
});

test("verify SDL YAML structure", async ({ page, context }) => {
const { sdlBuilderPage } = await setup({ page, context, imageName: "ubuntu:22.04" });

await sdlBuilderPage.clickPreview();

await expect(sdlBuilderPage.getPreviewTextLocator("version:")).toBeVisible();
await expect(sdlBuilderPage.getPreviewTextLocator("services:")).toBeVisible();
await expect(sdlBuilderPage.getPreviewTextLocator("profiles:")).toBeVisible();
await expect(sdlBuilderPage.getPreviewTextLocator("deployment:")).toBeVisible();

await sdlBuilderPage.closePreview();
});

test("add service then preview shows both services", async ({ page, context }) => {
const { sdlBuilderPage } = await setup({ page, context, imageName: "nginx:latest" });

await sdlBuilderPage.addService();
await sdlBuilderPage.waitForServiceAdded("service-2");

await sdlBuilderPage.clickPreview();

await expect(sdlBuilderPage.getServiceLocator("service-1")).toBeVisible();
await expect(sdlBuilderPage.getServiceLocator("service-2")).toBeVisible();

await sdlBuilderPage.closePreview();
});

test("preview button always available with valid image", async ({ page, context }) => {
const sdlBuilderPage = new BuildTemplatePage(context, page, "sdl-builder");
await sdlBuilderPage.gotoInteractive();

await sdlBuilderPage.fillImageName("alpine:latest");

await expect(sdlBuilderPage.getPreviewButton()).toBeEnabled();
});

async function setup({ page, context, imageName }: { page: Page; context: BrowserContext; imageName?: string }) {
const sdlBuilderPage = new BuildTemplatePage(context, page, "sdl-builder");
await sdlBuilderPage.gotoInteractive();

if (imageName) {
await sdlBuilderPage.fillImageName(imageName);
}

return { sdlBuilderPage };
}
});