<?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: Divya Manohar</title>
    <description>The latest articles on DEV Community by Divya Manohar (@divya_devassure).</description>
    <link>https://dev.to/divya_devassure</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%2F1337994%2Fb5a37998-b6b2-4208-b109-fa3509ac1c24.jpeg</url>
      <title>DEV Community: Divya Manohar</title>
      <link>https://dev.to/divya_devassure</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/divya_devassure"/>
    <language>en</language>
    <item>
      <title>Why We Built DevAssure with Tauri</title>
      <dc:creator>Divya Manohar</dc:creator>
      <pubDate>Sun, 09 Feb 2025 12:53:19 +0000</pubDate>
      <link>https://dev.to/devassure/why-we-built-devassure-with-tauri-on</link>
      <guid>https://dev.to/devassure/why-we-built-devassure-with-tauri-on</guid>
      <description>&lt;p&gt;At DevAssure, we are dedicated to delivering high-quality testing solutions, and choosing the right technology stack is crucial to achieving this goal. We decided to build our app with &lt;a href="https://v2.tauri.app/" rel="noopener noreferrer"&gt;Tauri&lt;/a&gt;, a framework that enables us to create small, fast, and secure desktop applications using web technologies and Rust. Here's why we made this choice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lightweight and Efficient&lt;/strong&gt;: Tauri apps are lightweight, resulting in smaller bundle sizes. This means faster downloads and reduced storage usage for our users. Tauri uses Rust as a native layer, which results in lower memory and CPU usage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;: Tauri's web renderer is built using Rust's memory-safe features. This helps us protect our users' data and maintain the integrity of our application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native Performance&lt;/strong&gt;: Tauri uses a custom web renderer that is designed to be more lightweight and performant than Chromium. Tauri's web renderer is built using Rust's memory-safe features and concurrency model, ensuring that our app is both fast and reliable, preventing common bugs and app crashes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-Platform&lt;/strong&gt;: With Tauri, DevAssure can run seamlessly on Windows, macOS, and Linux, ensuring a consistent experience for all our users.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By building with Tauri and Rust, we're able to create a superior user experience and maintain a high standard of quality for the DevAssure app. We're proud of the technological choices we've made and excited to continue innovating in the software testing space.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Beginner's Guide: How to set up PostgreSQL within Playwright for Test Automation</title>
      <dc:creator>Divya Manohar</dc:creator>
      <pubDate>Sun, 09 Feb 2025 12:22:27 +0000</pubDate>
      <link>https://dev.to/devassure/how-to-set-up-postgresql-within-playwright-for-test-automation-1ike</link>
      <guid>https://dev.to/devassure/how-to-set-up-postgresql-within-playwright-for-test-automation-1ike</guid>
      <description>&lt;p&gt;When automating test scenarios, it's important to validate how the data is being stored, processed and retrieved. This ensures data integrity, guaranteeing the application's overall functionality and user experience remain reliable. In this blog we will learn how to set up and add database validations in your test scripts developed with Playwright. In this blog the focus will be on Postgres set up, necessary libraries and code snippets that need to be added within your test scripts. &lt;/p&gt;

&lt;h2&gt;
  
  
  How can Database integration help improve test automation?
&lt;/h2&gt;

&lt;p&gt;Database integration will help improve the test automation in multiple ways -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Backend validations to ensure data integrity for end to end tests.&lt;/li&gt;
&lt;li&gt;Query the database to get specific information, to continue execution of the front end tests. &lt;/li&gt;
&lt;li&gt;Prepare data before test execution to save test execution time and improve test automation stability.&lt;/li&gt;
&lt;li&gt;Purge data post test execution to reduce test flakiness. &lt;/li&gt;
&lt;li&gt;Manipulate or update data, to enable component level testing with ease. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While scripting UI tests, one question we should always ask is - &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How can I make the test more reliable and stable?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not all validations or actions need to be performed on the UI, some of them can be easily achieved through database integrations which help improve the stability, speed of execution and reliability of the test automation suite. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to set up postgres within your playwright scripts?
&lt;/h2&gt;

