Added Playwright test for creating and using a free-trial Offer

refs https://www.notion.so/ghost/Critical-Paths-980dd089c3e74a6fbc619271f5a9ce42

- this test will create a free-trial Offer and go through Stripe
  checkout, ensuring the member is created as paid
- also changes some utils to support creating the free-trial offer vs
  just a discounted Offer
This commit is contained in:
Daniel Lockyer 2022-12-07 11:29:05 +07:00
parent 41e1f0b568
commit d64d8c0ddd
No known key found for this signature in database
3 changed files with 54 additions and 6 deletions

View File

@ -14,7 +14,8 @@ test.describe('Admin', () => {
const offerName = await createOffer(page, {
name: 'Get 5% Off!',
tierName,
percentOff: 5
offerType: 'discount',
amount: 5
});
await page.locator('.gh-nav a[href="#/offers/"]').click();

View File

@ -3,7 +3,44 @@ const {deleteAllMembers, createTier, createOffer, completeStripeSubscription} =
test.describe('Portal', () => {
test.describe('Offers', () => {
test('Uses an offer successfully', async ({page}) => {
test('Creates and uses a free-trial Offer', async ({page}) => {
page.goto('/ghost');
await deleteAllMembers(page);
const tierName = 'Portal Tier';
await createTier(page, {
name: tierName,
monthlyPrice: 6,
yearlyPrice: 60
});
const offerName = await createOffer(page, {
name: 'Black Friday Special',
tierName,
offerType: 'freeTrial',
amount: 14
});
await page.locator('.gh-offers-list .gh-list-row').filter({hasText: offerName}).click();
const portalUrl = await page.locator('input#url').inputValue();
await page.goto(portalUrl);
const portalFrame = page.frameLocator('#ghost-portal-root div iframe');
await portalFrame.locator('#input-name').fill('Testy McTesterson');
await portalFrame.locator('#input-email').fill('testy@example.com');
await portalFrame.getByRole('button', {name: 'Start 14-day free trial'}).click();
await completeStripeSubscription(page);
await page.waitForSelector('h1.site-title', {state: 'visible'});
await page.goto('/ghost');
await page.locator('.gh-nav a[href="#/members/"]').click();
// 1 member, should be Testy, on Portal Tier
await expect(page.getByRole('link', {name: 'Testy McTesterson testy@example.com'}), 'Should have 1 paid member').toBeVisible();
await expect(page.getByRole('link', {name: tierName}), `Paid member should be on ${tierName}`).toBeVisible();
});
test('Creates and uses a discount Offer', async ({page}) => {
page.goto('/ghost');
await deleteAllMembers(page);
const tierName = 'Portal Tier';
@ -15,7 +52,8 @@ test.describe('Portal', () => {
const offerName = await createOffer(page, {
name: 'Black Friday Special',
tierName: tierName,
percentOff: 10
offerType: 'discount',
amount: 10
});
await page.locator('.gh-offers-list .gh-list-row').filter({hasText: offerName}).click();

View File

@ -160,10 +160,11 @@ const createTier = async (page, {name, monthlyPrice, yearlyPrice}) => {
* @param {object} options
* @param {string} options.name
* @param {string} options.tierName
* @param {number} options.percentOff
* @param {string} options.offerType
* @param {number} options.amount
* @returns {Promise<string>} Unique offer name
*/
const createOffer = async (page, {name, tierName, percentOff}) => {
const createOffer = async (page, {name, tierName, offerType, amount}) => {
await page.goto('/ghost');
await page.locator('.gh-nav a[href="#/offers/"]').click();
@ -199,9 +200,17 @@ const createOffer = async (page, {name, tierName, percentOff}) => {
await page.getByRole('link', {name: 'New offer'}).click();
await page.locator('input#name').fill(offerName);
await page.locator('input#amount').fill(`${percentOff}`);
if (offerType === 'freeTrial') {
await page.getByRole('button', {name: 'Free trial Give free access for a limited time.'}).click();
await page.locator('input#trial-duration').fill(`${amount}`);
} else if (offerType === 'discount') {
await page.locator('input#amount').fill(`${amount}`);
}
const priceId = await page.locator(`.gh-select-product-cadence>select>option`).getByText(`${tierName} - Monthly`).getAttribute('value');
await page.locator('.gh-select-product-cadence>select').selectOption(priceId);
await page.getByRole('button', {name: 'Save'}).click();
// Wait for the "Saved" button, ensures that next clicks don't trigger the unsaved work modal
await page.getByRole('button', {name: 'Saved'}).waitFor({