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');