<?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: krishnamurthy yarram</title>
    <description>The latest articles on DEV Community by krishnamurthy yarram (@krishnamurthy_yarram_5cf5).</description>
    <link>https://dev.to/krishnamurthy_yarram_5cf5</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%2F3790959%2F37f29e05-2088-4263-9a60-70a1d6b4c997.png</url>
      <title>DEV Community: krishnamurthy yarram</title>
      <link>https://dev.to/krishnamurthy_yarram_5cf5</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/krishnamurthy_yarram_5cf5"/>
    <language>en</language>
    <item>
      <title>Stop Using Thread.sleep(): Smart Polling for CloudWatch Log Validation in Java (AWS Test Automation)</title>
      <dc:creator>krishnamurthy yarram</dc:creator>
      <pubDate>Wed, 25 Feb 2026 06:27:21 +0000</pubDate>
      <link>https://dev.to/krishnamurthy_yarram_5cf5/stop-using-threadsleep-smart-polling-for-cloudwatch-log-validation-in-java-aws-test-automation-2mj6</link>
      <guid>https://dev.to/krishnamurthy_yarram_5cf5/stop-using-threadsleep-smart-polling-for-cloudwatch-log-validation-in-java-aws-test-automation-2mj6</guid>
      <description>&lt;p&gt;While building automation frameworks for distributed systems, I ran into a common but frustrating issue:&lt;/p&gt;

&lt;p&gt;Our tests would trigger an API, but the logs in AWS CloudWatch would appear 2–4 minutes later.&lt;/p&gt;

&lt;p&gt;The result?&lt;/p&gt;

&lt;p&gt;❌ Tests failing even though the system was working perfectly.&lt;/p&gt;

&lt;p&gt;At first, the “quick fix” seemed obvious:&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="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;240000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that’s one of the worst things we can do in automation.&lt;/p&gt;

&lt;p&gt;Here’s how I solved it properly using a smart polling mechanism in Java.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚨 The Problem: Asynchronous Systems
&lt;/h2&gt;

&lt;p&gt;Modern systems are asynchronous.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API triggers background processing&lt;/li&gt;
&lt;li&gt;Services communicate via queues&lt;/li&gt;
&lt;li&gt;Logs appear with delay&lt;/li&gt;
&lt;li&gt;Eventual consistency is normal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your test validates logs immediately after triggering an API, it will often fail.&lt;/p&gt;

&lt;p&gt;Not because the system is broken.&lt;/p&gt;

&lt;p&gt;But because your test is impatient.&lt;/p&gt;




&lt;h2&gt;
  
  
  ❌ The Wrong Approach
&lt;/h2&gt;

&lt;p&gt;Using fixed waits:&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="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;240000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Wait 4 minutes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why this is bad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slows down your entire suite&lt;/li&gt;
&lt;li&gt;Wastes CI/CD time&lt;/li&gt;
&lt;li&gt;Still fails if logs take 5 minutes&lt;/li&gt;
&lt;li&gt;Makes tests flaky&lt;/li&gt;
&lt;li&gt;Hides real timing behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fixed waits are blind waits.&lt;/p&gt;

&lt;p&gt;We need intelligent waits.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ The Right Approach: Smart Polling
&lt;/h2&gt;

&lt;p&gt;Instead of waiting blindly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Execute CloudWatch Insights query&lt;/li&gt;
&lt;li&gt;Check query status&lt;/li&gt;
&lt;li&gt;Verify results are not empty&lt;/li&gt;
&lt;li&gt;Retry until timeout&lt;/li&gt;
&lt;li&gt;Fail gracefully if condition never met&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Waits only as long as needed&lt;/li&gt;
&lt;li&gt;Stops early if logs appear&lt;/li&gt;
&lt;li&gt;Avoids unnecessary delays&lt;/li&gt;
&lt;li&gt;Makes automation resilient&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗 Architecture Overview
&lt;/h2&gt;

&lt;p&gt;Test&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Trigger API&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Execute CloudWatch Query&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Polling Utility&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Wait Until Condition Met&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Assert Logs  &lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 Implementing Smart Polling in Java
&lt;/h2&gt;

&lt;p&gt;Here’s a clean polling utility method:&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BooleanSupplier&lt;/span&gt; &lt;span class="n"&gt;condition&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;timeoutSeconds&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;pollIntervalSeconds&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;endTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timeoutSeconds&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000L&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endTime&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAsBoolean&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="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pollIntervalSeconds&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;interrupt&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="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Condition not met within timeout."&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;h2&gt;
  
  
  🔍 Using It for CloudWatch Log Validation
