Popular Searches
Popular Course Categories
Popular Courses

Handling JavaScript-Based Applications

Handling JavaScript-Based Applications

JavaScript with Selenium

Handling JavaScript-Based Applications in Selenium WebDriver

Modern web applications are heavily dependent on JavaScript to create dynamic, interactive, and responsive user interfaces. Applications built with JavaScript frameworks such as React, Angular, Vue.js, and other client-side technologies frequently update page content without performing a complete browser refresh. Handling such JavaScript-based applications effectively is an important skill for Selenium WebDriver automation.

In Selenium automation, JavaScript can control page elements, load dynamic content, modify the DOM, trigger browser events, display or hide elements, handle asynchronous operations, and communicate with backend services through AJAX or Fetch APIs. Because of this dynamic behavior, Selenium tests must be designed carefully to locate elements at the correct time, wait for required conditions, handle DOM changes, and interact with elements reliably.

This topic explains how Selenium WebDriver works with JavaScript-based applications, including dynamic elements, AJAX requests, JavaScriptExecutor, waits, asynchronous content, DOM updates, React and Angular applications, event handling, stale elements, scrolling, hidden elements, overlays, and practical automation techniques.

Selenium Training Course | Register for Course Demo


 

1. What is a JavaScript-Based Application?

A JavaScript-based application is a web application that uses JavaScript extensively to control the user interface, perform calculations, communicate with servers, update page content, and respond to user actions.

Unlike traditional websites where clicking a link may reload the entire page, JavaScript applications can update only a specific section of the page while the rest of the application remains unchanged.

User Action

     |

     v

JavaScript Event

     |

     v

API / Server Request

     |

     v

Response Received

     |

     v

DOM Updated

     |

     v

User Interface Changes

 

2. Examples of JavaScript-Based Applications

  • React applications
  • Angular applications
  • Vue.js applications
  • Single Page Applications (SPA)
  • AJAX-based applications
  • Dynamic dashboards
  • E-commerce websites
  • Online banking applications
  • Booking applications
  • CRM applications
  • Real-time chat applications
  • Social media applications

 

3. Why JavaScript Applications Are Challenging for Selenium?

JavaScript applications continuously modify the DOM. An element that exists when the page initially loads may be replaced, removed, or recreated later. Selenium therefore needs to synchronize with the application state rather than simply waiting for the page to load.

  • Elements may appear dynamically
  • DOM elements may be replaced
  • Content may load through AJAX
  • Buttons may become enabled later
  • Loading overlays may block interactions
  • Elements may be rendered after JavaScript execution
  • Page content may change without a refresh
  • Network requests may complete at different times
  • Frameworks may re-render elements
  • JavaScript events may control application behavior

 

4. Traditional Website vs JavaScript Application

Traditional WebsiteJavaScript-Based Application
Frequent full-page refreshesPartial DOM updates
Content often available after page loadContent may load asynchronously
Simple page navigationClient-side routing
Static elements are commonDynamic elements are common
Synchronization is relatively simpleSynchronization requires careful waits
Server generates much of the HTMLJavaScript may generate or modify HTML

 

5. Understanding the DOM

The Document Object Model (DOM) represents the structure of an HTML document as objects that JavaScript can access and modify.

<html>

    <body>

        <div id="app">

            <button id="login">Login</button>

        </div>

    </body>

</html>

JavaScript can modify this DOM by changing attributes, text, styles, classes, values, or by creating and removing elements.

 

6. Selenium and the Browser DOM

Selenium WebDriver communicates with the browser and allows automation scripts to locate and interact with DOM elements.

Test Script

    |

    v

Selenium WebDriver

    |

    v

Browser Driver

    |

    v

Browser

    |

    v

DOM / Web Application

 

7. Basic Selenium Setup

import java.time.Duration;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.support.ui.WebDriverWait;

import org.openqa.selenium.support.ui.ExpectedConditions;

 

8. Starting WebDriver

WebDriver driver = new ChromeDriver();

 

driver.manage().window().maximize();

 

driver.get("https://example.com");

 

9. Locating Elements in JavaScript Applications

Locators are especially important when automating dynamic applications. Whenever possible, use stable attributes such as IDs, names, accessible attributes, or application-specific test attributes.

WebElement username =

    driver.findElement(By.id("username"));

 

WebElement login =

    driver.findElement(By.id("login"));

 

10. Common Selenium Locators

LocatorExampleUsage
IDBy.id("username")Stable unique element ID
NameBy.name("email")Name attribute
Class NameBy.className("login")CSS class
Tag NameBy.tagName("button")HTML tag
Link TextBy.linkText("Login")Exact link text
CSS SelectorBy.cssSelector("#login")CSS-based selection
XPathBy.xpath("//button[@id='login']")Flexible element selection

 

11. Understanding Dynamic Elements

A dynamic element is an element whose presence, attributes, location, text, or state changes during application execution.

Page Load

   |

   v

Loading...

   |

   v

JavaScript Request

   |

   v

Data Received

   |

   v

Element Created

   |

   v

Element Available

 

12. Why Thread.sleep() Is Not the Best Solution

Using fixed delays can make tests slower and less reliable because the required element may become available before or after the specified delay.

Thread.sleep(5000);

A better approach is to wait for a meaningful application condition.

 

13. Explicit Wait

Explicit waits allow Selenium to wait until a specific condition becomes true.

WebDriverWait wait =

    new WebDriverWait(driver, Duration.ofSeconds(10));

 

WebElement login =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("login")

        )

    );

 

14. Wait for Element to Be Present

WebElement element =

    wait.until(

        ExpectedConditions.presenceOfElementLocated(

            By.id("username")

        )

    );

 

15. Wait for Element to Be Visible

WebElement element =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("username")

        )

    );

 

16. Wait for Element to Be Clickable

WebElement button =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("login")

        )

    );

 

button.click();

 

17. Wait for Text to Appear

wait.until(

    ExpectedConditions.textToBePresentInElementLocated(

        By.id("message"),

        "Login successful"

    )

);

 

18. Handling AJAX Requests

AJAX allows a web application to communicate with the server without refreshing the entire page. Selenium does not directly wait for an AJAX request itself. Instead, the test should wait for a visible application state that indicates that the request has completed.

Click Search

    |

    v

AJAX Request

    |

    v

Loading Indicator

    |

    v

Server Response

    |

    v

Results Rendered

    |

    v

Result Element Available

 

19. Handling AJAX Results

driver.findElement(By.id("search")).click();

 

WebElement result =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".search-result")

        )

    );

 

System.out.println(result.getText());

 

20. Handling Loading Indicators

JavaScript applications often display a loading spinner while an operation is in progress.

wait.until(

    ExpectedConditions.invisibilityOfElementLocated(

        By.cssSelector(".loading-spinner")

    )

);

 

21. Handling Dynamic Buttons

A button may initially be disabled and become enabled after JavaScript validation.

WebElement submit =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("submit")

        )

    );

 

submit.click();

 

22. Handling Dynamically Generated Text

wait.until(

    ExpectedConditions.textToBePresentInElementLocated(

        By.id("status"),

        "Completed"

    )

);

 

23. Understanding JavaScriptExecutor

JavaScriptExecutor is a Selenium interface that allows JavaScript code to be executed inside the browser.

import org.openqa.selenium.JavascriptExecutor;

 

JavascriptExecutor js =

    (JavascriptExecutor) driver;

 

24. Executing JavaScript

js.executeScript(

    "alert('Hello Selenium');"

);

 

25. Passing a WebElement to JavaScript

