From 9612e50770acf90cff656f767e4e6c9f9e4c6073 Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 16:51:28 +0530 Subject: [PATCH 01/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 20 ++++++-------------- test/spec/login-desktop-integ-test.js | 20 ++++++-------------- test/spec/login-shared.js | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 28 deletions(-) create mode 100644 test/spec/login-shared.js diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index 61c6560736..fed6a3f508 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -23,6 +23,7 @@ define(function (require, exports, module) { const SpecRunnerUtils = require("spec/SpecRunnerUtils"); + const LoginShared = require("./login-shared"); describe("integration: login/logout browser app tests", function () { @@ -39,7 +40,9 @@ define(function (require, exports, module) { LoginBrowserExports, ProDialogsExports, originalOpen, - originalFetch; + originalFetch, + SharedUtils, + setupTrialState; beforeAll(async function () { testWindow = await SpecRunnerUtils.createTestWindowAndRun(); @@ -72,6 +75,8 @@ define(function (require, exports, module) { "Profile button to be available", 3000 ); + SharedUtils = LoginShared.getSharedUtils(testWindow); + setupTrialState = SharedUtils.setupTrialState; }, 30000); afterAll(async function () { @@ -97,19 +102,6 @@ define(function (require, exports, module) { // Note: We can't easily reset login state, so tests should handle this }); - // Helper functions for promotion testing (browser-specific) - async function setupTrialState(daysRemaining) { - const PromotionExports = testWindow._test_promo_login_exports; - const mockNow = Date.now(); - await PromotionExports._setTrialData({ - proVersion: "3.1.0", - endDate: mockNow + (daysRemaining * PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY) - }); - // Trigger entitlements changed event to update branding - const LoginService = PromotionExports.LoginService; - LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); - } - async function setupExpiredTrial() { const PromotionExports = testWindow._test_promo_login_exports; const mockNow = Date.now(); diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index 49a599a510..cdd31d3171 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -23,6 +23,7 @@ define(function (require, exports, module) { const SpecRunnerUtils = require("spec/SpecRunnerUtils"); + const LoginShared = require("./login-shared"); describe("integration: login/logout desktop app tests", function () { @@ -47,7 +48,9 @@ define(function (require, exports, module) { ProDialogsExports, originalOpenURLInDefaultBrowser, originalCopyToClipboard, - originalFetch; + originalFetch, + SharedUtils, + setupTrialState; beforeAll(async function () { testWindow = await SpecRunnerUtils.createTestWindowAndRun(); @@ -80,6 +83,8 @@ define(function (require, exports, module) { "Profile button to be available", 3000 ); + SharedUtils = LoginShared.getSharedUtils(testWindow); + setupTrialState = SharedUtils.setupTrialState; }, 30000); afterAll(async function () { @@ -107,19 +112,6 @@ define(function (require, exports, module) { // Note: We can't easily reset login state, so tests should handle this }); - // Helper functions for desktop login testing - async function setupTrialState(daysRemaining) { - const PromotionExports = testWindow._test_promo_login_exports; - const mockNow = Date.now(); - await PromotionExports._setTrialData({ - proVersion: "3.1.0", - endDate: mockNow + (daysRemaining * PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY) - }); - // Trigger entitlements changed event to update branding - const LoginService = PromotionExports.LoginService; - LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); - } - async function setupExpiredTrial() { const PromotionExports = testWindow._test_promo_login_exports; const mockNow = Date.now(); diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js new file mode 100644 index 0000000000..3fc0c2cb0c --- /dev/null +++ b/test/spec/login-shared.js @@ -0,0 +1,22 @@ +define(function (require, exports, module) { + + function getSharedUtils(testWindow) { + // Helper functions for promotion testing (browser-specific) + async function setupTrialState(daysRemaining) { + const PromotionExports = testWindow._test_promo_login_exports; + const mockNow = Date.now(); + await PromotionExports._setTrialData({ + proVersion: "3.1.0", + endDate: mockNow + (daysRemaining * PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY) + }); + // Trigger entitlements changed event to update branding + const LoginService = PromotionExports.LoginService; + LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); + } + return { + setupTrialState + }; + } + + exports.getSharedUtils = getSharedUtils; +}); From 46ed42c5da983c62bfbebe48cc7f481e9d8cdbaa Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 17:01:55 +0530 Subject: [PATCH 02/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 46 +++------------------------ test/spec/login-desktop-integ-test.js | 46 +++------------------------ test/spec/login-shared.js | 45 +++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 83 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index fed6a3f508..49d54ac6cd 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -42,7 +42,9 @@ define(function (require, exports, module) { originalOpen, originalFetch, SharedUtils, - setupTrialState; + setupTrialState, + setupExpiredTrial, + verifyProBranding; beforeAll(async function () { testWindow = await SpecRunnerUtils.createTestWindowAndRun(); @@ -77,6 +79,8 @@ define(function (require, exports, module) { ); SharedUtils = LoginShared.getSharedUtils(testWindow); setupTrialState = SharedUtils.setupTrialState; + setupExpiredTrial = SharedUtils.setupExpiredTrial; + verifyProBranding = SharedUtils.verifyProBranding; }, 30000); afterAll(async function () { @@ -102,18 +106,6 @@ define(function (require, exports, module) { // Note: We can't easily reset login state, so tests should handle this }); - async function setupExpiredTrial() { - const PromotionExports = testWindow._test_promo_login_exports; - const mockNow = Date.now(); - await PromotionExports._setTrialData({ - proVersion: "3.1.0", - endDate: mockNow - PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY - }); - // Trigger entitlements changed event to update branding - const LoginService = PromotionExports.LoginService; - LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); - } - function setupProUserMock(hasActiveSubscription = true) { let userSignedOut = false; @@ -208,34 +200,6 @@ define(function (require, exports, module) { ProDialogsExports.setFetchFn(fetchMock); } - async function verifyProBranding(shouldShowPro, testDescription) { - const $brandingLink = testWindow.$("#phcode-io-main-nav"); - console.log(`llgT: Browser verifying branding for ${testDescription}, shouldShowPro: ${shouldShowPro}`); - console.log(`llgT: Browser branding link classes: ${$brandingLink.attr('class')}`); - console.log(`llgT: Browser branding link text: '${$brandingLink.text()}'`); - - if (shouldShowPro) { - await awaitsFor( - function () { - return testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); - }, - `Verify Pro branding to appear: ${testDescription}`, 5000 - ); - expect($brandingLink.hasClass("phoenix-pro")).toBe(true); - expect($brandingLink.text()).toContain("Phoenix Pro"); - expect($brandingLink.find(".fa-feather").length).toBe(1); - } else { - await awaitsFor( - function () { - return !testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); - }, - `Verify Pro branding to go away: ${testDescription}`, 5000 - ); - expect($brandingLink.hasClass("phoenix-pro")).toBe(false); - expect($brandingLink.text()).toBe("phcode.io"); - } - } - const VIEW_TRIAL_DAYS_LEFT = "VIEW_TRIAL_DAYS_LEFT"; const VIEW_PHOENIX_PRO = "VIEW_PHOENIX_PRO"; const VIEW_PHOENIX_FREE = "VIEW_PHOENIX_FREE"; diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index cdd31d3171..d1e5a52951 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -50,7 +50,9 @@ define(function (require, exports, module) { originalCopyToClipboard, originalFetch, SharedUtils, - setupTrialState; + setupTrialState, + setupExpiredTrial, + verifyProBranding; beforeAll(async function () { testWindow = await SpecRunnerUtils.createTestWindowAndRun(); @@ -85,6 +87,8 @@ define(function (require, exports, module) { ); SharedUtils = LoginShared.getSharedUtils(testWindow); setupTrialState = SharedUtils.setupTrialState; + setupExpiredTrial = SharedUtils.setupExpiredTrial; + verifyProBranding = SharedUtils.verifyProBranding; }, 30000); afterAll(async function () { @@ -112,18 +116,6 @@ define(function (require, exports, module) { // Note: We can't easily reset login state, so tests should handle this }); - async function setupExpiredTrial() { - const PromotionExports = testWindow._test_promo_login_exports; - const mockNow = Date.now(); - await PromotionExports._setTrialData({ - proVersion: "3.1.0", - endDate: mockNow - PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY - }); - // Trigger entitlements changed event to update branding - const LoginService = PromotionExports.LoginService; - LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); - } - function setupProUserMock(hasActiveSubscription = true) { let userSignedOut = false; @@ -230,34 +222,6 @@ define(function (require, exports, module) { ProDialogsExports.setFetchFn(fetchMock); } - async function verifyProBranding(shouldShowPro, testDescription) { - const $brandingLink = testWindow.$("#phcode-io-main-nav"); - console.log(`llgT: Desktop verifying branding for ${testDescription}, shouldShowPro: ${shouldShowPro}`); - console.log(`llgT: Desktop branding link classes: ${$brandingLink.attr('class')}`); - console.log(`llgT: Desktop branding link text: '${$brandingLink.text()}'`); - - if (shouldShowPro) { - await awaitsFor( - function () { - return testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); - }, - `Verify Pro branding to appear: ${testDescription}`, 5000 - ); - expect($brandingLink.hasClass("phoenix-pro")).toBe(true); - expect($brandingLink.text()).toContain("Phoenix Pro"); - expect($brandingLink.find(".fa-feather").length).toBe(1); - } else { - await awaitsFor( - function () { - return !testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); - }, - `Verify Pro branding to go away: ${testDescription}`, 5000 - ); - expect($brandingLink.hasClass("phoenix-pro")).toBe(false); - expect($brandingLink.text()).toBe("phcode.io"); - } - } - const VIEW_TRIAL_DAYS_LEFT = "VIEW_TRIAL_DAYS_LEFT"; const VIEW_PHOENIX_PRO = "VIEW_PHOENIX_PRO"; const VIEW_PHOENIX_FREE = "VIEW_PHOENIX_FREE"; diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index 3fc0c2cb0c..4e3e10212d 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -1,3 +1,6 @@ + +/*global expect, awaitsFor*/ + define(function (require, exports, module) { function getSharedUtils(testWindow) { @@ -13,8 +16,48 @@ define(function (require, exports, module) { const LoginService = PromotionExports.LoginService; LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); } + + async function setupExpiredTrial() { + const PromotionExports = testWindow._test_promo_login_exports; + const mockNow = Date.now(); + await PromotionExports._setTrialData({ + proVersion: "3.1.0", + endDate: mockNow - PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY + }); + // Trigger entitlements changed event to update branding + const LoginService = PromotionExports.LoginService; + LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); + } + + async function verifyProBranding(shouldShowPro, testDescription) { + const $brandingLink = testWindow.$("#phcode-io-main-nav"); + + if (shouldShowPro) { + await awaitsFor( + function () { + return testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); + }, + `Verify Pro branding to appear: ${testDescription}`, 5000 + ); + expect($brandingLink.hasClass("phoenix-pro")).toBe(true); + expect($brandingLink.text()).toContain("Phoenix Pro"); + expect($brandingLink.find(".fa-feather").length).toBe(1); + } else { + await awaitsFor( + function () { + return !testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); + }, + `Verify Pro branding to go away: ${testDescription}`, 5000 + ); + expect($brandingLink.hasClass("phoenix-pro")).toBe(false); + expect($brandingLink.text()).toBe("phcode.io"); + } + } + return { - setupTrialState + setupTrialState, + setupExpiredTrial, + verifyProBranding }; } From 7152308e369cd8d554f978bd450f1a91a5a09414 Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 17:07:23 +0530 Subject: [PATCH 03/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 76 ++++---------------------- test/spec/login-desktop-integ-test.js | 77 +++++---------------------- test/spec/login-shared.js | 68 ++++++++++++++++++++++- 3 files changed, 90 insertions(+), 131 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index 49d54ac6cd..1f900dfdf6 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -40,11 +40,15 @@ define(function (require, exports, module) { LoginBrowserExports, ProDialogsExports, originalOpen, - originalFetch, - SharedUtils, + originalFetch; + let SharedUtils, setupTrialState, setupExpiredTrial, - verifyProBranding; + verifyProBranding, + verifyProfilePopupContent, + VIEW_TRIAL_DAYS_LEFT, + VIEW_PHOENIX_PRO, + VIEW_PHOENIX_FREE; beforeAll(async function () { testWindow = await SpecRunnerUtils.createTestWindowAndRun(); @@ -78,9 +82,13 @@ define(function (require, exports, module) { 3000 ); SharedUtils = LoginShared.getSharedUtils(testWindow); + VIEW_TRIAL_DAYS_LEFT = SharedUtils.VIEW_TRIAL_DAYS_LEFT; + VIEW_PHOENIX_PRO = SharedUtils.VIEW_PHOENIX_PRO; + VIEW_PHOENIX_FREE = SharedUtils.VIEW_PHOENIX_FREE; setupTrialState = SharedUtils.setupTrialState; setupExpiredTrial = SharedUtils.setupExpiredTrial; verifyProBranding = SharedUtils.verifyProBranding; + verifyProfilePopupContent = SharedUtils.verifyProfilePopupContent; }, 30000); afterAll(async function () { @@ -200,68 +208,6 @@ define(function (require, exports, module) { ProDialogsExports.setFetchFn(fetchMock); } - const VIEW_TRIAL_DAYS_LEFT = "VIEW_TRIAL_DAYS_LEFT"; - const VIEW_PHOENIX_PRO = "VIEW_PHOENIX_PRO"; - const VIEW_PHOENIX_FREE = "VIEW_PHOENIX_FREE"; - async function verifyProfilePopupContent(expectedView, testDescription) { - await awaitsFor( - function () { - return testWindow.$('.profile-popup').length > 0; - }, - `Profile popup to appear: ${testDescription}`, - 3000 - ); - - if (expectedView === VIEW_PHOENIX_PRO) { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return planText.includes("Phoenix Pro"); - }, - `Profile popup should say phoenix pro: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).toContain("Phoenix Pro"); - expect(planText).not.toContain("days left"); - expect($popup.find(".fa-feather").length).toBe(1); - } else if (expectedView === VIEW_TRIAL_DAYS_LEFT) { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return planText.includes("Phoenix Pro") && planText.includes("days left"); - }, - `Profile popup should say phoenix pro trial: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).toContain("Phoenix Pro"); - expect(planText).toContain("days left"); - expect($popup.find(".fa-feather").length).toBe(1); - } else { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return !planText.includes("Phoenix Pro"); - }, - `Profile popup should not say phoenix pro: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).not.toContain("Phoenix Pro"); - expect($popup.find(".fa-feather").length).toBe(0); - } - } - async function cleanupTrialState() { const PromotionExports = testWindow._test_promo_login_exports; await PromotionExports._cleanTrialData(); diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index d1e5a52951..3b5057b821 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -48,11 +48,16 @@ define(function (require, exports, module) { ProDialogsExports, originalOpenURLInDefaultBrowser, originalCopyToClipboard, - originalFetch, - SharedUtils, + originalFetch; + + let SharedUtils, setupTrialState, setupExpiredTrial, - verifyProBranding; + verifyProBranding, + verifyProfilePopupContent, + VIEW_TRIAL_DAYS_LEFT, + VIEW_PHOENIX_PRO, + VIEW_PHOENIX_FREE; beforeAll(async function () { testWindow = await SpecRunnerUtils.createTestWindowAndRun(); @@ -86,9 +91,13 @@ define(function (require, exports, module) { 3000 ); SharedUtils = LoginShared.getSharedUtils(testWindow); + VIEW_TRIAL_DAYS_LEFT = SharedUtils.VIEW_TRIAL_DAYS_LEFT; + VIEW_PHOENIX_PRO = SharedUtils.VIEW_PHOENIX_PRO; + VIEW_PHOENIX_FREE = SharedUtils.VIEW_PHOENIX_FREE; setupTrialState = SharedUtils.setupTrialState; setupExpiredTrial = SharedUtils.setupExpiredTrial; verifyProBranding = SharedUtils.verifyProBranding; + verifyProfilePopupContent = SharedUtils.verifyProfilePopupContent; }, 30000); afterAll(async function () { @@ -222,68 +231,6 @@ define(function (require, exports, module) { ProDialogsExports.setFetchFn(fetchMock); } - const VIEW_TRIAL_DAYS_LEFT = "VIEW_TRIAL_DAYS_LEFT"; - const VIEW_PHOENIX_PRO = "VIEW_PHOENIX_PRO"; - const VIEW_PHOENIX_FREE = "VIEW_PHOENIX_FREE"; - async function verifyProfilePopupContent(expectedView, testDescription) { - await awaitsFor( - function () { - return testWindow.$('.profile-popup').length > 0; - }, - `Profile popup to appear: ${testDescription}`, - 3000 - ); - - if (expectedView === VIEW_PHOENIX_PRO) { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return planText.includes("Phoenix Pro"); - }, - `Profile popup should say phoenix pro: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).toContain("Phoenix Pro"); - expect(planText).not.toContain("days left"); - expect($popup.find(".fa-feather").length).toBe(1); - } else if (expectedView === VIEW_TRIAL_DAYS_LEFT) { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return planText.includes("Phoenix Pro") && planText.includes("days left"); - }, - `Profile popup should say phoenix pro trial: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).toContain("Phoenix Pro"); - expect(planText).toContain("days left"); - expect($popup.find(".fa-feather").length).toBe(1); - } else { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return !planText.includes("Phoenix Pro"); - }, - `Profile popup should not say phoenix pro: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).not.toContain("Phoenix Pro"); - expect($popup.find(".fa-feather").length).toBe(0); - } - } - async function cleanupTrialState() { const PromotionExports = testWindow._test_promo_login_exports; await PromotionExports._cleanTrialData(); diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index 4e3e10212d..20f852df98 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -54,10 +54,76 @@ define(function (require, exports, module) { } } + const VIEW_TRIAL_DAYS_LEFT = "VIEW_TRIAL_DAYS_LEFT"; + const VIEW_PHOENIX_PRO = "VIEW_PHOENIX_PRO"; + const VIEW_PHOENIX_FREE = "VIEW_PHOENIX_FREE"; + async function verifyProfilePopupContent(expectedView, testDescription) { + await awaitsFor( + function () { + return testWindow.$('.profile-popup').length > 0; + }, + `Profile popup to appear: ${testDescription}`, + 3000 + ); + + if (expectedView === VIEW_PHOENIX_PRO) { + await awaitsFor( + function () { + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + return planText.includes("Phoenix Pro"); + }, + `Profile popup should say phoenix pro: ${testDescription}`, 5000 + ); + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + expect(planText).toContain("Phoenix Pro"); + expect(planText).not.toContain("days left"); + expect($popup.find(".fa-feather").length).toBe(1); + } else if (expectedView === VIEW_TRIAL_DAYS_LEFT) { + await awaitsFor( + function () { + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + return planText.includes("Phoenix Pro") && planText.includes("days left"); + }, + `Profile popup should say phoenix pro trial: ${testDescription}`, 5000 + ); + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + expect(planText).toContain("Phoenix Pro"); + expect(planText).toContain("days left"); + expect($popup.find(".fa-feather").length).toBe(1); + } else { + await awaitsFor( + function () { + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + return !planText.includes("Phoenix Pro"); + }, + `Profile popup should not say phoenix pro: ${testDescription}`, 5000 + ); + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + expect(planText).not.toContain("Phoenix Pro"); + expect($popup.find(".fa-feather").length).toBe(0); + } + } + return { setupTrialState, setupExpiredTrial, - verifyProBranding + verifyProBranding, + verifyProfilePopupContent, + VIEW_TRIAL_DAYS_LEFT, + VIEW_PHOENIX_PRO, + VIEW_PHOENIX_FREE }; } From e6aabc3a69a221c3fd656cac464c9f5db201e608 Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 17:27:28 +0530 Subject: [PATCH 04/11] test: should show free branding for user without pro subscription (expired trial) --- test/spec/login-browser-integ-test.js | 45 +++++++++++++++++++++++++++ test/spec/login-desktop-integ-test.js | 45 +++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index 1f900dfdf6..01f644d0d1 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -529,6 +529,51 @@ define(function (require, exports, module) { await popupToAppear(SIGNIN_POPUP); await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, "trial user profile popup for logged out user"); + + // Close popup + $profileButton.trigger('click'); + }); + + it("should show free branding for user without pro subscription (expired trial)", async function () { + console.log("llgT: Starting desktop trial user test"); + + // Setup: No pro subscription + active trial (15 days) + setupProUserMock(false); + await setupExpiredTrial(); + + // Verify initial state (no pro branding) + await verifyProBranding(false, "no pro branding to start with"); + + // Perform login + await performFullLoginFlow(); + + // Verify pro branding remains after login + await verifyProBranding(false, "after trial free user login"); + + // Check profile popup shows free plan status + const $profileButton = testWindow.$("#user-profile-button"); + $profileButton.trigger('click'); + await popupToAppear(PROFILE_POPUP); + await verifyProfilePopupContent(VIEW_PHOENIX_FREE, + "free plan user profile popup for logged in user"); + + // Close popup + $profileButton.trigger('click'); + + // Perform logout + await performFullLogoutFlow(); + + // Verify pro branding remains after logout (trial continues) + await verifyProBranding(false, "Trial branding to remain after logout"); + + // Check profile popup still shows free plan status as trial expired + $profileButton.trigger('click'); + await popupToAppear(SIGNIN_POPUP); + // not logged in user, we wont show free plan tag as base editor is always free. + expect(testWindow.$(`.profile-popup .trial-plan-info`).length).toBe(0); + + // Close popup + $profileButton.trigger('click'); }); }); }); diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index 3b5057b821..db0b7d68f7 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -602,6 +602,51 @@ define(function (require, exports, module) { await popupToAppear(SIGNIN_POPUP); await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, "trial user profile popup for logged out user"); + + // Close popup + $profileButton.trigger('click'); + }); + + it("should show free branding for user without pro subscription (expired trial)", async function () { + console.log("llgT: Starting desktop trial user test"); + + // Setup: No pro subscription + active trial (15 days) + setupProUserMock(false); + await setupExpiredTrial(); + + // Verify initial state (no pro branding) + await verifyProBranding(false, "no pro branding to start with"); + + // Perform login + await performFullLoginFlow(); + + // Verify pro branding remains after login + await verifyProBranding(false, "after trial free user login"); + + // Check profile popup shows free plan status + const $profileButton = testWindow.$("#user-profile-button"); + $profileButton.trigger('click'); + await popupToAppear(PROFILE_POPUP); + await verifyProfilePopupContent(VIEW_PHOENIX_FREE, + "free plan user profile popup for logged in user"); + + // Close popup + $profileButton.trigger('click'); + + // Perform logout + await performFullLogoutFlow(); + + // Verify pro branding remains after logout (trial continues) + await verifyProBranding(false, "Trial branding to remain after logout"); + + // Check profile popup still shows free plan status as trial expired + $profileButton.trigger('click'); + await popupToAppear(SIGNIN_POPUP); + // not logged in user, we wont show free plan tag as base editor is always free. + expect(testWindow.$(`.profile-popup .trial-plan-info`).length).toBe(0); + + // Close popup + $profileButton.trigger('click'); }); }); }); From bfca50dfef5f9d91f16fa40778798b0d12d6415a Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 17:31:28 +0530 Subject: [PATCH 05/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 30 +++++++++------------------ test/spec/login-desktop-integ-test.js | 29 ++++++++------------------ test/spec/login-shared.js | 25 +++++++++++++++++++++- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index 01f644d0d1..4b7da8072e 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -41,14 +41,19 @@ define(function (require, exports, module) { ProDialogsExports, originalOpen, originalFetch; + let SharedUtils, setupTrialState, setupExpiredTrial, verifyProBranding, verifyProfilePopupContent, + cleanupTrialState, + popupToAppear, VIEW_TRIAL_DAYS_LEFT, VIEW_PHOENIX_PRO, - VIEW_PHOENIX_FREE; + VIEW_PHOENIX_FREE, + SIGNIN_POPUP, + PROFILE_POPUP; beforeAll(async function () { testWindow = await SpecRunnerUtils.createTestWindowAndRun(); @@ -85,10 +90,14 @@ define(function (require, exports, module) { VIEW_TRIAL_DAYS_LEFT = SharedUtils.VIEW_TRIAL_DAYS_LEFT; VIEW_PHOENIX_PRO = SharedUtils.VIEW_PHOENIX_PRO; VIEW_PHOENIX_FREE = SharedUtils.VIEW_PHOENIX_FREE; + SIGNIN_POPUP = SharedUtils.SIGNIN_POPUP; + PROFILE_POPUP = SharedUtils.PROFILE_POPUP; setupTrialState = SharedUtils.setupTrialState; setupExpiredTrial = SharedUtils.setupExpiredTrial; verifyProBranding = SharedUtils.verifyProBranding; verifyProfilePopupContent = SharedUtils.verifyProfilePopupContent; + cleanupTrialState = SharedUtils.cleanupTrialState; + popupToAppear = SharedUtils.popupToAppear; }, 30000); afterAll(async function () { @@ -208,25 +217,6 @@ define(function (require, exports, module) { ProDialogsExports.setFetchFn(fetchMock); } - async function cleanupTrialState() { - const PromotionExports = testWindow._test_promo_login_exports; - await PromotionExports._cleanTrialData(); - } - - const SIGNIN_POPUP = "SIGNIN_POPUP"; - const PROFILE_POPUP = "PROFILE_POPUP"; - async function popupToAppear(popupType = SIGNIN_POPUP) { - const statusText = popupType === SIGNIN_POPUP ? - "Sign In popup to appear" : "Profile popup to appear"; - await awaitsFor( - function () { - const selector = popupType === SIGNIN_POPUP ? ".login-profile-popup" : ".user-profile-popup"; - return testWindow.$('.modal').length > 0 || testWindow.$(selector).length > 0; - }, - statusText, 3000 - ); - } - async function performFullLoginFlow() { // Mock window.open like the original test let capturedURL = null; diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index db0b7d68f7..9f21a872a0 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -55,9 +55,13 @@ define(function (require, exports, module) { setupExpiredTrial, verifyProBranding, verifyProfilePopupContent, + cleanupTrialState, + popupToAppear, VIEW_TRIAL_DAYS_LEFT, VIEW_PHOENIX_PRO, - VIEW_PHOENIX_FREE; + VIEW_PHOENIX_FREE, + SIGNIN_POPUP, + PROFILE_POPUP; beforeAll(async function () { testWindow = await SpecRunnerUtils.createTestWindowAndRun(); @@ -94,10 +98,14 @@ define(function (require, exports, module) { VIEW_TRIAL_DAYS_LEFT = SharedUtils.VIEW_TRIAL_DAYS_LEFT; VIEW_PHOENIX_PRO = SharedUtils.VIEW_PHOENIX_PRO; VIEW_PHOENIX_FREE = SharedUtils.VIEW_PHOENIX_FREE; + SIGNIN_POPUP = SharedUtils.SIGNIN_POPUP; + PROFILE_POPUP = SharedUtils.PROFILE_POPUP; setupTrialState = SharedUtils.setupTrialState; setupExpiredTrial = SharedUtils.setupExpiredTrial; verifyProBranding = SharedUtils.verifyProBranding; verifyProfilePopupContent = SharedUtils.verifyProfilePopupContent; + cleanupTrialState = SharedUtils.cleanupTrialState; + popupToAppear = SharedUtils.popupToAppear; }, 30000); afterAll(async function () { @@ -231,25 +239,6 @@ define(function (require, exports, module) { ProDialogsExports.setFetchFn(fetchMock); } - async function cleanupTrialState() { - const PromotionExports = testWindow._test_promo_login_exports; - await PromotionExports._cleanTrialData(); - } - - const SIGNIN_POPUP = "SIGNIN_POPUP"; - const PROFILE_POPUP = "PROFILE_POPUP"; - async function popupToAppear(popupType = SIGNIN_POPUP) { - const statusText = popupType === SIGNIN_POPUP ? - "Sign In popup to appear" : "Profile popup to appear"; - await awaitsFor( - function () { - const selector = popupType === SIGNIN_POPUP ? ".login-profile-popup" : ".user-profile-popup"; - return testWindow.$('.modal').length > 0 || testWindow.$(selector).length > 0; - }, - statusText, 3000 - ); - } - async function performFullLoginFlow() { // Mock desktop app functions for login flow testWindow.Phoenix.app.openURLInDefaultBrowser = function(url) { diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index 20f852df98..a9377539d4 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -116,14 +116,37 @@ define(function (require, exports, module) { } } + async function cleanupTrialState() { + const PromotionExports = testWindow._test_promo_login_exports; + await PromotionExports._cleanTrialData(); + } + + const SIGNIN_POPUP = "SIGNIN_POPUP"; + const PROFILE_POPUP = "PROFILE_POPUP"; + async function popupToAppear(popupType = SIGNIN_POPUP) { + const statusText = popupType === SIGNIN_POPUP ? + "Sign In popup to appear" : "Profile popup to appear"; + await awaitsFor( + function () { + const selector = popupType === SIGNIN_POPUP ? ".login-profile-popup" : ".user-profile-popup"; + return testWindow.$('.modal').length > 0 || testWindow.$(selector).length > 0; + }, + statusText, 3000 + ); + } + return { setupTrialState, setupExpiredTrial, verifyProBranding, verifyProfilePopupContent, + cleanupTrialState, + popupToAppear, VIEW_TRIAL_DAYS_LEFT, VIEW_PHOENIX_PRO, - VIEW_PHOENIX_FREE + VIEW_PHOENIX_FREE, + SIGNIN_POPUP, + PROFILE_POPUP }; } From 9a36c7e7a8b10af4ddc5d39850f5c20eab4c0eaf Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 17:37:36 +0530 Subject: [PATCH 06/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 42 ++++----------------------- test/spec/login-desktop-integ-test.js | 41 ++++---------------------- test/spec/login-shared.js | 39 ++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 74 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index 4b7da8072e..4d08411c5a 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -49,6 +49,8 @@ define(function (require, exports, module) { verifyProfilePopupContent, cleanupTrialState, popupToAppear, + performFullLogoutFlow, + verifyProfileIconBlanked, VIEW_TRIAL_DAYS_LEFT, VIEW_PHOENIX_PRO, VIEW_PHOENIX_FREE, @@ -86,7 +88,7 @@ define(function (require, exports, module) { "Profile button to be available", 3000 ); - SharedUtils = LoginShared.getSharedUtils(testWindow); + SharedUtils = LoginShared.getSharedUtils(testWindow, LoginServiceExports); VIEW_TRIAL_DAYS_LEFT = SharedUtils.VIEW_TRIAL_DAYS_LEFT; VIEW_PHOENIX_PRO = SharedUtils.VIEW_PHOENIX_PRO; VIEW_PHOENIX_FREE = SharedUtils.VIEW_PHOENIX_FREE; @@ -98,6 +100,8 @@ define(function (require, exports, module) { verifyProfilePopupContent = SharedUtils.verifyProfilePopupContent; cleanupTrialState = SharedUtils.cleanupTrialState; popupToAppear = SharedUtils.popupToAppear; + performFullLogoutFlow = SharedUtils.performFullLogoutFlow; + verifyProfileIconBlanked = SharedUtils.verifyProfileIconBlanked; }, 30000); afterAll(async function () { @@ -277,42 +281,6 @@ define(function (require, exports, module) { ); } - function verifyProfileIconBlanked() { - const $profileIcon = testWindow.$("#user-profile-button"); - const initialContent = $profileIcon.html(); - expect(initialContent).not.toContain('TU'); - } - - async function performFullLogoutFlow() { - // Click profile button to open popup - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - - // Wait for profile popup - await popupToAppear(PROFILE_POPUP); - - // Find and click sign out button - let popupContent = testWindow.$('.profile-popup'); - const signOutButton = popupContent.find('#phoenix-signout-btn'); - signOutButton.trigger('click'); - - // Wait for sign out confirmation dialog and dismiss it - await testWindow.__PR.waitForModalDialog(".modal"); - testWindow.__PR.clickDialogButtonID(testWindow.__PR.Dialogs.DIALOG_BTN_OK); - await testWindow.__PR.waitForModalDialogClosed(".modal"); - - // Wait for sign out to complete - await awaitsFor( - function () { - return !LoginServiceExports.LoginService.isLoggedIn(); - }, - "User to be signed out", - 10000 - ); - - verifyProfileIconBlanked(); - } - describe("Browser Login Tests", function () { beforeEach(async function () { diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index 9f21a872a0..25ab1ead7d 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -57,6 +57,8 @@ define(function (require, exports, module) { verifyProfilePopupContent, cleanupTrialState, popupToAppear, + performFullLogoutFlow, + verifyProfileIconBlanked, VIEW_TRIAL_DAYS_LEFT, VIEW_PHOENIX_PRO, VIEW_PHOENIX_FREE, @@ -94,7 +96,7 @@ define(function (require, exports, module) { "Profile button to be available", 3000 ); - SharedUtils = LoginShared.getSharedUtils(testWindow); + SharedUtils = LoginShared.getSharedUtils(testWindow, LoginServiceExports); VIEW_TRIAL_DAYS_LEFT = SharedUtils.VIEW_TRIAL_DAYS_LEFT; VIEW_PHOENIX_PRO = SharedUtils.VIEW_PHOENIX_PRO; VIEW_PHOENIX_FREE = SharedUtils.VIEW_PHOENIX_FREE; @@ -106,6 +108,8 @@ define(function (require, exports, module) { verifyProfilePopupContent = SharedUtils.verifyProfilePopupContent; cleanupTrialState = SharedUtils.cleanupTrialState; popupToAppear = SharedUtils.popupToAppear; + performFullLogoutFlow = SharedUtils.performFullLogoutFlow; + verifyProfileIconBlanked = SharedUtils.verifyProfileIconBlanked; }, 30000); afterAll(async function () { @@ -289,41 +293,6 @@ define(function (require, exports, module) { ); } - async function performFullLogoutFlow() { - // Click profile button to open popup - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - - // Wait for profile popup - await popupToAppear(PROFILE_POPUP); - - // Find and click sign out button - let popupContent = testWindow.$('.profile-popup'); - const signOutButton = popupContent.find('#phoenix-signout-btn'); - signOutButton.trigger('click'); - - // Wait for sign out confirmation dialog and dismiss it - await testWindow.__PR.waitForModalDialog(".modal"); - testWindow.__PR.clickDialogButtonID(testWindow.__PR.Dialogs.DIALOG_BTN_OK); - await testWindow.__PR.waitForModalDialogClosed(".modal"); - - // Wait for sign out to complete - await awaitsFor( - function () { - return !LoginServiceExports.LoginService.isLoggedIn(); - }, - "User to be signed out", - 10000 - ); - verifyProfileIconBlanked(); - } - - function verifyProfileIconBlanked() { - const $profileIcon = testWindow.$("#user-profile-button"); - const initialContent = $profileIcon.html(); - expect(initialContent).not.toContain('TU'); - } - describe("Desktop Login and Promotion Tests", function () { beforeEach(async function () { diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index a9377539d4..f844f3057d 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -3,7 +3,7 @@ define(function (require, exports, module) { - function getSharedUtils(testWindow) { + function getSharedUtils(testWindow, LoginServiceExports) { // Helper functions for promotion testing (browser-specific) async function setupTrialState(daysRemaining) { const PromotionExports = testWindow._test_promo_login_exports; @@ -135,6 +135,41 @@ define(function (require, exports, module) { ); } + function verifyProfileIconBlanked() { + const $profileIcon = testWindow.$("#user-profile-button"); + const initialContent = $profileIcon.html(); + expect(initialContent).not.toContain('TU'); + } + + async function performFullLogoutFlow() { + // Click profile button to open popup + const $profileButton = testWindow.$("#user-profile-button"); + $profileButton.trigger('click'); + + // Wait for profile popup + await popupToAppear(PROFILE_POPUP); + + // Find and click sign out button + let popupContent = testWindow.$('.profile-popup'); + const signOutButton = popupContent.find('#phoenix-signout-btn'); + signOutButton.trigger('click'); + + // Wait for sign out confirmation dialog and dismiss it + await testWindow.__PR.waitForModalDialog(".modal"); + testWindow.__PR.clickDialogButtonID(testWindow.__PR.Dialogs.DIALOG_BTN_OK); + await testWindow.__PR.waitForModalDialogClosed(".modal"); + + // Wait for sign out to complete + await awaitsFor( + function () { + return !LoginServiceExports.LoginService.isLoggedIn(); + }, + "User to be signed out", + 10000 + ); + verifyProfileIconBlanked(); + } + return { setupTrialState, setupExpiredTrial, @@ -142,6 +177,8 @@ define(function (require, exports, module) { verifyProfilePopupContent, cleanupTrialState, popupToAppear, + performFullLogoutFlow, + verifyProfileIconBlanked, VIEW_TRIAL_DAYS_LEFT, VIEW_PHOENIX_PRO, VIEW_PHOENIX_FREE, From a90ae30425ed6deb2137e8c49e613f9a6cef8cdc Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 17:59:39 +0530 Subject: [PATCH 07/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 31 ++- test/spec/login-desktop-integ-test.js | 31 ++- test/spec/login-shared.js | 330 +++++++++++++------------- 3 files changed, 195 insertions(+), 197 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index 4d08411c5a..b5392b416b 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -42,8 +42,7 @@ define(function (require, exports, module) { originalOpen, originalFetch; - let SharedUtils, - setupTrialState, + let setupTrialState, setupExpiredTrial, verifyProBranding, verifyProfilePopupContent, @@ -88,20 +87,20 @@ define(function (require, exports, module) { "Profile button to be available", 3000 ); - SharedUtils = LoginShared.getSharedUtils(testWindow, LoginServiceExports); - VIEW_TRIAL_DAYS_LEFT = SharedUtils.VIEW_TRIAL_DAYS_LEFT; - VIEW_PHOENIX_PRO = SharedUtils.VIEW_PHOENIX_PRO; - VIEW_PHOENIX_FREE = SharedUtils.VIEW_PHOENIX_FREE; - SIGNIN_POPUP = SharedUtils.SIGNIN_POPUP; - PROFILE_POPUP = SharedUtils.PROFILE_POPUP; - setupTrialState = SharedUtils.setupTrialState; - setupExpiredTrial = SharedUtils.setupExpiredTrial; - verifyProBranding = SharedUtils.verifyProBranding; - verifyProfilePopupContent = SharedUtils.verifyProfilePopupContent; - cleanupTrialState = SharedUtils.cleanupTrialState; - popupToAppear = SharedUtils.popupToAppear; - performFullLogoutFlow = SharedUtils.performFullLogoutFlow; - verifyProfileIconBlanked = SharedUtils.verifyProfileIconBlanked; + LoginShared.setup(testWindow, LoginServiceExports); + VIEW_TRIAL_DAYS_LEFT = LoginShared.VIEW_TRIAL_DAYS_LEFT; + VIEW_PHOENIX_PRO = LoginShared.VIEW_PHOENIX_PRO; + VIEW_PHOENIX_FREE = LoginShared.VIEW_PHOENIX_FREE; + SIGNIN_POPUP = LoginShared.SIGNIN_POPUP; + PROFILE_POPUP = LoginShared.PROFILE_POPUP; + setupTrialState = LoginShared.setupTrialState; + setupExpiredTrial = LoginShared.setupExpiredTrial; + verifyProBranding = LoginShared.verifyProBranding; + verifyProfilePopupContent = LoginShared.verifyProfilePopupContent; + cleanupTrialState = LoginShared.cleanupTrialState; + popupToAppear = LoginShared.popupToAppear; + performFullLogoutFlow = LoginShared.performFullLogoutFlow; + verifyProfileIconBlanked = LoginShared.verifyProfileIconBlanked; }, 30000); afterAll(async function () { diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index 25ab1ead7d..cda4d938b8 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -50,8 +50,7 @@ define(function (require, exports, module) { originalCopyToClipboard, originalFetch; - let SharedUtils, - setupTrialState, + let setupTrialState, setupExpiredTrial, verifyProBranding, verifyProfilePopupContent, @@ -96,20 +95,20 @@ define(function (require, exports, module) { "Profile button to be available", 3000 ); - SharedUtils = LoginShared.getSharedUtils(testWindow, LoginServiceExports); - VIEW_TRIAL_DAYS_LEFT = SharedUtils.VIEW_TRIAL_DAYS_LEFT; - VIEW_PHOENIX_PRO = SharedUtils.VIEW_PHOENIX_PRO; - VIEW_PHOENIX_FREE = SharedUtils.VIEW_PHOENIX_FREE; - SIGNIN_POPUP = SharedUtils.SIGNIN_POPUP; - PROFILE_POPUP = SharedUtils.PROFILE_POPUP; - setupTrialState = SharedUtils.setupTrialState; - setupExpiredTrial = SharedUtils.setupExpiredTrial; - verifyProBranding = SharedUtils.verifyProBranding; - verifyProfilePopupContent = SharedUtils.verifyProfilePopupContent; - cleanupTrialState = SharedUtils.cleanupTrialState; - popupToAppear = SharedUtils.popupToAppear; - performFullLogoutFlow = SharedUtils.performFullLogoutFlow; - verifyProfileIconBlanked = SharedUtils.verifyProfileIconBlanked; + LoginShared.setup(testWindow, LoginServiceExports); + VIEW_TRIAL_DAYS_LEFT = LoginShared.VIEW_TRIAL_DAYS_LEFT; + VIEW_PHOENIX_PRO = LoginShared.VIEW_PHOENIX_PRO; + VIEW_PHOENIX_FREE = LoginShared.VIEW_PHOENIX_FREE; + SIGNIN_POPUP = LoginShared.SIGNIN_POPUP; + PROFILE_POPUP = LoginShared.PROFILE_POPUP; + setupTrialState = LoginShared.setupTrialState; + setupExpiredTrial = LoginShared.setupExpiredTrial; + verifyProBranding = LoginShared.verifyProBranding; + verifyProfilePopupContent = LoginShared.verifyProfilePopupContent; + cleanupTrialState = LoginShared.cleanupTrialState; + popupToAppear = LoginShared.popupToAppear; + performFullLogoutFlow = LoginShared.performFullLogoutFlow; + verifyProfileIconBlanked = LoginShared.verifyProfileIconBlanked; }, 30000); afterAll(async function () { diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index f844f3057d..68bcf7892d 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -2,190 +2,190 @@ /*global expect, awaitsFor*/ define(function (require, exports, module) { + let testWindow, LoginServiceExports; + + async function setupTrialState(daysRemaining) { + const PromotionExports = testWindow._test_promo_login_exports; + const mockNow = Date.now(); + await PromotionExports._setTrialData({ + proVersion: "3.1.0", + endDate: mockNow + (daysRemaining * PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY) + }); + // Trigger entitlements changed event to update branding + const LoginService = PromotionExports.LoginService; + LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); + } - function getSharedUtils(testWindow, LoginServiceExports) { - // Helper functions for promotion testing (browser-specific) - async function setupTrialState(daysRemaining) { - const PromotionExports = testWindow._test_promo_login_exports; - const mockNow = Date.now(); - await PromotionExports._setTrialData({ - proVersion: "3.1.0", - endDate: mockNow + (daysRemaining * PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY) - }); - // Trigger entitlements changed event to update branding - const LoginService = PromotionExports.LoginService; - LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); - } + async function setupExpiredTrial() { + const PromotionExports = testWindow._test_promo_login_exports; + const mockNow = Date.now(); + await PromotionExports._setTrialData({ + proVersion: "3.1.0", + endDate: mockNow - PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY + }); + // Trigger entitlements changed event to update branding + const LoginService = PromotionExports.LoginService; + LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); + } - async function setupExpiredTrial() { - const PromotionExports = testWindow._test_promo_login_exports; - const mockNow = Date.now(); - await PromotionExports._setTrialData({ - proVersion: "3.1.0", - endDate: mockNow - PromotionExports.TRIAL_CONSTANTS.MS_PER_DAY - }); - // Trigger entitlements changed event to update branding - const LoginService = PromotionExports.LoginService; - LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED); - } + async function verifyProBranding(shouldShowPro, testDescription) { + const $brandingLink = testWindow.$("#phcode-io-main-nav"); - async function verifyProBranding(shouldShowPro, testDescription) { - const $brandingLink = testWindow.$("#phcode-io-main-nav"); - - if (shouldShowPro) { - await awaitsFor( - function () { - return testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); - }, - `Verify Pro branding to appear: ${testDescription}`, 5000 - ); - expect($brandingLink.hasClass("phoenix-pro")).toBe(true); - expect($brandingLink.text()).toContain("Phoenix Pro"); - expect($brandingLink.find(".fa-feather").length).toBe(1); - } else { - await awaitsFor( - function () { - return !testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); - }, - `Verify Pro branding to go away: ${testDescription}`, 5000 - ); - expect($brandingLink.hasClass("phoenix-pro")).toBe(false); - expect($brandingLink.text()).toBe("phcode.io"); - } - } - - const VIEW_TRIAL_DAYS_LEFT = "VIEW_TRIAL_DAYS_LEFT"; - const VIEW_PHOENIX_PRO = "VIEW_PHOENIX_PRO"; - const VIEW_PHOENIX_FREE = "VIEW_PHOENIX_FREE"; - async function verifyProfilePopupContent(expectedView, testDescription) { + if (shouldShowPro) { await awaitsFor( function () { - return testWindow.$('.profile-popup').length > 0; + return testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); }, - `Profile popup to appear: ${testDescription}`, - 3000 + `Verify Pro branding to appear: ${testDescription}`, 5000 ); - - if (expectedView === VIEW_PHOENIX_PRO) { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return planText.includes("Phoenix Pro"); - }, - `Profile popup should say phoenix pro: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).toContain("Phoenix Pro"); - expect(planText).not.toContain("days left"); - expect($popup.find(".fa-feather").length).toBe(1); - } else if (expectedView === VIEW_TRIAL_DAYS_LEFT) { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return planText.includes("Phoenix Pro") && planText.includes("days left"); - }, - `Profile popup should say phoenix pro trial: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).toContain("Phoenix Pro"); - expect(planText).toContain("days left"); - expect($popup.find(".fa-feather").length).toBe(1); - } else { - await awaitsFor( - function () { - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - return !planText.includes("Phoenix Pro"); - }, - `Profile popup should not say phoenix pro: ${testDescription}`, 5000 - ); - const $popup = testWindow.$('.profile-popup'); - const $planName = $popup.find('.user-plan-name'); - const planText = $planName.text(); - expect(planText).not.toContain("Phoenix Pro"); - expect($popup.find(".fa-feather").length).toBe(0); - } - } - - async function cleanupTrialState() { - const PromotionExports = testWindow._test_promo_login_exports; - await PromotionExports._cleanTrialData(); - } - - const SIGNIN_POPUP = "SIGNIN_POPUP"; - const PROFILE_POPUP = "PROFILE_POPUP"; - async function popupToAppear(popupType = SIGNIN_POPUP) { - const statusText = popupType === SIGNIN_POPUP ? - "Sign In popup to appear" : "Profile popup to appear"; + expect($brandingLink.hasClass("phoenix-pro")).toBe(true); + expect($brandingLink.text()).toContain("Phoenix Pro"); + expect($brandingLink.find(".fa-feather").length).toBe(1); + } else { await awaitsFor( function () { - const selector = popupType === SIGNIN_POPUP ? ".login-profile-popup" : ".user-profile-popup"; - return testWindow.$('.modal').length > 0 || testWindow.$(selector).length > 0; + return !testWindow.$("#phcode-io-main-nav").hasClass("phoenix-pro"); }, - statusText, 3000 + `Verify Pro branding to go away: ${testDescription}`, 5000 ); + expect($brandingLink.hasClass("phoenix-pro")).toBe(false); + expect($brandingLink.text()).toBe("phcode.io"); } + } - function verifyProfileIconBlanked() { - const $profileIcon = testWindow.$("#user-profile-button"); - const initialContent = $profileIcon.html(); - expect(initialContent).not.toContain('TU'); - } - - async function performFullLogoutFlow() { - // Click profile button to open popup - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - - // Wait for profile popup - await popupToAppear(PROFILE_POPUP); - - // Find and click sign out button - let popupContent = testWindow.$('.profile-popup'); - const signOutButton = popupContent.find('#phoenix-signout-btn'); - signOutButton.trigger('click'); - - // Wait for sign out confirmation dialog and dismiss it - await testWindow.__PR.waitForModalDialog(".modal"); - testWindow.__PR.clickDialogButtonID(testWindow.__PR.Dialogs.DIALOG_BTN_OK); - await testWindow.__PR.waitForModalDialogClosed(".modal"); - - // Wait for sign out to complete + const VIEW_TRIAL_DAYS_LEFT = "VIEW_TRIAL_DAYS_LEFT"; + const VIEW_PHOENIX_PRO = "VIEW_PHOENIX_PRO"; + const VIEW_PHOENIX_FREE = "VIEW_PHOENIX_FREE"; + async function verifyProfilePopupContent(expectedView, testDescription) { + await awaitsFor( + function () { + return testWindow.$('.profile-popup').length > 0; + }, + `Profile popup to appear: ${testDescription}`, + 3000 + ); + + if (expectedView === VIEW_PHOENIX_PRO) { await awaitsFor( function () { - return !LoginServiceExports.LoginService.isLoggedIn(); + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + return planText.includes("Phoenix Pro"); }, - "User to be signed out", - 10000 + `Profile popup should say phoenix pro: ${testDescription}`, 5000 ); - verifyProfileIconBlanked(); + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + expect(planText).toContain("Phoenix Pro"); + expect(planText).not.toContain("days left"); + expect($popup.find(".fa-feather").length).toBe(1); + } else if (expectedView === VIEW_TRIAL_DAYS_LEFT) { + await awaitsFor( + function () { + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + return planText.includes("Phoenix Pro") && planText.includes("days left"); + }, + `Profile popup should say phoenix pro trial: ${testDescription}`, 5000 + ); + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + expect(planText).toContain("Phoenix Pro"); + expect(planText).toContain("days left"); + expect($popup.find(".fa-feather").length).toBe(1); + } else { + await awaitsFor( + function () { + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + return !planText.includes("Phoenix Pro"); + }, + `Profile popup should not say phoenix pro: ${testDescription}`, 5000 + ); + const $popup = testWindow.$('.profile-popup'); + const $planName = $popup.find('.user-plan-name'); + const planText = $planName.text(); + expect(planText).not.toContain("Phoenix Pro"); + expect($popup.find(".fa-feather").length).toBe(0); } + } + + async function cleanupTrialState() { + const PromotionExports = testWindow._test_promo_login_exports; + await PromotionExports._cleanTrialData(); + } + + const SIGNIN_POPUP = "SIGNIN_POPUP"; + const PROFILE_POPUP = "PROFILE_POPUP"; + async function popupToAppear(popupType = SIGNIN_POPUP) { + const statusText = popupType === SIGNIN_POPUP ? + "Sign In popup to appear" : "Profile popup to appear"; + await awaitsFor( + function () { + const selector = popupType === SIGNIN_POPUP ? ".login-profile-popup" : ".user-profile-popup"; + return testWindow.$('.modal').length > 0 || testWindow.$(selector).length > 0; + }, + statusText, 3000 + ); + } + + function verifyProfileIconBlanked() { + const $profileIcon = testWindow.$("#user-profile-button"); + const initialContent = $profileIcon.html(); + expect(initialContent).not.toContain('TU'); + } + + async function performFullLogoutFlow() { + // Click profile button to open popup + const $profileButton = testWindow.$("#user-profile-button"); + $profileButton.trigger('click'); + + // Wait for profile popup + await popupToAppear(PROFILE_POPUP); + + // Find and click sign out button + let popupContent = testWindow.$('.profile-popup'); + const signOutButton = popupContent.find('#phoenix-signout-btn'); + signOutButton.trigger('click'); + + // Wait for sign out confirmation dialog and dismiss it + await testWindow.__PR.waitForModalDialog(".modal"); + testWindow.__PR.clickDialogButtonID(testWindow.__PR.Dialogs.DIALOG_BTN_OK); + await testWindow.__PR.waitForModalDialogClosed(".modal"); + + // Wait for sign out to complete + await awaitsFor( + function () { + return !LoginServiceExports.LoginService.isLoggedIn(); + }, + "User to be signed out", + 10000 + ); + verifyProfileIconBlanked(); + } - return { - setupTrialState, - setupExpiredTrial, - verifyProBranding, - verifyProfilePopupContent, - cleanupTrialState, - popupToAppear, - performFullLogoutFlow, - verifyProfileIconBlanked, - VIEW_TRIAL_DAYS_LEFT, - VIEW_PHOENIX_PRO, - VIEW_PHOENIX_FREE, - SIGNIN_POPUP, - PROFILE_POPUP - }; + function setup(_testWindow, _LoginServiceExports) { + testWindow = _testWindow; + LoginServiceExports = _LoginServiceExports; } - exports.getSharedUtils = getSharedUtils; + exports.setup = setup; + exports.setupTrialState = setupTrialState; + exports.setupExpiredTrial = setupExpiredTrial; + exports.verifyProBranding = verifyProBranding; + exports.verifyProfilePopupContent = verifyProfilePopupContent; + exports.cleanupTrialState = cleanupTrialState; + exports.popupToAppear = popupToAppear; + exports.performFullLogoutFlow = performFullLogoutFlow; + exports.verifyProfileIconBlanked = verifyProfileIconBlanked; + exports.VIEW_TRIAL_DAYS_LEFT = VIEW_TRIAL_DAYS_LEFT; + exports.VIEW_PHOENIX_PRO = VIEW_PHOENIX_PRO; + exports.VIEW_PHOENIX_FREE = VIEW_PHOENIX_FREE; + exports.SIGNIN_POPUP = SIGNIN_POPUP; + exports.PROFILE_POPUP = PROFILE_POPUP; }); From 6baa682e5020b7216a5e389f54bc02e3056ad0a3 Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 18:05:10 +0530 Subject: [PATCH 08/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 15 ++------------ test/spec/login-desktop-integ-test.js | 16 ++------------- test/spec/login-shared.js | 28 ++++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index b5392b416b..ba5faff77a 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -87,7 +87,7 @@ define(function (require, exports, module) { "Profile button to be available", 3000 ); - LoginShared.setup(testWindow, LoginServiceExports); + LoginShared.setup(testWindow, LoginServiceExports, setupProUserMock, performFullLoginFlow); VIEW_TRIAL_DAYS_LEFT = LoginShared.VIEW_TRIAL_DAYS_LEFT; VIEW_PHOENIX_PRO = LoginShared.VIEW_PHOENIX_PRO; VIEW_PHOENIX_FREE = LoginShared.VIEW_PHOENIX_FREE; @@ -290,18 +290,7 @@ define(function (require, exports, module) { await cleanupTrialState(); }); - it("should complete login and logout flow", async function () { - // Setup basic user mock - setupProUserMock(false); - - // Perform full login flow - await performFullLoginFlow(); - expect(LoginServiceExports.LoginService.isLoggedIn()).toBe(true); - - // Perform full logout flow - await performFullLogoutFlow(); - expect(LoginServiceExports.LoginService.isLoggedIn()).toBe(false); - }); + LoginShared.setupSharedTests(); it("should update profile icon after login", async function () { // Setup basic user mock diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index cda4d938b8..0637a1df34 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -95,7 +95,7 @@ define(function (require, exports, module) { "Profile button to be available", 3000 ); - LoginShared.setup(testWindow, LoginServiceExports); + LoginShared.setup(testWindow, LoginServiceExports, setupProUserMock, performFullLoginFlow); VIEW_TRIAL_DAYS_LEFT = LoginShared.VIEW_TRIAL_DAYS_LEFT; VIEW_PHOENIX_PRO = LoginShared.VIEW_PHOENIX_PRO; VIEW_PHOENIX_FREE = LoginShared.VIEW_PHOENIX_FREE; @@ -306,19 +306,7 @@ define(function (require, exports, module) { await cleanupTrialState(); }); - it("should complete login and logout flow", async function () { - // Setup basic user mock - setupProUserMock(false); - - // Perform full login flow - await performFullLoginFlow(); - expect(LoginServiceExports.LoginService.isLoggedIn()).toBe(true); - - // Perform full logout flow - await performFullLogoutFlow(); - expect(LoginServiceExports.LoginService.isLoggedIn()).toBe(false); - verifyProfileIconBlanked(); - }); + LoginShared.setupSharedTests(); it("should open browser and copy validation code", async function () { // Setup basic user mock diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index 68bcf7892d..613ec2236a 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -1,8 +1,8 @@ -/*global expect, awaitsFor*/ +/*global expect, it, awaitsFor*/ define(function (require, exports, module) { - let testWindow, LoginServiceExports; + let testWindow, LoginServiceExports, setupProUserMock, performFullLoginFlow; async function setupTrialState(daysRemaining) { const PromotionExports = testWindow._test_promo_login_exports; @@ -169,9 +169,28 @@ define(function (require, exports, module) { verifyProfileIconBlanked(); } - function setup(_testWindow, _LoginServiceExports) { + function setup(_testWindow, _LoginServiceExports, _setupProUserMock, _performFullLoginFlow) { testWindow = _testWindow; LoginServiceExports = _LoginServiceExports; + setupProUserMock = _setupProUserMock; + performFullLoginFlow = _performFullLoginFlow; + } + + function setupSharedTests() { + + it("should complete login and logout flow", async function () { + // Setup basic user mock + setupProUserMock(false); + + // Perform full login flow + await performFullLoginFlow(); + expect(LoginServiceExports.LoginService.isLoggedIn()).toBe(true); + + // Perform full logout flow + await performFullLogoutFlow(); + expect(LoginServiceExports.LoginService.isLoggedIn()).toBe(false); + verifyProfileIconBlanked(); + }); } exports.setup = setup; @@ -188,4 +207,7 @@ define(function (require, exports, module) { exports.VIEW_PHOENIX_FREE = VIEW_PHOENIX_FREE; exports.SIGNIN_POPUP = SIGNIN_POPUP; exports.PROFILE_POPUP = PROFILE_POPUP; + + // test runner + exports.setupSharedTests = setupSharedTests; }); From f1be751c3503ff3284f1a8435a760fdc3f7b9518 Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 18:10:10 +0530 Subject: [PATCH 09/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 20 ----------------- test/spec/login-desktop-integ-test.js | 32 --------------------------- test/spec/login-shared.js | 31 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 52 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index ba5faff77a..0e231b67fa 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -292,26 +292,6 @@ define(function (require, exports, module) { LoginShared.setupSharedTests(); - it("should update profile icon after login", async function () { - // Setup basic user mock - setupProUserMock(false); - - // Verify initial state - verifyProfileIconBlanked(); - - // Perform login - await performFullLoginFlow(); - - // Verify profile icon updated with user initials - const $profileIcon = testWindow.$("#user-profile-button"); - const updatedContent = $profileIcon.html(); - expect(updatedContent).toContain('svg'); - expect(updatedContent).toContain('TU'); - - // Logout for cleanup - await performFullLogoutFlow(); - }); - it("should show correct popup states", async function () { // Setup basic user mock setupProUserMock(false); diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index 0637a1df34..a79ac98a99 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -352,38 +352,6 @@ define(function (require, exports, module) { expect(capturedBrowserURL).toContain('test-session-123'); }); - it("should update profile icon after login", async function () { - // Setup basic user mock - setupProUserMock(false); - - // Verify initial state - const $profileIcon = testWindow.$("#user-profile-button"); - const initialContent = $profileIcon.html(); - expect(initialContent).not.toContain('TU'); - - // Perform login - await performFullLoginFlow(); - - // Wait for profile icon to update - await awaitsFor( - function () { - const $profileIcon = testWindow.$("#user-profile-button"); - const profileIconContent = $profileIcon.html(); - return profileIconContent && profileIconContent.includes('TU'); - }, - "profile icon to contain user initials", - 5000 - ); - - // Verify profile icon updated with user initials - const updatedContent = $profileIcon.html(); - expect(updatedContent).toContain('svg'); - expect(updatedContent).toContain('TU'); - - // Logout for cleanup - await performFullLogoutFlow(); - }); - it("should show correct popup states", async function () { // Setup basic user mock setupProUserMock(false); diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index 613ec2236a..917a8d6f07 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -191,6 +191,37 @@ define(function (require, exports, module) { expect(LoginServiceExports.LoginService.isLoggedIn()).toBe(false); verifyProfileIconBlanked(); }); + + it("should update profile icon after login", async function () { + // Setup basic user mock + setupProUserMock(false); + + // Verify initial state + verifyProfileIconBlanked(); + + // Perform login + await performFullLoginFlow(); + + // Wait for profile icon to update + await awaitsFor( + function () { + const $profileIcon = testWindow.$("#user-profile-button"); + const profileIconContent = $profileIcon.html(); + return profileIconContent && profileIconContent.includes('TU'); + }, + "profile icon to contain user initials", + 5000 + ); + + // Verify profile icon updated with user initials + const $profileIcon = testWindow.$("#user-profile-button"); + const updatedContent = $profileIcon.html(); + expect(updatedContent).toContain('svg'); + expect(updatedContent).toContain('TU'); + + // Logout for cleanup + await performFullLogoutFlow(); + }); } exports.setup = setup; From 1cec53a5271329b2d26c63844caf5b22c010614d Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 18:11:22 +0530 Subject: [PATCH 10/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 53 --------------------------- test/spec/login-desktop-integ-test.js | 53 --------------------------- test/spec/login-shared.js | 53 +++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 106 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index 0e231b67fa..5edac97b1c 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -292,59 +292,6 @@ define(function (require, exports, module) { LoginShared.setupSharedTests(); - it("should show correct popup states", async function () { - // Setup basic user mock - setupProUserMock(false); - - const $profileButton = testWindow.$("#user-profile-button"); - - // Test initial state - should show signin popup - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - - let popupContent = testWindow.$('.profile-popup'); - const signInButton = popupContent.find('#phoenix-signin-btn'); - const signOutButton = popupContent.find('#phoenix-signout-btn'); - - expect(signInButton.length).toBe(1); - expect(signOutButton.length).toBe(0); - - // Close popup - $profileButton.trigger('click'); - - // Perform login - await performFullLoginFlow(); - - // Test logged in state - should show profile popup - $profileButton.trigger('click'); - await popupToAppear(PROFILE_POPUP); - - popupContent = testWindow.$('.profile-popup'); - const newSignInButton = popupContent.find('#phoenix-signin-btn'); - const newSignOutButton = popupContent.find('#phoenix-signout-btn'); - - expect(newSignInButton.length).toBe(0); - expect(newSignOutButton.length).toBe(1); - - // Close popup and logout for cleanup - $profileButton.trigger('click'); - await performFullLogoutFlow(); - - // Test final state - should be back to signin popup - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - - popupContent = testWindow.$('.profile-popup'); - const finalSignInButton = popupContent.find('#phoenix-signin-btn'); - const finalSignOutButton = popupContent.find('#phoenix-signout-btn'); - - expect(finalSignInButton.length).toBe(1); - expect(finalSignOutButton.length).toBe(0); - - // Close popup - $profileButton.trigger('click'); - }); - it("should show pro branding for user with pro subscription (expired trial)", async function () { console.log("llgT: Starting browser pro user with expired trial test"); diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index a79ac98a99..f0855a1535 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -352,59 +352,6 @@ define(function (require, exports, module) { expect(capturedBrowserURL).toContain('test-session-123'); }); - it("should show correct popup states", async function () { - // Setup basic user mock - setupProUserMock(false); - - const $profileButton = testWindow.$("#user-profile-button"); - - // Test initial state - should show signin popup - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - - let popupContent = testWindow.$('.profile-popup'); - const signInButton = popupContent.find('#phoenix-signin-btn'); - const signOutButton = popupContent.find('#phoenix-signout-btn'); - - expect(signInButton.length).toBe(1); - expect(signOutButton.length).toBe(0); - - // Close popup - $profileButton.trigger('click'); - - // Perform login - await performFullLoginFlow(); - - // Test logged in state - should show profile popup - $profileButton.trigger('click'); - await popupToAppear(PROFILE_POPUP); - - popupContent = testWindow.$('.profile-popup'); - const newSignInButton = popupContent.find('#phoenix-signin-btn'); - const newSignOutButton = popupContent.find('#phoenix-signout-btn'); - - expect(newSignInButton.length).toBe(0); - expect(newSignOutButton.length).toBe(1); - - // Close popup and logout for cleanup - $profileButton.trigger('click'); - await performFullLogoutFlow(); - - // Test final state - should be back to signin popup - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - - popupContent = testWindow.$('.profile-popup'); - const finalSignInButton = popupContent.find('#phoenix-signin-btn'); - const finalSignOutButton = popupContent.find('#phoenix-signout-btn'); - - expect(finalSignInButton.length).toBe(1); - expect(finalSignOutButton.length).toBe(0); - - // Close popup - $profileButton.trigger('click'); - }); - it("should show pro branding for user with pro subscription (expired trial)", async function () { console.log("llgT: Starting desktop pro user with expired trial test"); diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index 917a8d6f07..4802360161 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -222,6 +222,59 @@ define(function (require, exports, module) { // Logout for cleanup await performFullLogoutFlow(); }); + + it("should show correct popup states", async function () { + // Setup basic user mock + setupProUserMock(false); + + const $profileButton = testWindow.$("#user-profile-button"); + + // Test initial state - should show signin popup + $profileButton.trigger('click'); + await popupToAppear(SIGNIN_POPUP); + + let popupContent = testWindow.$('.profile-popup'); + const signInButton = popupContent.find('#phoenix-signin-btn'); + const signOutButton = popupContent.find('#phoenix-signout-btn'); + + expect(signInButton.length).toBe(1); + expect(signOutButton.length).toBe(0); + + // Close popup + $profileButton.trigger('click'); + + // Perform login + await performFullLoginFlow(); + + // Test logged in state - should show profile popup + $profileButton.trigger('click'); + await popupToAppear(PROFILE_POPUP); + + popupContent = testWindow.$('.profile-popup'); + const newSignInButton = popupContent.find('#phoenix-signin-btn'); + const newSignOutButton = popupContent.find('#phoenix-signout-btn'); + + expect(newSignInButton.length).toBe(0); + expect(newSignOutButton.length).toBe(1); + + // Close popup and logout for cleanup + $profileButton.trigger('click'); + await performFullLogoutFlow(); + + // Test final state - should be back to signin popup + $profileButton.trigger('click'); + await popupToAppear(SIGNIN_POPUP); + + popupContent = testWindow.$('.profile-popup'); + const finalSignInButton = popupContent.find('#phoenix-signin-btn'); + const finalSignOutButton = popupContent.find('#phoenix-signout-btn'); + + expect(finalSignInButton.length).toBe(1); + expect(finalSignOutButton.length).toBe(0); + + // Close popup + $profileButton.trigger('click'); + }); } exports.setup = setup; From 47a0165a40f5049500c6994facea95fa989f8742 Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 17 Sep 2025 18:14:29 +0530 Subject: [PATCH 11/11] refactor: login desktop and browser tests common code --- test/spec/login-browser-integ-test.js | 157 ------------------------- test/spec/login-desktop-integ-test.js | 159 +------------------------- test/spec/login-shared.js | 157 +++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 315 deletions(-) diff --git a/test/spec/login-browser-integ-test.js b/test/spec/login-browser-integ-test.js index 5edac97b1c..f058a5e3d6 100644 --- a/test/spec/login-browser-integ-test.js +++ b/test/spec/login-browser-integ-test.js @@ -291,163 +291,6 @@ define(function (require, exports, module) { }); LoginShared.setupSharedTests(); - - it("should show pro branding for user with pro subscription (expired trial)", async function () { - console.log("llgT: Starting browser pro user with expired trial test"); - - // Setup: Pro subscription + expired trial - setupProUserMock(true); - await setupExpiredTrial(); - - // Verify initial state (no pro branding) - await verifyProBranding(false, "no pro branding to start with"); - - // Perform login - await performFullLoginFlow(); - await verifyProBranding(true, "pro branding to appear after pro user login"); - - // Check profile popup shows pro status (not trial) - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - - // Wait for profile popup to show "phoenix pro " - await verifyProfilePopupContent(VIEW_PHOENIX_PRO, "pro user profile popup"); - - // Close popup - $profileButton.trigger('click'); - - // Perform logout - await performFullLogoutFlow(); - - // For user with pro subscription + expired trial: - // After logout, pro branding should disappear because: - // 1. No server entitlements (logged out) - // 2. Trial is expired (0 days remaining) - await verifyProBranding(false, "Pro branding to disappear after logout"); - }); - - it("should show trial branding for user without pro subscription (active trial)", async function () { - console.log("llgT: Starting browser trial user test"); - - // Setup: No pro subscription + active trial (15 days) - setupProUserMock(false); - await setupTrialState(15); - - // Verify initial state shows pro branding due to trial - await verifyProBranding(true, "Trial branding to appear initially"); - - // Perform login - await performFullLoginFlow(); - - // Verify pro branding remains after login - await verifyProBranding(true, "after trial user login"); - - // Check profile popup shows trial status - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - await popupToAppear(PROFILE_POPUP); - await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, - "trial user profile popup for logged in user"); - - // Close popup - $profileButton.trigger('click'); - - // Perform logout - await performFullLogoutFlow(); - - // Verify pro branding remains after logout (trial continues) - await verifyProBranding(true, "Trial branding to remain after logout"); - - // Check profile popup still shows trial status - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, - "trial user profile popup for logged out user"); - - // Close popup - $profileButton.trigger('click'); - }); - - it("should prioritize pro subscription over trial in profile popup", async function () { - console.log("llgT: Starting browser trial user with pro subscription test"); - - // Setup: Pro subscription + active trial - setupProUserMock(true); - await setupTrialState(10); - - // Perform login - await performFullLoginFlow(); - - // Verify pro branding appears - await verifyProBranding(true, "Pro branding to appear for pro user"); - - // Check profile popup shows pro status (not trial text) - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - await popupToAppear(PROFILE_POPUP); - - // Should show pro, not trial, since user has paid subscription - await verifyProfilePopupContent(VIEW_PHOENIX_PRO, - "pro+trial user profile should not show trial branding"); - - // Close popup - $profileButton.trigger('click'); - - // Perform logout - await performFullLogoutFlow(); - - // Verify pro branding remains due to trial (even though subscription is gone) - await verifyProBranding(true, "Pro branding should remain after logout as trial user"); - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, - "trial user profile popup for logged out user"); - - // Close popup - $profileButton.trigger('click'); - }); - - it("should show free branding for user without pro subscription (expired trial)", async function () { - console.log("llgT: Starting desktop trial user test"); - - // Setup: No pro subscription + active trial (15 days) - setupProUserMock(false); - await setupExpiredTrial(); - - // Verify initial state (no pro branding) - await verifyProBranding(false, "no pro branding to start with"); - - // Perform login - await performFullLoginFlow(); - - // Verify pro branding remains after login - await verifyProBranding(false, "after trial free user login"); - - // Check profile popup shows free plan status - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - await popupToAppear(PROFILE_POPUP); - await verifyProfilePopupContent(VIEW_PHOENIX_FREE, - "free plan user profile popup for logged in user"); - - // Close popup - $profileButton.trigger('click'); - - // Perform logout - await performFullLogoutFlow(); - - // Verify pro branding remains after logout (trial continues) - await verifyProBranding(false, "Trial branding to remain after logout"); - - // Check profile popup still shows free plan status as trial expired - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - // not logged in user, we wont show free plan tag as base editor is always free. - expect(testWindow.$(`.profile-popup .trial-plan-info`).length).toBe(0); - - // Close popup - $profileButton.trigger('click'); - }); }); }); }); diff --git a/test/spec/login-desktop-integ-test.js b/test/spec/login-desktop-integ-test.js index f0855a1535..3184733d7b 100644 --- a/test/spec/login-desktop-integ-test.js +++ b/test/spec/login-desktop-integ-test.js @@ -306,8 +306,6 @@ define(function (require, exports, module) { await cleanupTrialState(); }); - LoginShared.setupSharedTests(); - it("should open browser and copy validation code", async function () { // Setup basic user mock setupProUserMock(false); @@ -352,162 +350,7 @@ define(function (require, exports, module) { expect(capturedBrowserURL).toContain('test-session-123'); }); - it("should show pro branding for user with pro subscription (expired trial)", async function () { - console.log("llgT: Starting desktop pro user with expired trial test"); - - // Setup: Pro subscription + expired trial - setupProUserMock(true); - await setupExpiredTrial(); - - // Verify initial state (no pro branding) - await verifyProBranding(false, "no pro branding to start with"); - - // Perform login - await performFullLoginFlow(); - await verifyProBranding(true, "pro branding to appear after pro user login"); - - // Check profile popup shows pro status (not trial) - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - - // Wait for profile popup to show "phoenix pro " - await verifyProfilePopupContent(VIEW_PHOENIX_PRO, "pro user profile popup"); - - // Close popup - $profileButton.trigger('click'); - - // Perform logout - await performFullLogoutFlow(); - - // For user with pro subscription + expired trial: - // After logout, pro branding should disappear because: - // 1. No server entitlements (logged out) - // 2. Trial is expired (0 days remaining) - await verifyProBranding(false, "Pro branding to disappear after logout"); - }); - - it("should show trial branding for user without pro subscription (active trial)", async function () { - console.log("llgT: Starting desktop trial user test"); - - // Setup: No pro subscription + active trial (15 days) - setupProUserMock(false); - await setupTrialState(15); - - // Verify initial state shows pro branding due to trial - await verifyProBranding(true, "Trial branding to appear initially"); - - // Perform login - await performFullLoginFlow(); - - // Verify pro branding remains after login - await verifyProBranding(true, "after trial user login"); - - // Check profile popup shows trial status - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - await popupToAppear(PROFILE_POPUP); - await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, - "trial user profile popup for logged in user"); - - // Close popup - $profileButton.trigger('click'); - - // Perform logout - await performFullLogoutFlow(); - - // Verify pro branding remains after logout (trial continues) - await verifyProBranding(true, "Trial branding to remain after logout"); - - // Check profile popup still shows trial status - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, - "trial user profile popup for logged out user"); - - // Close popup - $profileButton.trigger('click'); - }); - - it("should prioritize pro subscription over trial in profile popup", async function () { - console.log("llgT: Starting desktop trial user with pro subscription test"); - - // Setup: Pro subscription + active trial - setupProUserMock(true); - await setupTrialState(10); - - // Perform login - await performFullLoginFlow(); - - // Verify pro branding appears - await verifyProBranding(true, "Pro branding to appear for pro user"); - - // Check profile popup shows pro status (not trial text) - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - await popupToAppear(PROFILE_POPUP); - - // Should show pro, not trial, since user has paid subscription - await verifyProfilePopupContent(VIEW_PHOENIX_PRO, - "pro+trial user profile should not show trial branding"); - - // Close popup - $profileButton.trigger('click'); - - // Perform logout - await performFullLogoutFlow(); - - // Verify pro branding remains due to trial (even though subscription is gone) - await verifyProBranding(true, "Pro branding should remain after logout as trial user"); - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, - "trial user profile popup for logged out user"); - - // Close popup - $profileButton.trigger('click'); - }); - - it("should show free branding for user without pro subscription (expired trial)", async function () { - console.log("llgT: Starting desktop trial user test"); - - // Setup: No pro subscription + active trial (15 days) - setupProUserMock(false); - await setupExpiredTrial(); - - // Verify initial state (no pro branding) - await verifyProBranding(false, "no pro branding to start with"); - - // Perform login - await performFullLoginFlow(); - - // Verify pro branding remains after login - await verifyProBranding(false, "after trial free user login"); - - // Check profile popup shows free plan status - const $profileButton = testWindow.$("#user-profile-button"); - $profileButton.trigger('click'); - await popupToAppear(PROFILE_POPUP); - await verifyProfilePopupContent(VIEW_PHOENIX_FREE, - "free plan user profile popup for logged in user"); - - // Close popup - $profileButton.trigger('click'); - - // Perform logout - await performFullLogoutFlow(); - - // Verify pro branding remains after logout (trial continues) - await verifyProBranding(false, "Trial branding to remain after logout"); - - // Check profile popup still shows free plan status as trial expired - $profileButton.trigger('click'); - await popupToAppear(SIGNIN_POPUP); - // not logged in user, we wont show free plan tag as base editor is always free. - expect(testWindow.$(`.profile-popup .trial-plan-info`).length).toBe(0); - - // Close popup - $profileButton.trigger('click'); - }); + LoginShared.setupSharedTests(); }); }); }); diff --git a/test/spec/login-shared.js b/test/spec/login-shared.js index 4802360161..ca8842c765 100644 --- a/test/spec/login-shared.js +++ b/test/spec/login-shared.js @@ -275,6 +275,163 @@ define(function (require, exports, module) { // Close popup $profileButton.trigger('click'); }); + + it("should show pro branding for user with pro subscription (expired trial)", async function () { + console.log("llgT: Starting pro user with expired trial test"); + + // Setup: Pro subscription + expired trial + setupProUserMock(true); + await setupExpiredTrial(); + + // Verify initial state (no pro branding) + await verifyProBranding(false, "no pro branding to start with"); + + // Perform login + await performFullLoginFlow(); + await verifyProBranding(true, "pro branding to appear after pro user login"); + + // Check profile popup shows pro status (not trial) + const $profileButton = testWindow.$("#user-profile-button"); + $profileButton.trigger('click'); + + // Wait for profile popup to show "phoenix pro " + await verifyProfilePopupContent(VIEW_PHOENIX_PRO, "pro user profile popup"); + + // Close popup + $profileButton.trigger('click'); + + // Perform logout + await performFullLogoutFlow(); + + // For user with pro subscription + expired trial: + // After logout, pro branding should disappear because: + // 1. No server entitlements (logged out) + // 2. Trial is expired (0 days remaining) + await verifyProBranding(false, "Pro branding to disappear after logout"); + }); + + it("should show trial branding for user without pro subscription (active trial)", async function () { + console.log("llgT: Starting trial user test"); + + // Setup: No pro subscription + active trial (15 days) + setupProUserMock(false); + await setupTrialState(15); + + // Verify initial state shows pro branding due to trial + await verifyProBranding(true, "Trial branding to appear initially"); + + // Perform login + await performFullLoginFlow(); + + // Verify pro branding remains after login + await verifyProBranding(true, "after trial user login"); + + // Check profile popup shows trial status + const $profileButton = testWindow.$("#user-profile-button"); + $profileButton.trigger('click'); + await popupToAppear(PROFILE_POPUP); + await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, + "trial user profile popup for logged in user"); + + // Close popup + $profileButton.trigger('click'); + + // Perform logout + await performFullLogoutFlow(); + + // Verify pro branding remains after logout (trial continues) + await verifyProBranding(true, "Trial branding to remain after logout"); + + // Check profile popup still shows trial status + $profileButton.trigger('click'); + await popupToAppear(SIGNIN_POPUP); + await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, + "trial user profile popup for logged out user"); + + // Close popup + $profileButton.trigger('click'); + }); + + it("should prioritize pro subscription over trial in profile popup", async function () { + console.log("llgT: Starting trial user with pro subscription test"); + + // Setup: Pro subscription + active trial + setupProUserMock(true); + await setupTrialState(10); + + // Perform login + await performFullLoginFlow(); + + // Verify pro branding appears + await verifyProBranding(true, "Pro branding to appear for pro user"); + + // Check profile popup shows pro status (not trial text) + const $profileButton = testWindow.$("#user-profile-button"); + $profileButton.trigger('click'); + await popupToAppear(PROFILE_POPUP); + + // Should show pro, not trial, since user has paid subscription + await verifyProfilePopupContent(VIEW_PHOENIX_PRO, + "pro+trial user profile should not show trial branding"); + + // Close popup + $profileButton.trigger('click'); + + // Perform logout + await performFullLogoutFlow(); + + // Verify pro branding remains due to trial (even though subscription is gone) + await verifyProBranding(true, "Pro branding should remain after logout as trial user"); + $profileButton.trigger('click'); + await popupToAppear(SIGNIN_POPUP); + await verifyProfilePopupContent(VIEW_TRIAL_DAYS_LEFT, + "trial user profile popup for logged out user"); + + // Close popup + $profileButton.trigger('click'); + }); + + it("should show free branding for user without pro subscription (expired trial)", async function () { + console.log("llgT: Starting desktop trial user test"); + + // Setup: No pro subscription + active trial (15 days) + setupProUserMock(false); + await setupExpiredTrial(); + + // Verify initial state (no pro branding) + await verifyProBranding(false, "no pro branding to start with"); + + // Perform login + await performFullLoginFlow(); + + // Verify pro branding remains after login + await verifyProBranding(false, "after trial free user login"); + + // Check profile popup shows free plan status + const $profileButton = testWindow.$("#user-profile-button"); + $profileButton.trigger('click'); + await popupToAppear(PROFILE_POPUP); + await verifyProfilePopupContent(VIEW_PHOENIX_FREE, + "free plan user profile popup for logged in user"); + + // Close popup + $profileButton.trigger('click'); + + // Perform logout + await performFullLogoutFlow(); + + // Verify pro branding remains after logout (trial continues) + await verifyProBranding(false, "Trial branding to remain after logout"); + + // Check profile popup still shows free plan status as trial expired + $profileButton.trigger('click'); + await popupToAppear(SIGNIN_POPUP); + // not logged in user, we wont show free plan tag as base editor is always free. + expect(testWindow.$(`.profile-popup .trial-plan-info`).length).toBe(0); + + // Close popup + $profileButton.trigger('click'); + }); } exports.setup = setup;