&lt;/h2&gt;

&lt;p&gt;Example usage:&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="n"&gt;waitUntil&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;QueryResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cloudWatchClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your query here"&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;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStatus&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Complete"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
           &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogs&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wait up to 300 seconds (5 minutes)&lt;/li&gt;
&lt;li&gt;Poll every 10 seconds&lt;/li&gt;
&lt;li&gt;Exit early if logs are found&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Much smarter than sleeping blindly.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Why This Matters in Real Projects
&lt;/h2&gt;

&lt;p&gt;In microservices architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs are delayed&lt;/li&gt;
&lt;li&gt;Events are processed asynchronously&lt;/li&gt;
&lt;li&gt;Systems rely on eventual consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your automation framework must understand that.&lt;/p&gt;

&lt;p&gt;Otherwise, you’ll end up debugging “failures” that are not actually failures.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 Advanced Improvements
&lt;/h2&gt;

&lt;p&gt;To make this production-grade:&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Add Logging
&lt;/h3&gt;

&lt;p&gt;Log every polling attempt for transparency.&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ Make Timeout Configurable
&lt;/h3&gt;

&lt;p&gt;Read timeout values from config files or environment variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ Add Exponential Backoff
&lt;/h3&gt;

&lt;p&gt;Instead of fixed intervals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with 5 seconds&lt;/li&gt;
&lt;li&gt;Increase gradually&lt;/li&gt;
&lt;li&gt;Reduce load on AWS APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4️⃣ Combine With Assertions
&lt;/h3&gt;

&lt;p&gt;Validate log content once logs appear.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Benefits of Smart Polling
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Faster execution (no unnecessary waiting)&lt;/li&gt;
&lt;li&gt;More reliable CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Reduced flakiness&lt;/li&gt;
&lt;li&gt;Better system-awareness&lt;/li&gt;
&lt;li&gt;Cleaner framework design&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Important Principle
&lt;/h2&gt;

&lt;p&gt;Good automation frameworks are not just about UI clicks.&lt;/p&gt;

&lt;p&gt;They must understand distributed system behavior.&lt;/p&gt;

&lt;p&gt;If your system is asynchronous,&lt;br&gt;
your tests must be asynchronous-aware.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Thread.sleep() is easy.&lt;/p&gt;

&lt;p&gt;But it’s rarely correct.&lt;/p&gt;

&lt;p&gt;Smart polling makes your automation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster&lt;/li&gt;
&lt;li&gt;Cleaner&lt;/li&gt;
&lt;li&gt;More professional&lt;/li&gt;
&lt;li&gt;More production-ready&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're validating CloudWatch logs or any asynchronous behavior, stop sleeping blindly and start polling intelligently.&lt;/p&gt;




</description>
      <category>java</category>
      <category>aws</category>
      <category>testautomation</category>
      <category>devops</category>
    </item>
    <item>
      <title>Building a Self-Healing XPath Mechanism in Selenium (Java) – Stop Fixing Broken Tests</title>
      <dc:creator>krishnamurthy yarram</dc:creator>
      <pubDate>Wed, 25 Feb 2026 06:14:15 +0000</pubDate>
      <link>https://dev.to/krishnamurthy_yarram_5cf5/building-a-self-healing-xpath-mechanism-in-selenium-java-stop-fixing-broken-tests-24p4</link>
      <guid>https://dev.to/krishnamurthy_yarram_5cf5/building-a-self-healing-xpath-mechanism-in-selenium-java-stop-fixing-broken-tests-24p4</guid>
      <description>&lt;h1&gt;
  
  
  Building a Self-Healing XPath Mechanism in Selenium (Java)
&lt;/h1&gt;

&lt;p&gt;If you’ve worked with Selenium long enough, you’ve experienced this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Tests passing yesterday
&lt;/li&gt;
&lt;li&gt;❌ Same tests failing today
&lt;/li&gt;
&lt;li&gt;🤯 Reason? Broken XPath
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern UI frameworks like React, Angular, and Vue constantly change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic IDs&lt;/li&gt;
&lt;li&gt;Auto-generated attributes&lt;/li&gt;
&lt;li&gt;DOM structure updates&lt;/li&gt;
&lt;li&gt;Component re-rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As automation engineers, we often spend more time fixing locators than building test logic.&lt;/p&gt;

&lt;p&gt;So I asked myself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we build a mechanism that automatically heals broken XPaths instead of failing immediately?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This blog walks through how I designed a basic self-healing locator mechanism using Java + Selenium.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 The Core Idea
&lt;/h2&gt;

