<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community:  Md. Sultan Parvez</title>
    <description>The latest articles on DEV Community by  Md. Sultan Parvez (@sultanparvez).</description>
    <link>https://dev.to/sultanparvez</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F719490%2F54cb8001-0630-4f69-907b-d7787a56883c.jpg</url>
      <title>DEV Community:  Md. Sultan Parvez</title>
      <link>https://dev.to/sultanparvez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sultanparvez"/>
    <language>en</language>
    <item>
      <title>Selector strategies</title>
      <dc:creator> Md. Sultan Parvez</dc:creator>
      <pubDate>Sat, 09 Mar 2024 00:19:43 +0000</pubDate>
      <link>https://dev.to/sultanparvez/selector-strategies-3bce</link>
      <guid>https://dev.to/sultanparvez/selector-strategies-3bce</guid>
      <description>&lt;p&gt;Selectors are crucial in Test Automation because they help identify and interact with elements within the user interface of an application or webpage.&lt;/p&gt;

&lt;p&gt;There are mainly two types of selectors, Xpath and CSS selectors. Depending on the situation both of these techniques can be helpful. So in this thread, I will discuss the basics of both techniques. &lt;/p&gt;

&lt;p&gt;Before starting with the strategies we need to understand some basics of a DOM( Document Object Model) tree. In the DOM tree, elements are represented as nodes, and each node can have different types. The main types of nodes in the DOM tree include element nodes, attribute nodes, and text nodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tagname:
&lt;/h2&gt;

&lt;p&gt;In the DOM tree, the tagname corresponds to the element node's name.&lt;br&gt;
Element nodes represent the structure of an XML or HTML document, and they contain other nodes or elements.&lt;br&gt;
For example, if you have&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;&amp;lt;book&amp;gt;Harry Potter&amp;lt;/book&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
, "book" is the tagname of the element node.&lt;/p&gt;
&lt;h2&gt;
  
  
  Attribute:
&lt;/h2&gt;

&lt;p&gt;Attributes are associated with element nodes in the DOM tree.&lt;br&gt;
They provide additional information about elements.In the DOM tree, attributes are represented as separate nodes attached to their respective element nodes.&lt;br&gt;
For instance, in&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;&amp;lt;book id="1"&amp;gt;Harry Potter&amp;lt;/book&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
, the attribute "id" with the value "1" is attached to the "book" element node.&lt;/p&gt;
&lt;h2&gt;
  
  
  Value:
&lt;/h2&gt;

&lt;p&gt;The value is usually associated with an attribute in the DOM tree. For example, in&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;&amp;lt;book id="1"&amp;gt;Harry Potter&amp;lt;/book&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
, “1" is the value of the attribute ‘id’ associated with the "book" element node.&lt;/p&gt;
&lt;h2&gt;
  
  
  Text :
&lt;/h2&gt;

&lt;p&gt;Text nodes contain the actual text content within XML or HTML elements.&lt;br&gt;
For example, in the XML&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;&amp;lt;book&amp;gt;Harry Potter&amp;lt;/book&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
, "Harry Potter" is the text node associated with the  element node.&lt;br&gt;
Text nodes can also represent whitespace characters such as spaces, tabs, and line breaks.&lt;/p&gt;
&lt;h2&gt;
  
  
  Xpath
&lt;/h2&gt;

&lt;p&gt;Xpath stands for XML path language. &lt;br&gt;
Most of the automation frameworks/tools utilize Xpath for finding &lt;br&gt;
locator/selector in HTML dom structure.&lt;/p&gt;

&lt;p&gt;There are two types of XPath. Absolute Xpath and Relative Xpath. Our focus will mainly be relative Xpath since absolute XPath are subject to changes hence not that useful for automation. An absolute XPath starts with '/' whereas a relative Xpath starts with '//' &lt;/p&gt;

&lt;p&gt;The basic XPath format of relative Xpath is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;@Attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;@Attribute&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in many cases for any given element the value of attributes is dynamic, that is the values are subject to change. To tackle this issue we can use functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  'starts-with' function:
&lt;/h2&gt;

&lt;p&gt;By utilizing this function we can target/select an element which have dynamic value but the starting text of the value is always the same.&lt;/p&gt;

&lt;p&gt;Here is the syntax of the starts-with() function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;starts-with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;@attribute&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  'contains' Function:
&lt;/h2&gt;

&lt;p&gt;The contains() function in XPath is utilized to select elements that contain a specified substring within their attribute values or text content.&lt;/p&gt;

