Repository: freeCodeCamp/freeCodeCamp
File: e2e/search-bar.spec.ts (TypeScript)

Code before:
    await search({ page, isMobile, query: '!@#$%^' });

    const resultList = page.getByRole('list', { name: 'Search results' });
    await expect(resultList.getByRole('listitem')).toHaveCount(1);
    await expect(resultList.getByRole('listitem')).toHaveText(
      'No tutorials found'
    );
  });

  test('should clear the input and hide the result dropdown when the user clicks the clear button', async ({
    page,
    isMobile
  }) => {
    const searchInput = await getSearchInput({ page, isMobile });
    await expect(searchInput).toBeVisible();

    await searchInput.fill('test');
    await page.getByRole('button', { name: 'Clear search terms' }).click();

    await expect(searchInput).toHaveValue('');
    await expect(
      page.getByRole('list', { name: 'Search results' })
    ).toBeHidden();
  });
});

test.describe('Search results when viewport height is greater than 768px', () => {
  test.use({
    viewport: { width: 1600, height: 1200 }
  });

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

    // Mock Algolia requests to prevent hitting Algolia server unnecessarily.
    // Comment out this line if you want to test against the real server.
    await mockAlgolia({ page, hitsPerPage: 8 });
  });

  test('should display 8 items', async ({ page, isMobile }) => {
    test.skip(!haveApiKeys, 'This test requires Algolia API keys');

    await search({ page, isMobile, query: 'article' });

    // Wait for the search results to show up
    const results = page.getByRole('list', { name: 'Search results' });
    await expect(results.getByRole('listitem')).toHaveCount(9); // 8 results + the footer
  });
});

test.describe('Search results when viewport height is equal to 768px', () => {

Review comment (suggestion):
I initially thought we could remove `onFocus` along with the outer div, but realized that the event handler is needed for this behavior. So I added a test to prevent future me from breaking it 😛 

Code after:
    await search({ page, isMobile, query: '!@#$%^' });

    const resultList = page.getByRole('list', { name: 'Search results' });
    await expect(resultList.getByRole('listitem')).toHaveCount(1);
    await expect(resultList.getByRole('listitem')).toHaveText(
      'No tutorials found'
    );
  });

  test('should clear the input and hide the result dropdown when the user clicks the clear button', async ({
    page,
    isMobile
  }) => {
    const searchInput = await getSearchInput({ page, isMobile });
    await expect(searchInput).toBeVisible();

    await searchInput.fill('test');
    await page.getByRole('button', { name: 'Clear search terms' }).click();

    await expect(searchInput).toHaveValue('');
    await expect(
      page.getByRole('list', { name: 'Search results' })
    ).toBeHidden();
  });

  test('should close the dropdown when the user clicks outside of the search bar', async ({
    page,
    isMobile
  }) => {
    const searchInput = await getSearchInput({ page, isMobile });
    await expect(searchInput).toBeVisible();

    await searchInput.fill('test');

    // Wait for the search results to show up
    const resultList = page.getByRole('list', { name: 'Search results' });
    await expect(resultList).toBeVisible();

    await page.getByRole('navigation', { name: 'primary' }).click();
    await expect(resultList).toBeHidden();
  });
});

test.describe('Search results when viewport height is greater than 768px', () => {
  test.use({
    viewport: { width: 1600, height: 1200 }
  });

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