From eb64fb3830d3287d0a4e09372c51e47598164001 Mon Sep 17 00:00:00 2001 From: Chris Raible Date: Thu, 6 Feb 2025 17:46:11 -0800 Subject: [PATCH] Fixed leftover state in invites browser tests (#22136) no issue - The invite tests were signing out as the owner user and then signing in as a user with different privileges. At the end of the test, it was left in this state, so the next file run by that playwright worker was still logged in as a user with lower than owner privileges so e.g. the settings couldn't be accessed. - This change signs out from the newly created user and signs back in as the owner user after each of the invites tests. --- .../test/e2e-browser/portal/invites.spec.js | 21 +++++++------- .../e2e-browser/utils/e2e-browser-utils.js | 28 +++++++++++++++---- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/ghost/core/test/e2e-browser/portal/invites.spec.js b/ghost/core/test/e2e-browser/portal/invites.spec.js index b2fb20ebf8..9efc7c751a 100644 --- a/ghost/core/test/e2e-browser/portal/invites.spec.js +++ b/ghost/core/test/e2e-browser/portal/invites.spec.js @@ -2,6 +2,7 @@ const {expect} = require('@playwright/test'); const test = require('../fixtures/ghost-test'); const security = require('@tryghost/security'); const models = require('../../../core/server/models'); +const {signInAsUserById, signOutCurrentUser} = require('../utils/e2e-browser-utils'); test.describe('Portal', () => { test.describe('Invites', () => { @@ -43,11 +44,7 @@ test.describe('Portal', () => { const encodedToken = security.url.encodeBase64(token); const inviteUrl = `${adminUrl}/signup/${encodedToken}/`; - //signout current user - await sharedPage.goto('/ghost/#/dashboard'); - await sharedPage.waitForLoadState('networkidle'); - await sharedPage.locator('[data-test-nav="arrow-down"]').click(); - await sharedPage.getByRole('link', {name: 'Sign out'}).click(); + await signOutCurrentUser(sharedPage); // Open invite URL await sharedPage.goto(inviteUrl); @@ -66,6 +63,10 @@ test.describe('Portal', () => { await sharedPage.locator('[data-test-nav="arrow-down"]').click(); await expect(sharedPage.locator(`text=${testEmail}`)).toBeVisible(); + + await signOutCurrentUser(sharedPage); + + await signInAsUserById(sharedPage, '1'); }); test.describe('2FA invite test', () => { @@ -126,11 +127,7 @@ test.describe('Portal', () => { const context = await sharedPage.context(); await context.clearCookies(); - //signout current user - await sharedPage.goto('/ghost/#/dashboard'); - await sharedPage.waitForLoadState('networkidle'); - await sharedPage.locator('[data-test-nav="arrow-down"]').click(); - await sharedPage.getByRole('link', {name: 'Sign out'}).click(); + await signOutCurrentUser(sharedPage); // Open invite URL await sharedPage.goto(inviteUrl); @@ -150,6 +147,10 @@ test.describe('Portal', () => { await sharedPage.locator('[data-test-nav="arrow-down"]').click(); await expect(sharedPage.locator(`text=${testEmail}`)).toBeVisible(); + + await signOutCurrentUser(sharedPage); + + await signInAsUserById(sharedPage, '1'); }); }); }); 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 d6b1da4915..7ff6502b32 100644 --- a/ghost/core/test/e2e-browser/utils/e2e-browser-utils.js +++ b/ghost/core/test/e2e-browser/utils/e2e-browser-utils.js @@ -43,12 +43,7 @@ const setupGhost = async (page) => { const ownerUser = DataGenerator.Content.users.find(user => user.id === '1'); if (action === actions.signin) { - // Fill email + password - await page.locator('#identification').fill(ownerUser.email); - await page.locator('#password').fill(ownerUser.password); - await page.getByRole('button', {name: 'Sign in'}).click(); - // Confirm we have reached Ghost Admin - await page.locator('.gh-nav').waitFor(options); + await signInAsUserById(page, '1'); } else if (action === actions.setup) { // Complete setup process await page.getByPlaceholder('The Daily Awesome').click(); @@ -65,6 +60,25 @@ const setupGhost = async (page) => { } }; +const signInAsUserById = async (page, userId) => { + await page.goto('/ghost'); + // Add owner user data from usual fixture + const user = DataGenerator.Content.users.find(u => u.id === userId); + + // Fill email + password + await page.locator('#identification').fill(user.email); + await page.locator('#password').fill(user.password); + await page.getByRole('button', {name: 'Sign in'}).click(); + // Confirm we have reached Ghost Admin + await page.locator('.gh-nav').waitFor({state: 'visible', timeout: 10000}); +}; + +const signOutCurrentUser = async (page) => { + await page.goto('/ghost/#/signout'); + await page.waitForLoadState('networkidle'); + await page.locator('.gh-signin').waitFor({state: 'visible', timeout: 10000}); +}; + const disconnectStripe = async (page) => { await deleteAllMembers(page); await page.locator('.gh-nav a[href="#/settings/"]').click(); @@ -530,6 +544,8 @@ module.exports = { generateStripeIntegrationToken, setupMailgun, deleteAllMembers, + signInAsUserById, + signOutCurrentUser, createTier, createOffer, createMember,