resiliotree
v1.1.3
Published
A high-performance library for comparing and finding nearest nodes in tree structures (e.g., DOM).
Maintainers
Readme
ResilioTree
A high-performance library for comparing and finding "nearest" nodes in tree structures (e.g., DOM). It uses a combination of path similarity (LCS) and heuristic node similarity (weighted attributes like tag, ID, classes, text, etc.) to reliably recover elements when the underlying tree has changed.
Perfect for Self-Healing Test Automation in both Web and Mobile environments.
🚀 Key Features
- Heuristic Similarity: Weighted scoring of node attributes for high-accuracy matching.
- Path Awareness: Uses the structural path (ancestry) to disambiguate similar elements.
- Mobile Native: Out-of-the-box support for iOS and Android mobile DOM attributes.
- Enterprise Persistence (v1.0): Serialize locators to JSON and restore them across sessions.
- Smart Thresholds: Filter matches by confidence score to prevent false-positive healing.
- Zero Dependencies: Lightweight and optimized for CI/CD performance.
📦 Installation
npm install resiliotree🛠 Usage
1. Basic Web Matching
import { PathFinder, JSDOMParser, Path, LCSPathDistance, HeuristicNodeDistance } from 'resiliotree';
// Initialize the engine
const pathFinder = new PathFinder(
new LCSPathDistance(),
new HeuristicNodeDistance()
);
const parser = new JSDOMParser();
const sourceTree = parser.parse('<div id="p"><button id="btn">Submit</button></div>');
const targetTree = parser.parse('<div id="p"><section><button id="btn-changed">Submit</button></section></div>');
// Define the path to the original element
const btnNode = sourceTree.children[0];
const path = new Path([sourceTree, btnNode]);
// Recover the element in the modified tree
const nearest = pathFinder.findNearest(path, targetTree);
console.log(nearest?.id); // "btn-changed"2. Mobile Self-Healing
Dedicated support for mobile-specific locators keeps your tests resilient.
import { NodeBuilder } from 'node-tree-comparing';
const androidNode = new NodeBuilder()
.setTag("android.widget.Button")
.setAndroidAttributes(new Map([
["resource-id", "com.example:id/login"],
["content-desc", "Login Button"]
]))
.build();
const iosNode = new NodeBuilder()
.setTag("XCUIElementTypeButton")
.setIOSAttributes(new Map([
["name", "login_btn"],
["label", "Login"]
]))
.build();📊 Scoring Model (Default Weights)
The matching engine uses a normalized scoring system (0.0 to 1.0).
| Attribute | Points | Strategy | | :--- | :--- | :--- | | Path (LCS) | 5.0 | Structural similarity of the ancestry tree | | ID | 5.0 | Exact match or high-confidence Levenshtein | | Tag | 2.0 | Case-insensitive tag name comparison | | Classes | 1.0 | Intersection/Union ratio with fuzzy fallback | | Other Attrs | 0.5 | Generic attribute value similarity | | Index | 0.1 | Tie-breaker based on sibling position |
[!TIP] You can create a custom
ScoringConfigto prioritize certain attributes based on your application's stability.
💾 Persistence & Advanced Usage (v1.0)
Save & Restore Locators
Enable persistent self-healing by storing paths in your database.
// Serialize for database storage
const locatorData = path.toJSON();
// Restore and find with a 85% confidence threshold
const restoredPath = Path.fromJSON(locatorData);
const match = pathFinder.findWithConfidence(restoredPath, newPage, 0.85);
if (!match) {
console.error("Confidence low: manual intervention required.");
}API Reference
PathFinder
The main engine for locating nodes.
findNearest(path: Path, root: Node): Node | null: Finds the best match.findWithConfidence(path: Path, root: Node, threshold: number): Node | null: Finds the best match only if it meets the quality bar.
NodeBuilder
Fluent API for manual tree construction.
setAndroidAttributes(attrs: Map<string, string>): Mapsresource-idandcontent-desc.setIOSAttributes(attrs: Map<string, string>): Mapsname,label, andvalue.
👤 Author
Rabindra Biswal
- GitHub: @Rabindra184
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