&lt;p&gt;Consider a scenario where after signing up, the user receives a token in an email that needs to be used during the first time they sign in. While automating such scenarios, instead of reading the email every time, we can fetch the token directly from the database - this makes the test faster and reliable since we do not have to wait for the email to arrive at the user’s inbox and we do not have to parse the email body to get token details. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.devassure.io/blog/database-test-automation-playwright-postgresql-testing/#how-devassure-simplifies-integration-with-postgresql-database" rel="noopener noreferrer"&gt;&lt;strong&gt;Learn how DevAssure simplifies this entire configuration and implementation&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Below is an example of how you can integrate PostgreSQL into your Playwright tests in &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; while supporting multiple environments (e.g., local, beta, prod). We'll use the following libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/pg" rel="noopener noreferrer"&gt;pg&lt;/a&gt;: A PostgreSQL client for Node.js.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/dotenv" rel="noopener noreferrer"&gt;dotenv&lt;/a&gt;: Loads environment variables from a file so you can configure different settings per environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Below are step-by-step instructions along with sample code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.devassure.io/blog/playwright-with-mailslurp/#playwright-set-up-instructions" rel="noopener noreferrer"&gt;Learn in detail how to set up playwright&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Postgres and dotenv Installation
&lt;/h3&gt;

&lt;p&gt;In your project root folder execute the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install pg dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Set Up Environment-Specific Configuration Files
&lt;/h3&gt;

&lt;p&gt;Postgres configurations will be different for different environments. We wouldn't want to create separate modules for each environment.  We will be storing the necessary information in .env files and reading the data using the dotenv library. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.env.local&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV=local
DB_HOST=localhost
DB_PORT=5432
DB_NAME=localhost_db
DB_USER=local_user
DB_PASSWORD=local_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;.env.beta&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV=beta
DB_HOST=beta.sample-app.com
DB_PORT=5432
DB_NAME=beta_db
DB_USER=beta_user
DB_PASSWORD=beta_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;.env.prod&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV=prod
DB_HOST=prod.sample-app.com
DB_PORT=5432
DB_NAME=prod_db
DB_USER=prod_user
DB_PASSWORD=prod_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create the base module
&lt;/h3&gt;

&lt;p&gt;Within the test automation project's root folder of your playwright scripts - create a folder config and add a file index.ts &lt;/p&gt;

&lt;p&gt;Based on the environment details provided at run time during test execution, this module will help identify the right PG database config to be read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;config/index.ts&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as dotenv from 'dotenv';
import path from 'path';

// Determine the current environment. Default to 'local' if not specified.
const env = process.env.NODE_ENV || 'local';

// Build the path to the correct .env file (e.g., .env.local, .env.beta, .env.prod)
const envFilePath = path.resolve(process.cwd(), `.env.${env}`);
dotenv.config({ path: envFilePath });

// Export the database configuration
export const dbConfig = {
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT || 5432),
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Include the Database query within your playwright script
&lt;/h3&gt;

&lt;p&gt;Here's a complete test script in Playwright using Typescript for the scenario mentioned above -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { test, expect } from '@playwright/test';
import { Client } from 'pg';
import { dbConfig } from '../config';


