Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEST] [E2E] Added test for setting balance and exporting gift cards #4650

Merged
merged 12 commits into from
Mar 15, 2024
5 changes: 5 additions & 0 deletions .changeset/nervous-toes-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": minor
---

Rewritten tests for setting balance and exporting gift cards
3 changes: 2 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ CYPRESS_USER_PASSWORD=xxxx
CYPRESS_SECOND_USER_NAME=xxxx
CYPRESS_PERMISSIONS_USERS_PASSWORD=xxxx
CYPRESS_baseUrl=http://localhost:9000/
CYPRESS_MAILPITURL=xxxx
CYPRESS_MAILPITURL=xxxx
MAILPITURL=xxxx #For playwright

E2E_USER_NAME=xxxx
E2E_USER_PASSWORD=xxxx
Expand Down
5 changes: 5 additions & 0 deletions .github/actions/run-pw-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ inputs:
SHARD:
description: "Shard number"
required: true
MAILPITURL:
description: "mailpit uri"
required: true

runs:
using: "composite"
steps:
Expand All @@ -43,6 +47,7 @@ runs:
E2E_USER_PASSWORD: ${{ inputs.E2E_USER_PASSWORD }}
E2E_PERMISSIONS_USERS_PASSWORD: ${{ inputs.E2E_PERMISSIONS_USERS_PASSWORD }}
SHARD_NUMBER: ${{ inputs.SHARD }}
MAILPITURL: ${{ inputs.MAILPITURL }}
run: npm run qa:pw-e2e -- --shard "$SHARD_NUMBER"

