1- # Getting Started #3 : From Codegen To Maintainable Tests
1+ # Getting Started #3 : From ` codegen ` To Maintainable Tests
22
33This guide outlines the process of taking a test generated using the ` playwright codegen ` tool to a state where it
44will be easy to maintain going forward.
55
66## Contents
77
8- - [ Getting Started #3 : From Codegen To Maintainable Tests] ( #getting-started-3-from-codegen-to-maintainable-tests )
8+ - [ Getting Started #3 : From ` codegen ` To Maintainable Tests] ( #getting-started-3-from-codegen-to-maintainable-tests )
99 - [ Contents] ( #contents )
1010 - [ Setting The Scene] ( #setting-the-scene )
1111 - [ Using ` codegen ` For A Test] ( #using-codegen-for-a-test )
12+ - [ Breaking The Test Down] ( #breaking-the-test-down )
13+ - [ Creating A Sign In Utility] ( #creating-a-sign-in-utility )
1214
1315## Setting The Scene
1416
@@ -20,18 +22,102 @@ To start, here is our application under test for the purposes of this guide:
2022- Login Screen: A simple username / password login screen.
2123
2224<!-- vale off -->
23- ![ An image of the Example Application login screen] ( ./img/3-1_example_login.png " Example login screen with a username and password field ")
25+ ![ An image of the example application login screen] ( ./img/3-1_example_login.png " Example login screen with a username and password field ")
2426<!-- vale on -->
2527
2628- Main Menu: The landing page once logged in.
2729
2830<!-- vale off -->
29- ![ An image of the Example Application home screen] ( ./img/3-2_example_home.png " Example home screen with a navigation menu, news and alerts section ")
31+ ![ An image of the example application home screen] ( ./img/3-2_example_home.png " Example home screen with a navigation menu, news and alerts section ")
3032<!-- vale on -->
3133
3234- Search Patient: Some functionality to search for patients in our application.
3335
36+ <!-- vale off -->
37+ ![ An image of the example application search patient screen] ( ./img/3-2_example_home.png " Example search patient screen with a search field and table ")
38+ <!-- vale on -->
39+
3440- View Patient: A page for viewing the patient we have selected from the search menu.
3541
42+ <!-- vale off -->
43+ ![ An image of the example application view patient screen] ( ./img/3-2_example_home.png " Example view patient screen showing an example patient ")
44+ <!-- vale on -->
45+
3646## Using ` codegen ` For A Test
3747
48+ To get our first test, we will use the ` codegen ` tool by using the following command:
49+
50+ playwright codegen <link to example application>
51+
52+ We then navigate through the application to do an assertion of the View Patient screen, doing the following actions:
53+
54+ 1 . Navigate to example application to reach the Sign In screen
55+ 2 . Click on the Username field and enter a test username ("Test")
56+ 3 . Click on the Password field and enter a test password ("test")
57+ 4 . Press the Sign In button to reach the Home / Welcome screen
58+ 5 . Click on the Search button in the navigation menu to reach the Search screen
59+ 6 . Click on the Patient Name field and enter a test patient ("Test Patient")
60+ 7 . Press the Search button to populate the results table
61+ 8 . Select the top result from the table and press the View button to reach the View Patient screen
62+ 9 . On the View Patient screen, confirm we've hit the correct screen by asserting the header of this screen is "View Patient"
63+
64+ This generates the following code (when setting ` pytest ` as the Target):
65+
66+ import re
67+ from playwright.sync_api import Page, expect
68+
69+
70+ def test_example(page: Page) -> None:
71+ page.goto("https://<example application url>/signin")
72+ page.get_by_role("textbox", name="Username").click()
73+ page.get_by_role("textbox", name="Username").fill("Test")
74+ page.get_by_role("textbox", name="Password").click()
75+ page.get_by_role("textbox", name="Password").fill("test")
76+ page.get_by_role("button", name="submit").click()
77+ page.get_by_role("link", name="Search").click()
78+ page.get_by_role("textbox", name="Patient Name").click()
79+ page.get_by_role("textbox", name="Patient Name").fill("Test Patient")
80+ page.get_by_role("button", name="search").click()
81+ page.get_by_role("button", name="view").nth(0).click()
82+ expect(page.get_by_role("heading")).to_contain_text("View Patient")
83+
84+ The immediate thing to notice with this test is that whilst it may work, there are a number of parts with this test
85+ that could easily be refactored or reworked in a way that could be utilised by multiple tests. There is also scope to
86+ add value to this test, and reduce the scope for potential flakiness.
87+
88+ ## Breaking The Test Down
89+
90+ Our first step with refining this test is to break down the individual components of the test, to work out logical points
91+ of reuse. The main things to consider with this are:
92+
93+ - Are there any steps that are repeatable or we would want to use many times?
94+ - Are there any consistent elements across the pages we are navigating through?
95+ - When running this test as-is, are there any areas which are prone to failure or flakiness?
96+
97+ The first part is the sign in step, which is likely applicable to every test we may want to run against this UI:
98+
99+ page.goto("https://<example application url>/signin")
100+ page.get_by_role("textbox", name="Username").click()
101+ page.get_by_role("textbox", name="Username").fill("Test")
102+ page.get_by_role("textbox", name="Password").click()
103+ page.get_by_role("textbox", name="Password").fill("test")
104+ page.get_by_role("button", name="submit").click()
105+
106+ The next part is navigating to the Search screen, which is a simple step but one we may wish to reuse many times across multiple tests:
107+
108+ page.get_by_role("link", name="Search").click()
109+
110+ The third part is the search of the patient on the Search screen itself and selecting the first entry:
111+
112+ page.get_by_role("textbox", name="Patient Name").click()
113+ page.get_by_role("textbox", name="Patient Name").fill("Test Patient")
114+ page.get_by_role("button", name="search").click()
115+ page.get_by_role("button", name="view").nth(0).click()
116+
117+ The final part is the assertion of the View Patient header once selecting a patient:
118+
119+ expect(page.get_by_role("heading")).to_contain_text("View Patient")
120+
121+ ## Creating A Sign In Utility
122+
123+ To do
0 commit comments