<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:space="preserve" xmlns="http://www.tei-c.org/ns/1.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.tei-c.org/ns/1.0 https://raw.githubusercontent.com/kermitt2/grobid/master/grobid-home/schemas/xsd/Grobid.xsd"
 xmlns:xlink="http://www.w3.org/1999/xlink">
	<teiHeader xml:lang="en">
		<fileDesc>
			<titleStmt>
				<title level="a" type="main">Implementing E2E tests with Cypress and Page Object Model: evolution of approaches</title>
			</titleStmt>
			<publicationStmt>
				<publisher/>
				<availability status="unknown"><licence/></availability>
			</publicationStmt>
			<sourceDesc>
				<biblStruct>
					<analytic>
						<author role="corresp">
							<persName><forename type="first">Inessa</forename><forename type="middle">V</forename><surname>Krasnokutska</surname></persName>
							<email>i.krasnokutska@chnu.edu.ua</email>
						</author>
						<author>
							<persName><forename type="first">Oleksandr</forename><forename type="middle">S</forename><surname>Krasnokutskyi</surname></persName>
						</author>
						<author>
							<affiliation key="aff0">
								<orgName type="institution">Yuriy Fedkovych Chernivtsi National University</orgName>
								<address>
									<addrLine>2 Kotsiubynskoho Str</addrLine>
									<postCode>58002</postCode>
									<settlement>Chernivtsi</settlement>
									<country key="UA">Ukraine</country>
								</address>
							</affiliation>
						</author>
						<author>
							<affiliation key="aff1">
								<orgName type="department">Workshop for Young Scientists in Computer Science &amp; Software Engineering</orgName>
								<address>
									<addrLine>February 2</addrLine>
									<postCode>2024</postCode>
									<settlement>Kryvyi Rih</settlement>
									<country key="UA">Ukraine</country>
								</address>
							</affiliation>
						</author>
						<title level="a" type="main">Implementing E2E tests with Cypress and Page Object Model: evolution of approaches</title>
					</analytic>
					<monogr>
						<idno type="ISSN">1613-0073</idno>
					</monogr>
					<idno type="MD5">599364A5EBB89F5D777524E1009E4D8B</idno>
				</biblStruct>
			</sourceDesc>
		</fileDesc>
		<encodingDesc>
			<appInfo>
				<application version="0.7.2" ident="GROBID" when="2025-04-23T16:25+0000">
					<desc>GROBID - A machine learning software for extracting information from scholarly documents</desc>
					<ref target="https://github.com/kermitt2/grobid"/>
				</application>
			</appInfo>
		</encodingDesc>
		<profileDesc>
			<textClass>
				<keywords>
					<term>Cypress JS</term>
					<term>Page Object Model</term>
					<term>POM design pattern</term>
					<term>automation testing</term>
					<term>E2E tests</term>
				</keywords>
			</textClass>
			<abstract>