WebElement element =

    driver.findElement(By.id("username"));

 

js.executeScript(

    "arguments[0].style.outline='3px solid red';",

    element

);

 

26. Understanding arguments[0]

The arguments[0] expression represents the first object passed to the JavaScript execution method.

js.executeScript(

    "arguments[0].click();",

    button

);

Here, button becomes arguments[0] inside the JavaScript code.

 

27. JavaScript Click

WebElement button =

    driver.findElement(By.id("submit"));

 

js.executeScript(

    "arguments[0].click();",

    button

);

JavaScript click should be used carefully because it can bypass some of the normal interaction behavior that a real user click would trigger.

 

28. Normal Selenium Click vs JavaScript Click

Normal SeleniumJavaScript
button.click()arguments[0].click()
Uses WebDriver interactionExecutes directly in page JavaScript
Better for normal user behaviorUseful for specialized DOM-level operations
Can expose interactability problemsMay bypass some UI restrictions

 

29. Handling Hidden Elements

JavaScript applications may create elements before displaying them. Selenium normally requires elements to be interactable for actions such as clicking.

WebElement element =

    driver.findElement(By.id("hiddenElement"));

 

js.executeScript(

    "arguments[0].style.display='block';",

    element

);

Changing visibility should be used only for controlled testing or debugging. It should not be used to hide genuine application defects.

 

30. Handling Disabled Elements

WebElement button =

    driver.findElement(By.id("submit"));

 

js.executeScript(

    "arguments[0].removeAttribute('disabled');",

    button

);

Removing the disabled attribute may bypass application validation. Therefore, it should be used only when the test specifically needs to inspect that DOM state.

 

31. Modifying Element Values with JavaScript

WebElement username =

    driver.findElement(By.id("username"));

 

js.executeScript(

    "arguments[0].value='admin';",

    username

);

 

32. JavaScript Value Changes and Application Events

A direct JavaScript change to an input's value does not necessarily produce the same events as typing through Selenium. JavaScript frameworks may depend on input, change, keyboard, or other events to update application state.

 

33. Dispatching an Input Event

js.executeScript(

    "arguments[0].value='admin';" +

    "arguments[0].dispatchEvent(" +

    "new Event('input',{bubbles:true})" +

    ");",

    username

);

 

34. Dispatching a Change Event

js.executeScript(

    "arguments[0].value='IN';" +

    "arguments[0].dispatchEvent(" +

    "new Event('change',{bubbles:true})" +

    ");",

    country

);

 

35. Why Events Matter in JavaScript Applications

Modern frameworks often listen for browser events to update their internal state. Changing the DOM alone may therefore not be enough.

User Action

    |

    v

Browser Event

    |

    v

Framework Event Handler

    |

    v

Application State

    |

    v

DOM Re-render

 

36. Handling React Applications

React applications commonly use component state and virtual DOM rendering. An element can be recreated after a state change, which means a previously stored WebElement reference may become stale.

For React applications, prefer normal Selenium interactions and explicit waits whenever possible. Use stable locators and re-locate elements after significant re-renders.

 

37. React Dynamic Element Example

WebElement username =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector("input[name='username']")

        )

    );

 

username.clear();

username.sendKeys("admin");

 

38. Handling React Re-Renders

If a React state change replaces an element, Selenium may report a StaleElementReferenceException.

WebElement button =

    driver.findElement(By.id("submit"));

 

button.click();

 

// Application re-renders the button

 

button =

    driver.findElement(By.id("submit"));

 

39. Handling Angular Applications

Angular applications can also dynamically render components and update elements based on application state, HTTP responses, form validation, and user events.

Use stable locators, explicit waits, and application-specific conditions rather than relying on arbitrary delays.

 

40. Handling Vue.js Applications

Vue.js applications dynamically update components and DOM elements based on reactive data. Selenium automation should wait for the required state rather than assuming that an element will remain unchanged after it is located.

 

41. Single Page Applications

A Single Page Application (SPA) can change views without performing a complete browser page refresh.

Login View

   |

   v

Dashboard View

   |

   v

Products View

   |

   v

Checkout View

The browser may remain on the same URL while the displayed DOM changes significantly.

 

42. Handling SPA Navigation

Because the page may not reload, a Selenium script should wait for an element or state that identifies the new view.

driver.findElement(By.id("dashboardLink")).click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("dashboard")

    )

);

 

43. Handling Dynamic URLs

SPA applications may change URL fragments or paths without a traditional page reload.

wait.until(

    ExpectedConditions.urlContains("/dashboard")

);

 

44. Handling DOM Changes

JavaScript can add, remove, replace, or modify DOM elements during execution. Tests should therefore avoid assuming that a WebElement reference remains valid indefinitely.

 

45. StaleElementReferenceException

StaleElementReferenceException occurs when Selenium has a reference to an element that is no longer attached to the current DOM.

WebElement element =

    driver.findElement(By.id("username"));

 

driver.navigate().refresh();

 

element =

    driver.findElement(By.id("username"));

 

46. Handling Stale Elements with Re-Locating

WebElement element =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("username")

        )

    );

 

element.click();

Re-locating the element after a known DOM refresh or re-render is often simpler than retaining an outdated reference.

 

47. Handling Stale Elements with a Retry Strategy

for (int i = 0; i < 3; i++) {

    try {

        WebElement button =

            driver.findElement(By.id("submit"));

 

        button.click();

        break;

    } catch (org.openqa.selenium.StaleElementReferenceException e) {

        System.out.println("Element became stale. Retrying...");

    }

}

 

48. Handling Dynamic Tables

JavaScript applications often update table rows dynamically after filtering, searching, pagination, or API responses.

WebElement row =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector("table tbody tr")

        )

    );

 

System.out.println(row.getText());

 

49. Handling Dynamic Dropdowns

A dropdown may load options only after the user clicks it or enters text.

WebElement search =

    driver.findElement(By.id("country"));

 

search.sendKeys("India");

 

WebElement option =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.xpath("//li[contains(.,'India')]")

        )

    );

 

option.click();

 

50. Handling Auto-Suggestion Boxes

WebElement search =

    driver.findElement(By.id("search"));

 

search.sendKeys("Mumbai");

 

WebElement suggestion =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".suggestion")

        )

    );

 

suggestion.click();

 

51. Handling Dynamic Search Results

driver.findElement(By.id("search"))

      .sendKeys("Selenium");

 

driver.findElement(By.id("searchButton"))

      .click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".search-result")

    )

);

 

52. Handling JavaScript Alerts

JavaScript applications may display browser alerts, confirmations, or prompts.

driver.findElement(By.id("delete")).click();

 

wait.until(

    ExpectedConditions.alertIsPresent()

);

 

driver.switchTo().alert().accept();

 

53. Handling JavaScript Confirmation

driver.switchTo().alert().dismiss();

 

54. Handling JavaScript Prompt

driver.switchTo().alert().sendKeys("Test Data");

driver.switchTo().alert().accept();

 

55. Handling Overlays

JavaScript applications frequently display modal dialogs, cookie banners, loading overlays, or notification layers above the target element.

wait.until(

    ExpectedConditions.invisibilityOfElementLocated(

        By.cssSelector(".overlay")

    )

);

 

driver.findElement(By.id("submit")).click();

 

56. Handling Modal Dialogs

WebElement modal =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".modal")

        )

    );

 

WebElement input =

    modal.findElement(By.cssSelector("input"));

 

input.sendKeys("Test Data");

 

57. Handling Cookie Banners

WebElement accept =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("acceptCookies")

        )

    );

 

