Refactor billing process in e2e tests
Code for billing process was refactored in end-to-end tests for clean code and better structure. In the described tests, related codes and classes have been moved to a new class named BillingPageObject. All corresponding calls were updated accordingly.
This commit is contained in:
@@ -1,18 +1,17 @@
|
|||||||
import { Page } from '@playwright/test';
|
import { Page } from '@playwright/test';
|
||||||
import { StripePageObject } from '../utils/stripe.po';
|
|
||||||
import { TeamAccountsPageObject } from '../team-accounts/team-accounts.po';
|
import { TeamAccountsPageObject } from '../team-accounts/team-accounts.po';
|
||||||
|
import { BillingPageObject } from '../utils/billing.po';
|
||||||
|
|
||||||
export class TeamBillingPageObject {
|
export class TeamBillingPageObject {
|
||||||
private readonly teamAccounts: TeamAccountsPageObject;
|
public readonly teamAccounts: TeamAccountsPageObject;
|
||||||
public readonly stripe: StripePageObject;
|
public readonly billing: BillingPageObject;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.teamAccounts = new TeamAccountsPageObject(page);
|
this.teamAccounts = new TeamAccountsPageObject(page);
|
||||||
this.stripe = new StripePageObject(page);
|
this.billing = new BillingPageObject(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setup() {
|
async setup() {
|
||||||
await this.teamAccounts.setup();
|
await this.teamAccounts.setup();
|
||||||
await this.teamAccounts.goToBilling();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,32 @@
|
|||||||
import { expect, Page, test } from '@playwright/test';
|
import { expect, Page, test } from '@playwright/test';
|
||||||
import { TeamBillingPageObject } from './team-billing.po';
|
import { TeamBillingPageObject } from './team-billing.po';
|
||||||
|
import exp from 'node:constants';
|
||||||
|
|
||||||
test.describe('Team Billing', () => {
|
test.describe('Team Billing', () => {
|
||||||
let page: Page;
|
let page: Page;
|
||||||
let billing: TeamBillingPageObject;
|
let po: TeamBillingPageObject;
|
||||||
|
|
||||||
test.beforeAll(async ({ browser }) => {
|
test.beforeAll(async ({ browser }) => {
|
||||||
page = await browser.newPage();
|
page = await browser.newPage();
|
||||||
billing = new TeamBillingPageObject(page);
|
po = new TeamBillingPageObject(page);
|
||||||
|
|
||||||
await billing.setup();
|
await po.setup();
|
||||||
|
await po.teamAccounts.goToBilling();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('a team can subscribe to a plan', async () => {
|
test('a team can subscribe to a plan', async () => {
|
||||||
await billing.stripe.selectPlan(0);
|
await po.billing.selectPlan(0);
|
||||||
await billing.stripe.proceedToCheckout();
|
await po.billing.proceedToCheckout();
|
||||||
|
|
||||||
await billing.stripe.fillForm();
|
await po.billing.stripe.fillForm();
|
||||||
await billing.stripe.submitForm();
|
await po.billing.stripe.submitForm();
|
||||||
|
|
||||||
await expect(billing.stripe.successStatus()).toBeVisible();
|
await expect(po.billing.successStatus()).toBeVisible();
|
||||||
|
await po.billing.returnToHome();
|
||||||
|
|
||||||
|
await po.teamAccounts.goToBilling();
|
||||||
|
|
||||||
|
await expect(await po.billing.getStatus()).toContainText('active');
|
||||||
|
await expect(po.billing.manageBillingButton()).toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import { Page } from '@playwright/test';
|
import { Page } from '@playwright/test';
|
||||||
import { AuthPageObject } from '../authentication/auth.po';
|
import { AuthPageObject } from '../authentication/auth.po';
|
||||||
import { StripePageObject } from '../utils/stripe.po';
|
import { BillingPageObject } from '../utils/billing.po';
|
||||||
|
|
||||||
export class UserBillingPageObject {
|
export class UserBillingPageObject {
|
||||||
private readonly auth: AuthPageObject;
|
private readonly auth: AuthPageObject;
|
||||||
public readonly stripe: StripePageObject;
|
public readonly billing: BillingPageObject;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.auth = new AuthPageObject(page);
|
this.auth = new AuthPageObject(page);
|
||||||
this.stripe = new StripePageObject(page);
|
this.billing = new BillingPageObject(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setup() {
|
async setup() {
|
||||||
|
|||||||
@@ -3,22 +3,27 @@ import { UserBillingPageObject } from './user-billing.po';
|
|||||||
|
|
||||||
test.describe('User Billing', () => {
|
test.describe('User Billing', () => {
|
||||||
let page: Page;
|
let page: Page;
|
||||||
let billing: UserBillingPageObject;
|
let po: UserBillingPageObject;
|
||||||
|
|
||||||
test.beforeAll(async ({ browser }) => {
|
test.beforeAll(async ({ browser }) => {
|
||||||
page = await browser.newPage();
|
page = await browser.newPage();
|
||||||
billing = new UserBillingPageObject(page);
|
po = new UserBillingPageObject(page);
|
||||||
|
|
||||||
await billing.setup();
|
await po.setup();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('user can subscribe to a plan', async () => {
|
test('user can subscribe to a plan', async ({page}) => {
|
||||||
await billing.stripe.selectPlan(0);
|
await po.billing.selectPlan(0);
|
||||||
await billing.stripe.proceedToCheckout();
|
await po.billing.proceedToCheckout();
|
||||||
|
|
||||||
await billing.stripe.fillForm();
|
await po.billing.stripe.fillForm();
|
||||||
await billing.stripe.submitForm();
|
await po.billing.stripe.submitForm();
|
||||||
|
|
||||||
await expect(billing.stripe.successStatus()).toBeVisible();
|
await expect(po.billing.successStatus()).toBeVisible();
|
||||||
|
|
||||||
|
await page.goto('/home/billing');
|
||||||
|
|
||||||
|
await expect(await po.billing.getStatus()).toContainText('active');
|
||||||
|
await expect(po.billing.manageBillingButton()).toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
42
apps/e2e/tests/utils/billing.po.ts
Normal file
42
apps/e2e/tests/utils/billing.po.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { Page } from '@playwright/test';
|
||||||
|
import { StripePageObject } from './stripe.po';
|
||||||
|
|
||||||
|
export class BillingPageObject {
|
||||||
|
public readonly stripe: StripePageObject;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly page: Page,
|
||||||
|
) {
|
||||||
|
this.stripe = new StripePageObject(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
plans() {
|
||||||
|
return this.page.locator('[data-test-plan]');
|
||||||
|
}
|
||||||
|
|
||||||
|
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"]');
|
||||||
|
}
|
||||||
|
|
||||||
|
async returnToHome() {
|
||||||
|
await this.successStatus().locator('button').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
proceedToCheckout() {
|
||||||
|
return this.page.click('[data-test="checkout-submit-button"]');
|
||||||
|
}
|
||||||
|
|
||||||
|
async getStatus() {
|
||||||
|
return this.page.locator('[data-test="current-plan-card-status-badge"]');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
import { Page, expect } from '@playwright/test';
|
import { Page, expect } from '@playwright/test';
|
||||||
|
import { BillingPageObject } from './billing.po';
|
||||||
|
|
||||||
export class StripePageObject {
|
export class StripePageObject {
|
||||||
private page: Page;
|
private readonly page: Page;
|
||||||
|
public readonly billing: BillingPageObject;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
}
|
this.billing = new BillingPageObject(page);
|
||||||
|
|
||||||
plans() {
|
|
||||||
return this.page.locator('[data-test-plan]');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getStripeCheckoutIframe() {
|
getStripeCheckoutIframe() {
|
||||||
@@ -66,22 +65,4 @@ export class StripePageObject {
|
|||||||
billingCountry() {
|
billingCountry() {
|
||||||
return this.getStripeCheckoutIframe().locator('#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"]');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ export function CurrentPlanBadge(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Badge variant={variant}>
|
<Badge data-test={'current-plan-card-status-badge'} variant={variant}>
|
||||||
<Trans i18nKey={text} />
|
<Trans i18nKey={text} />
|
||||||
</Badge>
|
</Badge>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ export function CurrentSubscriptionCard({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span>{product.name}</span>
|
<span data-test={'current-plan-card-product-name'}>
|
||||||
|
{product.name}
|
||||||
|
</span>
|
||||||
|
|
||||||
<CurrentPlanBadge status={subscription.status} />
|
<CurrentPlanBadge status={subscription.status} />
|
||||||
</div>
|
</div>
|
||||||
@@ -84,7 +86,7 @@ export function CurrentSubscriptionCard({
|
|||||||
(e.g. trial ending soon, subscription canceled, etc.)
|
(e.g. trial ending soon, subscription canceled, etc.)
|
||||||
*/}
|
*/}
|
||||||
<If condition={!subscription.active}>
|
<If condition={!subscription.active}>
|
||||||
<div>
|
<div data-test={'current-plan-card-status-alert'}>
|
||||||
<CurrentPlanAlert status={subscription.status} />
|
<CurrentPlanAlert status={subscription.status} />
|
||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
|
|||||||
Reference in New Issue
Block a user