test('Automate Signup with Token Fetch from Database', async ({ page }) =&amp;gt; {


   // Create a new PostgreSQL client using the configuration
   const client = new Client(dbConfig);


   // Perform sign up
   await page.goto('https://appurl/login');
   await page.getByRole('link', { name: 'Join free today' }).click();
   await page.getByPlaceholder('Enter your email').click();
   await page.getByPlaceholder('Enter your email').fill('email@test.com');
   await page.getByPlaceholder('Enter your name').click();
   await page.getByPlaceholder('Enter your name').fill('This is a test - Please ignore');
   await page.getByPlaceholder('Enter your password', { exact: true }).click();
   await page.getByPlaceholder('Enter your password', { exact: true }).fill('password');
   await page.getByPlaceholder('Enter your password again').click();
   await page.getByPlaceholder('Enter your password again').fill('password');
   await page.getByRole('button', { name: 'Sign Up' }).click();


   try{
       // Connect to the database
       await client.connect();


       // Execute a query
       const result = await client.query('SELECT token FROM your_table');


       if (result.rows.length &amp;gt; 0) {
           console.log('Token:', result.rows[0].token);

           // Use the token to sign in
           await page.goto('https://appurl/login?token=?' + result.rows[0].token);


           // Validate user signed in
           await expect(page).toHaveTitle('Welcome');


       } else {


           // throw error if token not found
           console.log('No token found in the query result.');
           throw new Error('No token found in the query result.');
       }
   } finally {
       // Ensure the client disconnects even if an error occurs
       await client.end();
   }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const client = new Client(dbConfig);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creates a new client using the configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await client.connect();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connects to the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const result = await client.query('SELECT token FROM your_table');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executes the query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result.rows[0].token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fetches the values from the result set returned by the query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await client.end();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is important to always close the connection after test execution, irrespective of the test result. &lt;/p&gt;

&lt;h3&gt;
  
  
  Test Execution
&lt;/h3&gt;

&lt;p&gt;When running your tests, set the NODE_ENV variable so the correct configuration is loaded. For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local Environment:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV=local npx playwright test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Beta Environment:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NODE_ENV=beta npx playwright test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.devassure.io/blog/database-test-automation-playwright-postgresql-testing/#how-devassure-simplifies-integration-with-postgresql-database" rel="noopener noreferrer"&gt;&lt;strong&gt;Learn how DevAssure simplifies this entire configuration and implementation&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>automation</category>
      <category>playwright</category>
      <category>devassure</category>
    </item>
    <item>
      <title>WebTable Automation using Selenium</title>
      <dc:creator>Divya Manohar</dc:creator>
      <pubDate>Fri, 14 Jun 2024 17:01:35 +0000</pubDate>
      <link>https://dev.to/divya_devassure/webtable-automation-using-selenium-p9h</link>
      <guid>https://dev.to/divya_devassure/webtable-automation-using-selenium-p9h</guid>
      <description>&lt;p&gt;A dynamic table is a table where the number of rows and columns can change frequently. To manage these changes, advanced techniques are required to locate and interact with elements within a dynamic table in Selenium.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automate Dynamic Tables using Selenium
&lt;/h2&gt;

&lt;p&gt;In this blog we will focus on automating dynamic tables. The challenge with dynamic tables is dealing with complex locators (mostly XPaths), loops, and most importantly dealing with the dynamic data. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample table to be considered for automation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://react.fluentui.dev/?path=/docs/components-table--default#focusable-elements-in-cells"&gt;Source: Fluent UI React Components&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faz4pkdezp9r82z21cjy2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faz4pkdezp9r82z21cjy2.png" alt="Image description" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the WebElement locators
&lt;/h3&gt;

&lt;p&gt;There are many good resources available to learn about XPaths. As a beginner, I found this &lt;a href="https://www.testrigtechnologies.com/blogs/how-to-use-xpath-in-selenium-comprehensive-overview/"&gt;blog&lt;/a&gt; to be very useful. &lt;/p&gt;

&lt;p&gt;For dynamic tables it's important to focus on building WebElement locators (mostly XPaths).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Locating the Table Rows&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElements&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;xpath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"//div[@id='story--components-table--focusable-elements-in-cells']//tbody//tr[not(th)]"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;An XPath is used to locate all the table rows.&lt;/li&gt;
&lt;li&gt;tr[not(th)] - this ensures that the headers if present are not included as part of the table rows because at this point we are only interested in the data rendered.&lt;/li&gt;
&lt;li&gt;This will return a list of locators to identify all the rows of the table except the table headers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Locating the cells in the table&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cells&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElements&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cssSelector&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"td"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For every row, the above locators helps find the child element - td &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialise the expected data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; For this example alone we will use static initialization, but this is NOT recommended.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;expectedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Meeting notes"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Max Mustermann"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7h ago"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Thursday presentation"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Erika Mustermann"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Yesterday at 1:45 PM"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Training recording"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"John Doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Yesterday at 1:45 PM"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Purchase order"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jane Doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Tue at 9:30 AM"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will now have to loop through all the table rows and cells to validate the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's the complete test code&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;validateTableData&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Load the URL&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://react.fluentui.dev/?path=/docs/components-table--default#focusable-elements-in-cells"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Initialise the expected data set&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;expectedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Meeting notes"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Max Mustermann"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7h ago"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Thursday presentation"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Erika Mustermann"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Yesterday at 1:45 PM"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Training recording"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"John Doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Yesterday at 1:45 PM"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Purchase order"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jane Doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Tue at 9:30 AM"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Locate the table rows&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElements&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;xpath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"//div[@id='story--components-table--focusable-elements-in-cells']//tbody//tr[not(th)]"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Validate the table data&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rowIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;rowIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="n"&gt;rowIndex&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rowIndex&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cells&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElements&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cssSelector&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"td"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cellIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;cellIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="n"&gt;cellIndex&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cellIndex&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// Get the cell value&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getText&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;trim&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
               &lt;span class="c1"&gt;// Validate&lt;/span&gt;
            &lt;span class="nc"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expectedData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rowIndex&lt;/span&gt;&lt;span class="o"&gt;)[&lt;/span&gt;&lt;span class="n"&gt;cellIndex&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"Mismatch in column ("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cellIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;") at row "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rowIndex&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a major issue in the above code sample -&lt;br&gt;
The expected data is hardcoded or is static. Ideally this should be obtained from the database or using APIs, which would require writing wrappers and a few lines of code as well. This will be handled as part of an upcoming blog.&lt;/p&gt;

&lt;p&gt;There is another solution, by the use of Dynamic XPaths.&lt;/p&gt;
&lt;h3&gt;
  
  
  What are dynamic XPaths
&lt;/h3&gt;

&lt;p&gt;Dynamic XPath is an advanced concept in Selenium WebDriver, crafted to handle web elements that change their attributes dynamically.&lt;br&gt;
You can learn more about dynamic XPaths &lt;a href="https://testgrid.io/blog/dynamic-xpath-in-selenium/"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;WebElement&lt;/span&gt; &lt;span class="nf"&gt;getTableRow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;updated&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;xpath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"//div[@id='story--components-table--focusable-elements-in-cells']//tbody//tr[.//td//*[text()='"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"']]//td//*[text()='"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"']//ancestor::td//following-sibling::td[text()='"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;updated&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"']"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here's the complete code with dynamic XPaths&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;validateTableDataWithDynamicXpath&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Load the URL&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://react.fluentui.dev/?path=/docs/components-table--default#focusable-elements-in-cells"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Initialise the expected data set&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;expectedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Meeting notes"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Max Mustermann"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7h ago"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Thursday presentation"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Erika Mustermann"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Yesterday at 1:45 PM"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Training recording"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"John Doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Yesterday at 1:45 PM"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"Purchase order"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jane Doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Tue at 9:30 AM"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expectedData&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the WebElement based on test data&lt;/span&gt;
        &lt;span class="nc"&gt;WebElement&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getTableRow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]);&lt;/span&gt;
        &lt;span class="c1"&gt;// Validate presence&lt;/span&gt;
        &lt;span class="nc"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isDisplayed&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"Row not found"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Which of the 2 approaches is better?