accept.click();

 

58. Handling Shadow DOM

Some modern web applications use Shadow DOM to encapsulate HTML, CSS, and JavaScript behavior. Standard locators may not always be able to access elements inside a shadow root directly.

 

59. JavaScript Access to Shadow Root

WebElement host =

    driver.findElement(By.cssSelector("my-component"));

 

WebElement shadowElement =

    (WebElement) js.executeScript(

        "return arguments[0].shadowRoot.querySelector('button');",

        host

    );

 

shadowElement.click();

 

60. Shadow DOM Considerations

  • Identify the shadow host
  • Access the shadow root
  • Locate the required element inside the shadow root
  • Use Selenium's supported Shadow DOM APIs where applicable
  • Avoid unnecessary JavaScript when normal WebDriver methods are sufficient

 

61. Handling Iframes in JavaScript Applications

Some JavaScript applications load payment forms, authentication widgets, advertisements, or external components inside iframes.

WebElement frame =

    wait.until(

        ExpectedConditions.presenceOfElementLocated(

            By.id("paymentFrame")

        )

    );

 

driver.switchTo().frame(frame);

 

WebElement card =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("cardNumber")

        )

    );

 

card.sendKeys("4111111111111111");

 

driver.switchTo().defaultContent();

 

62. Handling Multiple Windows and Tabs

JavaScript applications can open new tabs or windows through user actions.

String originalWindow =

    driver.getWindowHandle();

 

driver.findElement(By.id("openWindow")).click();

 

wait.until(

    d -> d.getWindowHandles().size() > 1

);

 

for (String windowHandle : driver.getWindowHandles()) {

    if (!windowHandle.equals(originalWindow)) {

        driver.switchTo().window(windowHandle);

        break;

    }

}

 

63. Handling JavaScript Scroll

WebElement element =

    driver.findElement(By.id("footer"));

 

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    element

);

 

64. Scrolling the Page

js.executeScript(

    "window.scrollTo(0, document.body.scrollHeight);"

);

 

65. Scroll by a Specific Amount

js.executeScript(

    "window.scrollBy(0,500);"

);

 

66. Handling Lazy-Loaded Elements

Lazy loading means content is loaded only when it becomes necessary, often when the user scrolls toward it.

WebElement product =

    driver.findElement(

        By.cssSelector(".lazy-product")

    );

 

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    product

);

 

wait.until(

    ExpectedConditions.visibilityOf(product)

);

 

67. Handling Infinite Scrolling

long previousHeight = 0;

 

while (true) {

    long currentHeight =

        ((Number) js.executeScript(

            "return document.body.scrollHeight;"

        )).longValue();

 

    if (currentHeight == previousHeight) {

        break;

    }

 

    previousHeight = currentHeight;

 

    js.executeScript(

        "window.scrollTo(0, document.body.scrollHeight);"

    );

 

    Thread.sleep(1000);

}

For production automation, condition-based synchronization is generally preferable to relying on a fixed sleep.

 

68. Handling Dynamic Forms

JavaScript applications frequently enable, disable, add, or remove fields depending on previous selections.

driver.findElement(By.id("accountType"))

      .click();

 

WebElement companyName =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("companyName")

        )

    );

 

companyName.sendKeys("ABC Technologies");

 

69. Handling Dependent Dropdowns

driver.findElement(By.id("country"))

      .sendKeys("India");

 

WebElement state =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("state")

        )

    );

 

state.sendKeys("Maharashtra");

 

70. Handling Dynamic Checkboxes

WebElement checkbox =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("terms")

        )

    );

 

if (!checkbox.isSelected()) {

    checkbox.click();

}

 

71. Handling Dynamic Radio Buttons

WebElement radio =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("male")

        )

    );

 

if (!radio.isSelected()) {

    radio.click();

}

 

72. Handling Dynamic Attributes

JavaScript frameworks can dynamically generate attributes such as IDs, classes, ARIA attributes, and data attributes.

Prefer stable application-specific attributes whenever possible.

WebElement element =

    driver.findElement(

        By.cssSelector("[data-testid='login-button']")

    );

 

73. Using data-testid for Automation

A dedicated test attribute can make automation locators more stable.

WebElement login =

    driver.findElement(

        By.cssSelector("[data-testid='login']")

    );

 

74. Handling Dynamic Class Names

Some frameworks generate changing CSS class names. Avoid depending on an unstable generated class when a more stable attribute is available.

By locator =

    By.xpath("//button[contains(.,'Login')]");

 

75. Handling Dynamic IDs

If an ID changes between sessions, use another stable locator.

By locator =

    By.cssSelector("input[name='username']");

 

76. Handling Web Components

Modern JavaScript applications may use custom web components. These components can contain their own internal DOM or Shadow DOM.

 

77. Handling Client-Side Validation

JavaScript applications frequently validate forms before sending data to the server.

WebElement email =

    driver.findElement(By.id("email"));

 

email.clear();

email.sendKeys("invalid-email");

 

driver.findElement(By.id("submit"))

      .click();

 

WebElement error =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".email-error")

        )

    );

 

System.out.println(error.getText());

 

78. Handling Real-Time Validation

Some applications validate fields immediately after input events.

email.sendKeys("[email protected]");

 

wait.until(

    ExpectedConditions.invisibilityOfElementLocated(

        By.cssSelector(".email-error")

    )

);

 

79. Handling Network-Dependent UI

When a UI depends on an API response, wait for a user-visible condition such as a result, status message, table row, or spinner disappearance.

driver.findElement(By.id("loadData")).click();

 

wait.until(

    ExpectedConditions.invisibilityOfElementLocated(

        By.cssSelector(".loading")

    )

);

 

WebElement result =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("result")

        )

    );

 

80. Handling API-Driven Tables

driver.findElement(By.id("loadUsers")).click();

 

wait.until(

    ExpectedConditions.numberOfElementsToBeMoreThan(

        By.cssSelector("table tbody tr"),

        0

    )

);

 

81. Handling Dynamic Notifications

driver.findElement(By.id("save")).click();

 

WebElement notification =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".notification")

        )

    );

 

System.out.println(notification.getText());

 

82. Handling Toast Messages

wait.until(

    ExpectedConditions.textToBePresentInElementLocated(

        By.cssSelector(".toast"),

        "Saved successfully"

    )

);

 

83. Handling Dynamic Menus

WebElement menu =

    driver.findElement(By.id("menu"));

 

menu.click();

 

WebElement item =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.xpath("//a[contains(.,'Dashboard')]")

        )

    );

 

item.click();

 

84. Handling Hover Menus

import org.openqa.selenium.interactions.Actions;

 

Actions actions =

    new Actions(driver);

 

WebElement menu =

    driver.findElement(By.id("products"));

 

actions.moveToElement(menu).perform();

 

WebElement item =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("electronics")

        )

    );

 

item.click();

 

85. Handling JavaScript-Based Login

WebElement username =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("username")

        )

    );

 

WebElement password =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("password")

        )

    );

 

username.clear();

username.sendKeys("admin");

 

password.clear();

password.sendKeys("Password123");

 

WebElement login =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("login")

        )

    );

 

login.click();

 

86. Verifying Login After JavaScript Processing

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("dashboard")

    )

);

 

System.out.println("Dashboard loaded successfully.");

 

87. Handling JavaScript-Based Logout

WebElement logout =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("logout")

        )

    );

 

logout.click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("login")

    )

);

 

88. Handling Dynamic E-Commerce Applications

E-commerce websites commonly use JavaScript for product filtering, cart updates, price calculations, stock information, coupons, checkout steps, and payment workflows.