&lt;p&gt;Instead of directly calling:&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="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;"//button[@id='loginBtn']"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a smart wrapper:&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="n"&gt;smartFindElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"//button[@id='loginBtn']"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the primary XPath fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attempt fallback search&lt;/li&gt;
&lt;li&gt;Scan DOM for similar elements&lt;/li&gt;
&lt;li&gt;Compare attributes&lt;/li&gt;
&lt;li&gt;Score possible matches&lt;/li&gt;
&lt;li&gt;Return the best candidate&lt;/li&gt;
&lt;li&gt;(Optional) Update locator storage&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗 Architecture Design
&lt;/h2&gt;

&lt;p&gt;Test Layer&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Smart Locator Manager&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Primary XPath Attempt&lt;br&gt;&lt;br&gt;
↓ (if fails)&lt;br&gt;&lt;br&gt;
Healing Engine&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Attribute Scoring&lt;br&gt;&lt;br&gt;
↓&lt;br&gt;&lt;br&gt;
Return Healed Element  &lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 Step 1: Smart Find Method
&lt;/h2&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;smartFindElement&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;xpath&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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="n"&gt;xpath&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;NoSuchElementException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Primary XPath failed. Attempting healing..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;healElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xpath&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;h2&gt;
  
  
  🧠 Step 2: Healing Logic
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;WebElement&lt;/span&gt; &lt;span class="nf"&gt;healElement&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;oldXpath&lt;/span&gt;&lt;span class="o"&gt;)&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;candidates&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;"//*"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="nc"&gt;WebElement&lt;/span&gt; &lt;span class="n"&gt;bestMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;highestScore&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="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;WebElement&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="o"&gt;)&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;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculateScore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;highestScore&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;highestScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;bestMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bestMatch&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NoSuchElementException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Element not found even after healing."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Healed element found with score: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;highestScore&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;bestMatch&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;h2&gt;
  
  
  🧠 Step 3: Attribute Scoring Strategy
&lt;/h2&gt;

&lt;p&gt;We assign weights to stable attributes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Weight&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;id&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;name&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Example implementation:&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;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;calculateScore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;WebElement&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;)&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;score&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&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="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;element&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;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"class"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;score&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;score&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;h2&gt;
  
  
  🔥 Advanced Improvements (Hackathon-Level Ideas)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Store Historical Locator Mapping
&lt;/h3&gt;

&lt;p&gt;When healing succeeds:&lt;/p&gt;

&lt;p&gt;Store:&lt;/p&gt;

&lt;p&gt;Old XPath → New Working XPath&lt;/p&gt;

&lt;p&gt;Options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON file
&lt;/li&gt;
&lt;li&gt;Database
&lt;/li&gt;
&lt;li&gt;Cloud storage
&lt;/li&gt;
&lt;li&gt;CI logs
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2️⃣ DOM Similarity Comparison
&lt;/h3&gt;

&lt;p&gt;Instead of simple scoring, compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tag name match
&lt;/li&gt;
&lt;li&gt;Parent structure similarity
&lt;/li&gt;
&lt;li&gt;Sibling index
&lt;/li&gt;
&lt;li&gt;Levenshtein distance for attribute values
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3️⃣ AI-Based Healing
&lt;/h3&gt;

&lt;p&gt;Train a lightweight ML model to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Predict stable attributes
&lt;/li&gt;
&lt;li&gt;Learn from past locator failures
&lt;/li&gt;
&lt;li&gt;Identify patterns in dynamic IDs
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reduced maintenance effort
&lt;/li&gt;
&lt;li&gt;Faster CI/CD execution
&lt;/li&gt;
&lt;li&gt;Fewer flaky tests
&lt;/li&gt;
&lt;li&gt;More resilient automation framework
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Challenges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Performance impact if scanning entire DOM
&lt;/li&gt;
&lt;li&gt;Risk of incorrect healing
&lt;/li&gt;
&lt;li&gt;Requires strong logging
&lt;/li&gt;
&lt;li&gt;Must avoid masking real UI bugs
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Self-healing locators are not magic.&lt;/p&gt;

&lt;p&gt;But when implemented carefully, they can drastically reduce maintenance overhead and make automation frameworks smarter.&lt;/p&gt;

&lt;p&gt;Instead of reacting to broken tests, we can build systems that adapt.&lt;/p&gt;

&lt;p&gt;If you're working on Selenium + Java frameworks, this is a great hackathon idea or framework enhancement project.&lt;/p&gt;

</description>
      <category>selenium</category>
      <category>java</category>
      <category>testautomation</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