&lt;p&gt;Here is the syntax of the contains() function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;@attribute&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  'text' Function:
&lt;/h2&gt;

&lt;p&gt;The text function can be used to select an element that contains certain text.&lt;/p&gt;

&lt;p&gt;Here is the syntax of the text() function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'actualValue'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AND, OR operator in XPath
&lt;/h2&gt;

&lt;p&gt;In some cases, we might need to target an element that has different locators that are based on other available actions of the page the locator changes in that case we can utilize the OR operator.&lt;/p&gt;

&lt;p&gt;Here is the syntax of the OR operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;@Attribute1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value1'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;OR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;@Attribute2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value2'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, in some other cases, we might need to target an element that doesn't have a unique attribute-value pair but if we combine two attribute-value then we can target the element. In such case, we can use the AND operator.&lt;/p&gt;

&lt;p&gt;Here is the syntax of the AND operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;@Attribute1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value1'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;AND&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;@Attribute2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value2'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Xpath Axes Method:
&lt;/h2&gt;

&lt;p&gt;We can utilize axes methods to traverse through the DOM tree. axes defines the relationship between elements.&lt;/p&gt;

&lt;p&gt;Here is the syntax for axes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;@Attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;axes&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;@Attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ancestor Axis (ancestor::): This axis selects all ancestors (parent, grandparent, etc.) of the current node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ancestor-or-Self Axis (ancestor-or-self::): This axis selects the current node and all of its ancestors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Child Axis (child::): This axis selects all children of the current node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Descendant Axis (descendant::): Selects all descendants (children, grandchildren, etc.) of the current node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Descendant-or-Self Axis (descendant-or-self::): This axis selects the current node and all of its descendants.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Following Axis (following::): Select all nodes that appear after the current node in document order.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Following-Sibling Axis (following-sibling::): Selects all siblings that appear after the current node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Namespace Axis (namespace::): This axis selects the namespace nodes of the current node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Parent Axis (parent::): Selects the parent of the current node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Preceding Axis (preceding::): Selects all nodes that appear before the current node in document order.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Preceding-Sibling Axis (preceding-sibling::): Selects all siblings that appear before the current node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Self Axis (self::): This axis selects the current node.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, we can also try different combinations of these function operators and axes as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS Selectors
&lt;/h2&gt;

&lt;p&gt;CSS stands for cascading style sheet. CSS selectors are very efficient in locating elements. A lot of automation tools/framework supports CSS selectors. Cypress, Robot Framework, and Puppeteer to name a few. &lt;/p&gt;

&lt;p&gt;The basic syntax for CSS selectors is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, we can also select any element based on its ID or class. &lt;/p&gt;

&lt;p&gt;Select By ID -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nt"&gt;ID&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select By Class -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sub-String Matching Technique
&lt;/h2&gt;

&lt;p&gt;Similar to the starts-with and contains the functionality of Xpath we can also do pattern matching in CSS selector.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prefix - '^':
&lt;/h2&gt;

&lt;p&gt;Utilizing this symbol we can target an element that has a dynamic &lt;br&gt;
value for a tagname but the value always starts with a specific sub-string.&lt;/p&gt;

&lt;p&gt;Here is the syntax for the prefix -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="err"&gt;^&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Suffix - '$':
&lt;/h2&gt;

&lt;p&gt;Similarly, if the value of the tagname ends with a specific pattern then we can match the end sub-string&lt;/p&gt;

&lt;p&gt;Here is the syntax for the suffix -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="err"&gt;='&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Contains - '*':
&lt;/h2&gt;

&lt;p&gt;Additionally, we can use the wildcard (*) symbol to just match the sub-string of the value at any given place.&lt;/p&gt;

&lt;p&gt;Here is the syntax for the contains -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;*=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AND, OR operation
&lt;/h2&gt;

&lt;p&gt;We can utilize the 'AND', and 'OR' operations in CSS selectors as well. &lt;/p&gt;

&lt;p&gt;Here is the syntax for the AND operation -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;Attribute1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value1'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nt"&gt;Attribute2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value2'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This CSS selector targets elements of tagname that have both Attribute1 with the value value1 and Attribute2 with the value value2..&lt;/p&gt;

&lt;p&gt;Here is the syntax for the OR operation -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;',' denotes the OR operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traversing In CSS Selector:
&lt;/h2&gt;