Search Product

    |

    v

API Request

    |

    v

Product Results

    |

    v

Select Product

    |

    v

Add to Cart

    |

    v

Cart Updated

    |

    v

Checkout

 

89. Handling Dynamic Product Cards

WebElement product =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".product-card")

        )

    );

 

WebElement addToCart =

    product.findElement(

        By.cssSelector(".add-to-cart")

    );

 

addToCart.click();

 

90. Verifying Dynamic Cart Updates

wait.until(

    ExpectedConditions.textToBePresentInElementLocated(

        By.id("cartCount"),

        "1"

    )

);

 

91. Handling Dynamic Price Updates

driver.findElement(By.id("quantity"))

      .clear();

 

driver.findElement(By.id("quantity"))

      .sendKeys("2");

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("totalPrice")

    )

);

 

System.out.println(

    driver.findElement(By.id("totalPrice")).getText()

);

 

92. Handling Search Suggestions

WebElement search =

    driver.findElement(By.id("search"));

 

search.sendKeys("Laptop");

 

WebElement suggestion =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.xpath("//li[contains(.,'Laptop')]")

        )

    );

 

suggestion.click();

 

93. Handling JavaScript-Based Pagination

WebElement next =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("nextPage")

        )

    );

 

next.click();

 

wait.until(

    ExpectedConditions.stalenessOf(

        driver.findElement(

            By.cssSelector("table tbody tr")

        )

    )

);

 

94. Handling Dynamic Search Filters

driver.findElement(By.id("category"))

      .click();

 

driver.findElement(

    By.xpath("//option[contains(.,'Electronics')]")

).click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".product-card")

    )

);

 

95. Handling Dynamic Modals

driver.findElement(By.id("openModal")).click();

 

WebElement modal =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".modal")

        )

    );

 

modal.findElement(

    By.id("username")

).sendKeys("admin");

 

96. Handling Animations

JavaScript applications may animate elements before making them available for interaction. If an animation blocks an interaction, wait for the appropriate state rather than assuming that visibility alone means the element is ready.

 

97. Handling Animated Elements

WebElement button =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("submit")

        )

    );

 

button.click();

 

98. Handling Elements Covered by Another Element

ElementClickInterceptedException may occur when an overlay, animation, sticky header, or another element is positioned above the target.

wait.until(

    ExpectedConditions.invisibilityOfElementLocated(

        By.cssSelector(".overlay")

    )

);

 

driver.findElement(By.id("submit")).click();

 

99. Handling ElementNotInteractableException

This exception can occur when an element exists in the DOM but cannot currently be interacted with.

  • Check visibility
  • Check whether the element is enabled
  • Check for overlays
  • Check whether the element is inside an iframe
  • Check whether the application is still rendering
  • Use explicit waits

 

100. Handling NoSuchElementException

NoSuchElementException usually means that Selenium could not locate the element at the time the locator was executed.

WebElement element =

    wait.until(

        ExpectedConditions.presenceOfElementLocated(

            By.id("username")

        )

    );

 

101. Handling TimeoutException

TimeoutException means that the expected condition was not satisfied within the configured wait period.

  • Verify the locator
  • Check whether the page is loaded correctly
  • Check whether an iframe is involved
  • Check whether the element appears only after an API response
  • Check for application errors
  • Use a suitable condition

 

102. Handling StaleElementReferenceException

For JavaScript-heavy applications, stale elements are common because frameworks can replace DOM nodes.

try {

    WebElement element =

        driver.findElement(By.id("submit"));

 

    element.click();

} catch (org.openqa.selenium.StaleElementReferenceException e) {

    WebElement element =

        driver.findElement(By.id("submit"));

 

    element.click();

}

 

103. Handling JavascriptException

JavascriptException can occur when JavaScript execution fails.

  • Check JavaScript syntax
  • Check whether the element exists
  • Check whether the element is in the correct document context
  • Check iframe or Shadow DOM boundaries
  • Verify that the JavaScript operation is supported

 

104. Debugging JavaScript Applications

When a Selenium test fails against a JavaScript application, inspect the application in the browser first.

  1. Open browser developer tools
  2. Inspect the target element
  3. Check whether the element exists
  4. Observe DOM changes
  5. Check Console errors
  6. Check Network requests
  7. Check loading indicators
  8. Check iframe boundaries
  9. Verify the locator
  10. Add an appropriate explicit wait

 

105. Using Browser Developer Tools

Browser developer tools are extremely useful when understanding JavaScript-based applications. The Elements panel shows the DOM, the Console shows JavaScript errors and messages, and the Network panel shows requests and responses.

 

106. Inspecting Dynamic Elements

Right Click

    |

    v

Inspect

    |

    v

Elements Panel

    |

    +---- Check ID

    +---- Check Class

    +---- Check Data Attributes

    +---- Check DOM Position

    +---- Check Shadow DOM

    |

    v

Create Stable Locator

 

107. Handling Console Errors

If a JavaScript application itself has a runtime error, Selenium may report symptoms such as missing elements, incomplete rendering, or unexpected states. Browser console inspection can help distinguish an automation synchronization problem from an application problem.

 

108. Handling Network Delays

Network delays can cause elements to appear later than expected. Tests should synchronize with application-visible conditions rather than using unnecessarily large fixed delays.

 

109. JavaScriptExecutor for Page Scrolling

WebElement element =

    driver.findElement(By.id("target"));

 

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    element

);

 

110. JavaScriptExecutor for Highlighting

js.executeScript(

    "arguments[0].style.outline='3px solid red';",

    element

);

 

111. JavaScriptExecutor for Reading DOM Information

String text =

    (String) js.executeScript(

        "return arguments[0].textContent;",

        element

    );

 

System.out.println(text);

 

112. JavaScriptExecutor for Reading the Current URL

String url =

    (String) js.executeScript(

        "return window.location.href;"

    );

 

System.out.println(url);

 

113. JavaScriptExecutor for Page Title

String title =

    (String) js.executeScript(

        "return document.title;"

    );

 

System.out.println(title);

 

114. JavaScriptExecutor for Document Ready State

String state =

    (String) js.executeScript(

        "return document.readyState;"

    );

 

System.out.println(state);

 

115. Understanding document.readyState

The document ready state can indicate whether the initial document has been loaded, but it does not necessarily mean that a JavaScript application has finished rendering all dynamic content.

StateMeaning
loadingDocument is still loading
interactiveInitial document has been parsed
completeDocument and dependent resources have finished loading

 

116. Waiting for document.readyState

wait.until(

    d -> ((JavascriptExecutor) d)

        .executeScript(

            "return document.readyState"

        )

        .equals("complete")

);

For JavaScript applications, this should generally be combined with waits for application-specific elements or states.

 

117. Handling Application-Specific Loading States

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("dashboard")

    )

);

 

118. Handling URL-Based SPA State

wait.until(

    ExpectedConditions.urlContains("/dashboard")

);

 

119. Handling JavaScript-Based File Uploads

File upload controls may be wrapped inside custom JavaScript components. Selenium should normally interact with the underlying file input using sendKeys() when possible.

WebElement upload =

    driver.findElement(By.cssSelector(

        "input[type='file']"

    ));

 

upload.sendKeys(

    "C:\\\\Users\\\\Test\\\\Documents\\\\sample.pdf"

);

 

120. Handling Custom File Upload Components

If the visible upload button is only a JavaScript wrapper around a hidden file input, locate the actual input element where possible rather than trying to automate the operating-system file chooser.

 

