mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-04-30 16:01:14 -04:00
refactor(e2e,playwright): input labels to test perf and improve coverage for landing page (#51501)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@@ -12,6 +12,7 @@ const AsSeenInText = (
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
{...props}
|
||||
fill={fill}
|
||||
data-playwright-test-label='landing-as-seen-in-container-logos'
|
||||
>
|
||||
<defs>
|
||||
<path
|
||||
|
||||
@@ -71,7 +71,10 @@ function MapLi({
|
||||
</>
|
||||
)}
|
||||
|
||||
<li data-test-label='curriculum-map-button'>
|
||||
<li
|
||||
data-test-label='curriculum-map-button'
|
||||
data-playwright-test-label='curriculum-map-button'
|
||||
>
|
||||
<Link className='btn link-btn btn-lg' to={`/learn/${superBlock}/`}>
|
||||
<div style={linkSpacingStyle}>
|
||||
{generateIconComponent(superBlock, 'map-icon')}
|
||||
|
||||
@@ -7,8 +7,17 @@ const AsSeenIn = (): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Container fluid={true} className='as-seen-in text-center'>
|
||||
<p className='big-heading'>{t('landing.as-seen-in')}</p>
|
||||
<Container
|
||||
fluid={true}
|
||||
className='as-seen-in text-center'
|
||||
data-playwright-test-label='landing-as-seen-in-container'
|
||||
>
|
||||
<p
|
||||
className='big-heading'
|
||||
data-playwright-test-label='landing-as-seen-in-text'
|
||||
>
|
||||
{t('landing.as-seen-in')}
|
||||
</p>
|
||||
<AsSeenInText fill='light' />
|
||||
</Container>
|
||||
);
|
||||
|
||||
@@ -6,7 +6,11 @@ const BigCallToAction = (): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Login block={true} data-test-label='landing-big-cta'>
|
||||
<Login
|
||||
block={true}
|
||||
data-test-label='landing-big-cta'
|
||||
data-playwright-test-label='landing-big-cta'
|
||||
>
|
||||
{t('buttons.logged-in-cta-btn')}
|
||||
</Login>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,11 @@ function CampersImage({ pageName }: CampersImageProps): JSX.Element {
|
||||
|
||||
return (
|
||||
<Media minWidth={LARGE_SCREEN_SIZE}>
|
||||
<figure style={figureSize} data-test-label='landing-page-figure'>
|
||||
<figure
|
||||
style={figureSize}
|
||||
data-test-label='landing-page-figure'
|
||||
data-playwright-test-label='landing-page-figure'
|
||||
>
|
||||
<LazyImage
|
||||
alt={t('landing.hero-img-alt')}
|
||||
src={wideImg}
|
||||
|
||||
@@ -18,7 +18,11 @@ const Faq = (): JSX.Element => {
|
||||
<h1 className='big-heading'>{t('landing.faq')}</h1>
|
||||
<Spacer size='small' />
|
||||
{faqItems.map((faq, i) => (
|
||||
<div data-test-label='landing-page-faq' key={i}>
|
||||
<div
|
||||
data-test-label='landing-page-faq'
|
||||
data-playwright-test-label='landing-page-faq'
|
||||
key={i}
|
||||
>
|
||||
<p className='faq-question'>{faq.question}</p>
|
||||
{faq.answer.map((answer, i) => (
|
||||
<p key={i}>{answer}</p>
|
||||
|
||||
@@ -30,13 +30,29 @@ function LandingTop(): JSX.Element {
|
||||
id='content-start'
|
||||
className='big-heading'
|
||||
data-test-label='landing-header'
|
||||
data-playwright-test-label='landing-big-heading-1'
|
||||
>
|
||||
{t('landing.big-heading-1')}
|
||||
</h1>
|
||||
<p className='big-heading'>{t('landing.big-heading-2')}</p>
|
||||
<p className='big-heading'>{t('landing.big-heading-3')}</p>
|
||||
<p>{t('landing.h2-heading')}</p>
|
||||
<div className='logo-row'>
|
||||
<p
|
||||
className='big-heading'
|
||||
data-playwright-test-label='landing-big-heading-2'
|
||||
>
|
||||
{t('landing.big-heading-2')}
|
||||
</p>
|
||||
<p
|
||||
className='big-heading'
|
||||
data-playwright-test-label='landing-big-heading-3'
|
||||
>
|
||||
{t('landing.big-heading-3')}
|
||||
</p>
|
||||
<p data-playwright-test-label='landing-h2-heading'>
|
||||
{t('landing.h2-heading')}
|
||||
</p>
|
||||
<div
|
||||
className='logo-row'
|
||||
data-playwright-test-label='brand-logo-container'
|
||||
>
|
||||
<AppleLogo />
|
||||
<GoogleLogo />
|
||||
<MicrosoftLogo />
|
||||
|
||||
@@ -12,12 +12,21 @@ const Testimonials = (): JSX.Element => {
|
||||
|
||||
return (
|
||||
<div className='testimonials'>
|
||||
<h1 className='big-heading text-center'>
|
||||
<h1
|
||||
className='big-heading text-center'
|
||||
data-playwright-test-label='testimonials-section-header'
|
||||
>
|
||||
{t('landing.testimonials.heading')}
|
||||
</h1>
|
||||
<div className='testimonials-row' data-test-label='testimonial-cards'>
|
||||
<div className='testimonial-card'>
|
||||
<div className='testimonial-card-header'>
|
||||
<div
|
||||
className='testimonial-card'
|
||||
data-playwright-test-label='testimonial-card'
|
||||
>
|
||||
<div
|
||||
className='testimonial-card-header'
|
||||
data-playwright-test-label='testimonials-endorser-image-container'
|
||||
>
|
||||
<LazyImage
|
||||
alt='Shawn Wang, a young-looking Asian man, smiling for a selfie with a snow-capped mountain in the background.'
|
||||
className='testimonial-image'
|
||||
@@ -27,24 +36,30 @@ const Testimonials = (): JSX.Element => {
|
||||
|
||||
<div className='testimonials-footer'>
|
||||
<div className='testimonial-meta'>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-location'>
|
||||
{' '}
|
||||
<Trans>landing.testimonials.shawn.location</Trans>
|
||||
</p>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-occupation'>
|
||||
<Trans>landing.testimonials.shawn.occupation</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<div className='testimony'>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-testimony'>
|
||||
<Trans>landing.testimonials.shawn.testimony</Trans>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='testimonial-card'>
|
||||
<div className='testimonial-card-header'>
|
||||
<div
|
||||
className='testimonial-card'
|
||||
data-playwright-test-label='testimonial-card'
|
||||
>
|
||||
<div
|
||||
className='testimonial-card-header'
|
||||
data-playwright-test-label='testimonials-endorser-image-container'
|
||||
>
|
||||
<LazyImage
|
||||
alt='Sarah Chima, a young-looking Black woman, smiling for the camera while sitting in a chair.'
|
||||
className='testimonial-image'
|
||||
@@ -54,24 +69,30 @@ const Testimonials = (): JSX.Element => {
|
||||
|
||||
<div className='testimonials-footer'>
|
||||
<div className='testimonial-meta'>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-location'>
|
||||
{' '}
|
||||
<Trans>landing.testimonials.sarah.location</Trans>
|
||||
</p>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-occupation'>
|
||||
<Trans>landing.testimonials.sarah.occupation</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<div className='testimony'>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-testimony'>
|
||||
<Trans>landing.testimonials.sarah.testimony</Trans>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='testimonial-card'>
|
||||
<div className='testimonial-card-header'>
|
||||
<div
|
||||
className='testimonial-card'
|
||||
data-playwright-test-label='testimonial-card'
|
||||
>
|
||||
<div
|
||||
className='testimonial-card-header'
|
||||
data-playwright-test-label='testimonials-endorser-image-container'
|
||||
>
|
||||
<LazyImage
|
||||
alt='Emma Bostian, a young-looking White woman, smiling for the camera in front of green foliage.'
|
||||
className='testimonial-image'
|
||||
@@ -81,16 +102,16 @@ const Testimonials = (): JSX.Element => {
|
||||
|
||||
<div className='testimonials-footer'>
|
||||
<div className='testimonial-meta'>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-location'>
|
||||
{' '}
|
||||
<Trans>landing.testimonials.emma.location</Trans>
|
||||
</p>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-occupation'>
|
||||
<Trans>landing.testimonials.emma.occupation</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<div className='testimony'>
|
||||
<p>
|
||||
<p data-playwright-test-label='testimonials-endorser-testimony'>
|
||||
<Trans>landing.testimonials.emma.testimony</Trans>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -39,35 +39,77 @@ test.afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('Should render', async () => {
|
||||
await expect(page).toHaveTitle(
|
||||
'Learn to Code — For Free — Coding Courses for Busy People'
|
||||
);
|
||||
const callToAction = page.getByTestId(landingPageElements.callToAction);
|
||||
const callToActionHeader = page.locator('a .login-btn-text').nth(1);
|
||||
await expect(callToActionHeader).toHaveText("Get started (it's free)");
|
||||
await expect(callToAction).toHaveCount(4);
|
||||
});
|
||||
test('The component Landing-top renders correctly', async () => {
|
||||
const landingHeading1 = page.getByTestId('landing-big-heading-1');
|
||||
await expect(landingHeading1).toHaveText('Learn to code — for free.');
|
||||
|
||||
test('Has visible header and sub-header', async () => {
|
||||
const heading = page.getByTestId(landingPageElements.heading);
|
||||
await expect(heading).toContainText('Learn to code — for free.');
|
||||
expect(await page.isVisible('text=Build projects.')).toBeTruthy();
|
||||
expect(await page.isVisible('text=Earn certifications.')).toBeTruthy();
|
||||
expect(
|
||||
await page.isVisible(
|
||||
'text=Since 2014, more than 40,000 freeCodeCamp.org ' +
|
||||
'graduates have gotten jobs at tech companies including:'
|
||||
)
|
||||
).toBeTruthy();
|
||||
const landingHeading2 = page.getByTestId('landing-big-heading-2');
|
||||
await expect(landingHeading2).toHaveText('Build projects.');
|
||||
|
||||
const landingHeading3 = page.getByTestId('landing-big-heading-3');
|
||||
await expect(landingHeading3).toHaveText('Earn certifications.');
|
||||
|
||||
const landingH2Heading = page.getByTestId('landing-h2-heading');
|
||||
await expect(landingH2Heading).toHaveText(
|
||||
'Since 2014, more than 40,000 freeCodeCamp.org graduates have gotten jobs at tech companies including:'
|
||||
);
|
||||
});
|
||||
|
||||
test('Has 5 brand logos', async () => {
|
||||
await expect(page.locator('#featured-logos')).toBeVisible();
|
||||
const logos = page.getByTestId('brand-logo-container').locator('svg');
|
||||
await expect(logos).toHaveCount(5);
|
||||
for (const logo of await logos.all()) {
|
||||
await expect(logo).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('Has `as seen in` section', async () => {
|
||||
await expect(page.locator('.as-seen-in')).toBeVisible();
|
||||
test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({
|
||||
isMobile
|
||||
}) => {
|
||||
const landingPageImage = page.getByTestId('landing-page-figure');
|
||||
|
||||
if (isMobile) {
|
||||
await expect(landingPageImage).toBeHidden();
|
||||
} else {
|
||||
await expect(landingPageImage).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('The as seen in container is visible with featured logos', async () => {
|
||||
const asSeenInContainer = page.getByTestId('landing-as-seen-in-text');
|
||||
await expect(asSeenInContainer).toHaveText('As seen in:');
|
||||
|
||||
const featuredLogos = page.getByTestId('landing-as-seen-in-container-logos');
|
||||
await expect(featuredLogos).toBeVisible();
|
||||
});
|
||||
|
||||
test('Testimonial section has a header', async () => {
|
||||
const testimonialsHeader = page.getByTestId('testimonials-section-header');
|
||||
await expect(testimonialsHeader).toHaveText(
|
||||
'Here is what our alumni say about freeCodeCamp:'
|
||||
);
|
||||
});
|
||||
|
||||
test('Testimonial endorser people have images, occupation, location and testimony visible', async () => {
|
||||
const cards = page.getByTestId('testimonial-card');
|
||||
|
||||
await expect(cards).toHaveCount(3);
|
||||
|
||||
for (const card of await cards.all()) {
|
||||
await expect(card).toBeVisible();
|
||||
await expect(
|
||||
card.getByTestId('testimonials-endorser-image-container')
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
card.getByTestId('testimonials-endorser-location')
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
card.getByTestId('testimonials-endorser-occupation')
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
card.getByTestId('testimonials-endorser-testimony')
|
||||
).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('Has links to all superblocks', async () => {
|
||||
@@ -79,11 +121,6 @@ test('Has links to all superblocks', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('Has 3 testimonial cards', async () => {
|
||||
const testimonials = page.locator(`.${landingPageElements.testimonials}`);
|
||||
await expect(testimonials).toHaveCount(3);
|
||||
});
|
||||
|
||||
test('Has FAQ section', async () => {
|
||||
const faqs = page.getByTestId(landingPageElements.faq);
|
||||
await expect(faqs).toHaveCount(9);
|
||||
|
||||
@@ -33,7 +33,7 @@ export default defineConfig({
|
||||
trace: 'on-first-retry',
|
||||
|
||||
/* Use custom test attribute */
|
||||
testIdAttribute: 'data-test-label'
|
||||
testIdAttribute: 'data-playwright-test-label'
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
|
||||
Reference in New Issue
Block a user