&lt;p&gt;The syntax for traversing is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nt"&gt;traverse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;symbol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;here&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Descendant selector ( ): This selects all elements that are descendants of a specified element. For example, &lt;code&gt;div p&lt;/code&gt; selects all &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; elements that are descendants of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Child selector (&amp;gt;): This selects all elements that are direct children of a specified element. For example, &lt;code&gt;div &amp;gt; p&lt;/code&gt; selects all &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; elements that are immediate children of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Adjacent sibling selector (+): This selects an element that is immediately preceded by a specified element. For example, &lt;code&gt;h2 + p&lt;/code&gt; selects the &lt;/p&gt;
&lt;p&gt; element that directly follows an &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; element.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;General sibling selector (~): This selects all elements that are siblings of a specified element and are preceded by the specified element. For example, h2 &lt;code&gt;~ p&lt;/code&gt; selects all &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; elements that are siblings of an &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; element and comes after it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately in the CSS selector technique traversing to the parent is not possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pseudo-classes:
&lt;/h2&gt;

&lt;p&gt;We can also utilize pseudo-classes to target our elements.&lt;/p&gt;

&lt;p&gt;The format for pseudo-classes is as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xpath"&gt;&lt;code&gt;&lt;span class="nt"&gt;tagname&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;pseudo-class&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;:hover: This pseudo-class is used to apply styles when the mouse pointer is over an element. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:active: Applied to an element while it is being activated by the user. For example, when a user clicks on a button, it becomes active.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:focus: Applied to an element when it receives focus, usually through keyboard navigation or clicking. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:visited: Applies to links that have been visited by the user. This pseudo-class is used to distinguish visited links from unvisited ones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:nth-child() and :nth-of-type(): These pseudo-classes allow you to select elements based on their position within a parent element. For example, &lt;code&gt;:nth-child(odd)&lt;/code&gt; selects every odd child element of its parent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:first-child and &lt;code&gt;:last-child:&lt;/code&gt; Selects the first or last child element of its parent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:not(): This pseudo-class selects elements that do not match a specific selector. For example,&lt;code&gt;:not(.class)&lt;/code&gt; selects all elements that do not have the specified class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:checked: Applied to input elements (such as checkboxes or radio buttons) that are checked.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:enabled: This pseudo-class selects elements that are enabled, which are the opposite of disabled elements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;:disabled: This pseudo-class selects elements that are disabled, typically form elements like buttons, input fields, checkboxes, and radio buttons.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pseudo-classes can be very powerful for assertion as you might have already guessed. We can also use the combinations of these techniques to target a unique element.&lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read this. I hope you found it informative and enjoyable. If you have any questions, comments, or feedback, please don't hesitate to reach out.&lt;/p&gt;

</description>
      <category>qa</category>
      <category>automation</category>
      <category>selectors</category>
      <category>sqa</category>
    </item>
    <item>
      <title>Getting started with Cypress</title>
      <dc:creator> Md. Sultan Parvez</dc:creator>
      <pubDate>Fri, 09 Feb 2024 12:10:19 +0000</pubDate>
      <link>https://dev.to/sultanparvez/getting-started-with-cypress-4p05</link>
      <guid>https://dev.to/sultanparvez/getting-started-with-cypress-4p05</guid>
      <description>&lt;p&gt;Cypress is a popular automation framework and unlike selenium cypress does not require a web driver. It is built on top of node.js and compatible with both JavaScript and TypeScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Prerequisites&lt;/em&gt;&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;As mentioned earlier it is built on top of node.js so it requires node.js as a Javascript run time environment. Having the latest version is recommended.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any IDE of our choice is fine as long as it supports javaScripts or typeScripts. Visual Studio Code is a popular one. I personally like WebStorm, you can also try out Atom and Intelij Idea.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Installation Process:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Cypress can be installed with the node package manager(npm). we can install Cypress with this simple command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm cypress &lt;span class="nb"&gt;install&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, it is recommended to use the command below since we want to add this as a dev dependency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;cypress &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specifying Cypress as a dev dependency allows us to specify the exact version of Cypress we are using. This also ensures consistency across different development environments and makes it easier to reproduce issues or run tests on different machines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Know Your Files&lt;/em&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Now that we are done with the installation we can start writing tests using cypress but first, let's get familiar with the files and folders.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cypress/Fixtures: Fixtures are used to store commonly used test data in JSON format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support/CustomCommand.js: This file helps in creating custom commands or global overrides that will be&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;package.json: It holds information about the project, dependencies, etc. This file also holds "scripts" metadata. These scripts can be called using "npm run ". These are various commands that can be run via terminals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cypress.config.js: This holds various cypress-related configurations like URL, admin username, password, timeouts, etc where behavior cypress can be modified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Screenshots: This folder stores the screenshots that were generated while the automation script was running.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Videos: This folder stores the video of the runtime so it is easier to trace defects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These files and folders automatically generate when we install Cypress along with some other files.&lt;/p&gt;

