Repository: freeCodeCamp/freeCodeCamp
File: e2e/profile.spec.ts (TypeScript)

Code before:
      page.getByRole('link', { name: 'Top Contributor' })
    ).toBeVisible();
    await expect(page.getByText('2019')).toBeVisible();
  });

  test('renders total points correctly', async ({ page }) => {
    await expect(page.getByText('Number of points: 1')).toBeVisible();
  });

  test('renders the heat map correctly', async ({ page }) => {
    await expect(page.locator('div.heatmap-nav.row')).toBeVisible();
    await expect(page.locator('svg.react-calendar-heatmap')).toBeVisible();
    await expect(page.locator('div.streak-container')).toBeVisible();
  });

  test('displays certifications correctly', async ({ page }) => {
    await expect(page.locator('div.certifications.row')).toBeVisible();
    await expect(
      page.getByRole('heading', { name: 'freeCodeCamp Certifications' })
    ).toBeVisible();
    await expect(
      page.getByRole('heading', { name: 'Legacy Certifications' })
    ).toBeVisible();
    expect(
      await page.locator('a[data-cy="claimed-certification"]').count()
    ).toEqual(certs.length + legacyCerts.length);
  });

  test('should not show portfolio when empty', async ({ page }) => {
    expect(
      await page.getByTestId(profilePageElements.portfolio).count()
    ).toEqual(0);
  });

  test('displays the timeline correctly', async ({ page }) => {
    await expect(page.getByRole('heading', { name: 'Timeline' })).toBeVisible();
    await expect(page.getByRole('table')).toBeVisible();
    await expect(
      page.getByRole('navigation', { name: 'Timeline Pagination' })
    ).toBeVisible();
  });
});


Review comment (suggestion):
`data-cy` is an attribute specific to Cypress, and shouldn't be used/mixed up with Playwright. Instead of looking for elements with a test attribute, we should look for links with certain text:

```ts
const certs = [
  {
    name: 'Responsive Web Design',
    url: '/certification/certifieduser/responsive-web-design'
  },
  // ...
]

for (const cert of certs) {
  const link = await page.getByRole('link', { name: `View ${cert.name} Certification` });
  await expect(link).toBeVisible();
  await expect(link).toHaveAttribute('href', cert.url);
}
```

Code after:
];

const legacyCerts = [
  { name: 'Front End', url: '/certification/certifieduser/legacy-front-end' },
  { name: 'Back End', url: '/certification/certifieduser/legacy-back-end' },
  {
    name: 'Data Visualization',
    url: '/certification/certifieduser/legacy-data-visualization'
  },
  {
    name: 'Information Security and Quality Assurance',
    url: '/certification/certifieduser/information-security-and-quality-assurance'
  },
  { name: 'Full Stack', url: '/certification/certifieduser/full-stack' }
];

test.use({ storageState: 'playwright/.auth/certified-user.json' });

test.beforeEach(async ({ page }) => {
  await page.goto('/certifieduser');

  // The following line is required if you're running the test in local development
  // await page.getByRole('button', { name: 'Preview custom 404 page' }).click();
});

test.describe('Profile component', () => {
  test('renders the camper profile correctly', async ({ page }) => {
    // There are multiple avatars on the page, one is in the navbar, one is in the page body.
    // The avatar we are interested in is the last one in the list
    const avatar = page
      .getByRole('img', {
        name: translations.icons.avatar,
        includeHidden: true // the svg has `aria-hidden` set to true
      })
      .last();

    // "visible" as in the element is in the DOM, but it is hidden from non-sighted users
    await expect(avatar).toBeVisible();

    await expect(
      page.getByRole('heading', { name: '@certifieduser' })
    ).toBeVisible();
    await expect(page.getByText('Full Stack User')).toBeVisible();
    await expect(page.getByText('Joined November 2020')).toBeVisible();
    await expect(
      page.getByRole('link', { name: 'Top Contributor' })
    ).toBeVisible();
    await expect(page.getByText('2019')).toBeVisible();
  });

  test('renders total points correctly', async ({ page }) => {