0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

Added playwright tests for forever and multiple month offers

- adds test that cover creating and signing up to multiple-month/forever offers
- checks that the offer information is shown to members during signup and in account detail
This commit is contained in:
Rishabh 2022-12-14 17:13:20 +05:30
parent 199d8644a5
commit 25c530293f
3 changed files with 119 additions and 3 deletions

View file

@ -192,6 +192,7 @@
<label for="product-cadence" class="fw6">Duration</label>
<span class="gh-select">
<OneWaySelect
@data-test-select="offer-duration"
@value={{this.offer.duration}}
@options={{this.durations}}
@optionValuePath="duration"

View file

@ -57,7 +57,7 @@ test.describe('Portal', () => {
await expect(locator).toContainText('1');
});
test('Creates and uses a discount Offer', async ({page}) => {
test('Creates and uses a one-time discount Offer', async ({page}) => {
page.goto('/ghost');
await deleteAllMembers(page);
const tierName = 'Portal Tier';
@ -97,7 +97,112 @@ test.describe('Portal', () => {
await portalTriggerButton.click();
// Discounted price should not be visible for member for one-time offers
await expect(portalFrame.locator('text=$5.40/month'), 'Portal should show discounted price').not.toBeVisible();
await expect(portalFrame.locator('text=$5.40/month'), 'Portal should not show discounted price').not.toBeVisible();
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 multiple-months discount Offer', async ({page}) => {
page.goto('/ghost');
await deleteAllMembers(page);
const tierName = 'Portal Tier';
await createTier(page, {
name: tierName,
monthlyPrice: 6,
yearlyPrice: 60
});
// Creates a one-time discount offer for 10% off
const offerName = await createOffer(page, {
name: 'Black Friday Special',
tierName: tierName,
offerType: 'discount',
discountType: 'multiple-months',
amount: 10,
discountDuration: 3
});
await expect(page.getByRole('link', {name: offerName}), 'Should have discount offer').toBeVisible();
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');
const portalTriggerButton = page.frameLocator('#ghost-portal-root iframe.gh-portal-triggerbtn-iframe').locator('div').nth(1);
await expect(portalFrame.locator('.gh-portal-offer-title'), 'URL should open Portal with discount offer').toBeVisible();
await expect(portalFrame.locator('text=10% off for first 3 months.'), 'URL should open Portal with discount offer').toBeVisible();
await expect(portalFrame.locator('text=$5.40'), 'URL should open Portal with discount offer').toBeVisible();
await portalFrame.locator('#input-name').fill('Testy McTesterson');
await portalFrame.locator('#input-email').fill('testy@example.com');
await portalFrame.getByRole('button', {name: 'Continue'}).click();
const hasContinueBtn = await portalFrame.locator('text="Continue"').isVisible();
if (hasContinueBtn) {
await portalFrame.getByRole('button', {name: 'Continue'}).click();
}
await completeStripeSubscription(page);
await page.waitForSelector('h1.site-title', {state: 'visible'});
await portalTriggerButton.click();
// Discounted price should not be visible for member for one-time offers
await expect(portalFrame.locator('text=$5.40/month'), 'Portal should show discounted price').toBeVisible();
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 forever discount Offer', async ({page}) => {
page.goto('/ghost');
await deleteAllMembers(page);
const tierName = 'Portal Tier';
await createTier(page, {
name: tierName,
monthlyPrice: 6,
yearlyPrice: 60
});
// Creates a one-time discount offer for 10% off
const offerName = await createOffer(page, {
name: 'Black Friday Special',
tierName: tierName,
offerType: 'discount',
discountType: 'forever',
amount: 10
});
await expect(page.getByRole('link', {name: offerName}), 'Should have discount offer').toBeVisible();
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');
const portalTriggerButton = page.frameLocator('#ghost-portal-root iframe.gh-portal-triggerbtn-iframe').locator('div').nth(1);
await expect(portalFrame.locator('.gh-portal-offer-title'), 'URL should open Portal with discount offer').toBeVisible();
await expect(portalFrame.locator('text=10% off forever.'), 'URL should open Portal with discount offer').toBeVisible();
await expect(portalFrame.locator('text=$5.40'), 'URL should open Portal with discount offer').toBeVisible();
await portalFrame.locator('#input-name').fill('Testy McTesterson');
await portalFrame.locator('#input-email').fill('testy@example.com');
await portalFrame.getByRole('button', {name: 'Continue'}).click();
const hasContinueBtn = await portalFrame.locator('text="Continue"').isVisible();
if (hasContinueBtn) {
await portalFrame.getByRole('button', {name: 'Continue'}).click();
}
await completeStripeSubscription(page);
await page.waitForSelector('h1.site-title', {state: 'visible'});
await portalTriggerButton.click();
// Discounted price should be visible for member for forever offers
await expect(portalFrame.locator('text=$5.40/month'), 'Portal should show discounted price').toBeVisible();
await page.goto('/ghost');
await page.locator('.gh-nav a[href="#/members/"]').click();

View file

@ -237,10 +237,12 @@ const createTier = async (page, {name, monthlyPrice, yearlyPrice}, enableInPorta
* @param {string} options.name
* @param {string} options.tierName
* @param {string} options.offerType
* @param {string} [options.discountType]
* @param {number} [options.discountDuration]
* @param {number} options.amount
* @returns {Promise<string>} Unique offer name
*/
const createOffer = async (page, {name, tierName, offerType, amount}) => {
const createOffer = async (page, {name, tierName, offerType, amount, discountType = null, discountDuration = 3}) => {
await page.goto('/ghost');
await page.locator('.gh-nav a[href="#/offers/"]').click();
@ -282,6 +284,14 @@ const createOffer = async (page, {name, tierName, offerType, amount}) => {
await page.locator('input#trial-duration').fill(`${amount}`);
} else if (offerType === 'discount') {
await page.locator('input#amount').fill(`${amount}`);
if (discountType === 'multiple-months') {
await page.locator('[data-test-select="offer-duration"]').selectOption('repeating');
await page.locator('input#duration-months').fill(discountDuration.toString());
}
if (discountType === 'forever') {
await page.locator('[data-test-select="offer-duration"]').selectOption('forever');
}
}
const priceId = await page.locator(`.gh-select-product-cadence>select>option`).getByText(`${tierName} - Monthly`).getAttribute('value');