Skip to content

Commit 2a5e0ac

Browse files
committed
Use getByLabel method instead of getByTestId
1 parent 70a7a39 commit 2a5e0ac

File tree

2 files changed

+106
-108
lines changed

2 files changed

+106
-108
lines changed

src/content/5/en/part5d.md

Lines changed: 54 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -358,43 +358,39 @@ describe('Note app', () => {
358358

359359
Both this and the previous version of the test work. However, both are problematic to the extent that if the registration form is changed, the tests may break, as they rely on the fields to be on the page in a certain order.
360360

361-
A better solution is to define unique test id attributes for the fields, to search for them in the tests using the method [getByTestId](https://playwright.dev/docs/api/class-page#page-get-by-test-id ).
361+
If an element is difficult to locate in tests, you can assign it a separate <i>test-id</i> attribute and find the element in tests using the [getByTestId](https://playwright.dev/docs/api/class-page#page-get-by-test-id) method.
362362

363-
Let's expand the login form as follows
363+
Let's now take advantage of the existing elements of the login form. The input fields of the login form have been assigned unique <i>labels</i>:
364364

365365
```js
366-
const LoginForm = ({ ... }) => {
367-
return (
368-
<div>
369-
<h2>Login</h2>
370-
<form onSubmit={handleSubmit}>
371-
<div>
372-
username
373-
<input
374-
data-testid='username' // highlight-line
375-
value={username}
376-
onChange={handleUsernameChange}
377-
/>
378-
</div>
379-
<div>
380-
password
381-
<input
382-
data-testid='password' // highlight-line
383-
type="password"
384-
value={password}
385-
onChange={handlePasswordChange}
386-
/>
387-
</div>
388-
<button type="submit">
389-
login
390-
</button>
391-
</form>
392-
</div>
393-
)
394-
}
366+
// ...
367+
<form onSubmit={handleSubmit}>
368+
<div>
369+
<label> // highlight-line
370+
username // highlight-line
371+
<input
372+
type="text"
373+
value={username}
374+
onChange={handleUsernameChange}
375+
/>
376+
</label> // highlight-line
377+
</div>
378+
<div>
379+
<label> // highlight-line
380+
password // highlight-line
381+
<input
382+
type="password"
383+
value={password}
384+
onChange={handlePasswordChange}
385+
/>
386+
</label> // highlight-line
387+
</div>
388+
<button type="submit">login</button>
389+
</form>
390+
// ...
395391
```
396392

397-
Test changes as follows:
393+
Input fields can and should be located in tests using <i>labels</i> with the [getByLabel](https://playwright.dev/docs/api/class-page#page-get-by-label) method:
398394

399395
```js
400396
describe('Note app', () => {
@@ -404,8 +400,8 @@ describe('Note app', () => {
404400
await page.goto('http://localhost:5173')
405401

406402
await page.getByRole('button', { name: 'login' }).click()
407-
await page.getByTestId('username').fill('mluukkai') // highlight-line
408-
await page.getByTestId('password').fill('salainen') // highlight-line
403+
await page.getByLabel('username').fill('mluukkai') // highlight-line
404+
await page.getByLabel('password').fill('salainen') // highlight-line
409405

410406
await page.getByRole('button', { name: 'login' }).click()
411407

@@ -414,8 +410,12 @@ describe('Note app', () => {
414410
})
415411
```
416412

413+
When locating elements, it makes sense to aim to utilize the content visible to the user in the interface, as this best simulates how a user would actually find the desired input field while navigating the application.
414+
417415
Note that passing the test at this stage requires that there is a user in the <i>test</i> database of the backend with username <i>mluukkai</i> and password <i>salainen</i>. Create a user if needed!
418416

417+
### Test Initialization
418+
419419
Since both tests start in the same way, i.e. by opening the page <i>http://localhost:5173</i>, it is recommended to isolate the common part in the <i>beforeEach</i> block that is executed before each test:
420420

421421
```js
@@ -436,8 +436,8 @@ describe('Note app', () => {
436436

437437
test('login form can be opened', async ({ page }) => {
438438
await page.getByRole('button', { name: 'login' }).click()
439-
await page.getByTestId('username').fill('mluukkai')
440-
await page.getByTestId('password').fill('salainen')
439+
await page.getByLabel('username').fill('mluukkai')
440+
await page.getByLabel('password').fill('salainen')
441441
await page.getByRole('button', { name: 'login' }).click()
442442
await expect(page.getByText('Matti Luukkainen logged in')).toBeVisible()
443443
})
@@ -457,8 +457,8 @@ describe('Note app', () => {
457457
describe('when logged in', () => {
458458
beforeEach(async ({ page }) => {
459459
await page.getByRole('button', { name: 'login' }).click()
460-
await page.getByTestId('username').fill('mluukkai')
461-
await page.getByTestId('password').fill('salainen')
460+
await page.getByLabel('username').fill('mluukkai')
461+
await page.getByLabel('password').fill('salainen')
462462
await page.getByRole('button', { name: 'login' }).click()
463463
})
464464

@@ -500,17 +500,17 @@ describe('Note app', () => {
500500

501501
test('user can log in', async ({ page }) => {
502502
await page.getByRole('button', { name: 'login' }).click()
503-
await page.getByTestId('username').fill('mluukkai')
504-
await page.getByTestId('password').fill('salainen')
503+
await page.getByLabel('username').fill('mluukkai')
504+
await page.getByLabel('password').fill('salainen')
505505
await page.getByRole('button', { name: 'login' }).click()
506506
await expect(page.getByText('Matti Luukkainen logged in')).toBeVisible()
507507
})
508508

509509
describe('when logged in', () => {
510510
beforeEach(async ({ page }) => {
511511
await page.getByRole('button', { name: 'login' }).click()
512-
await page.getByTestId('username').fill('mluukkai')
513-
await page.getByTestId('password').fill('salainen')
512+
await page.getByLabel('username').fill('mluukkai')
513+
await page.getByLabel('password').fill('salainen')
514514
await page.getByRole('button', { name: 'login' }).click()
515515
})
516516

@@ -667,8 +667,8 @@ describe('Note app', () => {
667667

668668
test('login fails with wrong password', async ({ page }) => {
669669
await page.getByRole('button', { name: 'login' }).click()
670-
await page.getByTestId('username').fill('mluukkai')
671-
await page.getByTestId('password').fill('wrong')
670+
await page.getByLabel('username').fill('mluukkai')
671+
await page.getByLabel('password').fill('wrong')
672672
await page.getByRole('button', { name: 'login' }).click()
673673

674674
await expect(page.getByText('wrong credentials')).toBeVisible()
@@ -729,8 +729,8 @@ Let's finalize the test so that it also ensures that the application **does not
729729
```js
730730
test('login fails with wrong password', async ({ page }) =>{
731731
await page.getByRole('button', { name: 'login' }).click()
732-
await page.getByTestId('username').fill('mluukkai')
733-
await page.getByTestId('password').fill('wrong')
732+
await page.getByLabel('username').fill('mluukkai')
733+
await page.getByLabel('password').fill('wrong')
734734
await page.getByRole('button', { name: 'login' }).click()
735735

736736
const errorDiv = page.locator('.error')
@@ -782,8 +782,8 @@ describe('Note app', () => {
782782

783783
test('user can login with correct credentials', async ({ page }) => {
784784
await page.getByRole('button', { name: 'login' }).click()
785-
await page.getByTestId('username').fill('mluukkai')
786-
await page.getByTestId('password').fill('salainen')
785+
await page.getByLabel('username').fill('mluukkai')
786+
await page.getByLabel('password').fill('salainen')
787787
await page.getByRole('button', { name: 'login' }).click()
788788
await expect(page.getByText('Matti Luukkainen logged in')).toBeVisible()
789789
})
@@ -795,8 +795,8 @@ describe('Note app', () => {
795795
describe('when logged in', () => {
796796
beforeEach(async ({ page, request }) => {
797797
await page.getByRole('button', { name: 'login' }).click()
798-
await page.getByTestId('username').fill('mluukkai')
799-
await page.getByTestId('password').fill('salainen')
798+
await page.getByLabel('username').fill('mluukkai')
799+
await page.getByLabel('password').fill('salainen')
800800
await page.getByRole('button', { name: 'login' }).click()
801801
})
802802

@@ -818,8 +818,8 @@ It is also worth striving for having non-repetitive code in tests. Let's isolate
818818
```js
819819
const loginWith = async (page, username, password) => {
820820
await page.getByRole('button', { name: 'login' }).click()
821-
await page.getByTestId('username').fill(username)
822-
await page.getByTestId('password').fill(password)
821+
await page.getByLabel('username').fill(username)
822+
await page.getByLabel('password').fill(password)
823823
await page.getByRole('button', { name: 'login' }).click()
824824
}
825825

@@ -886,8 +886,8 @@ Creation of a note is also isolated as its helper function. The file _tests/help
886886
```js
887887
const loginWith = async (page, username, password) => {
888888
await page.getByRole('button', { name: 'login' }).click()
889-
await page.getByTestId('username').fill(username)
890-
await page.getByTestId('password').fill(password)
889+
await page.getByLabel('username').fill(username)
890+
await page.getByLabel('password').fill(password)
891891
await page.getByRole('button', { name: 'login' }).click()
892892
}
893893

0 commit comments

Comments
 (0)