&lt;/h3&gt;

&lt;p&gt;That depends on what needs to be validated. If it's for a single row or single value, approach #2 works. &lt;br&gt;
But with approach #2 the XPaths need to be as simplified as possible to enable ease of maintenance and this will not work if the table's columns keep changing.&lt;br&gt;
For entire table validations, I would prefer approach #1, again the key here is to simplify the XPaths as much as possible for maintainability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automating components with Dynamic Locators using DevAssure
&lt;/h3&gt;

&lt;p&gt;With DevAssure you can automate components with dynamic locators with ease. You will have a custom automation framework that align with your product requirements without the overhead of maintaining the framework itself. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.devassure.io/features"&gt;Learn more about the DevAssure Automation App&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>selenium</category>
      <category>testing</category>
    </item>
    <item>
      <title>Leveraging AI for Automated Test Case Generation</title>
      <dc:creator>Divya Manohar</dc:creator>
      <pubDate>Wed, 12 Jun 2024 06:01:02 +0000</pubDate>
      <link>https://dev.to/divya_devassure/leveraging-ai-for-automated-test-case-generation-1lkd</link>
      <guid>https://dev.to/divya_devassure/leveraging-ai-for-automated-test-case-generation-1lkd</guid>
      <description>&lt;p&gt;The art of writing effective test cases comes with the ability to understand and decode the feature specification documents (PRDs) and UI mockups. Besides the ability to understand the features and the product, one needs to be able to understand the real time scenarios, how users interact with the product, analyse and identify the key hindering factors on the product to write more comprehensive test cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's decode the process of test case writing
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Read through the PRDs and mockups.&lt;/li&gt;
&lt;li&gt;Identify the feature based scenarios.&lt;/li&gt;
&lt;li&gt;Identify the dependent/regression scenarios.&lt;/li&gt;
&lt;li&gt;Define the template for the test cases - this depends on the complexity of the application, how the validations are performed, how the test data is managed and the test case management tools used.&lt;/li&gt;
&lt;li&gt;Talk to PMs, QAs from other teams and Devs to identify dependencies between the features / components and add more test cases.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;QA Engineers carry the knowledge base of the entire product, they understand which new features could potentially impact the existing product workflows and thereby identify the points of regression.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5usqexd4fglyqh2qall5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5usqexd4fglyqh2qall5.jpg" alt="Small Dev/QA Teams" width="664" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But when the team keeps growing, this is not scalable. A single QA engineer or team cannot have the entire knowledge of how an application with multiple workflows would behave. Can AI be leveraged here to store the user flows and product behaviours as the team scales?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkqkmt2xd4iggvhimlkq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkqkmt2xd4iggvhimlkq.jpg" alt="Big Dev/QA Teams" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's explore if AI tools can enable teams to achieve all the steps in test case authoring. More specifically, if free Gen AI tools like ChatGPT can be used for test generation.&lt;/p&gt;

