Skip to content

Commit b6e4916

Browse files
committed
part5d fixes
1 parent e305d11 commit b6e4916

File tree

1 file changed

+81
-45
lines changed

1 file changed

+81
-45
lines changed

src/content/5/fi/osa5d.md

Lines changed: 81 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Jos valintasi on Playwright, jatka eteenpäin. Jos päädyt käyttämään Cypre
3535

3636
Kirjastojen vertailuista on kirjoitettu monia blojeja, esim. [tämä](https://www.lambdatest.com/blog/cypress-vs-playwright/) ja [tämä](https://www.browserstack.com/guide/playwright-vs-cypress).
3737

38-
On vaikea sanoa kumpi kirjastoista on parempi. Eräs Playwrightin etu on sen selaintuki, Playwright tukee Chromea, Firefoxia ja Webkit-pohjaisia selaimia kuten Safaria. Nykyisin Cypress sisältää tuen kaikkiin näihin selaimiin, Webkit-tuki on tosin vasta kokeellinen ja ei tue kaikkia Cypressin ominaisuuksia. Oma preferenssini kallisuu kirjoitushetkellö (29.2.2024) hieman Playwrightin puolelle.
38+
On vaikea sanoa kumpi kirjastoista on parempi. Eräs Playwrightin etu on sen selaintuki, Playwright tukee Chromea, Firefoxia ja Webkit-pohjaisia selaimia kuten Safaria. Nykyisin Cypress sisältää tuen kaikkiin näihin selaimiin, Webkit-tuki on tosin vasta kokeellinen ja ei tue kaikkia Cypressin ominaisuuksia. Oma preferenssini kallisuu kirjoitushetkellö (1.3.2024) hieman Playwrightin puolelle.
3939

4040
Tutustutaan nyt Playwrightin käyttöön.
4141

@@ -164,7 +164,7 @@ test('front page can be opened', async ({ page }) => {
164164

165165
const locator = await page.getByText('Notes')
166166
await expect(locator).toBeVisible()
167-
await expect(await page.getByText('Note app, Department of Computer Science, University of Helsinki 2023')).toBeVisible()
167+
await expect(page.getByText('Note app, Department of Computer Science, University of Helsinki 2023')).toBeVisible()
168168
})
169169
```
170170

@@ -389,7 +389,7 @@ describe('Note app', () => {
389389

390390
await page.getByRole('button', { name: 'login' }).click()
391391

392-
await expect(await page.getByText('Matti Luukkainen logged in')).toBeVisible()
392+
await expect(page.getByText('Matti Luukkainen logged in')).toBeVisible()
393393
})
394394
})
395395
```
@@ -413,15 +413,15 @@ describe('Note app', () => {
413413
test('front page can be opened', async ({ page }) => {
414414
const locator = await page.getByText('Notes')
415415
await expect(locator).toBeVisible()
416-
await expect(await page.getByText('Note app, Department of Computer Science, University of Helsinki 2024')).toBeVisible()
416+
await expect(page.getByText('Note app, Department of Computer Science, University of Helsinki 2024')).toBeVisible()
417417
})
418418

419419
test('login form can be opened', async ({ page }) => {
420420
await page.getByRole('button', { name: 'log in' }).click()
421421
await page.getByTestId('username').fill('mluukkai')
422422
await page.getByTestId('password').fill('salainen')
423423
await page.getByRole('button', { name: 'login' }).click()
424-
await expect(await page.getByText('Matti Luukkainen logged in')).toBeVisible()
424+
await expect(page.getByText('Matti Luukkainen logged in')).toBeVisible()
425425
})
426426
})
427427

@@ -449,7 +449,7 @@ describe('Note app', () => {
449449
await page.getByRole('button', { name: 'new note' }).click()
450450
await page.getByRole('textbox').fill('a note created by playwright')
451451
await page.getByRole('button', { name: 'save' }).click()
452-
await expect(await page.getByText('a note created by playwright')).toBeVisible()
452+
await expect(page.getByText('a note created by playwright')).toBeVisible()
453453
})
454454
})
455455
})
@@ -469,7 +469,7 @@ Jos kenttiä olisi useampia, testi hajoaisi Tämän takia olisi jälleen parempi
469469
**Huom:** testi ei mene läpi kuin ensimmäisellä kerralla suoritettaessa. Syynä tälle on se, että ekspektaatio
470470