&lt;p&gt;Additionally, you would like to create some other folders and files as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cypress/TestSuites: The TestSuites folder includes all the test files. The test files are written as ".js" or ".ts".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cypress/Reusables: this folder contains methods that can be commonly used throughout our tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cypress/Support/API: The API folder contains some commonly used API-related methods, API methods related to specific modules, and a file containing methods for API calls in general&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CustomCommand.js: This file helps in creating custom commands or global overrides that will be available for all other classes and functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cypress/PageObjects: The PageObjects folder contains classes that help separate page-specific functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cypress/Wiring: The wiring folder contains locators and getter functions of the locators that are used in PageObjects helper functions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Project Layout:&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cypress/
├── fixtures/
│   └── data.json
├── support/
│   ├── commands/
│   │   ├─ API 
│   ├── pageObjects/
│   │   ├── Page1/
│   │   │   └── Page1Objects.js
│   │   ├── Page2/
│   │   │   └── Page2Objects.js
│   ├── wiring/
│   │   ├── Reusables/
│   │   │   └── Reusable.js
│   │   ├── Page1/
│   │   │   └── Page1Functions.js
│   │   ├── Page2/
│   │   │   └── Page2Functions.js
├── tests/
│   ├── verifyWorkflow.js
├── support/
│   ├── customCommands.js
└── screenshots/
└── videos/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Test Case&lt;/em&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Now inside the testSuites folder, we can create a new file with .js or .ts extension this file will be considered a test file. Inside a test file, we need to have at least a "describe" block and a "it" block. The "describe" block is used for grouping related test cases whereas the "it" block represents a single end-to-end test. There are also some hooks available in Cypress such as "before", "beforeEach", "after", and "afterEach" These hooks can be utilized for setting up and cleaning up the test data as well as for prerequisites for the test cases. &lt;/p&gt;

&lt;p&gt;Cypress utilizes Mocha, a popular testing framework, for structuring tests. Mocha provides a flexible and intuitive syntax for organizing test suites and cases, enhancing test readability. Additionally, Cypress utilizes Chai, an assertion library, for writing clear and expressive assertions within tests. Chai offers a wide range of assertion styles, including should, expect, and assert, enabling developers to choose the syntax that best fits their testing preferences. Together, Mocha and Chai help in creating comprehensive and readable test suites, which helps a great deal in terms of facilitating effective testing and ensuring the robustness of web applications built with Cypress. This is what a typical test file would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// login.spec.js&lt;/span&gt;

&lt;span class="c1"&gt;// Describe block to group related test cases&lt;/span&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login Page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// before block to run once before any test cases&lt;/span&gt;
  &lt;span class="nf"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Perform any setup tasks before any test cases&lt;/span&gt;
    &lt;span class="c1"&gt;// This can include starting the application server or preparing test data&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// beforeEach block to run before each test case&lt;/span&gt;
  &lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Visit the login page&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Test case to verify successful login&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should allow user to log in with valid credentials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Enter username and password&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name="username"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name="password"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Click the login button&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button[type="submit"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Assertion to verify successful login&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Test case to verify error message with invalid credentials&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should display error message with invalid credentials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Enter invalid username and password&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name="username"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;invalid_username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name="password"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;invalid_password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Click the login button&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button[type="submit"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Assertion to verify error message&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid username or password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// afterEach block to run after each test case&lt;/span&gt;
  &lt;span class="nf"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Clear any logged-in state or cookies&lt;/span&gt;
    &lt;span class="c1"&gt;// This ensures a clean state before each test case&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearCookies&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearLocalStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// after block to run after all test cases&lt;/span&gt;
  &lt;span class="nf"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Perform any cleanup tasks after all test cases&lt;/span&gt;
    &lt;span class="c1"&gt;// This can be useful for resetting the application or cleaning up resources&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you for taking the time to read this. I hope you found it informative and enjoyable. If you have any questions, comments, or feedback, please don't hesitate to reach out. &lt;/p&gt;

</description>
      <category>sqa</category>
      <category>automation</category>
      <category>cypress</category>
    </item>
  </channel>
</rss>
