Merge pull request #15798 from overleaf/mj-features-page-teardown

[web] Tear down features-page split test

GitOrigin-RevId: 346064bea8775033d226f4405843717b380085fd
This commit is contained in:
Mathias Jakobsen 2023-11-20 10:24:16 +00:00 committed by Copybot
parent 9ca43ebc4e
commit 7c8014d791
16 changed files with 41 additions and 230 deletions

View file

@ -81,10 +81,7 @@ function getWebpackAssets(entrypoint, section) {
module.exports = function (webRouter, privateApiRouter, publicApiRouter) { module.exports = function (webRouter, privateApiRouter, publicApiRouter) {
webRouter.use( webRouter.use(
expressify( expressify(
SplitTestMiddleware.loadAssignmentsInLocals([ SplitTestMiddleware.loadAssignmentsInLocals(['design-system-updates'])
'design-system-updates',
'features-page',
])
) )
) )

View file

@ -1,5 +1,3 @@
- var featuresPageVariant = splitTestVariants && splitTestVariants['features-page']
footer.fat-footer.hidden-print footer.fat-footer.hidden-print
.fat-footer-container(role="navigation" aria-label=translate('footer_navigation')) .fat-footer-container(role="navigation" aria-label=translate('footer_navigation'))
.fat-footer-sections(class=hideFatFooter ? 'hidden' : undefined) .fat-footer-sections(class=hideFatFooter ? 'hidden' : undefined)
@ -43,10 +41,7 @@ footer.fat-footer.hidden-print
ul.list-unstyled ul.list-unstyled
li li
if !featuresPageVariant || featuresPageVariant === 'default' a(href="/learn/how-to/Overleaf_premium_features") #{translate('premium_features')}
a(href="/learn/how-to/Overleaf_premium_features" event-tracking="features-page-link" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={splitTest: "features-page", splitTestVariant: "default", locationInPage: "footer"}) #{translate('premium_features')}
else
a(href="/about/features-overview" event-tracking="features-page-link" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={splitTest: "features-page", splitTestVariant: "new", locationInPage: "footer"}) #{translate('features')}
li li
a(href="/user/subscription/plans?itm_referrer=footer-for-indv-groups") !{translate('for_individuals_and_groups')} a(href="/user/subscription/plans?itm_referrer=footer-for-indv-groups") !{translate('for_individuals_and_groups')}
li li

View file

@ -30,7 +30,6 @@ nav.navbar.navbar-default.navbar-main
- var canDisplayAdminRedirect = canRedirectToAdminDomain() - var canDisplayAdminRedirect = canRedirectToAdminDomain()
- var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement))) - var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement)))
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu - var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
- var featuresPageVariant = splitTestVariants && splitTestVariants['features-page']
if (typeof(suppressNavbarRight) == "undefined") if (typeof(suppressNavbarRight) == "undefined")
.navbar-collapse.collapse(data-ol-navbar-main-collapse) .navbar-collapse.collapse(data-ol-navbar-main-collapse)
@ -101,15 +100,14 @@ nav.navbar.navbar-default.navbar-main
else else
li li
if child.url if child.url
if !child.splitTest || child.splitTest && child.splitTest === 'features-page' && child.splitTestVariant === featuresPageVariant a(
a( href=child.url,
href=child.url, class=child.class,
class=child.class, event-tracking=child.event
event-tracking=child.event event-tracking-mb="true"
event-tracking-mb="true" event-tracking-trigger="click"
event-tracking-trigger="click" event-segmentation=child.eventSegmentation
event-segmentation=child.eventSegmentation ) !{translate(child.text)}
) !{translate(child.text)}
else else
| !{translate(child.text)} | !{translate(child.text)}
else else

View file