121. Handling JavaScript-Based Date Pickers

Modern date pickers frequently generate calendar elements dynamically.

driver.findElement(By.id("date"))

      .click();

 

WebElement date =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.xpath("//button[contains(.,'25')]")

        )

    );

 

date.click();

 

122. Handling Calendar Navigation

driver.findElement(By.id("nextMonth"))

      .click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".calendar")

    )

);

 

123. Handling Dynamic Tooltips

WebElement icon =

    driver.findElement(By.id("help"));

 

new Actions(driver)

    .moveToElement(icon)

    .perform();

 

WebElement tooltip =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".tooltip")

        )

    );

 

System.out.println(tooltip.getText());

 

124. Handling Dynamic Tabs

driver.findElement(By.id("profileTab"))

      .click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("profileContent")

    )

);

 

125. Handling Dynamic Accordions

driver.findElement(By.id("faq1"))

      .click();

 

WebElement answer =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("answer1")

        )

    );

 

System.out.println(answer.getText());

 

126. Handling JavaScript-Based Drag and Drop

WebElement source =

    driver.findElement(By.id("source"));

 

WebElement target =

    driver.findElement(By.id("target"));

 

Actions actions =

    new Actions(driver);

 

actions.dragAndDrop(source, target)

       .perform();

 

127. Handling Dynamic Mouse Interactions

Actions actions =

    new Actions(driver);

 

actions.moveToElement(

    driver.findElement(By.id("menu"))

).click().perform();

 

128. Handling JavaScript-Based Rich Text Editors

Rich text editors may use contenteditable elements rather than standard input elements.

WebElement editor =

    driver.findElement(

        By.cssSelector("[contenteditable='true']")

    );

 

editor.click();

editor.sendKeys("Hello Selenium");

 

129. Using JavaScript with contenteditable

js.executeScript(

    "arguments[0].innerHTML='Hello Selenium';",

    editor

);

When using JavaScript to modify contenteditable elements, consider whether the application's event handlers also need to be triggered.

 

130. Handling Dynamic Chat Applications

Chat applications frequently append new messages dynamically without refreshing the page.

driver.findElement(By.id("message"))

      .sendKeys("Hello");

 

driver.findElement(By.id("send"))

      .click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".message")

    )

);

 

131. Handling Real-Time Notifications

WebSocket or other real-time communication can update the UI without a page refresh. Selenium should wait for the resulting visible UI state.

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".notification")

    )

);

 

132. Handling WebSocket-Driven Applications

Selenium does not directly control the WebSocket protocol. Instead, it interacts with the UI state produced by the application's real-time communication.

 

133. Handling Dynamic Dashboards

Dashboards often contain charts, cards, tables, and statistics that are loaded asynchronously.

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("dashboard")

    )

);

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".dashboard-card")

    )

);

 

134. Handling Dynamic Charts

Charts may be rendered using SVG, Canvas, or JavaScript chart libraries. Selenium can validate the surrounding DOM, labels, legends, and displayed values. Canvas graphics may require additional application-specific strategies because the visual content may not exist as ordinary DOM text.

 

135. Handling SVG Elements

WebElement svgElement =

    driver.findElement(

        By.cssSelector("svg")

    );

 

System.out.println(

    svgElement.getAttribute("outerHTML")

);

 

136. Handling Canvas Elements

Canvas content is drawn programmatically and may not expose individual graphical objects as normal HTML elements. Validation may therefore require accessible labels, underlying data, application APIs, or screenshot-based techniques depending on the test objective.

 

137. JavaScript-Based Application Testing Strategy

Start

 |

 v

Open Application

 |

 v

Identify Dynamic Behavior

 |

 v

Locate Stable Element

 |

 v

Wait for Required State

 |

 v

Perform Selenium Action

 |

 v

Wait for Application Update

 |

 v

Verify Result

 |

 v

Handle DOM Changes

 |

 v

Continue Test

 |

 v

End

 

138. Recommended Synchronization Strategy

SituationRecommended Approach
Element appears laterExplicit wait
Button becomes enabledelementToBeClickable or enabled-state condition
Loading spinner disappearsinvisibilityOfElementLocated
Text changestextToBePresentInElementLocated
URL changesurlContains or urlToBe
DOM element is replacedRe-locate element
Iframe contentswitchTo().frame()
Special DOM operationJavaScriptExecutor when appropriate

 

139. Common Mistake: Using Thread.sleep() Everywhere

Large fixed sleeps make tests slow and may still fail when application behavior takes longer than expected.

Prefer condition-based explicit waits.

 

140. Common Mistake: Using JavaScript for Everything

JavaScriptExecutor is powerful, but it should not automatically replace normal Selenium commands.

// Prefer this for normal interaction

element.click();

 

// Use JavaScript when a DOM-level operation is specifically required

js.executeScript(

    "arguments[0].click();",

    element

);

 

141. Common Mistake: Keeping Old WebElements

JavaScript frameworks can replace DOM nodes during re-rendering. Re-locate elements after known DOM changes.

 

142. Common Mistake: Ignoring Application Events

Directly changing an input value through JavaScript may not update the application's internal state.

When required, trigger the relevant input or change event and verify the resulting application behavior.

 

143. Common Mistake: Using Unstable Locators

A locator based on generated CSS classes or changing IDs can make tests fragile.

Prefer stable identifiers such as data-testid, name, accessible attributes, or other application-supported test hooks.

 

144. Common Mistake: Ignoring Iframes

If the target element belongs to an iframe, Selenium must switch into the correct frame before interacting with it.

 

145. Common Mistake: Ignoring Overlays

A loading overlay or modal can prevent interaction even when the target element is visible.

 

146. Common Mistake: Verifying Only Element Presence

Presence does not always mean that the application is ready. A stronger test verifies the expected state, text, enabled state, or resulting UI change.

 

147. Best Practices for JavaScript-Based Applications

  • Prefer normal Selenium WebDriver methods for normal user interactions.
  • Use explicit waits for dynamic conditions.
  • Use stable locators.
  • Re-locate elements after major DOM changes.
  • Wait for loading indicators to disappear.
  • Verify application state after important actions.
  • Use JavaScriptExecutor for specialized DOM operations.
  • Understand application-specific events.
  • Handle iframes and Shadow DOM correctly.
  • Avoid unnecessary fixed delays.
  • Keep JavaScript snippets small and readable.
  • Use reusable wait and utility methods.
  • Do not bypass application validation unless the test specifically requires it.

 

148. Creating a Reusable JavaScript Utility

public class JavaScriptUtils {

 

    public static void click(

            WebDriver driver,

            WebElement element) {

 

        JavascriptExecutor js =

            (JavascriptExecutor) driver;

 

        js.executeScript(

            "arguments[0].click();",

            element

        );

    }

 

    public static void scrollIntoView(

            WebDriver driver,

            WebElement element) {

 

        JavascriptExecutor js =

            (JavascriptExecutor) driver;

 

        js.executeScript(

            "arguments[0].scrollIntoView({block:'center'});",

            element

        );

    }

 

    public static void highlight(

            WebDriver driver,

            WebElement element) {

 

        JavascriptExecutor js =

            (JavascriptExecutor) driver;

 

        js.executeScript(

            "arguments[0].style.outline='3px solid red';",

            element

        );

    }

}

 

149. Using the JavaScript Utility

WebElement login =

    driver.findElement(By.id("login"));

 

JavaScriptUtils.scrollIntoView(

    driver,

    login

);

 

JavaScriptUtils.highlight(

    driver,

    login

);

 

login.click();

 

