Skip to content

Commit

Permalink
feat(docs) automate screenshotting for the readme WD-11363
Browse files Browse the repository at this point in the history
Signed-off-by: David Edler <david.edler@canonical.com>
  • Loading branch information
edlerd committed May 22, 2024
1 parent 487ba59 commit e0a8d65
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,6 @@ dist/
/playwright-report/
/playwright/.cache/
/coverage
tests/screenshots

haproxy-local.cfg
26 changes: 18 additions & 8 deletions tests/helpers/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ export const randomInstanceName = (): string => {
export const createInstance = async (
page: Page,
instance: string,
type = "container",
type: string = "container",
project: string = "default",
image: string = "alpine/3.19/cloud",
) => {
await page.goto("/ui/");
await page.goto(`/ui/project/${project}`);
await page
.getByRole("link", { name: "Instances", exact: true })
.first()
Expand All @@ -20,8 +22,8 @@ export const createInstance = async (
await page.getByLabel("Instance name").fill(instance);
await page.getByRole("button", { name: "Browse images" }).click();
await page.getByPlaceholder("Search an image").click();
await page.getByPlaceholder("Search an image").fill("alpine/3.19/cloud");
await page.getByRole("button", { name: "Select" }).click();
await page.getByPlaceholder("Search an image").fill(image);
await page.getByRole("button", { name: "Select" }).first().click();
await page
.getByRole("combobox", { name: "Instance type" })
.selectOption(type);
Expand All @@ -30,8 +32,12 @@ export const createInstance = async (
await page.waitForSelector(`text=Created instance ${instance}.`);
};

export const visitInstance = async (page: Page, instance: string) => {
await page.goto("/ui/");
export const visitInstance = async (
page: Page,
instance: string,
project: string = "default",
) => {
await page.goto(`/ui/project/${project}`);
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill(instance);
await page.getByRole("link", { name: instance }).first().click();
Expand All @@ -49,8 +55,12 @@ export const saveInstance = async (page: Page, instance: string) => {
await page.getByRole("button", { name: "Close notification" }).click();
};

export const deleteInstance = async (page: Page, instance: string) => {
await visitInstance(page, instance);
export const deleteInstance = async (
page: Page,
instance: string,
project: string = "default",
) => {
await visitInstance(page, instance, project);
const stopButton = page.getByRole("button", { name: "Stop", exact: true });
if (await stopButton.isEnabled()) {
await page.keyboard.down("Shift");
Expand Down
32 changes: 24 additions & 8 deletions tests/helpers/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@ export const randomProfileName = (): string => {
return `playwright-profile-${randomNameSuffix()}`;
};

export const createProfile = async (page: Page, profile: string) => {
await startProfileCreation(page, profile);
export const createProfile = async (
page: Page,
profile: string,
project: string = "default",
) => {
await startProfileCreation(page, profile, project);
await finishProfileCreation(page, profile);
};

export const startProfileCreation = async (page: Page, profile: string) => {
await page.goto("/ui/");
export const startProfileCreation = async (
page: Page,
profile: string,
project: string = "default",
) => {
await page.goto(`/ui/project/${project}`);
await page.getByRole("link", { name: "Profiles" }).click();
await page.getByRole("button", { name: "Create profile" }).click();
await page.getByLabel("Profile name").fill(profile);
Expand All @@ -22,8 +30,12 @@ export const finishProfileCreation = async (page: Page, profile: string) => {
await page.waitForSelector(`text=Profile ${profile} created.`);
};

export const deleteProfile = async (page: Page, profile: string) => {
await visitProfile(page, profile);
export const deleteProfile = async (
page: Page,
profile: string,
project: string = "default",
) => {
await visitProfile(page, profile, project);
await page.getByRole("button", { name: "Delete" }).click();
await page
.getByRole("dialog", { name: "Confirm delete" })
Expand All @@ -32,8 +44,12 @@ export const deleteProfile = async (page: Page, profile: string) => {
await page.waitForSelector(`text=Profile ${profile} deleted.`);
};

export const visitProfile = async (page: Page, profile: string) => {
await page.goto("/ui/");
export const visitProfile = async (
page: Page,
profile: string,
project: string = "default",
) => {
await page.goto(`/ui/project/${project}`);
await page.getByRole("link", { name: "Profiles" }).click();
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill(profile);
Expand Down
158 changes: 158 additions & 0 deletions tests/readme-screenshots.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { expect, test } from "./fixtures/lxd-test";
import {
createInstance,
deleteInstance,
visitAndStartInstance,
} from "./helpers/instances";
import { createProject, deleteProject } from "./helpers/projects";
import { createProfile, deleteProfile, visitProfile } from "./helpers/profile";

test("instance creation screen", async ({ page }) => {
await page.goto("/ui/");
await page.getByText("Instances").click();
await page.getByText("Create instance").click();
await page.getByPlaceholder("Enter name").fill("comic-glider");
await page.getByRole("button", { name: "Browse images" }).click();
await page
.locator("tr")
.filter({ hasText: "Ubuntu24.04 LTS" })
.first()
.getByRole("button")
.click();
await page.screenshot({ path: "tests/screenshots/create-instance.png" });
});

test("instance list screen", async ({ page }) => {
await page.goto("/ui/");
const project = "my-cluster";
await createProject(page, project);
await visitProfile(page, "default", project);
await page.getByTestId("tab-link-Configuration").click();
await page.getByRole("button", { name: "Edit profile" }).click();
await page.getByText("Disk devices").click();
await page.getByRole("button", { name: "Create override" }).click();
await page.getByRole("button", { name: "Save changes" }).click();
const instances = [
"comic-glider",
"deciding-flounder",
"native-sailfish",
"precise-lacewing",
"ready-grizzly",
"singular-moose",
];
for (const instance of instances) {
await createInstance(page, instance, "container", project, "24.04");
}
await page.goto(`/ui/project/${project}`);
await page
.getByRole("row", {
name: "Select comic-glider Name Type Description Status Actions",
})
.getByLabel("Type")
.click();

await page.screenshot({ path: "tests/screenshots/instance-list.png" });

for (const instance of instances) {
await deleteInstance(page, instance, project);
}
await page.getByRole("link", { name: "Images" }).click();
await page.getByRole("button", { name: "Delete", exact: true }).click();
await page.getByText("Delete", { exact: true }).click();

await deleteProject(page, project);
});

test("instance terminal screen", async ({ page }) => {
await page.goto("/ui/");
const instance = "comic-glider";
await createInstance(page, instance, "container", "default", "24.04");
await visitAndStartInstance(page, instance);
await page.getByRole("button", { name: "Close notification" }).click();
await page.getByTestId("tab-link-Terminal").click();
await expect(page.getByText("~#")).toBeVisible();
await page.waitForTimeout(1000); // ensure the terminal is ready
await page.keyboard.type("cd /");
await page.keyboard.press("Enter");
await page.keyboard.type("ll");
await page.keyboard.press("Enter");
await page.keyboard.type("cat /etc/issue");
await page.keyboard.press("Enter");

await page.screenshot({ path: "tests/screenshots/instance-terminal.png" });

await deleteInstance(page, instance);
});

test("instance graphical console screen", async ({ page }) => {
test.skip(Boolean(process.env.CI), "github runners lack vm support");

await page.goto("/ui/");
const instance = "upright-pangolin";
await page.getByText("Instances").click();
await page.getByText("Create instance").click();
await page.getByPlaceholder("Enter name").fill(instance);
await page.getByRole("button", { name: "Browse images" }).click();
await page
.locator("tr")
.filter({ hasText: "ubuntu/24.04/desktop" })
.first()
.getByRole("button")
.click();
await page.getByRole("button", { name: "Create", exact: true }).click();
await visitAndStartInstance(page, instance);
await page.getByRole("button", { name: "Close notification" }).click();
await page.getByTestId("tab-link-Console").click();
await page.waitForTimeout(40000); // ensure the vm is booted

await page.screenshot({
path: "tests/screenshots/instance-graphical-console.png",
});

await deleteInstance(page, instance);
});

test("profile list screen", async ({ page }) => {
await page.goto("/ui/");
const project = "my-cluster";
await createProject(page, project);
await createProfile(page, "small", project);
await createProfile(page, "medium", project);
await createProfile(page, "large", project);
await page.goto(`/ui/project/${project}/profiles`);

await page.screenshot({ path: "tests/screenshots/profile-list.png" });

await deleteProfile(page, "small", project);
await deleteProfile(page, "medium", project);
await deleteProfile(page, "large", project);
await deleteProject(page, project);
});

test("storage pool screen", async ({ page }) => {
await page.goto("/ui/");
await page.getByText("Storage").click();
await page.getByText("Pools").click();
await page.getByText("Created").first().click();

await page.screenshot({ path: "tests/screenshots/storage-pool-list.png" });
});

test("operations screen", async ({ page }) => {
await page.goto("/ui/");
await createInstance(page, "comic-glider");
await page.getByRole("button", { name: "Close notification" }).click();
await page.getByText("Operations").click();
await page.getByText("Creating instance").first().click();

await page.screenshot({ path: "tests/screenshots/operations-list.png" });

await deleteInstance(page, "comic-glider");
});

test("warnings screen", async ({ page }) => {
await page.goto("/ui/");
await page.getByText("Warnings").click();

await page.screenshot({ path: "tests/screenshots/warnings-list.png" });
});

0 comments on commit e0a8d65

Please sign in to comment.