Skip to content

Commit 22ec87d

Browse files
authored
improve playwright tests with refactoring and clean up (#2809)
1 parent b87b415 commit 22ec87d

File tree

10 files changed

+335
-47
lines changed

10 files changed

+335
-47
lines changed

portal-ui/e2e/auth.setup.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
import { test as setup } from "@playwright/test";
17-
import { minioadminFile } from "./consts";
18-
import { pagePort } from "./consts";
17+
import { adminAccessKey, adminSecretKey, minioadminFile } from "./consts";
18+
import { BUCKET_LIST_PAGE } from "./consts";
1919

2020
setup("authenticate as admin", async ({ page }) => {
2121
// Perform authentication steps. Replace these actions with your own.
22-
await page.goto(pagePort);
22+
await page.goto(BUCKET_LIST_PAGE);
2323
await page.getByPlaceholder("Username").click();
24-
await page.getByPlaceholder("Username").fill("minioadmin");
24+
await page.getByPlaceholder("Username").fill(adminAccessKey);
2525
await page.getByPlaceholder("Password").click();
26-
await page.getByPlaceholder("Password").fill("minioadmin");
26+
await page.getByPlaceholder("Password").fill(adminSecretKey);
2727
await page.getByRole("button", { name: "Login" }).click();
2828

2929
// we need to give the browser time to store the cookies

portal-ui/e2e/buckets.spec.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
import { expect } from "@playwright/test";
1717
import { generateUUID, test } from "./fixtures/baseFixture";
1818
import { minioadminFile } from "./consts";
19-
import { pagePort } from "./consts";
19+
import { BUCKET_LIST_PAGE } from "./consts";
2020

2121
test.use({ storageState: minioadminFile });
2222

2323
test.beforeEach(async ({ page }) => {
24-
await page.goto(pagePort);
24+
await page.goto(BUCKET_LIST_PAGE);
2525
});
2626

2727
test("create a new bucket", async ({ page }) => {
@@ -34,6 +34,13 @@ test("create a new bucket", async ({ page }) => {
3434
await page.getByLabel("Bucket Name*").fill(bucketName);
3535
await page.getByRole("button", { name: "Create Bucket" }).click();
3636
await expect(page.locator(`#manageBucket-${bucketName}`)).toBeTruthy();
37+
const bucketLocatorEl = `#manageBucket-${bucketName}`;
38+
await page.locator(bucketLocatorEl).click();
39+
await page.locator("#delete-bucket-button").click();
40+
//confirm modal
41+
await page.locator("#confirm-ok").click();
42+
const listItemsCount = await page.locator(bucketLocatorEl).count();
43+
await expect(listItemsCount).toEqual(0);
3744
});
3845

3946
test("invalid bucket name", async ({ page }) => {

portal-ui/e2e/consts.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
export const minioadminFile = "playwright/.auth/admin.json";
18-
export const pagePort = "http://localhost:9090/buckets";
18+
19+
export const SERVER_ENDPOINT = "http://localhost:9090";
20+
export const BUCKET_LIST_PAGE = `${SERVER_ENDPOINT}/buckets`;
21+
22+
export const adminAccessKey = "minioadmin";
23+
export const adminSecretKey = "minioadmin";

portal-ui/e2e/groups.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
import { expect } from "@playwright/test";
1818
import { generateUUID, test } from "./fixtures/baseFixture";
1919
import { minioadminFile } from "./consts";
20-
import { pagePort } from "./consts";
20+
import { BUCKET_LIST_PAGE } from "./consts";
2121

2222
test.use({ storageState: minioadminFile });
2323

2424
test.beforeEach(async ({ page }) => {
25-
await page.goto(pagePort);
25+
await page.goto(BUCKET_LIST_PAGE);
2626
});
2727

2828
test("Add a new group", async ({ page }) => {

portal-ui/e2e/lifecycle.spec.ts

Lines changed: 90 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,100 @@
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
import { expect } from "@playwright/test";
18-
import { test } from "./fixtures/baseFixture";
17+
import { expect, Page } from "@playwright/test";
18+
import { test as baseTest } from "./fixtures/baseFixture";
1919
import { minioadminFile } from "./consts";
20-
import { pagePort } from "./consts";
20+
import { BucketsListPage } from "./pom/BucketsListPage";
21+
import { CreateBucketPage } from "./pom/CreateBucketPage";
22+
import { BucketSummaryPage } from "./pom/BucketSummaryPage";
2123

22-
test.use({ storageState: minioadminFile });
24+
type LifeCycleObjectVersionFx = {
25+
activeBucketName: string;
26+
bucketsListPage: BucketsListPage;
27+
createBucketPage: CreateBucketPage;
28+
bucketSummaryPage: any;
29+
};
2330

24-
test.beforeEach(async ({ page }) => {
25-
await page.goto(pagePort);
31+
const test = baseTest.extend<LifeCycleObjectVersionFx>({
32+
activeBucketName: "",
33+
bucketListPage: async ({ page }: { page: Page }, use: any) => {
34+
let bucketListPage = new BucketsListPage(page);
35+
await bucketListPage.loadPage();
36+
await bucketListPage.goToCreateBucket();
37+
await use(bucketListPage);
38+
},
39+
createBucketPage: async ({ page }: { page: Page }, use: any) => {
40+
let createBucketPage = new CreateBucketPage(page);
41+
await use(createBucketPage);
42+
},
43+
//bucket name is dynamic in parallel test runs.
44+
bucketSummaryPage: async ({ page }: { page: Page }, use: any) => {
45+
await use((bucketName: string) => {
46+
return new BucketSummaryPage(page, bucketName);
47+
});
48+
},
2649
});
2750

28-
test("Test if Object Version selector is present in Lifecycle rule modal", async ({
29-
page,
30-
}) => {
31-
await page.locator("#create-bucket").click();
32-
await page.getByLabel("Bucket Name*").click();
33-
await page.getByLabel("Bucket Name*").fill("versioned-bucket");
34-
await page.locator("#versioned").check();
35-
await page.getByRole("button", { name: "Create Bucket" }).click();
36-
await page.locator("#manageBucket-versioned-bucket").click();
37-
await page.getByRole("tab", { name: "Lifecycle" }).click();
38-
await page.getByRole("button", { name: "Add Lifecycle Rule" }).click();
39-
await expect(await page.locator("#object_version")).toBeTruthy();
40-
});
51+
test.use({ storageState: minioadminFile });
52+
53+
const versionedBucketName = "versioned-bucket";
54+
const nonVersionedBucketName = "non-versioned-bucket";
55+
56+
test.describe("Add Lifecycle Rule Modal in bucket settings tests for object version ", () => {
57+
test("Test if Object Version selector is present in Lifecycle rule modal", async ({
58+
page,
59+
bucketListPage,
60+
createBucketPage,
61+
bucketSummaryPage,
62+
}) => {
63+
await test.step("Create Versioned Bucket", async () => {
64+
await createBucketPage.createVersionedBucket(versionedBucketName);
65+
await bucketListPage.clickOnBucketRow(versionedBucketName);
66+
bucketSummaryPage = bucketSummaryPage(versionedBucketName);
67+
await bucketSummaryPage.clickOnTab("Lifecycle"); //Tab Text is used.
68+
});
69+
70+
await test.step("Check if object version option is available on a versioned bucket", async () => {
71+
const objectVersionsEl = await bucketSummaryPage.getObjectVersionOption();
72+
await expect(await objectVersionsEl).toHaveText("Current Version");
73+
await expect(await objectVersionsEl).toBeTruthy();
74+
await bucketSummaryPage.getLocator("#close").click();
75+
});
76+
77+
await test.step("Clean up bucket and verify the clean up", async () => {
78+
await bucketSummaryPage.confirmDeleteBucket();
79+
const existBukCount = await bucketListPage.isBucketExist(
80+
versionedBucketName
81+
);
82+
await expect(existBukCount).toEqual(0);
83+
});
84+
});
85+
86+
test("Test if Object Version selector is NOT present in Lifecycle rule modal", async ({
87+
page,
88+
createBucketPage,
89+
bucketListPage,
90+
bucketSummaryPage,
91+
}) => {
92+
await test.step("Create NON Versioned Bucket and navigate to lifecycle settings in summary page", async () => {
93+
await createBucketPage.createBucket(nonVersionedBucketName);
94+
await bucketListPage.clickOnBucketRow(nonVersionedBucketName);
95+
bucketSummaryPage = bucketSummaryPage(versionedBucketName);
96+
await bucketSummaryPage.clickOnTab("Lifecycle");
97+
});
98+
99+
await test.step("Check if object version option is NOT available on a non versioned bucket", async () => {
100+
const objectVersionsEl = await bucketSummaryPage.getObjectVersionOption();
101+
await expect(await objectVersionsEl.count()).toEqual(0);
102+
await bucketSummaryPage.getLocator("#close").click();
103+
});
41104

42-
test("Test if Object Version selector is not present when bucket is not versioned", async ({
43-
page,
44-
}) => {
45-
await page.locator("#create-bucket").click();
46-
await page.getByLabel("Bucket Name*").click();
47-
await page.getByLabel("Bucket Name*").fill("non-versioned-bucket");
48-
await page.getByRole("button", { name: "Create Bucket" }).click();
49-
await page.locator("#manageBucket-non-versioned-bucket").click();
50-
await page.getByRole("tab", { name: "Lifecycle" }).click();
51-
await page.getByRole("button", { name: "Add Lifecycle Rule" }).click();
52-
await expect(await page.locator("#object_version").count()).toEqual(0);
105+
await test.step("Clean up bucket and verify the clean up", async () => {
106+
await bucketSummaryPage.confirmDeleteBucket();
107+
const existBukCount = await bucketListPage.isBucketExist(
108+
nonVersionedBucketName
109+
);
110+
await expect(existBukCount).toEqual(0);
111+
});
112+
});
53113
});

portal-ui/e2e/login.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { test, expect } from "@playwright/test";
2-
import { pagePort } from "./consts";
2+
import { adminAccessKey, adminSecretKey, BUCKET_LIST_PAGE } from "./consts";
33

44
test("Basic `minioadmin` Login", async ({ page, context }) => {
5-
await page.goto(pagePort);
5+
await page.goto(BUCKET_LIST_PAGE);
66
await page.getByPlaceholder("Username").click();
7-
await page.getByPlaceholder("Username").fill("minioadmin");
7+
await page.getByPlaceholder("Username").fill(adminAccessKey);
88
await page.getByPlaceholder("Password").click();
9-
await page.getByPlaceholder("Password").fill("minioadmin");
9+
await page.getByPlaceholder("Password").fill(adminSecretKey);
1010
await page.getByRole("button", { name: "Login" }).click();
1111
await context.storageState({ path: "storage/minioadmin.json" });
1212
await expect(page.getByRole("main").getByText("Object Browser")).toBeTruthy();

portal-ui/e2e/policies.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@
1616
import { expect } from "@playwright/test";
1717
import { generateUUID, test } from "./fixtures/baseFixture";
1818
import { minioadminFile } from "./consts";
19-
import { pagePort } from "./consts";
19+
import { BUCKET_LIST_PAGE } from "./consts";
2020

2121
test.use({ storageState: minioadminFile });
2222

2323
test.beforeEach(async ({ page }) => {
24-
await page.goto(pagePort);
24+
await page.goto(BUCKET_LIST_PAGE);
2525
});
2626

2727
test("Can create a policy", async ({ page }) => {
28-
await page.getByRole("link", { name: "Policies Policies" }).click();
28+
await page.getByRole("link", { name: "Policies" }).click();
2929
await page.getByRole("button", { name: "Create Policy" }).click();
3030
await page.getByLabel("Policy Name").click();
3131

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { Page, Locator } from "@playwright/test";
2+
3+
export class BucketSummaryPage {
4+
page: Page;
5+
bucketName: string;
6+
7+
/* Locators */
8+
deleteBucketBtn: Locator | undefined;
9+
10+
constructor(page: Page, bucketName: string) {
11+
this.page = page;
12+
this.bucketName = bucketName;
13+
14+
this.initLocators();
15+
}
16+
getLocator(selector: string): Locator {
17+
const page = this.page;
18+
const locator: Locator = page.locator(`${selector}`);
19+
return locator;
20+
}
21+
22+
initLocators() {
23+
this.deleteBucketBtn = this.getLocator("#delete-bucket-button");
24+
}
25+
26+
async loadPage() {
27+
await this.clickOnTab(`Summary`);
28+
}
29+
30+
async clickOnTab(tabName: string) {
31+
const page = this.page;
32+
await page.getByRole("tab", { name: tabName }).click();
33+
34+
// await page.goto(`${BUCKET_LIST_PAGE}/${this.bucketName}/admin/${tabName}`);
35+
}
36+
37+
async confirmDeleteBucket() {
38+
await this.getLocator("#delete-bucket-button").click();
39+
await this.getLocator("#confirm-ok").click();
40+
}
41+
42+
async getObjectVersionOption() {
43+
await this.page.getByRole("button", { name: "Add Lifecycle Rule" }).click();
44+
return this.getLocator("#object_version");
45+
}
46+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { Page, Locator } from "@playwright/test";
2+
import { BUCKET_LIST_PAGE } from "../consts";
3+
4+
export class BucketsListPage {
5+
page: Page;
6+
7+
/* Locators */
8+
9+
createBucketBtn: Locator | undefined;
10+
refreshBucketsBtn: Locator | undefined;
11+
setReplicationBtn: Locator | undefined;
12+
13+
bucketListItemPrefix = "#manageBucket-";
14+
15+
constructor(page: Page) {
16+
this.page = page;
17+
this.initLocators();
18+
}
19+
getLocator(selector: string): Locator {
20+
const page = this.page;
21+
const locator: Locator = page.locator(`${selector}`);
22+
return locator;
23+
}
24+
25+
initLocators() {
26+
this.createBucketBtn = this.getLocator("#create-bucket");
27+
this.refreshBucketsBtn = this.getLocator("#refresh-buckets");
28+
this.setReplicationBtn = this.getLocator("#set-replication");
29+
}
30+
31+
locateBucket(bucketName: string): Locator {
32+
const bucketRow = this.getLocator(
33+
`${this.bucketListItemPrefix}${bucketName}`
34+
);
35+
return bucketRow;
36+
}
37+
38+
async clickOnBucketRow(bucketName: string) {
39+
const bucketRow = this.locateBucket(bucketName);
40+
await bucketRow.click();
41+
}
42+
async goToCreateBucket() {
43+
await this.createBucketBtn?.click();
44+
}
45+
46+
async isBucketExist(bucketName: string) {
47+
const existBukCount = await this.locateBucket(bucketName).count();
48+
49+
return existBukCount;
50+
}
51+
52+
async loadPage() {
53+
const page = this.page;
54+
await page.goto(BUCKET_LIST_PAGE);
55+
}
56+
}

0 commit comments

Comments
 (0)