150. Combining Explicit Wait and JavaScript

WebDriverWait wait =

    new WebDriverWait(

        driver,

        Duration.ofSeconds(10)

    );

 

WebElement button =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("submit")

        )

    );

 

JavaScriptUtils.scrollIntoView(

    driver,

    button

);

 

JavaScriptUtils.highlight(

    driver,

    button

);

 

151. Page Object Model for JavaScript Applications

Page Object Model helps organize locators and interactions into reusable classes. This becomes particularly useful when working with complex JavaScript applications containing many dynamic components.

public class LoginPage {

 

    private WebDriver driver;

 

    private By username =

        By.id("username");

 

    private By password =

        By.id("password");

 

    private By login =

        By.id("login");

 

    public LoginPage(WebDriver driver) {

        this.driver = driver;

    }

 

    public void login(

            String user,

            String pass) {

 

        driver.findElement(username)

              .clear();

 

        driver.findElement(username)

              .sendKeys(user);

 

        driver.findElement(password)

              .clear();

 

        driver.findElement(password)

              .sendKeys(pass);

 

        driver.findElement(login)

              .click();

    }

}

 

152. Page Object with Explicit Wait

public class LoginPage {

 

    private WebDriver driver;

    private WebDriverWait wait;

 

    private By username =

        By.id("username");

 

    private By password =

        By.id("password");

 

    private By login =

        By.id("login");

 

    public LoginPage(WebDriver driver) {

        this.driver = driver;

 

        this.wait =

            new WebDriverWait(

                driver,

                Duration.ofSeconds(10)

            );

    }

 

    public void login(

            String user,

            String pass) {

 

        WebElement userElement =

            wait.until(

                ExpectedConditions.visibilityOfElementLocated(

                    username

                )

            );

 

        userElement.clear();

        userElement.sendKeys(user);

 

        WebElement passwordElement =

            wait.until(

                ExpectedConditions.visibilityOfElementLocated(

                    password

                )

            );

 

        passwordElement.clear();

        passwordElement.sendKeys(pass);

 

        WebElement loginButton =

            wait.until(

                ExpectedConditions.elementToBeClickable(

                    login

                )

            );

 

        loginButton.click();

    }

}

 

153. TestNG with JavaScript-Based Applications

import org.testng.Assert;

import org.testng.annotations.Test;

 

public class LoginTest {

 

    @Test

    public void loginTest() {

 

        WebDriver driver =

            new ChromeDriver();

 

        driver.get(

            "https://example.com/login"

        );

 

        LoginPage loginPage =

            new LoginPage(driver);

 

        loginPage.login(

            "admin",

            "Password123"

        );

 

        WebElement dashboard =

            new WebDriverWait(

                driver,

                Duration.ofSeconds(10)

            ).until(

                ExpectedConditions.visibilityOfElementLocated(

                    By.id("dashboard")

                )

            );

 

        Assert.assertTrue(

            dashboard.isDisplayed()

        );

 

        driver.quit();

    }

}

 

154. Practical Example: Dynamic Login Application

WebDriver driver =

    new ChromeDriver();

 

driver.manage()

      .window()

      .maximize();

 

driver.get(

    "https://example.com/login"

);

 

WebDriverWait wait =

    new WebDriverWait(

        driver,

        Duration.ofSeconds(10)

    );

 

WebElement username =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("username")

        )

    );

 

WebElement password =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("password")

        )

    );

 

username.clear();

username.sendKeys("admin");

 

password.clear();

password.sendKeys("Password123");

 

WebElement login =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("login")

        )

    );

 

login.click();

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("dashboard")

    )

);

 

System.out.println(

    "Login successful"

);

 

driver.quit();

 

155. Practical Example: AJAX Search

WebDriver driver =

    new ChromeDriver();

 

WebDriverWait wait =

    new WebDriverWait(

        driver,

        Duration.ofSeconds(10)

    );

 

driver.get(

    "https://example.com"

);

 

WebElement search =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("search")

        )

    );

 

search.sendKeys("Selenium");

 

driver.findElement(

    By.id("searchButton")

).click();

 

WebElement result =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".search-result")

        )

    );

 

System.out.println(

    "Result: " + result.getText()

);

 

driver.quit();

 

156. Practical Example: Dynamic Product Cart

WebDriverWait wait =

    new WebDriverWait(

        driver,

        Duration.ofSeconds(10)

    );

 

WebElement product =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".product-card")

        )

    );

 

WebElement addToCart =

    product.findElement(

        By.cssSelector(".add-to-cart")

    );

 

addToCart.click();

 

wait.until(

    ExpectedConditions.textToBePresentInElementLocated(

        By.id("cartCount"),

        "1"

    )

);

 

System.out.println(

    "Product added to cart."

);

 

157. Practical Example: Dynamic Dashboard

driver.get(

    "https://example.com/dashboard"

);

 

WebDriverWait wait =

    new WebDriverWait(

        driver,

        Duration.ofSeconds(10)

    );

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.id("dashboard")

    )

);

 

wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.cssSelector(".dashboard-card")

    )

);

 

System.out.println(

    "Dashboard loaded."

);

 

158. Practical Example: JavaScript Highlighting

JavascriptExecutor js =

    (JavascriptExecutor) driver;

 

WebElement element =

    driver.findElement(

        By.id("username")

    );

 

js.executeScript(

    "arguments[0].style.outline='3px solid red';",

    element

);

 

159. Practical Example: JavaScript Scrolling and Clicking

WebElement button =

    driver.findElement(

        By.id("submit")

    );

 

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    button

);

 

wait.until(

    ExpectedConditions.elementToBeClickable(

        button

    )

);

 

button.click();

 

160. Practical Example: Handling a Dynamic Modal

driver.findElement(

    By.id("openModal")

).click();

 

WebElement modal =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".modal")

        )

    );

 

WebElement input =

    modal.findElement(

        By.cssSelector("input")

    );

 

input.sendKeys("Test Data");

 

WebElement close =

    modal.findElement(

        By.cssSelector(".close")

    );

 

close.click();

 

wait.until(

    ExpectedConditions.invisibilityOf(modal)

);

 

161. Practical Example: Handling a Dynamic Table

driver.findElement(

    By.id("loadUsers")

).click();

 

wait.until(

    ExpectedConditions.numberOfElementsToBeMoreThan(

        By.cssSelector("table tbody tr"),

        0

    )

);

 

List<WebElement> rows =

    driver.findElements(

        By.cssSelector("table tbody tr")

    );

 

for (WebElement row : rows) {

    System.out.println(

        row.getText()

    );

}

 

162. Practical Example: Handling Dynamic Form Validation

WebElement email =

    driver.findElement(By.id("email"));

 

email.clear();

email.sendKeys("invalid");

 

driver.findElement(By.id("submit"))

      .click();

 

WebElement error =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.cssSelector(".error")

        )

    );

 

System.out.println(

    "Validation: " + error.getText()

);

 

163. Practical Example: Handling Dynamic Loading

driver.findElement(

    By.id("loadData")

).click();

 

wait.until(

    ExpectedConditions.invisibilityOfElementLocated(

        By.cssSelector(".spinner")

    )

);

 

WebElement data =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("data")

        )

    );

 

System.out.println(

    data.getText()

);

 

164. Practical Example: Handling a JavaScript Alert

driver.findElement(

    By.id("delete")

).click();

 

wait.until(

    ExpectedConditions.alertIsPresent()

);

 

Alert alert =

    driver.switchTo().alert();

 

System.out.println(

    alert.getText()

);

 

alert.accept();

 