471471
```js
472-
await expect(await page.getByText('a note created by playwright')).toBeVisible()
472+
await expect(page.getByText('a note created by playwright')).toBeVisible()
473473
```
474474

475475
aiheuttaa ongelmia siinä vaiheessa kun sovellukseen luodaan sama muistiinpano useammin kuin kertaalleen. Ongelmasta päästään eroon seuraavassa luvussa.
@@ -487,7 +487,7 @@ describe('Note app', () => {
487487
await page.getByTestId('username').fill('mluukkai')
488488
await page.getByTestId('password').fill('salainen')
489489
await page.getByRole('button', { name: 'login' }).click()
490-
await expect(await page.getByText('Matti Luukkainen logged in')).toBeVisible()
490+
await expect(page.getByText('Matti Luukkainen logged in')).toBeVisible()
491491
})
492492

493493
describe('when logged in', () => {
@@ -502,7 +502,7 @@ describe('Note app', () => {
502502
await page.getByRole('button', { name: 'new note' }).click()
503503
await page.getByRole('textbox').fill('a note created by playwright')
504504
await page.getByRole('button', { name: 'save' }).click()
505-
await expect(await page.getByText('a note created by playwright')).toBeVisible()
505+
await expect(page.getByText('a note created by playwright')).toBeVisible()
506506
})
507507
})
508508
})
@@ -619,14 +619,14 @@ describe('Note app', () => {
619619

620620
test('importance can be changed', async ({ page }) => {
621621
await page.getByRole('button', { name: 'make not important' }).click()
622-
await expect(await page.getByText('make important')).toBeVisible()
622+
await expect(page.getByText('make important')).toBeVisible()
623623
})
624624
})
625625
})
626626
})
627627
```
628628

629-
Ensimmäinen komento etsii ensin komponentin, missä on teksti <i>another note cypress</i> ja sen sisältä painikkeen <i>make not important</i> ja klikkaa sitä.
629+
Ensimmäinen komento etsii ensin komponentin, missä on teksti <i>another note by playwright</i> ja sen sisältä painikkeen <i>make not important</i> ja klikkaa sitä.
630630

631631
Toinen komento varmistaa, että saman napin teksti on vaihtunut muotoon <i>make important</i>.
632632

@@ -650,7 +650,7 @@ describe('Note app', () => {
650650
await page.getByTestId('password').fill('wrong')
651651
await page.getByRole('button', { name: 'login' }).click()
652652

653-
await expect(await page.getByText('wrong credentials')).toBeVisible()
653+
await expect(page.getByText('wrong credentials')).toBeVisible()
654654
})
655655

656656
// ...
@@ -718,7 +718,7 @@ test('login fails with wrong password', async ({ page }) =>{
718718
await expect(errorDiv).toHaveCSS('border-style', 'solid')
719719
await expect(errorDiv).toHaveCSS('color', 'rgb(255, 0, 0)')
720720

721-
await expect(await page.getByText('Matti Luukkainen logged in')).not.toBeVisible() // highlight-line
721+
await expect(page.getByText('Matti Luukkainen logged in')).not.toBeVisible() // highlight-line
722722
})
723723
```
724724
@@ -765,7 +765,7 @@ describe('Note app', () => {
765765
await page.getByTestId('username').fill('mluukkai')
766766
await page.getByTestId('password').fill('salainen')
767767
await page.getByRole('button', { name: 'login' }).click()
768-
await expect(await page.getByText('Matti Luukkainen logged in')).toBeVisible()
768+
await expect(page.getByText('Matti Luukkainen logged in')).toBeVisible()
769769
})
770770