<div xmlns="http://www.tei-c.org/ns/1.0"><p>This article shows eight approaches how to construct Cypress tests using POM. The connections between them are stressed as their evolution while writing code developing E2E tests. The authors highlight advantages and disadvantages of the approaches and offer the solution of problems. This article can be used both as a combined overview of different approaches and as a manual for those who are struggling to write tests with Cypress in a better way.</p></div>
			</abstract>
		</profileDesc>
	</teiHeader>
	<text xml:lang="en">
		<body>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="1.">Introduction</head><p>Suppose we have a problem to cover the functionality of certain website with automation tests. For instance we can consider the website https://www.saucedemo.com/v1/index.html without loss of generality. The website is devoted to illustrating of different test cases that occur during unsuccessful login process. It contains the form with username and password fields to get the access to the next page, and in case of unsuccessful log in, the error message with corresponding text is shown. This website is convenient to be used as a model example for all typical flows of users behaviour that could be covered by tests with a minimum amount of effort.</p><p>Successful login without any doubt as a positive test case means inputting correct username and password. Negative tests occur when a user is left on the same page and an appropriate error message is shown. It can happen when a user enters an empty or wrong username or password. Different tests can be considered to cover those cases. However, taking into account that most of developed tests are quite similar and optimising the cases authors demonstrate only valuable and significant of them in this article. More test cases can be found in the project repository at https://github.com/InaKrasnokutska/CypressPOM. To run the solution you just need to pull and run npm i to setup dependencies, and later npm run cy:open to see how it works.</p><p>Cypress is chosen to demonstrate how to create tests in different manners. All pros and cons of each approach are analysed and highlighted. There is a lack of good resources on the Internet about usage of the Page Object design pattern in Cypress Cypress <ref type="bibr" target="#b0">[1]</ref>, and each resource shows only one point of view and it is hard to understand the correlation between them.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.">Main results</head><p>All possible variations of implementing Page Object Model (POM) are constructed in this article. It happens when a locked out user enters his/her username and password and receives an appropriate error message. Other test cases can be found at https://github.com/InaKrasnokutska/CypressPOM. In the next subsections we will discuss 9 approaches to organise selected test case. For convenience and quick search of files with tests (specs) in the repository they have names according to subsection numbers in this article where they are discussed.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.1.">Tests without POM</head><p>Before diving into the Page Object design pattern, let us create a Cypress test without it.</p><p>According to this decision the code appears very strict forward because in the spec file we need to prescribe the interaction with each DOM element of the page. This interaction is done with the help of the function cy.get() that locates an element with the corresponding selector of the element passed into it as the parameter.</p><p>Next we emulate the user's action by typing username and password and clicking the button (.type() and .click() functions). At the end of the scenario we validate the error message using .should() function for assertion. This approach lets us to obtain expected result of testing but in the same time it does not fit list of quality criteria <ref type="bibr" target="#b1">[2]</ref> because of • complexity of maintenance and updating, • level of duplication increase dependent on covered scenarios growth, • violation of principles: KISS, DRY, SOLID etc.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.2.">Tests with POM using selectors for elements</head><p>For improving the code above let us use the Page Object design pattern and update the code according to style used in Selenium/Java <ref type="bibr" target="#b2">[3]</ref>.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.2.1.">POM using selectors</head><p>First of all, we describe the class that contains selectors of elements in variables. Then, implementing functions and locators we use selectors predefined in variables. Here locators are implemented with cy.get() help and are used to perform actions on page. Considering pros and cons of this approach, we can say that it isolates the logics of selecting elements apart from processing scenarios. This isolation improves disadvantages illuminated in the previous approach. At the same time this approach has disadvantage because assertions are performed by class methods, and it is better to leave assertions in the spec file.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.2.2.">POM using getter for error message</head><p>Thus, the next step of optimization is extension of class functionality for providing a possibility to make assertions within the spec file.</p><p>With this aim, let us define a function in class that will give access to the element, a kind of getter for error messages.</p><p>Listing 4: File login_2. As a result of optimisation we obtained improvement of code. However, at the same time, the code is still not uniformed, as one element on the page has accessor function, and others do not have. Code can be understood better when we suppose that the necessity to call those elements directly in a spec file exists. For instance, when we need to verify that in case of unsuccessful username input the element changes its style (red color etc.).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.2.3.">POM using getters for all elements</head><p>Let us eliminate the shortcomings of the previous version and define functions for access to each page element.  Evaluating the code, we observe that it currently seems overloaded with functions. That happens because we keep separately selectors of each element and create distinct functions to access each element that with help of selectors return us the locators of elements.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.3.">Tests with POM using locators for elements</head><p>One of the methods to simplify and optimise the code is the union of selectors and locators. It can be done because out of class only wrapped elements are used to perform actions on them. That is why there is no sense to keep distinct properties only for selectors.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.3.1.">POM using named functions as locators</head><p>Let us delete from the previous variant all the variables for selectors and strictly pass selectors as arguments in cy.get(). Each locator is obtained as a method that returns the element. As a consequence the tests in spec_2.3.1.cy.js look the same as ones in spec_2.2.2.cy.js and work as well.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.3.2.">POM with anonymous functions as locators</head><p>Another way to define methods is the usage of anonymous functions. Function expressions are not hoisted, which means it is created only when the execution flow reaches it and can be used from that moment onwards.</p><p>Listing 8: Part of file login_2.3.2.page.js g e t U s e r n a m e I n p u t = f u n c t i o n ( ) { return cy . g e t ( ' # u s e r −name ' ) ; } g e t P a s s w o r d I n p u t = f u n c t i o n ( ) { return cy . g e t ( ' # p a s s w o r d ' ) ; } g e t L o g i n B u t t o n = f u n c t i o n ( ) { return cy . g e t ( ' # l o g i n − b u t t o n ' ) ; } g e t E r r o r M e s s a g e = f u n c t i o n ( ) { return cy . g e t ( ' [ d a t a − t e s t = " e r r o r " ] ' ) ; }</p><p>The same as in the previous case, tests do not have changes (tests in spec_2.2.3.cy.js are the same as in spec_2.2.2.cy.js).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.4.">Tests using POM using locators in elements object</head><p>The usage of previous approach does not make semantic separation between different parts of the Page Object file, that is why we can perform aggregation and place locators into the elements object thereby dividing the functions into two groups: functions devoted to access elements and functions devoted to actions.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.4.1.">POM using locators as functions in elements object</head><p>Let us use getters names as the keys and locators functions as the values in elements. According to this approach we refer firstly to the elements object and then to corresponding function every time we need to refer to the locators functions in code of action functions. Similar style we need to keep in the spec code also. This approach can be found on some legacy projects or on projects not supporting modern stack.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.4.2.">POM using arrow functions as locators in elements object</head><p>Analyzing a block of elements we can note that it contains a long construction function() { return . . . } and the idea to shorten or optimize it appears. It can be done if the project uses standard JavaScript EcmaScript 6 or higher. Then, using arrow functions syntax we can obtain a more concise look of code. Investigating available articles on this topic we found out that most of the resources on the Internet recommend writing code with POM as it is shown in this subsection. However, in most cases they use incorrect names for functions in the elements object. The emphasis is on the subject and not on performing an action over the subject (verbs get, take etc. are omitted), for instance usernameInput(), loginButton(). When we need to refer to the part of elements in the tests definitely we want to name the elements as a noun, but round brackets for function call cannot be omitted. In that way code looks incomprehensible and weird violating name convention (loginPage.elements.errorMessage().should('be.visible')).</p><p>On the one hand this kind of names has benefits because they are used to denote locators of elements. But on the other hand it has the drawback: this part of code is performing some action and first of all it is a function and it should respect the name conventions for functions.</p></div><figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_0"><head>Figure 1 :</head><label>1</label><figDesc>Figure 1: Test cases you can find at https://github.com/InaKrasnokutska/CypressPOM and run in Cypress.</figDesc><graphic coords="2,191.01,84.19,213.25,103.00" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_1"><head>Figure 2 :</head><label>2</label><figDesc>Figure 2: Error message the locked out user tries to log in.</figDesc><graphic coords="2,200.26,365.32,194.75,127.25" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_2"><head>Figure 3 :</head><label>3</label><figDesc>Figure 3: Spec's names corresponding to subsections where they were discussed.</figDesc><graphic coords="3,243.26,84.19,108.75,171.50" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_3"><head>Listing 2 :</head><label>2</label><figDesc>File login_2.2.1.page.js c l a s s MainPage { u s e r n a m e I n p u t S e l e c t o r = ' # u s e r −name ' ; p a s s w o r d I n p u t S e l e c t o r = ' # p a s s w o r d ' ; l o g i n B u t t o n S e l e c t o r = ' # l o g i n − b u t t o n ' ; e r r o r M e s s a g e S e l e c t o r = ' [ d a t a − t e s t = " e r r o r " ] ' ; t y p e U s e r n a m e I n p u t ( username ) { cy . g e t ( t h i s . u s e r n a m e I n p u t S e l e c t o r ) . type ( username ) ; } t y p e P a s s w o r d I n p u t ( p a s s w o r d ) { cy . g e t ( t h i s . p a s s w o r d I n p u t S e l e c t o r ) . type ( p a s s w o r d ) ; } c l i c k L o g i n B u t t o n ( ) { cy . g e t ( t h i s . l o g i n B u t t o n S e l e c t o r ) . c l i c k ( ) ; } c h e c k E r r o r M e s s a g e ( message ) { cy . g e t ( t h i s . e r r o r M e s s a g e S e l e c t o r ) . s h o u l d ( ' be . v i s i b l e ' ) . and ( ' c o n t a i n . t e x t ' , message ) ; } } module . e x p o r t s = new L o g i n P a g e ( ) ; As a result spec file will take the following form. Listing 3: File spec_2.2.1.cy.js import l o g i n P a g e from " . . / p a g e s / l o g i n _ 2 . 2 . 1 . page " ; d e s c r i b e ( 'CHECK SWAG LABS LOG IN WITH POM 2 . 2 . 1 ' , ( ) =&gt; { i t ( ' V a l i d a t e l o c k e d o u t u s e r ' , ( ) =&gt; { l o g i n P a g e . t y p e U s e r n a m e I n p u t ( ' l o c k e d _ o u t _ u s e r ' ) ; l o g i n P a g e . t y p e P a s s w o r d I n p u t ( ' s e c r e t _ s a u c e ' ) ; l o g i n P a g e . c l i c k L o g i n B u t t o n ( ) ; l o g i n P a g e . c h e c k E r r o r M e s s a g e ( ' E p i c s a d f a c e : " + ' S o r r y , t h i s u s e r h a s been l o c k e d o u t . ' ) ; } ) ;</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_4"><head>Listing 6 :</head><label>6</label><figDesc>File login_2.2.3.page.js c l a s s MainPage { u s e r n a m e I n p u t S e l e c t o r = ' # u s e r −name ' ; p a s s w o r d I n p u t S e l e c t o r = ' # p a s s w o r d ' ; l o g i n B u t t o n S e l e c t o r = ' # l o g i n − b u t t o n ' ; e r r o r M e s s a g e S e l e c t o r = ' [ d a t a − t e s t = " e r r o r " ] ' ; g e t U s e r n a m e I n p u t ( ) { return cy . g e t ( t h i s . u s e r n a m e I n p u t S e l e c t o r ) ; } g e t P a s s w o r d I n p u t ( ) { return cy . g e t ( t h i s . p a s s w o r d I n p u t S e l e c t</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_5"><head>Listing 7 :</head><label>7</label><figDesc>Part of file login_2.3.1.page.js g e t U s e r n a m e I n p u t ( ) { return cy . g e t ( ' # u s e r −name ' ) ; } g e t P a s s w o r d I n p u t ( ) { return cy . g e t ( ' # p a s s w o r d ' ) ; } g e t L o g i n B u t t o n ( ) { return cy . g e t ( ' # l o g i n − b u t t o n ' ) ; } g e t E r r o r M e s s a g e ( ) { return cy . g e t ( ' [ d a t a − t e s t = " e r r o r " ] ' ) ; } We obtain 4 getter functions and focus on the necessary functionality. Then when we work with functions (typeUsernameInput(), typePasswordInput(), clickLoginButton()), we use the predefined locators of this class.</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_6"><head>Listing 9 :</head><label>9</label><figDesc>File login_2.4.1.page.js c l a s s MainPage { e l e m e n t s = { g e t U s e r n a m e I n p u t : f u n c t i o n ( ) { return cy . g e t ( ' # u s e r −name ' ) ; } , g e t P a s s w o r d I n p u t : f u n c t i o n ( ) { return cy . g e t ( ' # p a s s w o r d ' ) ; } , g e t L o g i n B u t t o n : f u n c t i o n ( ) { return cy . g e t ( ' # l o g i n − b u t t o n ' ) ; } , g e t E r r o r M e s s a g e : f u n c t i o n ( ) { return cy . g e t ( ' [ d a t a − t e s t = " e r r o r " ] ' ) ; } } t y p e U s e r n a m e I n p u t ( username ) { t h i s . e l e m e n t s . g e t U s e r n a m e I n p u t ( ) . type ( username ) ; } t y p e P a s s w o r d I n p u t ( p a s s w o r d ) { t h i s . e l e m e n t s . g e t P a s s w o r d I n p u t ( ) . type ( p a s s w o r d ) ; } c l i c k L o g i n B u t t o n ( ) { t h i s . e l e m e n t s . g e t L o g i n B u t t o n ( ) . c l i c k ( ) ; } } module . e x p o r t s = new L o g i n P a g e ( ) ;</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_7"><head>Listing 10 :</head><label>10</label><figDesc>File spec_2.4.1.cy.js import l o g i n P a g e from " . . / p a g e s / l o g i n _ 2 . 4 . 1 . page " ; d e s c r i b e ( 'CHECK SWAG LABS LOG IN WITH POM 2 . 4 . 1 ' , ( ) =&gt; { i t ( ' V a l i d a t e l o c k e d o u t u s e r ' , ( ) =&gt; { l o g i n P a g e . t y p e U s e r n a m e I n p u t ( ' l o c k e d _ o u t _ u s e r ' ) ; l o g i n P a g e . t y p e P a s s w o r d I n p u t ( ' s e c r e t _ s a u c e ' ) ; l o g i n P a g e . c l i c k L o g i n B u t t o n ( ) ; l o g i n P a g e . e l e m e n t s . g e t E r r o r M e s s a g e ( ) . s h o u l d ( ' be . v i s i b l e ' ) . and ( ' c o n t a i n . t e x t ' , ' E p i c s a d f a c e : S o r r y , t h i s u s e r h a s been l o c k e d o u t . ' ) ; } ) ; } ) ;</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_8"><head>Listing 11 :</head><label>11</label><figDesc>Part of file login_2.4.2.page.js e l e m e n t s = { g e t U s e r n a m e I n p u t : ( ) =&gt; cy . g e t ( ' # u s e r −name ' ) , g e t P a s s w o r d I n p u t : ( ) =&gt; cy . g e t ( ' # p a s s w o r d ' ) , g e t L o g i n B u t t o n : ( ) =&gt; cy . g e t ( ' # l o g i n − b u t t o n ' ) , g e t E r r o r M e s s a g e : ( ) =&gt; cy . g e t ( ' [ d a t a − t e s t = " e r r o r " ] ' ) } Due to point localization of the file, no updates needed for tests in spec_2.4.2.cy.js (they look the same as in spec_2.4.1.cy.js).</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_0"><head>Listing 1 : File spec_2.1.cy.js</head><label>1</label><figDesc></figDesc><table><row><cell>d e s c r i b e ( 'CHECK SWAG LABS LOG IN WITHOUT POM 2 . 1 ' , ( ) =&gt; {</cell></row><row><cell>i t ( ' V a l i d a t e l o c k e d o u t u s e r ' , ( ) =&gt; {</cell></row><row><cell>cy . g e t ( ' # u s e r −name ' ) . type ( ' l o c k e d _ o u t _ u s e r ' ) ;</cell></row><row><cell>cy . g e t ( ' # p a s s w o r d ' ) . type ( ' s e c r e t _ s a u c e ' ) ;</cell></row><row><cell>cy . g e t ( ' # l o g i n − b u t t o n ' ) . c l i c k ( ) ;</cell></row><row><cell>cy . g e t ( ' [ d a t a − t e s t = " e r r o r " ] ' ) . s h o u l d ( ' be . v i s i b l e ' )</cell></row><row><cell>. and ( ' c o n t a i n . t e x t ' ,</cell></row><row><cell>' E p i c s a d f a c e : S o r r y , t h i s u s e r h a s been l o c k e d o u t . ' ) ;</cell></row><row><cell>} ) ;</cell></row><row><cell>} ) ;</cell></row></table></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_1"><head>2.2.page.js</head><label></label><figDesc></figDesc><table><row><cell>g e t E r r o r M e s s a g e ( )</cell></row><row><cell>{ return cy . g e t ( t h i s . e r r o r M e s s a g e S e l e c t o r ) ; }</cell></row><row><cell>Listing 5: File spec_2.2.2.cy.js</cell></row><row><cell>import l o g i n P a g e from " . . / p a g e s / l o g i n _ 2 . 2 . 2 . page " ;</cell></row><row><cell>d e s c r i b e ( 'CHECK SWAG LABS LOG IN WITH POM 2 . 2 . 2 ' , ( ) =&gt; {</cell></row></table><note>i t ( ' V a l i d a t e l o c k e d o u t u s e r ' , ( ) =&gt; { l o g i n P a g e . t y p e U s e r n a m e I n p u t ( ' l o c k e d _ o u t _ u s e r ' ) ; l o g i n P a g e . t y p e P a s s w o r d I n p u t ( ' s e c r e t _ s a u c e ' ) ; l o g i n P a g e . c l i c k L o g i n B u t t o n ( ) ; l o g i n P a g e . g e t E r r o r M e s s a g e ( ) . s h o u l d ( ' be . v i s i b l e ' ) . and ( ' c o n t a i n . t e x t ' , ' E p i c s a d f a c e : S o r r y , t h i s u s e r h a s been l o c k e d o u t . ' ) ; } ) ;</note></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_2"><head>3.cy.js file</head><label></label><figDesc>are the same as in spec_2.2.2.cy.js file. At the same time, the new version contains more functionality for further extension and can cover bigger amount of user behavior scenarios with slight updates.</figDesc><table><row><cell cols="2">g e t E r r o r M e s s a g e ( ) { return cy . g e t ( t h i s . e r r o r M e s s a g e S e l e c t o r ) ; }</cell></row><row><cell cols="2">t y p e U s e r n a m e I n p u t ( username )</cell></row><row><cell cols="2">{ t h i s . g e t U s e r n a m e I n p u t ( ) . type ( username ) ; }</cell></row><row><cell cols="2">t y p e P a s s w o r d I n p u t ( p a s s w o r d )</cell></row><row><cell cols="2">{ t h i s . g e t P a s s w o r d I n p u t ( ) . type ( p a s s w o r d ) ; }</cell></row><row><cell>c l i c k L o g i n B u t t o n ( )</cell><cell></cell></row><row><cell cols="2">{ t h i s . g e t L o g i n B u t t o n ( ) . c l i c k ( ) ; }</cell></row><row><cell>}</cell><cell></cell></row><row><cell cols="2">module . e x p o r t s = new L o g i n P a g e ( ) ;</cell></row><row><cell>Tests in spec_2.2.</cell><cell></cell></row><row><cell></cell><cell>o r ) ; }</cell></row><row><cell>g e t L o g i n B u t t o n ( )</cell><cell>{ return cy . g e t ( t h i s . l o g i n B u t t o n S e l e c t o r ) ; }</cell></row></table></figure>
		</body>
		<back>

			<div type="acknowledgement">
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.">Conclusions</head><p>This article shows eight approaches how to construct Cypress tests using POM. The connections between them are stressed as their evolution while writing code developing E2E tests. Project using approaches highlighted in first subsections still can be found on the Internet while studying how to write tests with Cypress JS. The authors highlight advantages and disadvantages of the approaches and offer the solution of problems. This article can be used both as a combined overview of different approaches and as a manual for those who are struggling to write tests with Cypress in a better way. For further investigation other patterns and solutions like Cypress commands, aliases, application actions, could be discovered.</p></div>
			</div>

			<div type="annex">
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.5.">Tests with POM using assessor properties</head><p>The drawback described above can be avoided by using assessor properties. They are property getters, new types of properties (along with the regular data properties). They are essentially functions that execute on getting value, but look like regular properties to an external code. "getter" methods are accessor properties . In an object literal they are denoted by get. Descriptor for accessor properties has get -a function without arguments, that works when a property is read. The getter works when errorMessage is read in spec. From the outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't call errorMessage as a function, we read it normally: the getter runs behind the scenes.</p><p>A minor drawback of this approach is that sometimes it is necessary to pass a parameter to the locator functions (for example referring to the i-th row of the table), then we need to combine the use of ordinary functions and assessor properties.</p></div>			</div>
			<div type="references">

				<listBibl>

