Repository: freeCodeCamp/freeCodeCamp
File: e2e/quiz-challenge.spec.ts (TypeScript)

Code before:
      challengeNode: {
        challenge: { quizzes: Quiz[] };
      };
    };
  };
}

test.describe('Quiz challenge', () => {
  test.beforeEach(async ({ page }) => {
    const fixturePath = path.join(__dirname, 'fixtures', 'quiz-fixture.json');
    const fixture = JSON.parse(fs.readFileSync(fixturePath, 'utf8')) as Quiz[];

    // Intercept Gatsby page-data and inject a deterministic quiz fixture
    await page.route('**/page-data/**/page-data.json', async route => {
      const response = await route.fetch();
      try {
        const body = await response.text();

        const pageData = JSON.parse(body) as PageData;
        pageData.result.data.challengeNode.challenge.quizzes = fixture;

        await route.fulfill({
          contentType: 'application/json',
          body: JSON.stringify(pageData)
        });
      }
    });

    await page.goto(
      '/learn/full-stack-developer/quiz-basic-html/quiz-basic-html'
    );
  });

  test('should display a list of unanswered questions if user has not answered all questions', async ({
    page
  }) => {
    // Wait for the page content to render
    await expect(page.getByRole('radiogroup')).toHaveCount(20);
    const radioGroups = await page.getByRole('radiogroup').all();

    // The radio label contents are rendered with `PrismFormatted`.
    // For accessibility we must ensure:
    // - The formatted content is wrapped in a `span`
    // - No ARIA role is added to `pre` elements
    const firstGroup = radioGroups[0];
    const spanLabel = firstGroup.locator('span.quiz-answer-label');
    await expect(spanLabel).toHaveCount(4);

    const preWithRole = firstGroup.locator('pre[role]');
    await expect(preWithRole).toHaveCount(0);


Review comment (suggestion):
```suggestion
      const body = await response.text();

      const pageData = JSON.parse(body) as PageData;
      pageData.result.data.challengeNode.challenge.quizzes = fixture;

      await route.fulfill({
        contentType: 'application/json',
        body: JSON.stringify(pageData)
      });
```

Code after:
      challengeNode: {
        challenge: { quizzes: Quiz[] };
      };
    };
  };
}

test.describe('Quiz challenge', () => {
  test.beforeEach(async ({ page }) => {
    const fixturePath = path.join(__dirname, 'fixtures', 'quiz-fixture.json');
    const fixture = JSON.parse(fs.readFileSync(fixturePath, 'utf8')) as Quiz[];

    // Intercept Gatsby page-data and inject a deterministic quiz fixture
    await page.route('**/page-data/**/page-data.json', async route => {
      const response = await route.fetch();
      const body = await response.text();

      const pageData = JSON.parse(body) as PageData;
      pageData.result.data.challengeNode.challenge.quizzes = fixture;

      await route.fulfill({
        contentType: 'application/json',
        body: JSON.stringify(pageData)
      });
    });

    await page.goto(
      '/learn/full-stack-developer/quiz-basic-html/quiz-basic-html'
    );
  });

  test('should display a list of unanswered questions if user has not answered all questions', async ({
    page
  }) => {
    // Wait for the page content to render
    await expect(page.getByRole('radiogroup')).toHaveCount(20);
    const radioGroups = await page.getByRole('radiogroup').all();

    // The radio label contents are rendered with `PrismFormatted`.
    // For accessibility we must ensure:
    // - The formatted content is wrapped in a `span`
    // - No ARIA role is added to `pre` elements
    const firstGroup = radioGroups[0];
    const spanLabel = firstGroup.locator('span.quiz-answer-label');
    await expect(spanLabel).toHaveCount(4);

    const preWithRole = firstGroup.locator('pre[role]');
    await expect(preWithRole).toHaveCount(0);

    for (let i = 0; i < 15; i++) {
      const radioGroups = await page.getByRole('radiogroup').all();