From 679caa61f3d5a169346b43eacb077f09661d8e29 Mon Sep 17 00:00:00 2001 From: Rodrigo Martin Date: Tue, 11 Mar 2025 12:06:28 -0300 Subject: [PATCH] feat: Update link styling (#1631) --- .../course/course-license/CourseLicense.jsx | 3 +++ .../course/course-license/messages.ts | 5 ++++ .../UpgradeNotification.jsx | 13 +++++++++- .../UpgradeNotification.test.jsx | 24 +++++++++---------- src/generic/upsell-bullets/UpsellBullets.jsx | 6 +++++ .../upsell-bullets/UpsellBullets.test.jsx | 2 +- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/courseware/course/course-license/CourseLicense.jsx b/src/courseware/course/course-license/CourseLicense.jsx index 870d7be4..656151fd 100644 --- a/src/courseware/course/course-license/CourseLicense.jsx +++ b/src/courseware/course/course-license/CourseLicense.jsx @@ -134,6 +134,9 @@ const CourseLicense = ({ ))} {intl.formatMessage(messages['learn.course.license.creativeCommons.text'])} + + {intl.formatMessage(messages['learn.course.license.creativeCommons.externalSite.screenreaderOnly.message'])} + ); diff --git a/src/courseware/course/course-license/messages.ts b/src/courseware/course/course-license/messages.ts index 65d6aeda..69dc5bfd 100644 --- a/src/courseware/course/course-license/messages.ts +++ b/src/courseware/course/course-license/messages.ts @@ -42,6 +42,11 @@ const messages = defineMessages({ defaultMessage: 'Some Rights Reserved', description: 'License text shown when using all Creative Commons license types.', }, + 'learn.course.license.creativeCommons.externalSite.screenreaderOnly.message': { + id: 'learn.course.license.creativeCommons.externalSite.screenreaderOnly.message', + defaultMessage: 'external site, in a new tab', + description: 'Screenreader only text for external site link', + }, }); export default messages; diff --git a/src/generic/upgrade-notification/UpgradeNotification.jsx b/src/generic/upgrade-notification/UpgradeNotification.jsx index 861299de..13e785c8 100644 --- a/src/generic/upgrade-notification/UpgradeNotification.jsx +++ b/src/generic/upgrade-notification/UpgradeNotification.jsx @@ -4,7 +4,7 @@ import classNames from 'classnames'; import { useIntl, FormattedDate, FormattedMessage } from '@edx/frontend-platform/i18n'; import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/analytics'; import { Button, Icon, IconButton } from '@openedx/paragon'; -import { Close } from '@openedx/paragon/icons'; +import { Close, Launch } from '@openedx/paragon/icons'; import { setLocalStorage } from '../../data/localStorage'; import { UpgradeButton } from '../upgrade-button'; import { @@ -57,6 +57,17 @@ const UpsellFBESoonCardContent = ({ accessExpirationDate, timezoneFormatArgs }) id="learning.generic.upgradeNotification.expirationVerifiedCert.benefits" defaultMessage="benefits of upgrading" /> + + + ); diff --git a/src/generic/upgrade-notification/UpgradeNotification.test.jsx b/src/generic/upgrade-notification/UpgradeNotification.test.jsx index 8d97e4c1..17d38f00 100644 --- a/src/generic/upgrade-notification/UpgradeNotification.test.jsx +++ b/src/generic/upgrade-notification/UpgradeNotification.test.jsx @@ -50,7 +50,7 @@ describe('Upgrade Notification', () => { it('renders non-FBE when there is a verified mode but no FBE', async () => { buildAndRender(); expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument(); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX'); expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument(); }); @@ -64,7 +64,7 @@ describe('Upgrade Notification', () => { }, }); expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument(); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX'); expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument(); }); @@ -75,7 +75,7 @@ describe('Upgrade Notification', () => { accessExpiration: null, }); expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument(); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX'); expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument(); }); @@ -94,7 +94,7 @@ describe('Upgrade Notification', () => { }, }); expect(screen.getByRole('heading', { name: 'Pursue a verified certificate' })).toBeInTheDocument(); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX'); expect(screen.getByText(/Upgrade for/).textContent).toMatch('$126.65 ($149)'); expect(screen.getByText(/Use code.*?at checkout/s).textContent).toMatch('Use code Welcome15 at checkout'); @@ -112,7 +112,7 @@ describe('Upgrade Notification', () => { expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument(); expect(screen.getByText('Less than 1 hour left')).toBeInTheDocument(); expect(screen.getByText(/You will lose all access to this course.*?on/s).textContent).toMatch('You will lose all access to this course, including any progress, on April 13.'); - expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading.'); + expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading in a new tab.'); expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument(); }); @@ -128,7 +128,7 @@ describe('Upgrade Notification', () => { expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument(); expect(screen.getByText('12 hours left')).toBeInTheDocument(); expect(screen.getByText(/You will lose all access to this course.*?on/s)).toHaveTextContent('You will lose all access to this course, including any progress, on April 13.'); - expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading.'); + expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading in a new tab.'); expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument(); }); @@ -144,7 +144,7 @@ describe('Upgrade Notification', () => { expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument(); expect(screen.getByText('6 days left')).toBeInTheDocument(); // setting the time to 12 will mean that it's slightly less than 12 expect(screen.getByText(/You will lose all access to this course.*?on/s).textContent).toMatch('You will lose all access to this course, including any progress, on April 19.'); - expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading.'); + expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading in a new tab.'); expect(screen.getByRole('link', { name: 'Upgrade for $149' })).toBeInTheDocument(); }); @@ -159,7 +159,7 @@ describe('Upgrade Notification', () => { }); expect(screen.getByRole('heading', { name: 'Upgrade your course today' })).toBeInTheDocument(); expect(screen.getByText(/Course access will expire/s).textContent).toMatch('Course access will expire April 27'); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments'); expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX'); @@ -187,7 +187,7 @@ describe('Upgrade Notification', () => { }); expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument(); expect(screen.getByText('Less than 1 hour left')).toBeInTheDocument(); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments'); expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX'); @@ -216,7 +216,7 @@ describe('Upgrade Notification', () => { }); expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument(); expect(screen.getByText(/hours left/s).textContent).toMatch('12 hours left'); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments'); expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX'); @@ -245,7 +245,7 @@ describe('Upgrade Notification', () => { }); expect(screen.getByRole('heading', { name: '15% First-Time Learner Discount' })).toBeInTheDocument(); expect(screen.getByText(/days left/s).textContent).toMatch('6 days left'); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments'); expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX'); @@ -275,7 +275,7 @@ describe('Upgrade Notification', () => { expect(screen.getByRole('heading', { name: 'Course Access Expiration' })).toBeInTheDocument(); expect(screen.getByText('5 days left')).toBeInTheDocument(); // setting the time to 12 will mean that it's slightly less than 12 expect(screen.getByText(/You will lose all access to this course.*?on/s).textContent).toMatch('You will lose all access to this course, including any progress, on April 18.'); - expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading.'); + expect(screen.getByText(/Upgrading your course enables you/s).textContent).toMatch('Upgrading your course enables you to pursue a verified certificate and unlocks numerous features. Learn more about the benefits of upgrading in a new tab.'); expect(screen.getByText(/Upgrade for/).textContent).toMatch('$126.65 ($149)'); expect(screen.getByText(/Use code.*?at checkout/s).textContent).toMatch('Use code Welcome15 at checkout'); }); diff --git a/src/generic/upsell-bullets/UpsellBullets.jsx b/src/generic/upsell-bullets/UpsellBullets.jsx index e631ebae..04c7de41 100644 --- a/src/generic/upsell-bullets/UpsellBullets.jsx +++ b/src/generic/upsell-bullets/UpsellBullets.jsx @@ -17,6 +17,12 @@ export const VerifiedCertBullet = () => { defaultMessage="verified certificate" description="Bolded words 'verified certificate', which is the name of credential the learner receives." /> + + + ); return ( diff --git a/src/generic/upsell-bullets/UpsellBullets.test.jsx b/src/generic/upsell-bullets/UpsellBullets.test.jsx index daf74943..046ae58f 100644 --- a/src/generic/upsell-bullets/UpsellBullets.test.jsx +++ b/src/generic/upsell-bullets/UpsellBullets.test.jsx @@ -27,7 +27,7 @@ describe('UpsellBullets', () => { it('upsell bullet text properly rendered', async () => { render(bullets); - expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate of completion to showcase on your resumé'); + expect(screen.getByText(/Earn a.*?of completion to showcase on your resumé/s).textContent).toMatch('Earn a verified certificate (learn more in a new tab) of completion to showcase on your resumé'); expect(screen.getByText(/Unlock your access/s).textContent).toMatch('Unlock your access to all course activities, including graded assignments'); expect(screen.getByText(/to course content and materials/s).textContent).toMatch('Full access to course content and materials, even after the course ends'); expect(screen.getByText(/Support our.*?at edX/s).textContent).toMatch('Support our mission at edX');