diff --git a/ghost/admin/app/components/settings/members-comment-access.hbs b/ghost/admin/app/components/settings/members-comment-access.hbs index c80eb61322..a40539153f 100644 --- a/ghost/admin/app/components/settings/members-comment-access.hbs +++ b/ghost/admin/app/components/settings/members-comment-access.hbs @@ -1,4 +1,4 @@ -
+

Commenting

@@ -14,7 +14,7 @@ @dropdownClass="gh-setting-dropdown-list" as |option| > -
+
{{svg-jar option.icon class=(concat "w8 h8 mr2 fill-" (or option.icon_color "green"))}}
{{option.name}}
@@ -22,4 +22,4 @@
-
\ No newline at end of file +
diff --git a/ghost/core/test/e2e-browser/admin/publishing.spec.js b/ghost/core/test/e2e-browser/admin/publishing.spec.js index 50dd5ced75..e03c906db4 100644 --- a/ghost/core/test/e2e-browser/admin/publishing.spec.js +++ b/ghost/core/test/e2e-browser/admin/publishing.spec.js @@ -1,6 +1,6 @@ const {expect, test} = require('@playwright/test'); const {DateTime} = require('luxon'); -const {createMember} = require('../utils'); +const {createMember, createPostDraft} = require('../utils'); const {slugify} = require('@tryghost/string'); /** @@ -59,30 +59,6 @@ const checkPostPublished = async (page, {slug, title, body}) => { await expect(page.locator('.gh-content.gh-canvas > p')).toHaveText(body); }; -/** - * Start a post draft with a filled in title and body. We can consider to move this to utils later. - * @param {import('@playwright/test').Page} page - * @param {Object} options - * @param {String} [options.title] - * @param {String} [options.body] - */ -const createPost = async (page, {title = 'Hello world', body = 'This is my post body.'} = {}) => { - await page.locator('.gh-nav a[href="#/posts/"]').click(); - - // Create a new post - await page.locator('[data-test-new-post-button]').click(); - - // Fill in the post title - await page.locator('[data-test-editor-title-input]').click(); - await page.locator('[data-test-editor-title-input]').fill(title); - - // Continue to the body by pressing enter - await page.keyboard.press('Enter'); - - await page.waitForTimeout(100); // allow new->draft switch to occur fully, without this some initial typing events can be missed - await page.keyboard.type(body); -}; - /** * Start a page draft with a filled in title and body. We can consider to move this to utils later. * @param {import('@playwright/test').Page} page @@ -210,7 +186,7 @@ test.describe('Publishing', () => { await createMember(page, {email: 'example@example.com', name: 'Publishing member'}); await page.goto('/ghost'); - await createPost(page, postData); + await createPostDraft(page, postData); await publishPost(page, {type: 'publish+send'}); await closePublishFlow(page); @@ -226,7 +202,7 @@ test.describe('Publishing', () => { }; await page.goto('/ghost'); - await createPost(page, postData); + await createPostDraft(page, postData); await publishPost(page); await closePublishFlow(page); @@ -243,7 +219,7 @@ test.describe('Publishing', () => { }; await page.goto('/ghost'); - await createPost(page, postData); + await createPostDraft(page, postData); await publishPost(page, {type: 'send'}); await closePublishFlow(page); await checkPostStatus(page, 'Sent to '); // can't test for 1 member for now, because depends on test ordering :( (sometimes 2 members are created) @@ -304,7 +280,7 @@ test.describe('Publishing', () => { const date = DateTime.now(); - await createPost(adminPage, {title: 'Testing publish update', body: 'This is the initial published text.'}); + await createPostDraft(adminPage, {title: 'Testing publish update', body: 'This is the initial published text.'}); await publishPost(adminPage); const frontendPage = await openPublishedPostBookmark(adminPage); await closePublishFlow(adminPage); @@ -349,7 +325,7 @@ test.describe('Publishing', () => { }; await page.goto('/ghost'); - await createPost(page, postData); + await createPostDraft(page, postData); // Schedule the post to publish asap (by setting it to 00:00, it will get auto corrected to the minimum time possible - 5 seconds in the future) await publishPost(page, {time: '00:00', type: 'publish+send'}); @@ -380,7 +356,7 @@ test.describe('Publishing', () => { }; await page.goto('/ghost'); - await createPost(page, postData); + await createPostDraft(page, postData); // Schedule the post to publish asap (by setting it to 00:00, it will get auto corrected to the minimum time possible - 5 seconds in the future) await publishPost(page, {time: '00:00'}); @@ -410,7 +386,7 @@ test.describe('Publishing', () => { }; await page.goto('/ghost'); - await createPost(page, postData); + await createPostDraft(page, postData); // Schedule the post to publish asap (by setting it to 00:00, it will get auto corrected to the minimum time possible - 5 seconds in the future) await publishPost(page, {type: 'send', time: '00:00'}); @@ -440,7 +416,7 @@ test.describe('Publishing', () => { }; await page.goto('/ghost'); - await createPost(page, postData); + await createPostDraft(page, postData); // Schedule far in the future await publishPost(page, {date: '2050-01-01', time: '10:09'}); @@ -473,7 +449,7 @@ test.describe('Updating post access', () => { test('Only logged-in members (free or paid) can see', async ({page}) => { await page.goto('/ghost'); - await createPost(page); + await createPostDraft(page); await openPostSettingsMenu(page); await setPostVisibility(page, 'members'); @@ -489,7 +465,7 @@ test.describe('Updating post access', () => { test('Only logged-in, paid members can see', async ({page}) => { await page.goto('/ghost'); - await createPost(page); + await createPostDraft(page); await openPostSettingsMenu(page); await setPostVisibility(page, 'paid'); @@ -505,7 +481,7 @@ test.describe('Updating post access', () => { test('Everyone can see', async ({page}) => { await page.goto('/ghost'); - await createPost(page); + await createPostDraft(page); await openPostSettingsMenu(page); await setPostVisibility(page, 'public'); diff --git a/ghost/core/test/e2e-browser/admin/site-settings.spec.js b/ghost/core/test/e2e-browser/admin/site-settings.spec.js index a34a76aae0..8d8b001281 100644 --- a/ghost/core/test/e2e-browser/admin/site-settings.spec.js +++ b/ghost/core/test/e2e-browser/admin/site-settings.spec.js @@ -1,17 +1,31 @@ const {expect, test} = require('@playwright/test'); +const {createPostDraft} = require('../utils'); const changeSubscriptionAccess = async (page, access) => { + // Go to settings page await page.locator('[data-test-nav="settings"]').click(); + + // Go to members settings page await page.locator('[data-test-nav="members-membership"]').click(); - // click data-test-members-subscription-option="all" - await page.locator('[data-test-members-subscription-option="all"]').click(); + // Change subscription access + await page.locator('[data-test-members-subscription-access] [data-test-members-subscription-option]').click(); await page.locator(`[data-test-members-subscription-option="${access}"]`).click(); - // save + // Save settings await page.locator('[data-test-button="save-settings"]').click(); }; +const checkPortalScriptLoaded = async (page, loaded = true) => { + const portalScript = page.locator('script[data-ghost][data-api]'); + + if (!loaded) { + await expect(portalScript).toHaveCount(0); + } else { + await expect(portalScript).toHaveAttribute('src', /\/portal.min.js$/); + } +}; + test.describe('Site Settings', () => { test.describe('Subscription Access', () => { test('Invite only', async ({page}) => { @@ -26,6 +40,32 @@ test.describe('Site Settings', () => { // Check sign up is disabled and a message is shown await expect(portalFrame.locator('.gh-portal-invite-only-notification')).toHaveText('This site is invite-only, contact the owner for access.'); + + // Check portal script loaded (just a negative test for the following test to test the test) + await checkPortalScriptLoaded(page, true); + }); + + test('Disabled subscription access', async ({page}) => { + await page.goto('/ghost'); + + await changeSubscriptionAccess(page, 'none'); + + // Go to the sigup page + await page.goto('/#/portal/signup'); + + // Check Portal not loaded, and thus the signup page is not shown + await expect(page.locator('#ghost-portal-root div iframe')).toHaveCount(0); + await checkPortalScriptLoaded(page, false); + + // Check publishing flow is different and has membership features disabled + await page.goto('/ghost'); + await createPostDraft(page, { + title: 'Test post', + body: 'Test post content' + }); + await page.locator('[data-test-button="publish-flow"]').click(); + await expect(page.locator('[data-test-setting="publish-type"] > button')).toHaveCount(0); + await expect(page.locator('[data-test-setting="email-recipients"]')).toHaveCount(0); }); }); }); diff --git a/ghost/core/test/e2e-browser/utils/e2e-browser-utils.js b/ghost/core/test/e2e-browser/utils/e2e-browser-utils.js index 4a3288bed2..bc57bac2b2 100644 --- a/ghost/core/test/e2e-browser/utils/e2e-browser-utils.js +++ b/ghost/core/test/e2e-browser/utils/e2e-browser-utils.js @@ -362,6 +362,30 @@ const createMember = async (page, {email, name, note, label = '', compedPlan}) = } }; +/** + * Start a post draft with a filled in title and body. + * @param {import('@playwright/test').Page} page + * @param {Object} options + * @param {String} [options.title] + * @param {String} [options.body] + */ +const createPostDraft = async (page, {title = 'Hello world', body = 'This is my post body.'} = {}) => { + await page.locator('.gh-nav a[href="#/posts/"]').click(); + + // Create a new post + await page.locator('[data-test-new-post-button]').click(); + + // Fill in the post title + await page.locator('[data-test-editor-title-input]').click(); + await page.locator('[data-test-editor-title-input]').fill(title); + + // Continue to the body by pressing enter + await page.keyboard.press('Enter'); + + await page.waitForTimeout(100); // allow new->draft switch to occur fully, without this some initial typing events can be missed + await page.keyboard.type(body); +}; + module.exports = { setupGhost, setupStripe, @@ -371,6 +395,7 @@ module.exports = { archiveAllTiers, createOffer, createMember, + createPostDraft, completeStripeSubscription, impersonateMember };