771771
test('login fails with wrong password', async ({ page }) =>{
@@ -815,7 +815,7 @@ const { loginWith } = require('./helper')
815815
describe('Note app', () => {
816816
test('user can log in', async ({ page }) => {
817817
await loginWith(page, 'mluukkai', 'salainen')
818-
await expect(await page.getByText('Matti Luukkainen logged in')).toBeVisible()
818+
await expect(page.getByText('Matti Luukkainen logged in')).toBeVisible()
819819
})
820820

821821
describe('when logged in', () => {
@@ -896,7 +896,7 @@ describe('Note app', () => {
896896

897897
test('a new note can be created', async ({ page }) => {
898898
await createNote(page, 'a note created by playwright', true)
899-
await expect(await page.getByText('a note created by playwright')).toBeVisible()
899+
await expect(page.getByText('a note created by playwright')).toBeVisible()
900900
})
901901

902902
describe('and a note exists', () => {
@@ -906,7 +906,7 @@ describe('Note app', () => {
906906

907907
test('importance can be changed', async ({ page }) => {
908908
await page.getByRole('button', { name: 'make not important' }).click()
909-
await expect(await page.getByText('make important')).toBeVisible()
909+
await expect(page.getByText('make important')).toBeVisible()
910910
})
911911
})
912912
})
@@ -959,45 +959,49 @@ await page.post('/api/tests/reset')
959959
960960
Testien tämänhetkinen koodi on [GitHubissa](https://github.com/fullstack-hy2020/notes-e2e/tree/part5-2), branchissa <i>part5-2</i>.
961961
962-
### Muistiinpanon tärkeyden muutos
962+
### Muistiinpanon tärkeyden muutos revisited
963+
964+
Tarkastellaan vielä aiemmin tekemäämme testiä, joka varmistaa että muistiinpanon tärkeyttä on mahdollista muuttaa.
963965
964-
Tarkastellaan vielä aiemmin tekemäämme testiä, joka varmistaa että muistiinpanon tärkeyttä on mahdollista muuttaa. Muutetaan testin alustuslohkoa siten, että se luo yhden sijaan kolme muistiinpanoa:
966+
Muutetaan testin alustuslohkoa siten, että se luo yhden sijaan kaksi muistiinpanoa:
965967
966968
```js
967969
describe('when logged in', () => {
968970
// ...
969971
describe('and several notes exists', () => {
970-
beforeEach(async ({ page, request }) => {
972+
beforeEach(async ({ page }) => {
971973
// highlight-start
972-
await createNote(page, request, 'first note', true)
973-
await createNote(page, request, 'second note', true)
974-
await createNote(page, request, 'third note', true)
974+
await createNote(page, 'first note', true)
975+
await createNote(page, 'second note', true)
975976
// highlight-end
976977
})
977978

978-
test('one of those can be made important', async ({ page }) => {
979-
const secondNoteElement = await page.getByText('second note')
979+
test('one of those can be made nonimportant', async ({ page }) => {
980+
const otherNoteElement = await page.getByText('first note')
980981

981-
await secondNoteElement.getByRole('button', { name: 'make not important' }).click()
982-
await expect(secondNoteElement.getByText('make important')).toBeVisible()
982+
await otherNoteElement
983+
.getByRole('button', { name: 'make not important' }).click()
984+
await expect(otherNoteElement.getByText('make important')).toBeVisible()
983985
})
984986
})
985987
})
986988
```
987989
988-
Testi etsii nyt metodin _getByRole_ avulla toisena luodun muistiinpanoa vastaavan elementin ja tallettaa sen muuttujaan. Tämän jälkeen elementin sisältä etsitään nappi missä on teksti _make not important_ ja painetaan sitä. Lopuksi teksi varmistaa että napin teksiksi on muuttunut _make important_.
990+
Testi etsii ensin metodin _getByRole_ avulla ensimmäisenä luotua muistiinpanoa vastaavan elementin ja tallettaa sen muuttujaan. Tämän jälkeen elementin sisältä etsitään nappi, missä on teksti _make not important_ ja painetaan nappia. Lopuksi teksi varmistaa että napin teksiksi on muuttunut _make important_.
989991
990992
Testi olisi voitu kirjoittaa myös ilman apumuuttujaa:
991993
992994
```js
993-
test('one of those can be made important', async ({ page }) => {
994-
await page.getByText('second note').getByRole('button', { name: 'make not important' }).click()
995+
test('one of those can be made nonimportant', async ({ page }) => {
996+
await page.getByText('first note')
997+
.getByRole('button', { name: 'make not important' }).click()
995998

996-
await expect(wait page.getByText('second note').getByText('make important')).toBeVisible()
999+
await expect(page.getByText('first note').getByText('make important'))
1000+
.toBeVisible()
9971001
})
9981002
```
9991003
1000-
Muutetaan komponenttia _Note_ siten, että muistiinpanon teksti renderöitään <i>span</i>-komponentin sisälle
1004+
Muutetaan komponenttia _Note_ siten, että muistiinpanon teksti renderöitään _span_-elementin sisälle
10011005
10021006
```js
10031007
const Note = ({ note, toggleImportance }) => {
@@ -1013,36 +1017,68 @@ const Note = ({ note, toggleImportance }) => {
10131017
}
10141018
```
10151019
1016-
Testit hajoavat! Kuten test runner paljastaa, komento _await page.getByText('second note')_ palauttaakin nyt ainoastaan tekstin sisältävän komponentin, ja nappi on sen ulkopuolella.
1017-
1020+
Testit hajoavat! Syynä ongelmalle on se, komento _await page.getByText('second note')_ palauttaakin nyt ainoastaan tekstin sisältävän _span_-elementin, ja nappi on sen ulkopuolella.
10181021
10191022
Eräs tapa korjata ongelma on seuraavassa:
10201023
10211024
```js
1022-
test('one of those can be made important', async ({ page }) => {
1023-
const secondNoteText = await page.getByText('second note') // highlight-line
1024-
const secondNoteElement = await secondNoteText.locator('..') // highlight-line
1025+
test('one of those can be made nonimportant', async ({ page }) => {
1026+
const otherNoteText = await page.getByText('first note') // highlight-line
1027+
const otherdNoteElement = await otherNoteText.locator('..') // highlight-line
10251028

1026-
await secondNoteElement.getByRole('button', { name: 'make not important' }).click()
1027-
await expect(secondNoteElement.getByText('make important')).toBeVisible()
1029+
await otherdNoteElement.getByRole('button', { name: 'make not important' }).click()
1030+
await expect(otherdNoteElement.getByText('make important')).toBeVisible()
10281031
})
10291032
```
10301033
1031-
Ensimmäinen rivi etsii nyt toiseen muistiinpanoon liittyvän tekstin sisältävän _span_-elementin. Toisella rivillä käytetään funktiota _locator_ ja annetaan parametriksi _.._, joka hakee elementin vanhempielementin. Funktio locator on hyvin joustava, ja hyödynnämme tässä sitä että se hyväksyy [parametrikseen](https://playwright.dev/docs/locators#locate-by-css-or-xpath) CSS-selektorien lisäksi myös [XPath](https://developer.mozilla.org/en-US/docs/Web/XPath)-muotoisen selektorin. Sama olisi mahdollista ilmaista myös CSS:n avulla, mutta tässä tapauksessa XPath tarjoaa yksinkertaisimman tavan elementin vanhemman etsimiseen.
1034+
Ensimmäinen rivi etsii nyt ensimmäisenä luotuun muistiinpanoon liittyvän tekstin sisältävän _span_-elementin. Toisella rivillä käytetään funktiota _locator_ ja annetaan parametriksi _.._, joka hakee elementin vanhempielementin. Funktio locator on hyvin joustava, ja hyödynnämme tässä sitä että funktio hyväksyy [parametrikseen](https://playwright.dev/docs/locators#locate-by-css-or-xpath) CSS-selektorien lisäksi myös [XPath](https://developer.mozilla.org/en-US/docs/Web/XPath)-muotoisen selektorin. Sama olisi mahdollista ilmaista myös CSS:n avulla, mutta tässä tapauksessa XPath tarjoaa yksinkertaisimman tavan elementin vanhemman etsimiseen.
10321035
10331036
Testi voidaan toki kirjoittaa myös ainoastaan yhtä apumuuttujaa käyttäen:
10341037
10351038
```js
1036-
test('one of those can be made important', async ({ page }) => {
1039+
test('one of those can be made nonimportant', async ({ page }) => {
10371040
const secondNoteElement = await page.getByText('second note').locator('..')
10381041
await secondNoteElement.getByRole('button', { name: 'make not important' }).click()
10391042
await expect(secondNoteElement.getByText('make important')).toBeVisible()
10401043
})
10411044
```
10421045
1046+
Muutentaan testiä vielä siten, että muistiinpanoja luodaankin kolme, ja tärkeyttä vaihdetaan toisena luodulta muistiinpanolta:
1047+
1048+
```js
1049+
describe('when logged in', () => {
1050+
beforeEach(async ({ page }) => {
1051+
await loginWith(page, 'mluukkai', 'salainen')
1052+
})
1053+
1054+
test('a new note can be created', async ({ page }) => {
1055+
await createNote(page, 'a note created by playwright', true)
1056+
await expect(page.getByText('a note created by playwright')).toBeVisible()
1057+
})
1058+
1059+
describe('and a note exists', () => {
1060+
beforeEach(async ({ page }) => {
1061+
await createNote(page, 'first note', true)
1062+
await createNote(page, 'second note', true)
1063+
await createNote(page, 'third note', true) // highlight-line
1064+
})
1065+
1066+
test('importance can be changed', async ({ page }) => {
1067+
const otherNoteText = await page.getByText('second note') // highlight-line
1068+
const otherdNoteElement = await otherNoteText.locator('..')
1069+
1070+
await otherdNoteElement.getByRole('button', { name: 'make not important' }).click()
1071+
await expect(otherdNoteElement.getByText('make important')).toBeVisible()
1072+
})
1073+
})
1074+
})
1075+
```
1076+
1077+
Jostain syystä testi alkaa toimia epäluotettavaksi, se menee välillä läpi ja välillä ei. On aika kääriä hihat ja opetella debuggaamaan testejä.
1078+
10431079
### Testien kehittäminen ja debuggaaminen
10441080
1045-
Playwright tarjoaa muutamia melki hyviä testin kehittämistä ja debuggaamista auttavia työkaluja. [Dokumentaatiota](https://playwright.dev/docs/intro) kannattaa ehdottomasti selailla, eritysen tärkeitä ovat
1081+
Playwright tarjoaa muutamia melko hyviä testin kehittämistä ja debuggaamista auttavia työkaluja. [Dokumentaatiota](https://playwright.dev/docs/intro) kannattaa ehdottomasti selailla, eritysen tärkeitä ovat
10461082
- [lokaattoreita](https://playwright.dev/docs/locators) kertova osa antaa hyviä vihjeitä testattavien elementtien etsimiseen
10471083
- osa [actions](https://playwright.dev/docs/input) kertoo miten selaimen kanssa käytävää vuorovaikutusta on mahdollista simuloida testeissä
10481084
- [assertioista](https://playwright.dev/docs/test-assertions) kertova osa demonstroi mitä erilaisia testauksessa käytettäviä ekspektaatioita Playwright tarjoaa
@@ -1081,7 +1117,7 @@ describe('Note app', () => {
10811117
await createNote(page, 'third note')
10821118
})
10831119

1084-
test('one of those can be made important', async ({ page }) => {
1120+
test('one of those can be made nonimportant', async ({ page }) => {
10851121
await page.pause() // highlight-line
10861122
const secondNoteElement = await page.getByText('second note').locator('..')
10871123
await secondNoteElement.getByRole('button', { name: 'make not important' }).click()
@@ -1114,7 +1150,7 @@ describe('and several notes exists', () => {
11141150
await createNote(page, 'third note')
11151151
})
11161152

1117-
test('one of those can be made important', async ({ page }) => {
1153+
test('one of those can be made nonimportant', async ({ page }) => {
11181154
const secondNoteElement = await page.getByText('second note').locator('..')
11191155
await secondNoteElement.getByRole('button', { name: 'make not important' }).click()
11201156
await expect(secondNoteElement.getByText('make important')).toBeVisible()
@@ -1183,7 +1219,7 @@ Testigeneraattori _Record_-tilan päälläollessa käyttäjän interaktion Playw
11831219
11841220
Komentorivin sijaan Playwrightiä voi käyttää myös [VS Code](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright)-pluginin kautta. Plugin tarjoaa monia käteviä ominaisuuksia, mm. breakpointien käytön testejä debugatessa.
11851221
1186-
Testien lopullinen versio on kokonaisuudessaan [GitHubissa](https://github.com/fullstack-hy2020/part2-notes-frontend/tree/part5-11), branchissa <i>part5-11</i>.
1222+
Testien lopullinen versio on kokonaisuudessaan [GitHubissa](https://github.com/fullstack-hy2020/notes-e2e/tree/part5-3), branchissa <i>part5-3</i>.
11871223
11881224
</div>
11891225

0 commit comments

Comments
 (0)