Add end-to-end tests for user and team billing features
This commit introduces end-to-end tests for the user and team billing features. It also enhances existing billing configurations, logging, and error handling mechanisms. Refactoring has been done to simplify the code and make it more readable. Adjustments have also been made in the visual aspects of some components. The addition of these tests will help ensure the reliability of the billing features.
This commit is contained in:
@@ -37,6 +37,12 @@ export class TeamAccountsPageObject {
|
||||
}).click();
|
||||
}
|
||||
|
||||
async goToBilling() {
|
||||
await this.page.locator('a', {
|
||||
hasText: 'Billing',
|
||||
}).click();
|
||||
}
|
||||
|
||||
async openAccountsSelector() {
|
||||
await this.page.click('[data-test="account-selector-trigger"]');
|
||||
}
|
||||
|
||||
18
apps/e2e/tests/team-billing/team-billing.po.ts
Normal file
18
apps/e2e/tests/team-billing/team-billing.po.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Page } from '@playwright/test';
|
||||
import { StripePageObject } from '../utils/stripe.po';
|
||||
import { TeamAccountsPageObject } from '../team-accounts/team-accounts.po';
|
||||
|
||||
export class TeamBillingPageObject {
|
||||
private readonly teamAccounts: TeamAccountsPageObject;
|
||||
public readonly stripe: StripePageObject;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.teamAccounts = new TeamAccountsPageObject(page);
|
||||
this.stripe = new StripePageObject(page);
|
||||
}
|
||||
|
||||
async setup() {
|
||||
await this.teamAccounts.setup();
|
||||
await this.teamAccounts.goToBilling();
|
||||
}
|
||||
}
|
||||
24
apps/e2e/tests/team-billing/team-billing.spec.ts
Normal file
24
apps/e2e/tests/team-billing/team-billing.spec.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import { TeamBillingPageObject } from './team-billing.po';
|
||||
|
||||
test.describe('Team Billing', () => {
|
||||
let page: Page;
|
||||
let billing: TeamBillingPageObject;
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
billing = new TeamBillingPageObject(page);
|
||||
|
||||
await billing.setup();
|
||||
});
|
||||
|
||||
test('a team can subscribe to a plan', async () => {
|
||||
await billing.stripe.selectPlan(0);
|
||||
await billing.stripe.proceedToCheckout();
|
||||
|
||||
await billing.stripe.fillForm();
|
||||
await billing.stripe.submitForm();
|
||||
|
||||
await expect(billing.stripe.successStatus()).toBeVisible();
|
||||
});
|
||||
});
|
||||
17
apps/e2e/tests/user-billing/user-billing.po.ts
Normal file
17
apps/e2e/tests/user-billing/user-billing.po.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Page } from '@playwright/test';
|
||||
import { AuthPageObject } from '../authentication/auth.po';
|
||||
import { StripePageObject } from '../utils/stripe.po';
|
||||
|
||||
export class UserBillingPageObject {
|
||||
private readonly auth: AuthPageObject;
|
||||
public readonly stripe: StripePageObject;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.auth = new AuthPageObject(page);
|
||||
this.stripe = new StripePageObject(page);
|
||||
}
|
||||
|
||||
async setup() {
|
||||
await this.auth.signUpFlow('/home/billing');
|
||||
}
|
||||
}
|
||||
24
apps/e2e/tests/user-billing/user-billing.spec.ts
Normal file
24
apps/e2e/tests/user-billing/user-billing.spec.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import { UserBillingPageObject } from './user-billing.po';
|
||||
|
||||
test.describe('User Billing', () => {
|
||||
let page: Page;
|
||||
let billing: UserBillingPageObject;
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
billing = new UserBillingPageObject(page);
|
||||
|
||||
await billing.setup();
|
||||
});
|
||||
|
||||
test('user can subscribe to a plan', async () => {
|
||||
await billing.stripe.selectPlan(0);
|
||||
await billing.stripe.proceedToCheckout();
|
||||
|
||||
await billing.stripe.fillForm();
|
||||
await billing.stripe.submitForm();
|
||||
|
||||
await expect(billing.stripe.successStatus()).toBeVisible();
|
||||
});
|
||||
});
|
||||
87
apps/e2e/tests/utils/stripe.po.ts
Normal file
87
apps/e2e/tests/utils/stripe.po.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { Page, expect } from '@playwright/test';
|
||||
|
||||
export class StripePageObject {
|
||||
private page: Page;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
plans() {
|
||||
return this.page.locator('[data-test-plan]');
|
||||
}
|
||||
|
||||
getStripeCheckoutIframe() {
|
||||
return this.page.frameLocator('[name="embedded-checkout"]');
|
||||
}
|
||||
|
||||
async fillForm(params: {
|
||||
billingName?: string;
|
||||
cardNumber?: string;
|
||||
expiry?: string;
|
||||
cvc?: string;
|
||||
billingCountry?: string;
|
||||
} = {}) {
|
||||
expect(() => {
|
||||
return this.getStripeCheckoutIframe().locator('form').isVisible();
|
||||
});
|
||||
|
||||
const billingName = this.billingName();
|
||||
const cardNumber = this.cardNumber();
|
||||
const expiry = this.expiry();
|
||||
const cvc = this.cvc();
|
||||
const billingCountry = this.billingCountry();
|
||||
|
||||
await billingName.fill(params.billingName ?? 'Mr Makerkit');
|
||||
await cardNumber.fill(params.cardNumber ?? '4242424242424242');
|
||||
await expiry.fill(params.expiry ?? '1228');
|
||||
await cvc.fill(params.cvc ?? '123');
|
||||
await billingCountry.selectOption(params.billingCountry ?? 'IT');
|
||||
}
|
||||
|
||||
submitForm() {
|
||||
return this.getStripeCheckoutIframe().locator('form button').click();
|
||||
}
|
||||
|
||||
cardNumber() {
|
||||
return this.getStripeCheckoutIframe().locator('#cardNumber');
|
||||
}
|
||||
|
||||
cvc() {
|
||||
return this.getStripeCheckoutIframe().locator('#cardCvc');
|
||||
}
|
||||
|
||||
expiry() {
|
||||
return this.getStripeCheckoutIframe().locator('#cardExpiry');
|
||||
}
|
||||
|
||||
billingName() {
|
||||
return this.getStripeCheckoutIframe().locator('#billingName');
|
||||
}
|
||||
|
||||
cardForm() {
|
||||
return this.getStripeCheckoutIframe().locator('form');
|
||||
}
|
||||
|
||||
billingCountry() {
|
||||
return this.getStripeCheckoutIframe().locator('#billingCountry');
|
||||
}
|
||||
|
||||
selectPlan(index: number = 0) {
|
||||
const plans = this.plans();
|
||||
|
||||
return plans.nth(index).click();
|
||||
}
|
||||
|
||||
manageBillingButton() {
|
||||
return this.page.locator('manage-billing-redirect-button');
|
||||
}
|
||||
|
||||
successStatus() {
|
||||
return this.page.locator('[data-test="payment-return-success"]');
|
||||
}
|
||||
|
||||
proceedToCheckout() {
|
||||
return this.page.click('[data-test="checkout-submit-button"]');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user