@ -15,7 +15,6 @@ nav.navbar.navbar-default.navbar-main
- var canDisplayAdminRedirect = canRedirectToAdminDomain() - var canDisplayAdminRedirect = canRedirectToAdminDomain()
- var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement))) - var canDisplaySplitTestMenu = hasFeature('saas') && (canDisplayAdminMenu || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement)))
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu - var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
- var featuresPageVariant = splitTestVariants && splitTestVariants['features-page']
if (typeof(suppressNavbarRight) == "undefined") if (typeof(suppressNavbarRight) == "undefined")
.navbar-collapse.collapse(collapse="navCollapsed") .navbar-collapse.collapse(collapse="navCollapsed")
@ -76,15 +75,14 @@ nav.navbar.navbar-default.navbar-main
else else
li li
if child.url if child.url
if !child.splitTest || child.splitTest && child.splitTest === 'features-page' && child.splitTestVariant === featuresPageVariant a(
a( href=child.url,
href=child.url, class=child.class,
class=child.class, event-tracking=child.event
event-tracking=child.event event-tracking-mb="true"
event-tracking-mb="true" event-tracking-trigger="click"
event-tracking-trigger="click" event-segmentation=child.eventSegmentation
event-segmentation=child.eventSegmentation ) !{translate(child.text)}
) !{translate(child.text)}
else else
| !{translate(child.text)} | !{translate(child.text)}
else else

View file

@ -404,7 +404,6 @@
"get_collaborative_benefits": "", "get_collaborative_benefits": "",
"get_discounted_plan": "", "get_discounted_plan": "",
"get_most_subscription_by_checking_features": "", "get_most_subscription_by_checking_features": "",
"get_most_subscription_by_checking_premium_features": "",
"git": "", "git": "",
"git_authentication_token": "", "git_authentication_token": "",
"git_authentication_token_create_modal_info_1": "", "git_authentication_token_create_modal_info_1": "",

View file