165. Practical Example: Complete JavaScript Application Test

import java.time.Duration;

 

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.support.ui.ExpectedConditions;

import org.openqa.selenium.support.ui.WebDriverWait;

 

public class JavaScriptApplicationTest {

 

    public static void main(String[] args) {

 

        WebDriver driver =

            new ChromeDriver();

 

        driver.manage()

              .window()

              .maximize();

 

        driver.get(

            "https://example.com"

        );

 

        WebDriverWait wait =

            new WebDriverWait(

                driver,

                Duration.ofSeconds(10)

            );

 

        JavascriptExecutor js =

            (JavascriptExecutor) driver;

 

        WebElement username =

            wait.until(

                ExpectedConditions.visibilityOfElementLocated(

                    By.id("username")

                )

            );

 

        username.clear();

        username.sendKeys("admin");

 

        WebElement password =

            wait.until(

                ExpectedConditions.visibilityOfElementLocated(

                    By.id("password")

                )

            );

 

        password.clear();

        password.sendKeys("Password123");

 

        WebElement login =

            wait.until(

                ExpectedConditions.elementToBeClickable(

                    By.id("login")

                )

            );

 

        js.executeScript(

            "arguments[0].scrollIntoView({block:'center'});",

            login

        );

 

        login.click();

 

        wait.until(

            ExpectedConditions.visibilityOfElementLocated(

                By.id("dashboard")

            )

        );

 

        System.out.println(

            "JavaScript application handled successfully."

        );

 

        driver.quit();

    }

}

 

166. Handling JavaScript Applications Flow

Start

 |

 v

Open Browser

 |

 v

Open JavaScript Application

 |

 v

Identify Dynamic Components

 |

 v

Locate Stable Element

 |

 v

Wait for Required Condition

 |

 v

Perform Selenium Action

 |

 v

Application Executes JavaScript

 |

 v

DOM / UI Changes

 |

 v

Wait for Updated State

 |

 v

Verify Result

 |

 +----> DOM Re-render?

 |          |

 |          v

 |       Re-locate Element

 |

 +----> AJAX/API Request?

 |          |

 |          v

 |       Wait for Result

 |

 +----> iframe?

 |          |

 |          v

 |       Switch Frame

 |

 +----> Shadow DOM?

            |

            v

         Access Shadow Root

 |

 v

Continue Test

 |

 v

End

 

167. JavaScript Application Handling Decision Guide

ProblemPossible Approach
Element appears laterExplicit Wait
Element is replacedRe-locate the element
Loading spinner visibleWait for spinner to disappear
AJAX result not availableWait for result element
Element is in iframeSwitch to iframe
Element is inside Shadow DOMAccess shadow root
Element is below viewportScroll into view
Normal click fails because of application-specific DOM behaviorInvestigate cause before considering JavaScript click
Need DOM-level modificationJavaScriptExecutor
Dynamic text changesWait for expected text
SPA route changesWait for URL or view-specific element

 

168. Common Selenium Exceptions in JavaScript Applications

ExceptionCommon Cause
NoSuchElementExceptionElement is not available when searched
StaleElementReferenceExceptionDOM element was replaced or removed
ElementNotInteractableExceptionElement exists but is not interactable
ElementClickInterceptedExceptionAnother element blocks the click
TimeoutExceptionExpected condition was not satisfied
JavascriptExceptionJavaScript execution failed
NoSuchFrameExceptionRequired iframe cannot be located

 

169. Debugging Checklist

  • Is the locator correct?
  • Does the element exist in the current DOM?
  • Is the element dynamically created?
  • Has the application completed its API request?
  • Is a loading overlay visible?
  • Is the element inside an iframe?
  • Is the element inside Shadow DOM?
  • Has the element been re-rendered?
  • Is the element enabled?
  • Is another element covering it?
  • Does the application require an input or change event?
  • Is the locator dependent on a dynamic class or ID?
  • Would a condition-based wait solve the synchronization problem?

 

170. Interview Question: What is a JavaScript-Based Application?

A JavaScript-based application is a web application that uses JavaScript to dynamically control the user interface, process user interactions, communicate with APIs, and update DOM content without necessarily performing a full page refresh.

 

171. Interview Question: Why Are JavaScript Applications Challenging in Selenium?

They frequently modify the DOM asynchronously. Elements can appear later, disappear, change state, or be replaced during execution. Therefore, synchronization and stable element identification are important.

 

172. Interview Question: What is AJAX?

AJAX is a technique that allows web applications to exchange data with a server asynchronously and update parts of the page without requiring a complete page reload.

 

173. Interview Question: How Do You Handle AJAX in Selenium?

Use explicit waits for application-visible conditions such as result elements, loading indicators, text changes, or enabled controls rather than relying on arbitrary fixed delays.

 

174. Interview Question: What is JavaScriptExecutor?

JavaScriptExecutor is a Selenium interface that allows JavaScript code to be executed in the browser context.

 

175. Interview Question: When Should JavaScriptExecutor Be Used?

It can be useful for specialized DOM-level operations such as scrolling, inspecting or modifying DOM properties, highlighting elements, or handling certain browser-side behaviors when normal WebDriver APIs are not suitable for the specific task.

 

176. Interview Question: Should JavaScriptExecutor Replace Selenium Methods?

No. Normal Selenium WebDriver methods should generally be preferred for normal browser interactions. JavaScriptExecutor should be used when there is a specific reason to perform a DOM-level JavaScript operation.

 

177. Interview Question: Why Does a WebElement Become Stale?

A WebElement becomes stale when the DOM node represented by the Selenium reference is removed or replaced, which is common after JavaScript framework re-rendering.

 

178. Interview Question: How Do You Handle Stale Elements?

Re-locate the element after the DOM change and use appropriate waits. In some situations, a controlled retry can also be used.

 

179. Interview Question: Does document.readyState Guarantee That a JavaScript Application Is Ready?

No. document.readyState describes document loading, but a JavaScript application may continue making API calls and rendering dynamic components after the document becomes complete. Application-specific waits are therefore often required.

 

180. Interview Question: How Do You Handle Dynamic Elements?

Use stable locators and explicit waits for conditions such as presence, visibility, clickability, text changes, URL changes, or application-specific states.

 

181. Interview Question: How Do You Handle Hidden Elements?

First determine why the element is hidden and whether the test should interact with it. For specialized debugging or DOM-state testing, JavaScript can change visibility, but doing so may bypass intended application behavior.

 

182. Interview Question: How Do You Handle Iframes?

driver.switchTo().frame(

    driver.findElement(By.id("frame"))

);

 

driver.findElement(

    By.id("username")

).sendKeys("admin");

 

driver.switchTo().defaultContent();

 

183. Interview Question: How Do You Handle Shadow DOM?

Identify the shadow host and access its shadow root using supported Selenium Shadow DOM APIs or JavaScript when appropriate. Then locate the required element within the shadow root.

 

184. Interview Question: Why Can JavaScript Value Changes Fail in React or Angular?

Because changing the DOM property directly does not necessarily trigger the events and framework state updates expected by the application. When required, the relevant input or change event must also be triggered and the resulting UI state should be verified.

 

185. Quick Revision Table

ConceptKey Point
JavaScript ApplicationDynamic client-side application
DOMObject representation of the page structure
AJAXAsynchronous server communication
SPAApplication updates views without full page reloads
Explicit WaitWait for a specific condition
JavaScriptExecutorExecute JavaScript in browser
Stale ElementStored element reference is no longer attached to current DOM
IframeSeparate browsing context
Shadow DOMEncapsulated DOM structure
Dynamic LocatorLocator must account for changing attributes or structure
Loading IndicatorSignals asynchronous processing
Application StateActual state that should be verified after actions

 