&lt;p&gt;I've conducted an experiment using ChatGPT to generate test cases while developing DevAssure's Desktop App.&lt;/p&gt;

&lt;p&gt;Below are some of the trials and results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trial 1 - Simple prompt
&lt;/h2&gt;

&lt;p&gt;"I am a QA Engineer trying to write test cases for a feature. Here are the details - “”, help me write the test cases for the same. Display the test cases in a tabular form."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Steps&lt;/th&gt;
&lt;th&gt;Expected Outcome&lt;/th&gt;
&lt;th&gt;Pass/Fail Criteria&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TC01&lt;/td&gt;
&lt;td&gt;Select New Web Test Case&lt;/td&gt;
&lt;td&gt;1. Open the app.&lt;br&gt;2. Navigate to the home screen.&lt;br&gt;3. Click on 'Select New Web Test Case'.&lt;/td&gt;
&lt;td&gt;'Create Web Test Case' screen should be displayed.&lt;/td&gt;
&lt;td&gt;Screen transition is successful.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC02&lt;/td&gt;
&lt;td&gt;Enter valid test case name&lt;/td&gt;
&lt;td&gt;1. Follow steps to TC01.&lt;br&gt;2. Enter a valid name in the 'Web Test Case Name' field.&lt;br&gt;3. Click 'Create'.&lt;/td&gt;
&lt;td&gt;New web test case is created with the provided name.&lt;/td&gt;
&lt;td&gt;Test case creation is successful.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC03&lt;/td&gt;
&lt;td&gt;Enter empty test case name&lt;/td&gt;
&lt;td&gt;1. Follow steps to TC01.&lt;br&gt;2. Leave the 'Web Test Case Name' field empty.&lt;br&gt;3. Click 'Create'.&lt;/td&gt;
&lt;td&gt;Error message should be displayed indicating name is required.&lt;/td&gt;
&lt;td&gt;Appropriate error is displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC04&lt;/td&gt;
&lt;td&gt;Enter excessively long test case name&lt;/td&gt;
&lt;td&gt;1. Follow steps to TC01.&lt;br&gt;2. Enter a name exceeding the maximum length limit in the 'Web Test Case Name' field.&lt;br&gt;3. Click 'Create'.&lt;/td&gt;
&lt;td&gt;Error message should be displayed indicating name is too long.&lt;/td&gt;
&lt;td&gt;Appropriate error is displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC05&lt;/td&gt;
&lt;td&gt;Use special characters in test case name&lt;/td&gt;
&lt;td&gt;1. Follow steps to TC01.&lt;br&gt;2. Enter a name with special characters in the 'Web Test Case Name' field.&lt;br&gt;3. Click 'Create'.&lt;/td&gt;
&lt;td&gt;Check if special characters are allowed or an error message is displayed.&lt;/td&gt;
&lt;td&gt;Behavior matches expected rules.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC06&lt;/td&gt;
&lt;td&gt;Cancel test case creation&lt;/td&gt;
&lt;td&gt;1. Follow steps to TC01.&lt;br&gt;2. Enter a valid name.&lt;br&gt;3. Click 'Cancel' instead of 'Create'.&lt;/td&gt;
&lt;td&gt;User should be returned to the previous screen without creating a test case.&lt;/td&gt;
&lt;td&gt;Navigation is correct without creation.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Trial 2 - Prompt to classify and tag tests
&lt;/h3&gt;

&lt;p&gt;"I am a &lt;strong&gt;QA Engineer&lt;/strong&gt; and I want to write &lt;strong&gt;functional test cases&lt;/strong&gt; for a feature. Find the details about the same below. Generate all possible functional test cases. Also identify the &lt;strong&gt;P0&lt;/strong&gt; scenarios and tag the test cases based on different components. &lt;/p&gt;