@ -1,8 +1,6 @@
import { useTranslation, Trans } from 'react-i18next' import { useTranslation, Trans } from 'react-i18next'
import { CommonsPlanSubscription } from '../../../../../../types/project/dashboard/subscription' import { CommonsPlanSubscription } from '../../../../../../types/project/dashboard/subscription'
import Tooltip from '../../../../shared/components/tooltip' import Tooltip from '../../../../shared/components/tooltip'
import getMeta from '../../../../utils/meta'
import * as eventTracking from '../../../../infrastructure/event-tracking'
type CommonsPlanProps = Pick< type CommonsPlanProps = Pick<
CommonsPlanSubscription, CommonsPlanSubscription,
@ -18,14 +16,6 @@ function CommonsPlan({
const currentPlanLabel = ( const currentPlanLabel = (
<Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} /> <Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} />
) )
const featuresPageVariant = getMeta('ol-splitTestVariants')?.['features-page']
function handleLinkClick() {
eventTracking.sendMB('features-page-link', {
splitTest: 'features-page',
splitTestVariant: featuresPageVariant,
})
}
return ( return (
<> <>
@ -38,11 +28,7 @@ function CommonsPlan({
id="commons-plan" id="commons-plan"
overlayProps={{ placement: 'bottom' }} overlayProps={{ placement: 'bottom' }}
> >
<a <a href={featuresPageURL} className="current-plan-label hidden-xs">
href={featuresPageURL}
className="current-plan-label hidden-xs"
onClick={handleLinkClick}
>
{currentPlanLabel} <span className="info-badge" /> {currentPlanLabel} <span className="info-badge" />
</a> </a>
</Tooltip> </Tooltip>

View file

@ -20,11 +20,7 @@ function CurrentPlanWidget() {
const isGroupPlan = type === 'group' const isGroupPlan = type === 'group'
const isCommonsPlan = type === 'commons' const isCommonsPlan = type === 'commons'
const newFeaturesPageVariant = const featuresPageURL = '/learn/how-to/Overleaf_premium_features'
getMeta('ol-splitTestVariants')?.['features-page'] === 'new'
const featuresPageURL = newFeaturesPageVariant
? '/about/features-overview'
: '/learn/how-to/Overleaf_premium_features'
let currentPlan let currentPlan

View file

@ -3,7 +3,6 @@ import { Button } from 'react-bootstrap'
import { FreePlanSubscription } from '../../../../../../types/project/dashboard/subscription' import { FreePlanSubscription } from '../../../../../../types/project/dashboard/subscription'
import Tooltip from '../../../../shared/components/tooltip' import Tooltip from '../../../../shared/components/tooltip'
import * as eventTracking from '../../../../infrastructure/event-tracking' import * as eventTracking from '../../../../infrastructure/event-tracking'
import getMeta from '../../../../utils/meta'
type FreePlanProps = Pick<FreePlanSubscription, 'featuresPageURL'> type FreePlanProps = Pick<FreePlanSubscription, 'featuresPageURL'>
@ -22,14 +21,6 @@ function FreePlan({ featuresPageURL }: FreePlanProps) {
}) })
} }
const featuresPageVariant = getMeta('ol-splitTestVariants')?.['features-page']
function handleLinkClick() {
eventTracking.sendMB('features-page-link', {
splitTest: 'features-page',
splitTestVariant: featuresPageVariant,
})
}
return ( return (
<> <>
<span className="current-plan-label visible-xs">{currentPlanLabel}</span> <span className="current-plan-label visible-xs">{currentPlanLabel}</span>
@ -38,11 +29,7 @@ function FreePlan({ featuresPageURL }: FreePlanProps) {
id="free-plan" id="free-plan"
overlayProps={{ placement: 'bottom' }} overlayProps={{ placement: 'bottom' }}
> >
<a <a href={featuresPageURL} className="current-plan-label hidden-xs">
href={featuresPageURL}
className="current-plan-label hidden-xs"
onClick={handleLinkClick}
>
{currentPlanLabel} <span className="info-badge" /> {currentPlanLabel} <span className="info-badge" />
</a> </a>
</Tooltip>{' '} </Tooltip>{' '}

View file

@ -1,8 +1,6 @@
import { useTranslation, Trans } from 'react-i18next' import { useTranslation, Trans } from 'react-i18next'
import { GroupPlanSubscription } from '../../../../../../types/project/dashboard/subscription' import { GroupPlanSubscription } from '../../../../../../types/project/dashboard/subscription'
import Tooltip from '../../../../shared/components/tooltip' import Tooltip from '../../../../shared/components/tooltip'
import getMeta from '../../../../utils/meta'
import * as eventTracking from '../../../../infrastructure/event-tracking'
type GroupPlanProps = Pick< type GroupPlanProps = Pick<
GroupPlanSubscription, GroupPlanSubscription,
@ -33,14 +31,6 @@ function GroupPlan({
<Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} /> <Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} />
) )
const featuresPageVariant = getMeta('ol-splitTestVariants')?.['features-page']
function handleLinkClick() {
eventTracking.sendMB('features-page-link', {
splitTest: 'features-page',
splitTestVariant: featuresPageVariant,
})
}
return ( return (
<> <>
<span className="current-plan-label visible-xs">{currentPlanLabel}</span> <span className="current-plan-label visible-xs">{currentPlanLabel}</span>
@ -56,11 +46,7 @@ function GroupPlan({
id="group-plan" id="group-plan"
overlayProps={{ placement: 'bottom' }} overlayProps={{ placement: 'bottom' }}
> >
<a <a href={featuresPageURL} className="current-plan-label hidden-xs">
href={featuresPageURL}
className="current-plan-label hidden-xs"
onClick={handleLinkClick}
>
{currentPlanLabel} <span className="info-badge" /> {currentPlanLabel} <span className="info-badge" />
</a> </a>
</Tooltip> </Tooltip>

View file

@ -1,8 +1,6 @@
import { useTranslation, Trans } from 'react-i18next' import { useTranslation, Trans } from 'react-i18next'
import { IndividualPlanSubscription } from '../../../../../../types/project/dashboard/subscription' import { IndividualPlanSubscription } from '../../../../../../types/project/dashboard/subscription'
import Tooltip from '../../../../shared/components/tooltip' import Tooltip from '../../../../shared/components/tooltip'
import getMeta from '../../../../utils/meta'
import * as eventTracking from '../../../../infrastructure/event-tracking'
type IndividualPlanProps = Pick< type IndividualPlanProps = Pick<
IndividualPlanSubscription, IndividualPlanSubscription,
@ -32,14 +30,6 @@ function IndividualPlan({
<Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} /> <Trans i18nKey="premium_plan_label" components={{ b: <strong /> }} />
) )
const featuresPageVariant = getMeta('ol-splitTestVariants')?.['features-page']
function handleLinkClick() {
eventTracking.sendMB('features-page-link', {
splitTest: 'features-page',
splitTestVariant: featuresPageVariant,
})
}
return ( return (
<> <>
<span className="current-plan-label visible-xs">{currentPlanLabel}</span> <span className="current-plan-label visible-xs">{currentPlanLabel}</span>
@ -48,11 +38,7 @@ function IndividualPlan({
id="individual-plan" id="individual-plan"
overlayProps={{ placement: 'bottom' }} overlayProps={{ placement: 'bottom' }}
> >
<a <a href={featuresPageURL} className="current-plan-label hidden-xs">
href={featuresPageURL}
className="current-plan-label hidden-xs"
onClick={handleLinkClick}
>
{currentPlanLabel} <span className="info-badge" /> {currentPlanLabel} <span className="info-badge" />
</a> </a>
</Tooltip> </Tooltip>

View file

@ -1,46 +1,16 @@
import { Trans } from 'react-i18next' import { Trans } from 'react-i18next'
import getMeta from '../../../../utils/meta'
import * as eventTracking from '../../../../infrastructure/event-tracking'
function PremiumFeaturesLink() { function PremiumFeaturesLink() {
const featuresPageVariant =
getMeta('ol-splitTestVariants')?.['features-page'] || 'default'
function handleLinkClick() {
eventTracking.sendMB('features-page-link', {
splitTest: 'features-page',
splitTestVariant: featuresPageVariant,
})
}
const featuresPageLink = ( const featuresPageLink = (
// translation adds content // translation adds content
// eslint-disable-next-line jsx-a11y/anchor-has-content // eslint-disable-next-line jsx-a11y/anchor-has-content
<a <a href="/about/features-overview" />
href={
featuresPageVariant === 'new'
? '/about/features-overview'
: '/learn/how-to/Overleaf_premium_features'
}
onClick={handleLinkClick}
/>
) )
if (featuresPageVariant === 'new') {
return (
<p>
<Trans
i18nKey="get_most_subscription_by_checking_features"
components={[featuresPageLink]}
/>
</p>
)
}
return ( return (
<p> <p>
<Trans <Trans
i18nKey="get_most_subscription_by_checking_premium_features" i18nKey="get_most_subscription_by_checking_features"
components={[featuresPageLink]} components={[featuresPageLink]}
/> />
</p> </p>

View file

@ -652,7 +652,6 @@
"get_in_touch_having_problems": "<a href=\"__link__\">Get in touch with support</a> if youre having problems", "get_in_touch_having_problems": "<a href=\"__link__\">Get in touch with support</a> if youre having problems",
"get_involved": "Get involved", "get_involved": "Get involved",
"get_most_subscription_by_checking_features": "Get the most out of your __appName__ subscription by checking out <0>__appName__s features</0>.", "get_most_subscription_by_checking_features": "Get the most out of your __appName__ subscription by checking out <0>__appName__s features</0>.",
"get_most_subscription_by_checking_premium_features": "Get the most out of your __appName__ subscription by checking out the list of <0>__appName__s premium features</0>.",
"get_same_latex_setup": "With __appName__ you get the same LaTeX set-up wherever you go. By working with your colleagues and students on __appName__, you know that youre not going to hit any version inconsistencies or package conflicts.", "get_same_latex_setup": "With __appName__ you get the same LaTeX set-up wherever you go. By working with your colleagues and students on __appName__, you know that youre not going to hit any version inconsistencies or package conflicts.",
"get_started_now": "Get started now", "get_started_now": "Get started now",
"get_the_most_out_headline": "Get the most out of __appName__ with features such as:", "get_the_most_out_headline": "Get the most out of __appName__ with features such as:",

View file

@ -246,12 +246,7 @@ describe('<CurrentPlanWidget />', function () {
}) })
}) })
describe('features page split test', function () { describe('features page', function () {
const variants = [
{ name: 'default', link: '/learn/how-to/Overleaf_premium_features' },
{ name: 'new', link: '/about/features-overview' },
]
const plans = [ const plans = [
{ type: 'free' }, { type: 'free' },
{ {
@ -281,38 +276,21 @@ describe('<CurrentPlanWidget />', function () {
}, },
] ]
for (const variant of variants) { for (const plan of plans) {
describe(`${variant.name} variant`, function () { it(`links to features page on ${plan.type} plan`, function () {
beforeEach(function () { window.metaAttributesCache.set('ol-usersBestSubscription', {
window.metaAttributesCache.set('ol-splitTestVariants', { ...plan,
'features-page': variant.name,
})
})
afterEach(function () {
window.metaAttributesCache.delete('ol-splitTestVariants')
}) })
render(<CurrentPlanWidget />)
for (const plan of plans) { const links = screen.getAllByRole('link')
it(`links to ${variant.name} features page on ${plan.type} plan and sends analytics event`, function () { expect(links[0].getAttribute('href')).to.equal(
window.metaAttributesCache.set('ol-usersBestSubscription', { '/learn/how-to/Overleaf_premium_features'
...plan, )
})
render(<CurrentPlanWidget />)
const links = screen.getAllByRole('link') fireEvent.click(links[0])
expect(links[0].getAttribute('href')).to.equal(variant.link)
fireEvent.click(links[0]) window.metaAttributesCache.delete('ol-usersBestSubscription')
expect(sendMBSpy).to.be.calledOnce
expect(sendMBSpy).calledWith('features-page-link', {
splitTest: 'features-page',
splitTestVariant: variant.name,
page: '/',
})
window.metaAttributesCache.delete('ol-usersBestSubscription')
})
}
}) })
} }
}) })

View file

@ -1,62 +0,0 @@
import { expect } from 'chai'
import sinon from 'sinon'
import { fireEvent, render, screen, within } from '@testing-library/react'
import * as eventTracking from '../../../../../../frontend/js/infrastructure/event-tracking'
import PremiumFeaturesLink from '../../../../../../frontend/js/features/subscription/components/dashboard/premium-features-link'
import * as useLocationModule from '../../../../../../frontend/js/shared/hooks/use-location'
describe('<PremiumFeaturesLink />', function () {
const originalLocation = window.location
let sendMBSpy: sinon.SinonSpy
const variants = [
{ name: 'default', link: '/learn/how-to/Overleaf_premium_features' },
{ name: 'new', link: '/about/features-overview' },
]
beforeEach(function () {
window.metaAttributesCache = new Map()
sendMBSpy = sinon.spy(eventTracking, 'sendMB')
this.locationStub = sinon.stub(useLocationModule, 'useLocation').returns({
assign: sinon.stub(),
reload: sinon.stub(),
})
})
afterEach(function () {
window.metaAttributesCache = new Map()
sendMBSpy.restore()
this.locationStub.restore()
})
for (const variant of variants) {
describe(`${variant.name} variant`, function () {
beforeEach(function () {
window.metaAttributesCache.set('ol-splitTestVariants', {
'features-page': variant.name,
})
})
afterEach(function () {
window.metaAttributesCache.delete('ol-splitTestVariants')
})
it('renders the premium features link and sends analytics event', function () {
render(<PremiumFeaturesLink />)
const premiumText = screen.getByText('Get the most out of your', {
exact: false,
})
const link = within(premiumText).getByRole('link')
fireEvent.click(link)
expect(sendMBSpy).to.be.calledOnce
expect(sendMBSpy).calledWith('features-page-link', {
splitTest: 'features-page',
splitTestVariant: variant.name,
page: originalLocation.pathname,
})
})
})
}
})

View file

@ -33,7 +33,7 @@ describe('<SubscriptionDashboard />', function () {
it('renders the "Get the most out of your" subscription text', function () { it('renders the "Get the most out of your" subscription text', function () {
screen.getByText( screen.getByText(
'Get the most out of your Overleaf subscription by checking out the list of', 'Get the most out of your Overleaf subscription by checking out',
{ exact: false } { exact: false }
) )
}) })

View file

@ -41,7 +41,7 @@ describe('successful subscription page', function () {
/its support from people like yourself that allows .* to continue to grow and improve/i /its support from people like yourself that allows .* to continue to grow and improve/i
) )
expect(screen.getByText(/get the most out of your/i).textContent).to.match( expect(screen.getByText(/get the most out of your/i).textContent).to.match(
/get the most out of your .* subscription by checking out the list of .*s premium features/i /get the most out of your .* subscription by checking out .*s features/i
) )
expect( expect(
screen screen
@ -70,11 +70,9 @@ describe('successful subscription page', function () {
) )
const helpLink = screen.getByRole('link', { const helpLink = screen.getByRole('link', {
name: /.*s premium features/i, name: /.*s features/i,
}) })
expect(helpLink.getAttribute('href')).to.equal( expect(helpLink.getAttribute('href')).to.equal('/about/features-overview')
'/learn/how-to/Overleaf_premium_features'
)
const backToYourProjectsLink = screen.getByRole('link', { const backToYourProjectsLink = screen.getByRole('link', {
name: /back to your projects/i, name: /back to your projects/i,