- name: Upload blob report to GitHub Actions Artifacts
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr-automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ jobs:
E2E_USER_NAME: ${{ secrets.CYPRESS_USER_NAME }}
E2E_USER_PASSWORD: ${{ secrets.CYPRESS_USER_PASSWORD }}
E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.CYPRESS_PERMISSIONS_USERS_PASSWORD }}
MAILPITURL: ${{ secrets.CYPRESS_MAILPITURL }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not cypress, i think you meant ${{ secrets.MAILPITURL }}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you approve it and maybe in next PR I will fix all variables: CYPRESS_MAILPITURL, CYPRESS_PERMISSIONS_USERS_PASSWORD, CYPRESS_USER_PASSWORD, CYPRESS_USER_NAME etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the status of it? Those comments has 3 weeks


merge-reports:
if: '!cancelled()'
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/run-test-cron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ jobs:
E2E_USER_NAME: ${{ secrets.CYPRESS_USER_NAME }}
E2E_USER_PASSWORD: ${{ secrets.CYPRESS_USER_PASSWORD }}
E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.CYPRESS_PERMISSIONS_USERS_PASSWORD }}
MAILPITURL: ${{ secrets.CYPRESS_MAILPITURL }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here


merge-reports:
if: '!cancelled()'
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/run-test-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ jobs:
E2E_USER_NAME: ${{ secrets.CYPRESS_USER_NAME }}
E2E_USER_PASSWORD: ${{ secrets.CYPRESS_USER_PASSWORD }}
E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.CYPRESS_PERMISSIONS_USERS_PASSWORD }}
MAILPITURL: ${{ secrets.CYPRESS_MAILPITURL }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here


merge-reports:
if: '!cancelled()'
Expand Down
21 changes: 17 additions & 4 deletions playwright/api/mailpit.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { URL_LIST } from "@data/url";
import { APIRequestContext, expect } from "@playwright/test";

const MAILPIT_URI = process.env.CYPRESS_MAILPITURL || "no mailpit url provided";
const mailpitUrl = "https://" + MAILPIT_URI;
const mailpitUrl = process.env.MAILPITURL || "no mailpit url provided";
export class MailpitService {
readonly request: APIRequestContext;

Expand Down Expand Up @@ -31,6 +30,19 @@ export class MailpitService {
return latestEmailsJson;
}

async getEmailsFromTime(fromTime = 10000){
const latestEmails = await this.getLastEmails()

latestEmails.messages = latestEmails.messages.filter(
(message: { Created: string }) => {
const timeMinusLastMs = Date.now() - fromTime;
const mailCreated = new Date(message.Created);
return mailCreated.getTime() > timeMinusLastMs;
},
);
return latestEmails;
}

async getEmailDetails(mailId: string) {
const emailDetails = await this.request.get(
`${mailpitUrl}/api/v1/message/${mailId}`,
Expand All @@ -45,7 +57,7 @@ export class MailpitService {
await expect
.poll(
async () => {
const emails = await this.getLastEmails();
const emails = await this.getEmailsFromTime();
userEmails = await emails.messages.filter((mails: { To: any[] }) =>
mails.To.map(
(recipientObj: { Address: any }) => `${recipientObj.Address}`,
Expand All @@ -55,14 +67,15 @@ export class MailpitService {
return userEmails.length;
},
{
message: `User: ${userEmail} messages were not found`,
message: `User: ${userEmail} messages were not found.`,
intervals: [2000, 3000, 5000, 5000],
timeout: 15000,
},
)
.toBeGreaterThanOrEqual(1);
return userEmails;
}

async checkDoesUserReceivedExportedData(
userEmail: string,
mailSubject: string,
Expand Down
16 changes: 16 additions & 0 deletions playwright/pages/dialogs/exportGiftCardsDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Page } from "@playwright/test";

export class ExportGiftCardsDialog {
readonly page: Page;

constructor(page: Page, readonly submitButton = page.getByTestId("submit")) {
this.page = page;
}

async exportGiftCardCodes(fileExtension: string) {
const fileExtensionCheckbox = this.page.getByTestId(fileExtension);
await fileExtensionCheckbox.click();
await this.submitButton.click();
karola312 marked this conversation as resolved.
Show resolved Hide resolved
await this.submitButton.waitFor({state: "hidden"})
}
}
18 changes: 18 additions & 0 deletions playwright/pages/dialogs/setGiftCardBalanceDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Page } from "@playwright/test";

export class SetGiftCardsBalanceDialog {
readonly page: Page;

constructor(
page: Page,
readonly submitButton = page.getByTestId("submit"),
readonly enterAmountInput = page.locator('[name="balanceAmount"]'),
) {
this.page = page;
}

async setBalance(balance: string){
await this.enterAmountInput.fill(balance);
await this.submitButton.click();
}
karola312 marked this conversation as resolved.
Show resolved Hide resolved
}
23 changes: 19 additions & 4 deletions playwright/pages/giftCardsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import { ResendGiftCardCodeDialog } from "@dialogs/resendGiftCardCodeDialog";
import { MetadataSeoPage } from "@pageElements/metadataSeoPage";
import { BasePage } from "@pages/basePage";
import type { Page } from "@playwright/test";
import { ExportGiftCardsDialog } from "@dialogs/exportGiftCardsDialog";
import { SetGiftCardsBalanceDialog } from "@dialogs/setGiftCardBalanceDialog";

export class GiftCardsPage extends BasePage {
readonly page: Page;
readonly issueGiftCardDialog: IssueGiftCardDialog;
readonly resendGiftCardCodeDialog: ResendGiftCardCodeDialog;
readonly metadataSeoPage: MetadataSeoPage;
readonly deleteDialog: DeleteDialog;
readonly exportGiftCardsDialog: ExportGiftCardsDialog;
readonly setGiftCardsBalanceDialog: SetGiftCardsBalanceDialog;

constructor(
page: Page,
Expand All @@ -21,13 +25,18 @@ export class GiftCardsPage extends BasePage {
readonly deactivateButton = page.getByTestId("enable-button"),
readonly saveButton = page.getByTestId("button-bar-confirm"),
readonly cardExpiresCheckbox = page.locator("[name='cardExpires']"),
readonly exportCardCodesButton = page.getByTestId("exportCodesMenuItem"),
readonly setBalanceButton = page.getByTestId("set-balance-button"),
readonly showMoreMenuButton = page.getByTestId("show-more-button"),
) {
super(page);
this.page = page;
this.issueGiftCardDialog = new IssueGiftCardDialog(page);
this.resendGiftCardCodeDialog = new ResendGiftCardCodeDialog(page);
this.metadataSeoPage = new MetadataSeoPage(page);
this.deleteDialog = new DeleteDialog(page);
this.exportGiftCardsDialog = new ExportGiftCardsDialog(page);
this.setGiftCardsBalanceDialog = new SetGiftCardsBalanceDialog(page);
}

async clickIssueCardButton() {
Expand All @@ -45,18 +54,24 @@ export class GiftCardsPage extends BasePage {
async clickDeactivateButton() {
await this.deactivateButton.click();
}
async clickExportGiftCards() {
await this.exportCardCodesButton.click();
}
async clickResendCodeButton() {
await this.resendCodeButton.click();
}
async clickSetBalance() {
await this.setBalanceButton.click();
}
async clickShowMoreMenu(){
await this.showMoreMenuButton.click();
}
async gotoGiftCardsListView() {
await this.page.goto(URL_LIST.giftCards);
}
async gotoExistingGiftCardView(giftCardId: string) {
const existingGiftCardUrl = URL_LIST.giftCards + giftCardId;
await console.log(
"Navigating to existing gift card: " + existingGiftCardUrl,
);

console.log("Navigating to existing gift card: " + existingGiftCardUrl);
await this.page.goto(existingGiftCardUrl);
}
}
32 changes: 31 additions & 1 deletion playwright/tests/girftCards.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { GIFT_CARDS } from "@data/e2eTestData";
import { GiftCardsPage } from "@pages/giftCardsPage";
import { expect, test } from "@playwright/test";
import { MailpitService } from "@api/mailpit";


test.use({ storageState: "playwright/.auth/admin.json" });
let giftCardsPage: GiftCardsPage;
test.beforeEach(({ page }) => {
let mailpitService: MailpitService;
test.beforeEach(({ page, request }) => {
giftCardsPage = new GiftCardsPage(page);
mailpitService = new MailpitService(request);
});

test("TC: SALEOR_105 Issue gift card @e2e @gift", async () => {
Expand Down Expand Up @@ -100,3 +104,29 @@ test("TC: SALEOR_111 Bulk delete gift cards @e2e @gift", async () => {
),
).toEqual([]);
});
test("TC: SALEOR_112 Set gift card balance @e2e @gift", async () => {
await giftCardsPage.gotoExistingGiftCardView(GIFT_CARDS.giftCardToBeEdited.id);
await giftCardsPage.clickSetBalance();
await giftCardsPage.setGiftCardsBalanceDialog.setBalance("34")
await giftCardsPage.expectSuccessBanner();
});
test("TC: SALEOR_113 Export gift card codes in XLSX file @e2e @gift", async () => {
await giftCardsPage.gotoGiftCardsListView();
await giftCardsPage.clickShowMoreMenu();
await giftCardsPage.clickExportGiftCards();
await giftCardsPage.exportGiftCardsDialog.exportGiftCardCodes("XLSX");
await mailpitService.checkDoesUserReceivedExportedData(
process.env.E2E_USER_NAME!,
"Your exported gift cards data is ready",
);
});
test("TC: SALEOR_114 Export gift card codes in CSV file @e2e @gift", async () => {
await giftCardsPage.gotoGiftCardsListView();
await giftCardsPage.clickShowMoreMenu();
await giftCardsPage.clickExportGiftCards();
await giftCardsPage.exportGiftCardsDialog.exportGiftCardCodes("CSV");
await mailpitService.checkDoesUserReceivedExportedData(
process.env.E2E_USER_NAME!,
"Your exported gift cards data is ready",
);
karola312 marked this conversation as resolved.
Show resolved Hide resolved
});
Loading