186. Best Practices Checklist

  • Understand how the JavaScript application renders its UI.
  • Use stable locators.
  • Prefer WebDriver methods for normal interactions.
  • Use explicit waits instead of unnecessary fixed delays.
  • Wait for application-specific conditions.
  • Re-locate elements after framework re-rendering.
  • Handle AJAX and asynchronous content carefully.
  • Check for overlays and loading indicators.
  • Switch into iframes when necessary.
  • Handle Shadow DOM correctly.
  • Use JavaScriptExecutor only for appropriate specialized tasks.
  • Understand that DOM changes may not update framework state.
  • Trigger relevant events when a test specifically requires a JavaScript value modification.
  • Verify the application result after every important action.
  • Keep JavaScript utility methods reusable and small.
  • Avoid unstable generated IDs and classes.
  • Use application-supported test attributes where available.
  • Do not use DOM manipulation to hide genuine application defects.
  • Capture screenshots and logs when debugging failures.
  • Use Page Object Model for maintainable test architecture.

 

187. Practical Mini Project: JavaScript E-Commerce Application Automation

A useful practice project is to automate a JavaScript-based e-commerce workflow.

Open Website

    |

    v

Login

    |

    v

Wait for Dashboard

    |

    v

Search Product

    |

    v

Wait for AJAX Suggestions

    |

    v

Select Product

    |

    v

Wait for Product Details

    |

    v

Add Product to Cart

    |

    v

Wait for Cart Update

    |

    v

Open Cart

    |

    v

Update Quantity

    |

    v

Wait for Price Update

    |

    v

Proceed to Checkout

    |

    v

Fill Dynamic Form

    |

    v

Verify Order

    |

    v

End Test

 

188. Practical Mini Project: Dynamic Login and Dashboard

  1. Open the JavaScript-based login application.
  2. Wait for the username field.
  3. Enter the username.
  4. Enter the password.
  5. Click Login.
  6. Wait for the authentication request to complete.
  7. Wait for the dashboard element.
  8. Verify dashboard content.
  9. Capture a screenshot.
  10. Logout.
  11. Verify that the login page is displayed again.

 

189. Practical Mini Project: AJAX Search Application

  1. Open the application.
  2. Locate the search field.
  3. Enter a search term.
  4. Click Search.
  5. Wait for the loading indicator.
  6. Wait for the loading indicator to disappear.
  7. Wait for search results.
  8. Verify the result count or result text.
  9. Open one result.
  10. Verify the details page.

 

190. Complete Practical Example

import java.time.Duration;

 

import org.openqa.selenium.By;

import org.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.support.ui.ExpectedConditions;

import org.openqa.selenium.support.ui.WebDriverWait;

 

public class DynamicJavaScriptAppTest {

 

    public static void main(String[] args) {

 

        WebDriver driver =

            new ChromeDriver();

 

        driver.manage()

              .window()

              .maximize();

 

        driver.get(

            "https://example.com"

        );

 

        WebDriverWait wait =

            new WebDriverWait(

                driver,

                Duration.ofSeconds(10)

            );

 

        JavascriptExecutor js =

            (JavascriptExecutor) driver;

 

        WebElement username =

            wait.until(

                ExpectedConditions.visibilityOfElementLocated(

                    By.id("username")

                )

            );

 

        username.clear();

        username.sendKeys("admin");

 

        WebElement password =

            wait.until(

                ExpectedConditions.visibilityOfElementLocated(

                    By.id("password")

                )

            );

 

        password.clear();

        password.sendKeys("Password123");

 

        WebElement login =

            wait.until(

                ExpectedConditions.elementToBeClickable(

                    By.id("login")

                )

            );

 

        js.executeScript(

            "arguments[0].scrollIntoView({block:'center'});",

            login

        );

 

        login.click();

 

        wait.until(

            ExpectedConditions.invisibilityOfElementLocated(

                By.cssSelector(".loading-spinner")

            )

        );

 

        WebElement dashboard =

            wait.until(

                ExpectedConditions.visibilityOfElementLocated(

                    By.id("dashboard")

                )

            );

 

        js.executeScript(

            "arguments[0].style.outline='3px solid green';",

            dashboard

        );

 

        System.out.println(

            "Dashboard loaded successfully."

        );

 

        driver.quit();

    }

}

 

191. Conclusion

Handling JavaScript-based applications is an important part of modern Selenium WebDriver automation. Dynamic applications frequently update their DOM, communicate with APIs asynchronously, render components after page load, and change element states during execution.

Reliable automation therefore depends on stable locators, explicit waits, correct frame and Shadow DOM handling, proper synchronization with application states, and careful handling of dynamically replaced elements. JavaScriptExecutor can be useful for specialized browser-side operations, but normal Selenium WebDriver APIs should generally be preferred for standard user interactions.

The most important principle is to synchronize the test with the application's actual state rather than simply waiting for a fixed amount of time. Once testers understand DOM changes, AJAX behavior, SPA navigation, framework re-rendering, events, overlays, and asynchronous content, Selenium automation becomes more reliable and maintainable.

 


192. Selenium Training Resources

To learn Selenium WebDriver, Core Java, automation frameworks, dynamic elements, waits, TestNG, Maven, debugging, and practical automation projects, explore the following resources:

Selenium Training Course

Register for Course Demo

 


193. Final Quick Reference

// Create WebDriver

WebDriver driver =

    new ChromeDriver();

 

// Open Application

driver.get("https://example.com");

 

// Create Explicit Wait

WebDriverWait wait =

    new WebDriverWait(

        driver,

        Duration.ofSeconds(10)

    );

 

// Create JavaScriptExecutor

JavascriptExecutor js =

    (JavascriptExecutor) driver;

 

// Locate Dynamic Element

WebElement element =

    wait.until(

        ExpectedConditions.visibilityOfElementLocated(

            By.id("username")

        )

    );

 

// Normal Selenium Interaction

element.clear();

element.sendKeys("Admin");

 

// Click Dynamic Button

WebElement button =

    wait.until(

        ExpectedConditions.elementToBeClickable(

            By.id("submit")

        )

    );

 

button.click();

 

// Scroll Element

js.executeScript(

    "arguments[0].scrollIntoView({block:'center'});",

    element

);

 

// Highlight Element

js.executeScript(

    "arguments[0].style.outline='3px solid red';",

    element

);

 

// Read Text

String text =

    element.getText();

 

// Read Attribute

String value =

    element.getAttribute("value");

 

// Wait for Text

wait.until(

    ExpectedConditions.textToBePresentInElementLocated(

        By.id("status"),

        "Completed"

    )

);

 

// Wait for Loading Indicator to Disappear

wait.until(

    ExpectedConditions.invisibilityOfElementLocated(

        By.cssSelector(".loading")

    )

);

 

// Switch to iframe

driver.switchTo().frame(

    driver.findElement(By.id("frame"))

);

 

// Return to Main Document

driver.switchTo().defaultContent();

 

// JavaScript Value

js.executeScript(

    "arguments[0].value='Test Data';",

    element

);

 

// Dispatch Input Event

js.executeScript(

    "arguments[0].dispatchEvent(" +

    "new Event('input',{bubbles:true})" +

    ");",

    element

);

 

// Re-locate After DOM Change

element =

    driver.findElement(

        By.id("username")

    );

 

// Close Browser

driver.quit();

 

whatsapp