&lt;p&gt;The test cases should be presented in a &lt;strong&gt;tabular format&lt;/strong&gt;."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Title&lt;/th&gt;
&lt;th&gt;Objective&lt;/th&gt;
&lt;th&gt;Preconditions&lt;/th&gt;
&lt;th&gt;Test Steps&lt;/th&gt;
&lt;th&gt;Expected Result&lt;/th&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TC01&lt;/td&gt;
&lt;td&gt;Create Test Case from Home Page&lt;/td&gt;
&lt;td&gt;Verify creating a test case from the home page.&lt;/td&gt;
&lt;td&gt;User logged in, on home page.&lt;/td&gt;
&lt;td&gt;1. Click "New Web Test Case".&lt;br&gt;2. Enter name, click "Create".&lt;/td&gt;
&lt;td&gt;New test case created, user redirected to editor.&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC02&lt;/td&gt;
&lt;td&gt;Create Test Case from Explorer&lt;/td&gt;
&lt;td&gt;Verify creating a test case from the Explorer.&lt;/td&gt;
&lt;td&gt;User logged in, on Explorer page.&lt;/td&gt;
&lt;td&gt;1. Navigate to Test Cases.&lt;br&gt;2. Click "Add new", enter name.&lt;/td&gt;
&lt;td&gt;New test case created, user redirected to editor.&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC03&lt;/td&gt;
&lt;td&gt;Enter Test Case Metadata&lt;/td&gt;
&lt;td&gt;Verify entering metadata details in the editor.&lt;/td&gt;
&lt;td&gt;New test case open in editor.&lt;/td&gt;
&lt;td&gt;1. Enter Summary, Tags, Feature in metadata fields.&lt;/td&gt;
&lt;td&gt;Metadata saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC04&lt;/td&gt;
&lt;td&gt;Create Detailed Test Steps&lt;/td&gt;
&lt;td&gt;Verify creation of detailed test steps.&lt;/td&gt;
&lt;td&gt;Test case selected, in Detailed Steps tab.&lt;/td&gt;
&lt;td&gt;1. Input actions and expected results in respective columns.&lt;/td&gt;
&lt;td&gt;Detailed steps saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC05&lt;/td&gt;
&lt;td&gt;Add Automation Test Steps&lt;/td&gt;
&lt;td&gt;Verify adding steps for automation.&lt;/td&gt;
&lt;td&gt;Test case selected, in Automation tab.&lt;/td&gt;
&lt;td&gt;1. Click "Add Step", select UI action for automation.&lt;/td&gt;
&lt;td&gt;Automation steps added and saved correctly.&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC06&lt;/td&gt;
&lt;td&gt;Edit Test Case Properties&lt;/td&gt;
&lt;td&gt;Verify editing properties of a test case.&lt;/td&gt;
&lt;td&gt;Test case open in editor.&lt;/td&gt;
&lt;td&gt;1. Update fields like Summary, Tags. Click to save.&lt;/td&gt;
&lt;td&gt;Updated properties saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Trial 3 - Prompt with PRD and details on existing functionality
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;More comprehensive test cases were generated.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Title&lt;/th&gt;
&lt;th&gt;Objective&lt;/th&gt;
&lt;th&gt;Preconditions&lt;/th&gt;
&lt;th&gt;Test Steps&lt;/th&gt;
&lt;th&gt;Expected Result&lt;/th&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TC01&lt;/td&gt;
&lt;td&gt;Create Test Case from Home Page&lt;/td&gt;
&lt;td&gt;Verify creating a test case from the home page.&lt;/td&gt;
&lt;td&gt;User logged in, on home page.&lt;/td&gt;
&lt;td&gt;1. Click "New Web Test Case".&lt;br&gt;2. Enter name, click "Create".&lt;/td&gt;
&lt;td&gt;New test case created, user redirected to editor.&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC02&lt;/td&gt;
&lt;td&gt;Create Test Case from Explorer&lt;/td&gt;
&lt;td&gt;Verify creating a test case from the Explorer.&lt;/td&gt;
&lt;td&gt;User logged in, on Explorer page.&lt;/td&gt;
&lt;td&gt;1. Navigate to Test Cases.&lt;br&gt;2. Click "Add new", enter name.&lt;/td&gt;
&lt;td&gt;New test case created, user redirected to editor.&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC03&lt;/td&gt;
&lt;td&gt;Enter Test Case Metadata&lt;/td&gt;
&lt;td&gt;Verify entering metadata details in the editor.&lt;/td&gt;
&lt;td&gt;New test case open in editor.&lt;/td&gt;
&lt;td&gt;1. Enter Summary, Tags, Feature in metadata fields.&lt;/td&gt;
&lt;td&gt;Metadata saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC04&lt;/td&gt;
&lt;td&gt;Create Detailed Test Steps&lt;/td&gt;
&lt;td&gt;Verify creation of detailed test steps.&lt;/td&gt;
&lt;td&gt;Test case selected, in Detailed Steps tab.&lt;/td&gt;
&lt;td&gt;1. Input actions and expected results in respective columns.&lt;/td&gt;
&lt;td&gt;Detailed steps saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC05&lt;/td&gt;
&lt;td&gt;Add Automation Test Steps&lt;/td&gt;
&lt;td&gt;Verify adding steps for automation.&lt;/td&gt;
&lt;td&gt;Test case selected, in Automation tab.&lt;/td&gt;
&lt;td&gt;1. Click "Add Step", select UI action for automation.&lt;/td&gt;
&lt;td&gt;Automation steps added and saved correctly.&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC06&lt;/td&gt;
&lt;td&gt;Edit Test Case Properties&lt;/td&gt;
&lt;td&gt;Verify editing properties of a test case.&lt;/td&gt;
&lt;td&gt;Test case open in editor.&lt;/td&gt;
&lt;td&gt;1. Update fields like Summary, Tags. Click to save.&lt;/td&gt;
&lt;td&gt;Updated properties saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC07&lt;/td&gt;
&lt;td&gt;Edit Automation Steps&lt;/td&gt;
&lt;td&gt;Verify editing of automation test steps.&lt;/td&gt;
&lt;td&gt;Automation steps exist in a test case.&lt;/td&gt;
&lt;td&gt;1. Navigate to Automation tab.&lt;br&gt;2. Hover and edit a step.&lt;/td&gt;
&lt;td&gt;Changes saved and updated step displayed correctly.&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC08&lt;/td&gt;
&lt;td&gt;Delete Automation Test Step&lt;/td&gt;
&lt;td&gt;Verify deletion of an automation test step.&lt;/td&gt;
&lt;td&gt;Automation step present in a test case.&lt;/td&gt;
&lt;td&gt;1. Select step, click "Delete".&lt;/td&gt;
&lt;td&gt;Step deleted and no longer displayed.&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC09&lt;/td&gt;
&lt;td&gt;Test Search and Filter with Tags&lt;/td&gt;
&lt;td&gt;Verify searching and filtering test cases using tags.&lt;/td&gt;
&lt;td&gt;Multiple test cases with various tags created.&lt;/td&gt;
&lt;td&gt;1. Use tags in search/filter box to find test cases.&lt;/td&gt;
&lt;td&gt;Test cases matching tags displayed.&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC10&lt;/td&gt;
&lt;td&gt;Copy Automation Test Step&lt;/td&gt;
&lt;td&gt;Verify ability to copy an automation test step.&lt;/td&gt;
&lt;td&gt;At least one automation step present.&lt;/td&gt;
&lt;td&gt;1. Select step, click "Copy", then paste to desired location.&lt;/td&gt;
&lt;td&gt;Copied step displayed correctly in new location.&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC11&lt;/td&gt;
&lt;td&gt;Add Comment to Test Step&lt;/td&gt;
&lt;td&gt;Verify adding a comment to a test step.&lt;/td&gt;
&lt;td&gt;Test step available in the test case.&lt;/td&gt;
&lt;td&gt;1. Select test step, add a comment.&lt;/td&gt;
&lt;td&gt;Comment saved and visible next to the test step.&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC12&lt;/td&gt;
&lt;td&gt;Enable/Disable Test Step (Commenting Test Steps)&lt;/td&gt;
&lt;td&gt;Verify ability to enable/disable a test step.&lt;/td&gt;
&lt;td&gt;Test step created in test case.&lt;/td&gt;
&lt;td&gt;1. Choose test step, toggle enable/disable.&lt;/td&gt;
&lt;td&gt;Test step enabled/disabled as per toggle status.&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC13&lt;/td&gt;
&lt;td&gt;Move Test Step&lt;/td&gt;
&lt;td&gt;Verify moving a test step to a different position.&lt;/td&gt;
&lt;td&gt;Multiple steps created in a test case.&lt;/td&gt;
&lt;td&gt;1. Select a test step, move to a new position.&lt;/td&gt;
&lt;td&gt;Test step displayed in the new position correctly.&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Trial 4 - Build more test cases on top of Trial 3
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;6 Additional tests but most of them were duplicates of previous results and there were hallucinations as well.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;Title&lt;/th&gt;
&lt;th&gt;Objective&lt;/th&gt;
&lt;th&gt;Preconditions&lt;/th&gt;
&lt;th&gt;Test Steps&lt;/th&gt;
&lt;th&gt;Expected Result&lt;/th&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TC14&lt;/td&gt;
&lt;td&gt;Validate Project Initialization&lt;/td&gt;
&lt;td&gt;Ensure a project can be properly initialized in the system.&lt;/td&gt;
&lt;td&gt;User logged in, on project creation page.&lt;/td&gt;
&lt;td&gt;1. Initiate project setup.&lt;br&gt;2. Verify initialization steps.&lt;/td&gt;
&lt;td&gt;Project is initialized and listed correctly in user dashboard.&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC15&lt;/td&gt;
&lt;td&gt;Test Case Duplication&lt;/td&gt;
&lt;td&gt;Verify that a test case can be duplicated correctly.&lt;/td&gt;
&lt;td&gt;Test case exists that can be duplicated.&lt;/td&gt;
&lt;td&gt;1. Select existing test case.&lt;br&gt;2. Duplicate it.&lt;/td&gt;
&lt;td&gt;New test case is a duplicate and contains the same details.&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC16&lt;/td&gt;
&lt;td&gt;Enter Test Case Metadata&lt;/td&gt;
&lt;td&gt;Verify entering metadata details in the editor.&lt;/td&gt;
&lt;td&gt;New test case open in editor.&lt;/td&gt;
&lt;td&gt;1. Enter Summary, Tags, Feature in metadata fields.&lt;/td&gt;
&lt;td&gt;Metadata saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC17&lt;/td&gt;
&lt;td&gt;Create Detailed Test Steps&lt;/td&gt;
&lt;td&gt;Verify creation of detailed test steps.&lt;/td&gt;
&lt;td&gt;Test case selected, in Detailed Steps tab.&lt;/td&gt;
&lt;td&gt;1. Input actions and expected results in respective columns.&lt;/td&gt;
&lt;td&gt;Detailed steps saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;P0&lt;/td&gt;
&lt;td&gt;Functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC18&lt;/td&gt;
&lt;td&gt;Edit Test Case Properties&lt;/td&gt;
&lt;td&gt;Verify editing properties of a test case.&lt;/td&gt;
&lt;td&gt;Test case open in editor.&lt;/td&gt;
&lt;td&gt;1. Update fields like Summary, Tags. Click to save.&lt;/td&gt;
&lt;td&gt;Updated properties saved and displayed correctly.&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TC19&lt;/td&gt;
&lt;td&gt;Load Test Case Efficiency&lt;/td&gt;
&lt;td&gt;Test the load efficiency of opening a test case.&lt;/td&gt;
&lt;td&gt;User selects a test case to open.&lt;/td&gt;
&lt;td&gt;1. Open test case.&lt;br&gt;2. Measure load time.&lt;/td&gt;
&lt;td&gt;Test case opens within acceptable time limits.&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Inferences
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trial 1&lt;/strong&gt; results are not relevant and not useful as there was no complete context of the feature / application. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trial 2&lt;/strong&gt; results are appropriate, but the test cases are very high level. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trial 3&lt;/strong&gt; results are accurate, but 14 test cases are not enough to validate the feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trial 4&lt;/strong&gt; results had duplicates from previous results, it required more effort to check and clean the list, and ended up having fewer tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trial 4&lt;/strong&gt; also had results that were not related to the data in the PRD, in other words the model started hallucinating.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are numerous factors to be considered while using AI to write test cases&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test cases list should cover all the user flows and negative tests as well.&lt;/li&gt;
&lt;li&gt;PRDs / Spec documents could be huge and might not fit in the LLM’s context window.&lt;/li&gt;
&lt;li&gt;Many UI applications rely on UI mockups in tools like Figma, rather than using PRDs as the source of truth.&lt;/li&gt;
&lt;li&gt;Duplicate test cases should not be created every time AI generates the tests.&lt;/li&gt;
&lt;li&gt;AI should have access to entire application information or existing test cases to create new tests based on the integration or dependent flows.&lt;/li&gt;
&lt;li&gt;AI should have access to test data store / sample data to create test cases with appropriate test data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given all these factors, we can leverage Gen AI and build an effective tool that can assist in test cases authoring and test case management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will this AI tool replace QA Engineers?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;No!&lt;/strong&gt;, this will help QA engineers to be more productive, and help teams to easily streamline the testing process. It will help engineering teams scale faster, ship faster with better quality. QA Engineers can start focussing on more impacting activities like exploratory testing, monkey testing, usability validations and let tools like DevAssure do the mundane tasks for them, and such tools can be consumed by anyone on the team - PMs, Developers and QA Engineers and the responsibility of owning quality should and can be shared across all the teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  DevAssure's Test Case Generation from Figma Mockups and PRDs
&lt;/h3&gt;

&lt;p&gt;DevAssure AI connects seamlessly with Figma and generates feature and regression test cases from specification documents and mockups within a few seconds. Save hundreds of hours of manual work in writing test cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.devassure.io/docs/DevAssure/Generate%20Tests/Autogenerate"&gt;Learn more&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>ai</category>
      <category>testcase</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
