Repository: freeCodeCamp/freeCodeCamp
File: e2e/link-ms-user.spec.ts (TypeScript)

Code before:
    await expect(linkText3).toHaveText(translations.learn.ms['link-li-3']);

    const linkText4 = page.getByTestId('link-li-4-text');
    await expect(linkText4).toBeVisible();
    await expect(linkText4).toHaveText(translations.learn.ms['link-li-4']);

    const linkText5 = page.getByTestId('link-li-5-text');
    await expect(linkText5).toBeVisible();
    await expect(linkText5).toHaveText(
      'Paste the URL into the input below, it should look similar to this: https://learn.microsoft.com/LOCALE/users/USERNAME/transcript/ID'
    );

    const linkText6 = page.getByTestId('link-li-6-text');
    await expect(linkText6).toBeVisible();
    await expect(linkText6).toHaveText(translations.learn.ms['link-li-6']);

    const transcriptLinkInput = page.getByLabel(
      translations.learn.ms['transcript-label']
    );
    await expect(transcriptLinkInput).toBeVisible();
    await expect(transcriptLinkInput).toHaveAttribute(
      'placeholder',
      'https://learn.microsoft.com/en-us/users/username/transcript/transcriptId'
    );
  });
});


Review comment (suggestion):
Elements such as `button` or `a` can be queried by:

```js
getByRole('elementRole', { name: 'accessible name' })
```

Because their content is considered their accessible name by default.

But for elements like `alert` or `listitem`, their accessible name is only available when we explicitly give them an `aria-label` (which is redundant in this case). So instead of looking for them using their accessible name, we find them using their text content:

```js
getByRole('elementRole').filter({ hasText: 'text content' })
```

Ref: https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/#namingtechniques.

Code after:
      page.getByText(
        'The Microsoft account with username "certifieduser" is currently linked to your freeCodeCamp account. If this is not your Microsoft username, remove the link.'
      )
    ).toBeVisible();
  });

  test('should allow the user to unlink their MS account and display a form for re-link', async ({
    page
  }) => {
    // Intercept the endpoint to prevent `msUsername` from being deleted
    // as the deletion will cause subsequent tests to fail
    await page.route('*/**/user/ms-username', async route => {
      const json = { msUsername: null };
      await route.fulfill({ json });
    });

    const unlinkButton = page.getByRole('button', {
      name: translations.buttons['unlink-account']
    });
    await expect(unlinkButton).toBeVisible();
    await unlinkButton.click();

    await expect(
      page
        .getByRole('alert')
        .filter({ hasText: translations.flash.ms.transcript.unlinked })
    ).toBeVisible();

    await expect(
      page.getByRole('heading', {
        name: translations.learn.ms['link-header'],
        level: 2
      })
    ).toBeVisible();
    await expect(page.getByText(translations.learn.ms.unlinked)).toBeVisible();
    await expect(
      page.getByRole('listitem').filter({
        hasText:
          'Using a browser where you are logged into your Microsoft account, go to https://learn.microsoft.com/users/me/transcript'
      })
    ).toBeVisible();
    await expect(
      page
        .getByRole('listitem')
        .filter({ hasText: translations.learn.ms['link-li-2'] })
    ).toBeVisible();
    await expect(
      page
        .getByRole('listitem')
        .filter({ hasText: translations.learn.ms['link-li-3'] })
    ).toBeVisible();