Change:
- Playwright test files are always with a `.spec.ts` extension. <del> ## Best Practices for writing e2e tests </del> <ins> ## Best Practices for writing E2E tests </ins> <del> This section will explain in detail about best practices for writing and documenting E2E tests based on playwright documentation and our community code-style. </del> <ins> This section will explain in detail about best practices for writing and documenting E2E tests based on Playwright documentation and our community code-style. </ins> ### - Identifying a DOM element <del> Always use the `data-playwright-test-label` attribute to identify DOM elements. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose. </del> <ins> Playwright comes with [multiple built-in locators](https://playwright.dev/docs/locators#quick-guide), but we recommend priritizing the following locators: - `getByRole` for querying semantic elements, whose role is important and allows assistive technology to perceive the page correctly. - `getByText` for querying non-semantic elements such as `div`, `span`, or `p`. </ins> <del> For example: </del> <ins> For example: ```ts await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible(); await expect(page.getByText('Hello World')).toBeVisible(); ``` In cases where the elements cannot be queried using the above-mentioned locators, you can use the `data-playwright-test-label` attribute as the last resort. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose. </ins> <del> ```html <div data-playwright-test-label="landing-page-figure"> <img src="..." alt="..." /> </div> ``` </del> <ins> For example: ```html <div data-playwright-test-label="landing-page-figure"> <img src="..." alt="..." /> </div> ``` </ins> <del> Make sure you use the getByTestId method to identify the element in the test file. </del> <ins> In the test file, you can use the `getByTestId` method to identify the element. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts const landingPageFigure = page.getByTestId('landing-page-figure'); ``` </del> <ins> ```ts await expect(page.getByTestId('landing-page-figure')).toBeVisible(); ``` </ins> ### - Imports <del> Always start with necessary imports at the beginning of the file. </del> <ins> Always start with necessary imports at the beginning of the file. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts import { test, expect, type Page } from '@playwright/test'; ``` </del> <ins> ```ts import { test, expect, type Page } from '@playwright/test'; ``` </ins> ### - Constants <del> Define any constant elements, data sets, or configurations used throughout your tests for easy reference. </del> <ins> Define any constant elements, data sets, or configurations used throughout your tests for easy reference. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts const landingPageElements = { ... }; const superBlocks = [ ... ]; ``` </del> <ins> ```ts const landingPageElements = { ... }; const superBlocks = [ ... ]; ``` </ins> ### - Shared Context <del> If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context. </del> <ins> If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts let page: Page; </del> <ins> ```ts let page: Page; </ins> <del> beforeAll(async ({ browser }) => { page = await browser.newPage(); }); </del> <ins> beforeAll(async ({ browser }) => { page = await browser.newPage(); }); </ins> <del> afterAll(async () => { await page.close(); }); ``` </del> <ins> afterAll(async () => { await page.close(); }); ``` </ins> ### - Descriptive test names <del> Each test block should have a clear and concise name describing exactly what it's testing. </del> <ins> Each test block should have a clear and concise name describing exactly what it's testing. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts test('The component landing-top renders correctly', async ({ page }) => { ... }); ``` </del> <ins> ```ts test('The component landing-top renders correctly', async ({ page }) => { // ... }); ``` </ins> ### - Human readable assertions <del> Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting. </del> <ins> Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts await expect(landingHeading1).toHaveText('Learn to code — for free.'); ``` </del> <ins> ```ts await expect(landingHeading1).toHaveText('Learn to code — for free.'); ``` </ins> ### - Keep it DRY <del> Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function. </del> <ins> Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts for (const logo of await logos.all()) { await expect(logo).toBeVisible(); } ``` </del> <ins> ```ts for (const logo of await logos.all()) { await expect(logo).toBeVisible(); } ``` </ins> ### - Tests for mobile screens <del> Use the 'isMobile' argument to run tests that incude logic that varies for mobile screens. </del> <ins> Use the `isMobile` argument to run tests that incude logic that varies for mobile screens. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) => { const landingPageImage = page.getByTestId('landing-page-figure'); </del> <ins> ```ts test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({ isMobile }) => { const landingPageImage = page.getByTestId('landing-page-figure'); </ins> <del> if (isMobile) { await expect(landingPageImage).toBeHidden(); } else { await expect(landingPageImage).toBeVisible(); } }); </del> <ins> if (isMobile) { await expect(landingPageImage).toBeHidden(); } else { await expect(landingPageImage).toBeVisible(); } }); </ins> ``` ### - Group related tests <del> Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing. </del> <ins> Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing. </ins> <del> For example: </del> <ins> For example: </ins> <del> ```ts describe('The campers landing page', () => { test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({isMobile}) => { ... }); test('The campers landing page figure has the correct image', async () => { ... }); </del> <ins> ```ts describe('The campers landing page', () => { test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({ isMobile }) => { // ... </ins> }); <del> ``` </del> <ins> test('The campers landing page figure has the correct image', async () => { // ... }); }); ``` </ins> ## How to Run Tests

Discussion:
In the , we say that: But IMHO, test IDs should be used sparingly in cases where we can't use any other locators as an alternative. The issue with test IDs is that it doesn't guarantee the page has the correct text or the page / section of the page has proper element usages (which is important to ensure that our pages are accessible). Here is an example, let's pretend we have the following HTML: If our test only checks for the test ID, the test would pass while this is not a valid implementation of a button and will cause a severe accessibility issue: But if we write the assertion with , the test would fail, which enables us to ensure the validity of the DOM: https://testing- N/A Update the guide and recommend using and instead of . We can also add the link to the for other recommended locators. No response
I agree. Recently, I've opened two PRs with E2E tests, and although I followed the guide and used , it just doesn't feel right to do it this way.
can you assign to me
I've created to update the guide with the new recommendation. For Hacktoberfest PRs that have already been using test IDs, I think we should still respect the authors' efforts and accept their code addition, and we can always improve the tests later on.