<biblStruct xml:id="b0">
	<analytic>
		<title level="a" type="main">Modern web automation with cypress.IO</title>
		<author>
			<persName><forename type="first">J</forename><forename type="middle">T</forename><surname>Othayoth</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Anuar</surname></persName>
		</author>
		<ptr target="https://oiji.utm.my/index.php/oiji/article/view/229" />
	</analytic>
	<monogr>
		<title level="j">Open International Journal of Informatics</title>
		<imprint>
			<biblScope unit="volume">10</biblScope>
			<biblScope unit="page" from="182" to="196" />
			<date type="published" when="2022">2022</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b1">
	<analytic>
		<title level="a" type="main">A Family of Experiments to Assess the Impact of Page Object Pattern in Web Test Suite Development</title>
		<author>
			<persName><forename type="first">M</forename><surname>Leotta</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Biagiola</surname></persName>
		</author>
		<author>
			<persName><forename type="first">F</forename><surname>Ricca</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Ceccato</surname></persName>
		</author>
		<author>
			<persName><forename type="first">P</forename><surname>Tonella</surname></persName>
		</author>
		<idno type="DOI">10.1109/ICST46399.2020.00035</idno>
	</analytic>
	<monogr>
		<title level="m">IEEE 13th International Conference on Software Testing, Validation and Verification (ICST)</title>
				<imprint>
			<date type="published" when="2020">2020. 2020</date>
			<biblScope unit="page" from="263" to="273" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b2">
	<analytic>
		<title level="a" type="main">Automation Testing Framework for Web Applications with Selenium WebDriver: Opportunities and Threats</title>
		<author>
			<persName><forename type="first">E</forename><surname>Vila</surname></persName>
		</author>
		<author>
			<persName><forename type="first">G</forename><surname>Novakova</surname></persName>
		</author>
		<author>
			<persName><forename type="first">D</forename><surname>Todorova</surname></persName>
		</author>
		<idno type="DOI">10.1145/3133264.3133300</idno>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the International Conference on Advances in Image Processing, ICAIP &apos;17</title>
				<meeting>the International Conference on Advances in Image Processing, ICAIP &apos;17<address><addrLine>New York, NY, USA</addrLine></address></meeting>
		<imprint>
			<publisher>Association for Computing Machinery</publisher>
			<date type="published" when="2017">2017</date>
			<biblScope unit="page" from="144" to="150" />
		</imprint>
	</monogr>
</biblStruct>

				</listBibl>
			</div>
		</back>
	</text>
</TEI>
