Handle Dynamic Data in Visual Tests
What is Dynamic Data?
Dynamic data refers to content on your web pages that changes between test runs, such as timestamps, user IDs, session tokens, randomly generated content, or data that updates in real-time. When conducting visual regression tests, these dynamic elements can cause false positives because the content differs between the baseline and current screenshots, even when the actual UI design remains unchanged.
SmartUI provides two powerful options to handle dynamic data:
- Ignore DOM Elements: Exclude specific elements from visual comparison
- Select DOM Elements: Include only specific elements in visual comparison
If you're experiencing high mismatch percentages or false positives, see our Comprehensive Troubleshooting Guide for solutions. For project-level settings, check Project Settings.
When to Use Dynamic Data Handling
You should use dynamic data handling in the following scenarios:
- Timestamps and Dates: Pages displaying current date/time that changes on each load
- User-Specific Content: User IDs, usernames, or personalized content
- Session Tokens: Authentication tokens or session identifiers
- Random Content: Randomly generated IDs, UUIDs, or nonces
- Live Data: Stock prices, weather data, or other real-time information
- Advertisements: Rotating ads or promotional content
- Cookie Banners: Consent banners that appear differently each time
- Notifications: Unread message counts or notification badges
Dynamic Data Handling Methods
- Ignore DOM Elements
- Select DOM Elements
- Combining Methods
- Best Practices
Ignore DOM Elements
Use ignoreDOM to exclude specific elements from visual comparison. This is useful when you want to compare the entire page but ignore certain dynamic elements.
Syntax
let options = {
ignoreDOM: {
id: ["element-id-1", "element-id-2"],
class: ["class-name-1", "class-name-2"],
cssSelector: ["selector-1", "selector-2"],
xpath: ["xpath-1", "xpath-2"]
}
}
smartuiSnapshot(driver, 'Screenshot Name', options);
Examples by Selector Type
- By ID
- By Class
- By CSS Selector
- By XPath
JavaScript (Selenium)
const { Builder } = require('selenium-webdriver');
const { smartuiSnapshot } = require('@lambdatest/selenium-driver');
let driver = await new Builder().forBrowser("chrome").build();
await driver.get('https://example.com');
let options = {
ignoreDOM: {
id: ["timestamp", "user-id", "session-token"]
}
};
await smartuiSnapshot(driver, 'Home Page', options);
Java (Selenium)
HashMap<String, ArrayList<String>> ignoreDOM = new HashMap<>();
ArrayList<String> ids = new ArrayList<>();
ids.add("timestamp");
ids.add("user-id");
ids.add("session-token");
ignoreDOM.put("id", ids);
HashMap<String, Object> options = new HashMap<>();
options.put("ignoreDOM", ignoreDOM);
SmartUISnapshot.smartuiSnapshot(driver, "Home Page", options);
Python (Selenium)
from lambdatest import smartui_snapshot
options = {
"ignoreDOM": {
"id": ["timestamp", "user-id", "session-token"]
}
}
smartui_snapshot(driver, "Home Page", options)
JavaScript (Selenium)
let options = {
ignoreDOM: {
class: ["dynamic-content", "timestamp", "user-info"]
}
};
await smartuiSnapshot(driver, 'Home Page', options);
Java (Selenium)
ArrayList<String> classes = new ArrayList<>();
classes.add("dynamic-content");
classes.add("timestamp");
classes.add("user-info");
ignoreDOM.put("class", classes);
Python (Selenium)
options = {
"ignoreDOM": {
"class": ["dynamic-content", "timestamp", "user-info"]
}
}
JavaScript (Selenium)
let options = {
ignoreDOM: {
cssSelector: [
"#timestamp",
".user-info",
"[data-testid='session-token']",
"div.dynamic-content > span"
]
}
};
await smartuiSnapshot(driver, 'Home Page', options);
Java (Selenium)
ArrayList<String> selectors = new ArrayList<>();
selectors.add("#timestamp");
selectors.add(".user-info");
selectors.add("[data-testid='session-token']");
ignoreDOM.put("cssSelector", selectors);
Python (Selenium)
options = {
"ignoreDOM": {
"cssSelector": [
"#timestamp",
".user-info",
"[data-testid='session-token']",
"div.dynamic-content > span"
]
}
}
JavaScript (Selenium)
let options = {
ignoreDOM: {
xpath: [
"//div[@id='timestamp']",
"//span[@class='user-id']",
"//*[@data-testid='session-token']"
]
}
};
await smartuiSnapshot(driver, 'Home Page', options);
Java (Selenium)
ArrayList<String> xpaths = new ArrayList<>();
xpaths.add("//div[@id='timestamp']");
xpaths.add("//span[@class='user-id']");
xpaths.add("//*[@data-testid='session-token']");
ignoreDOM.put("xpath", xpaths);
Python (Selenium)
options = {
"ignoreDOM": {
"xpath": [
"//div[@id='timestamp']",
"//span[@class='user-id']",
"//*[@data-testid='session-token']"
]
}
}
Select DOM Elements
Use selectDOM to include only specific elements in visual comparison. This is useful when you want to compare only certain parts of the page, ignoring everything else.
Syntax
let options = {
selectDOM: {
id: ["element-id-1", "element-id-2"],
class: ["class-name-1", "class-name-2"],
cssSelector: ["selector-1", "selector-2"],
xpath: ["xpath-1", "xpath-2"]
}
}
smartuiSnapshot(driver, 'Screenshot Name', options);
Examples by Selector Type
- By ID
- By Class
- By CSS Selector
- By XPath
JavaScript (Selenium)
let options = {
selectDOM: {
id: ["main-content", "header", "footer"]
}
};
await smartuiSnapshot(driver, 'Home Page', options);
Java (Selenium)
HashMap<String, ArrayList<String>> selectDOM = new HashMap<>();
ArrayList<String> ids = new ArrayList<>();
ids.add("main-content");
ids.add("header");
ids.add("footer");
selectDOM.put("id", ids);
HashMap<String, Object> options = new HashMap<>();
options.put("selectDOM", selectDOM);
Python (Selenium)
options = {
"selectDOM": {
"id": ["main-content", "header", "footer"]
}
}
JavaScript (Selenium)
let options = {
selectDOM: {
class: ["product-card", "price", "description"]
}
};
await smartuiSnapshot(driver, 'Product Page', options);
Java (Selenium)
ArrayList<String> classes = new ArrayList<>();
classes.add("product-card");
classes.add("price");
classes.add("description");
selectDOM.put("class", classes);
Python (Selenium)
options = {
"selectDOM": {
"class": ["product-card", "price", "description"]
}
}
JavaScript (Selenium)
let options = {
selectDOM: {
cssSelector: [
".main-content",
"#product-grid",
"[data-testid='product-list']"
]
}
};
await smartuiSnapshot(driver, 'Product Page', options);
Java (Selenium)
ArrayList<String> selectors = new ArrayList<>();
selectors.add(".main-content");
selectors.add("#product-grid");
selectors.add("[data-testid='product-list']");
selectDOM.put("cssSelector", selectors);
Python (Selenium)
options = {
"selectDOM": {
"cssSelector": [
".main-content",
"#product-grid",
"[data-testid='product-list']"
]
}
}
JavaScript (Selenium)
let options = {
selectDOM: {
xpath: [
"//div[@class='main-content']",
"//section[@id='product-grid']",
"//ul[@data-testid='product-list']"
]
}
};
await smartuiSnapshot(driver, 'Product Page', options);
Java (Selenium)
ArrayList<String> xpaths = new ArrayList<>();
xpaths.add("//div[@class='main-content']");
xpaths.add("//section[@id='product-grid']");
xpaths.add("//ul[@data-testid='product-list']");
selectDOM.put("xpath", xpaths);
Python (Selenium)
options = {
"selectDOM": {
"xpath": [
"//div[@class='main-content']",
"//section[@id='product-grid']",
"//ul[@data-testid='product-list']"
]
}
}
Combining ignoreDOM and selectDOM
You can combine both ignoreDOM and selectDOM in the same options object. When both are specified, selectDOM is applied first to include elements, then ignoreDOM is applied to exclude specific elements from the selected set.
let options = {
selectDOM: {
cssSelector: [".main-content"]
},
ignoreDOM: {
id: ["timestamp", "user-id"]
}
};
await smartuiSnapshot(driver, 'Home Page', options);
Use Cases
Use Case 1: E-commerce Product Page
Scenario: Product pages display prices, stock counts, and user reviews that change frequently.
Solution: Ignore dynamic pricing and review elements while comparing the overall layout.
let options = {
ignoreDOM: {
cssSelector: [
".price",
".stock-count",
".review-count",
"[data-testid='timestamp']"
]
}
};
await smartuiSnapshot(driver, 'Product Page', options);
Use Case 2: Dashboard with Real-time Data
Scenario: Dashboard displays live metrics, timestamps, and user-specific data.
Solution: Select only the static layout elements for comparison.
let options = {
selectDOM: {
cssSelector: [
".dashboard-layout",
".navigation",
".sidebar"
]
},
ignoreDOM: {
class: ["metric-value", "timestamp", "user-info"]
}
};
await smartuiSnapshot(driver, 'Dashboard', options);
Use Case 3: News Article Page
Scenario: Article pages have timestamps, author info, and related articles that change.
Solution: Ignore dynamic metadata while comparing article content.
let options = {
ignoreDOM: {
id: ["article-timestamp", "author-info"],
class: ["related-articles", "social-share-count"]
}
};
await smartuiSnapshot(driver, 'Article Page', options);
Best Practices
-
Use Specific Selectors: Prefer IDs or data attributes over generic class names for more precise targeting.
-
Test Selectors First: Verify your selectors work correctly before using them in visual tests.
-
Document Your Choices: Document why certain elements are ignored or selected for future reference.
-
Combine Strategically: Use
selectDOMfor broad filtering andignoreDOMfor fine-tuning. -
Avoid Over-ignoring: Only ignore elements that are truly dynamic. Over-ignoring can hide real UI issues.
-
Use Data Attributes: Add
data-testidattributes to elements you need to target for better test stability.
Troubleshooting
- Elements Not Being Ignored
- selectDOM Not Working
- False Positives Still Occurring
Issue: Elements Not Being Ignored
Possible Causes:
- Selector is incorrect or doesn't match any elements
- Element is loaded dynamically after the snapshot
- Selector syntax error
Solutions:
- Verify the selector using browser DevTools
- Add a wait before taking the snapshot to ensure elements are loaded
- Check selector syntax (CSS selectors vs XPath)
// Wait for element before snapshot
await driver.wait(until.elementLocated(By.id('timestamp')), 5000);
let options = {
ignoreDOM: {
id: ["timestamp"]
}
};
await smartuiSnapshot(driver, 'Page', options);
Issue: selectDOM Not Working
Possible Causes:
- No elements match the selectors
- Elements are not visible at snapshot time
- Selector targets elements outside the viewport
Solutions:
- Verify elements exist and are visible
- Use more specific selectors
- Ensure elements are in the viewport
Issue: False Positives Still Occurring
Possible Causes:
- Not all dynamic elements are ignored
- Elements change structure, not just content
- Timing issues with element loading
Solutions:
- Review the diff to identify missed dynamic elements
- Add more selectors to ignoreDOM
- Increase wait times or use explicit waits
Additional Resources
- Comprehensive Troubleshooting Guide - Detailed solutions for common issues
- SmartUI SDK Configuration Options
- Handling Videos
- Handling Lazy Loading
- Smart Ignore Feature
- Project Settings - Configure pixel thresholds and comparison settings
- Baseline Management - Learn how to manage baselines effectively
