Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Locator Intelligence

БесплатноНе проверен

Generates, validates, ranks, and heals UI element locators using DOM/XML analysis and visual correlation for Playwright automation.

GitHubEmbed

Описание

Generates, validates, ranks, and heals UI element locators using DOM/XML analysis and visual correlation for Playwright automation.

README

Generate, validate, rank, and auto-heal UI locators for Playwright, Selenium, and Appium — directly inside Cursor AI.

Build Tests Node License MCP


📋 Table of Contents

# Section What you'll find
1 What LIMS Does Problem solved, core capabilities
2 Quick Start Install, build, connect to Cursor
3 Architecture How all pieces fit together
4 The 7 MCP Tools Every tool, its input, its output
5 File Map Every file explained — what it does, when to touch it
6 Locator Priority Strategy Why certain selectors win over others
7 Confidence Score Explained What 0.98 vs 0.61 actually means
8 Ranking Weights The scoring formula, every knob
9 Customisation Guide Where to change configs, priorities, thresholds
10 Runtime Modes Playwright MCP subprocess vs HTTP vs standalone
11 Platform Support Web, Android, iOS
12 Using LIMS with Your Framework Step-by-step guide with real paths
13 Documentation Index All docs with descriptions

🎯 What LIMS Does

Writing automation code in Playwright, Selenium, or Appium has one recurring problem: finding locators that do not break.

LIMS solves this as an MCP server inside Cursor. You describe an element in plain language. LIMS opens the page, inspects the DOM, generates ranked locators ordered by stability, validates them against a real browser, writes your Page Object files, and heals them automatically when the UI changes.

You say:  "Generate locators for the Login button on https://myapp.com"

LIMS:     captures DOM + screenshot
          runs 7 priority tiers of candidate generation
          enforces: must match exactly 1 element
          ranks by stability + uniqueness + readability
          validates in real Chromium browser
          returns ──────────────────────────────────────────────────────
          {
            bestLocator:  page.getByTestId('login-btn')   confidence: 0.98
            fallbacks: [
              page.getByRole('button', { name: 'Login' }) confidence: 0.91
              page.locator('#login-submit')                confidence: 0.85
              //button[text()='Login']                     confidence: 0.40
            ]
          }
          writes: login.locator.ts  login.page.ts  login.spec.ts

⚡ Quick Start

Option A — Use via npx (recommended — no clone needed)

The easiest way on any machine. Requires Node 20 or 22.

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "Playwright": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp@latest"]
    },
    "LIMS": {
      "command": "npx",
      "args": ["-y", "lims-mcp"],
      "env": {
        "LIMS_PLAYWRIGHT_MCP_COMMAND":    "npx",
        "LIMS_PLAYWRIGHT_MCP_ARGS":       "[\"-y\", \"@playwright/mcp@latest\"]",
        "LIMS_PLAYWRIGHT_AUTO_BRIDGE":    "false",
        "LIMS_LEARNING_ENABLED":          "true",
        "LIMS_ARTIFACTS_ENABLED":         "true",
        "LIMS_ARTIFACTS_DIR":             "/Users/<your-username>/.lims/artifacts",
        "LIMS_PLAYWRIGHT_MCP_TIMEOUT_MS": "10000",
        "PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD": "1"
      }
    }
  }
}

Replace <your-username> with your system username. Playwright MCP requires npm install -g @playwright/mcp. If you skip it, LIMS falls back to local DOM mode automatically.

Option B — Clone and build locally (for development / contribution)

git clone https://github.com/imran-imz7/lims-mcp
cd lims-mcp

npm install
npm run build   # compiles TypeScript → dist/
npm test        # runs 67 tests — all should pass

Then in ~/.cursor/mcp.json use the local build:

{
  "mcpServers": {
    "LIMS": {
      "command": "node",
      "args": ["/absolute/path/to/lims-mcp/dist/cli.js"],
      "env": {
        "LIMS_PLAYWRIGHT_MCP_COMMAND": "npx",
        "LIMS_PLAYWRIGHT_MCP_ARGS":    "[\"-y\", \"@playwright/mcp@latest\"]",
        "LIMS_LEARNING_ENABLED":       "true",
        "LIMS_ARTIFACTS_ENABLED":      "true",
        "PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD": "1"
      }
    }
  }
}

3 — Restart Cursor and use it

"Generate Playwright locators and a test file for the login form at https://myapp.com"

🏗 Architecture

flowchart LR
    U["You / Tester"]
    C["Cursor AI Agent"]
    PW["Playwright MCP\n(Cursor's — browser control)"]
    L["LIMS MCP Server"]
    LP["LIMS internal\nplaywright-mcp\n(validation only)"]
    AF[".lims/artifacts/\n{ref}.json per element"]
    LS[".lims/locator-learning.json\nmax 1000 records"]
    FS["Framework Files\nfeature.locator.ts\nfeature.page.ts\nfeature.spec.ts"]

    U  -->|"plain language prompts"| C
    C  -->|"browser_navigate\nbrowser_snapshot"| PW
    PW -->|"DOM + accessibility tree"| C
    C  -->|"MCP tool calls"| L

    L  -->|"browser_run_code\n(validate + capture)"| LP
    LP -->|"runtime results\ncaptured page data"| L

    L  --> AF
    L  --> LS
    AF -->|"fingerprint reuse\nfor healing"| L
    LS -->|"ranking bias\npreferred/failed/healed"| L

    L  -->|"write / merge\ninside lims blocks"| FS
    FS -->|"playwright test run"| PW
    PW -->|"pass / fail"| C
    C  -->|"report_locator_result"| L

Key rule: Playwright MCP (Cursor's) and LIMS are isolated MCP processes — the Cursor agent bridges them. LIMS has its own separate internal playwright-mcp subprocess for locator validation only.


🔄 How It Works — Full Workflow

Step 1 — Capture & Generate

sequenceDiagram
    actor U  as "You / Tester"
    participant C  as "Cursor AI Agent"
    participant L  as "LIMS MCP Server"
    participant PW as "Playwright MCP (Cursor's)"
    participant LP as "LIMS Internal playwright-mcp"
    participant S  as ".lims/ Store"
    participant FS as "Framework Files on Disk"

    U  ->> C : Describe the element to test
    C  ->> PW : browser_navigate(pageUrl)
    PW -->> C : page loaded
    C  ->> PW : browser_snapshot()
    PW -->> C : DOM + accessibility tree
    C  ->> L  : generate_locator(dom, target, platform)

    Note over L: Schema validation → LocatorEngine.generate<br/>Tier 1: data-testid / data-test / data-qa<br/>Tier 2: aria-label / role / getByRole<br/>Tier 3: id / name (non-dynamic only)<br/>Tier 4: placeholder / label[for]<br/>Tier 5: visible static text<br/>Tier 6: relative (near/above/below)<br/>Tier 7: XPath fallback<br/>Tier 8: class (last resort)

    L  ->> L  : UniquenessEngine — reject if ≠ 1 match
    L  ->> L  : RankingEngine — score each candidate
    L  ->> LP : validate top 8 candidates live in browser
    LP -->> L : executed / unique / visible / interactable
    L  ->> L  : ConfidenceFusionEngine.fuse<br/>dom×0.50 + visual×0.20 + runtime×0.30
    L  ->> S  : saveArtifact → .lims/artifacts/{ref}.json
    L  -->> C : bestLocator + confidence + fallbacks + locatorCatalog

    C  ->> L  : sync_playwright_framework(feature, locatorBindings, testCases)
    L  ->> FS : write feature.locator.ts
    L  ->> FS : write feature.page.ts
    L  ->> FS : write feature.spec.ts
    L  -->> C : written file paths

Step 2 — Test, Feedback & Self-Healing

sequenceDiagram
    actor U  as "You / Tester"
    participant C  as "Cursor AI Agent"
    participant PW as "Playwright Test Runner"
    participant L  as "LIMS MCP Server"
    participant LP as "LIMS Internal playwright-mcp"
    participant S  as ".lims/ Store"
    participant FS as "Framework Files on Disk"

    U  ->> PW : npx playwright test feature.spec.ts
    PW -->> C : pass OR fail + error message
    C  ->> L  : report_locator_result(locator, status, artifactRef)
    L  ->> S  : appendOutcome + recordOutcome in learning store

    alt status = "passed"
        L  -->> C : learned:true ✓
    else status = "failed" → self-heal
        L  ->> S  : load original fingerprint + DOM from artifact
        L  ->> LP : capture current page DOM
        LP -->> L : fresh DOM
        L  ->> L  : SimilarityEngine.bestMatch<br/>tag×0.12 + text×0.28 + attrs×0.35 + hierarchy×0.25
        L  ->> L  : LocatorEngine.generate on matched node
        L  ->> LP : validate healed locator live
        LP -->> L : runtime result
        L  ->> S  : appendOutcome(healed) + recordOutcome(healed)
        L  -->> C : healedLocator + confidence + diff + explanation
        C  ->> L  : sync_playwright_framework (healed locator)
        L  ->> FS : update feature.locator.ts
        L  -->> C : written ✓
    end

🛠 The 7 MCP Tools

Tool When to use Key inputs Key outputs
capture_generate_locator Point at a live URL — capture + generate in one call pageUrl or runtimeContext.useCurrentPage=true, target bestLocator, fallbacks, artifactRef
generate_locator You already have the HTML/XML snapshot dom or xml, platform, target bestLocator, confidence, fallbacks, automation
heal_locator A locator broke after a UI change dom, oldLocator, optional fingerprint healedLocator, confidence, diff, explanation
report_locator_result After running your test — tell LIMS pass or fail locator, status, artifactRef learned, optional improved
sync_playwright_framework Write Page Object files to disk feature, language, locatorBindings Written file paths: *.spec.*, *.page.*, *.locator.*
analyze_dom Inspect a page before generating locators dom or xml framework, recommendedAttributes, stabilityReport
health_check Verify server and all integrations are working none healthy, prerequisites, runtime, issues

🗂 File Map

Every file in the project — what it does, when you need to open it.

Entry Points

src/index.ts          MCP server startup, StdioServerTransport wiring
src/cli.ts            CLI entry point (node dist/cli.js)
src/di/container.ts   Composition root — wires every dependency together

To add a new dependency or swap an adapter: src/di/container.ts


src/mcp/ — MCP Transport Layer

Rule: No business logic here. Only input/output schema and tool registration.

File Purpose When to touch it
schemas.ts Zod schemas for every tool input Add or change a tool's input fields
register-tools.ts Registers all 7 tools with the MCP server Add a new MCP tool

src/application/ — Use Cases (Orchestration)

Each file = one use case. Composes domain engines and integration adapters.

File Purpose When to touch it
locator-generation.service.ts Full pipeline: parse → resolve → generate → validate → fuse → catalog Change the generation flow or add a new signal
locator-healing.service.ts Healing flow: try old → fingerprint → similarity → regenerate → validate Change how healing decisions are made
locator-analysis.service.ts DOM analysis: framework detection + stability report Change what analyze_dom returns
locator-capture.service.ts Capture live page then generate Change the capture + generate pipeline
locator-feedback.service.ts Record pass/fail, trigger healing on failure Change learning or feedback behaviour
playwright-framework-sync.service.ts Write .spec, .page, .locator files Change file-writing logic
health-check.service.ts Check Playwright, Tesseract, runtime mode Add new health checks

src/domain/ — Core Intelligence

Framework-agnostic business logic. No MCP types. No file I/O.

Locator Generation

File Purpose When to touch it
locator/locator-engine.ts Main engine — runs all 7 priority tiers, deduplicates, enforces uniqueness, calls ranking Change candidate generation logic
locator/locator-engine-patterns.ts Pattern helpers for candidate extraction Add new attribute patterns
locator/locator-engine-trading-helpers.ts Trading/financial UI special cases Add trading platform support
locator/locator-engine-runtime-uniqueness.ts Runtime uniqueness bridge Change uniqueness checking
locator/target-resolver.ts Resolves target string/descriptor to a DOM node Change how targets are identified
locator/multi-platform-codegen.ts Generates platform-specific locator strings Add Appium, Selenium, or custom formats
locator/ui-pattern-intelligence.ts Detects UI patterns: tables, modals, forms Add new UI pattern detection
locator/locator-extension.ts LocatorCandidateProvider interface Implement a custom locator provider

Locator Providers (plug-in pattern)

File Purpose Register in
locator/providers/ag-grid-provider.ts AG Grid row/cell locators src/di/container.ts
locator/providers/react-virtualized-provider.ts React Virtualized list locators src/di/container.ts
locator/providers/flutter-web-provider.ts Flutter web element locators src/di/container.ts

To add a new framework provider: implement LocatorCandidateProvider, add to container.ts.

Scoring and Ranking

File Purpose When to touch it
ranking-engine/ranking-engine.ts Weighted ranking of candidates Change how candidates are ordered
confidence/confidence-fusion-engine.ts Fuses DOM score + visual + runtime into final confidence Change how confidence is calculated
uniqueness-engine/uniqueness-engine.ts Enforces 1-match rule per candidate Change uniqueness enforcement
attribute-stability/attribute-stability-analyzer.ts Scores attribute stability Add new stable/unstable attribute rules
selector-validator/selector-validator.ts Validates selector syntax Add selector syntax rules

Healing

File Purpose When to touch it
similarity-engine/similarity-engine.ts Structural similarity for healing (tag, text, attributes, hierarchy) Change how broken locators are matched to new DOM
element-fingerprint/element-fingerprint.ts Element fingerprint generation Change what gets stored in an artifact

Dynamic / Temporal

File Purpose When to touch it
dynamic/temporal-stability-engine.ts Compares snapshots across time, rates mutation Change temporal stability scoring
dynamic/snapshot-comparator.ts DOM diff between two snapshots Change snapshot comparison logic
dynamic/index.ts STATIC / SEMI_DYNAMIC / HIGHLY_DYNAMIC text classifier Change dynamic text classification rules

Visual / Chart

File Purpose When to touch it
visual/visual-locator-engine.ts Screenshot + OCR correlation Change visual locator logic
visual/canvas-element-detector.ts Canvas / WebGL / SVG detection Add chart surface detection
visual/dom-correlation-engine.ts Correlates DOM elements with visual regions Change visual-DOM mapping

Framework Detection and Codegen

File Purpose When to touch it
framework-detector/framework-detector.ts Detects React, Angular, Vue, etc. Add new framework detection
framework-sync/playwright-framework-codegen.ts Renders .spec, .page, .locator TypeScript/JavaScript Change generated file templates

Other Domain

File Purpose
heuristics/heuristics-engine.ts DOM heuristics (placeholder, label, input type detection)
css-builder/css-builder.ts Builds CSS selectors from element attributes
xpath-builder/xpath-builder.ts Builds XPath expressions
relative-locator-engine/relative-locator-engine.ts near(), above(), below() relative locators
trading/trading-ui-support.ts Trading/financial dashboard special handling
runtime/playwright-validator.ts Domain facade for runtime validation
contracts/types.ts All shared TypeScript types
contracts/ports.ts All interface contracts (ports)
plugin/plugin-registry.ts Plugin registry wiring

src/infrastructure/ — Storage, Config, Parsing

File Purpose When to touch it
config/app-config.ts All environment variable definitions and defaults Add or change any config option
cache/locator-artifact-store.ts Reads/writes .lims/artifacts/*.json Change artifact format
cache/locator-learning-store.ts Reads/writes .lims/locator-learning.json Change learning data format
cache/memory-cache.ts In-memory TTL cache Change cache eviction
parsers/dom-repository.ts Parses HTML/XML into Cheerio + xmldom Change DOM parsing
files/text-file-repository.ts Writes framework files to disk Change file output
logging/pino-logger.ts Structured JSON logging via pino Change log format

src/integrations/ — External Adapters

File Purpose When to touch it
playwright/playwright-mcp-validator.adapter.ts Connects to playwright-mcp via stdio or HTTP Change how LIMS talks to playwright-mcp
playwright/playwright-validator.adapter.ts Tries MCP → HTTP bridge → local DOM fallback Change validation fallback chain
playwright/playwright-web-capture.adapter.ts Local Playwright page capture Change local capture logic
playwright/composite-page-capture.adapter.ts Tries adapters in order (MCP first, local second) Change capture priority
playwright/runtime-validator-bridge.ts Optional local HTTP validation server Change HTTP bridge behaviour
ocr/tesseract-cli-ocr.adapter.ts Tesseract CLI for screenshot OCR Swap OCR engine
vision/basic-screenshot-analyzer.ts Screenshot analysis using OCR Change screenshot analysis

src/utils/ — Shared Utilities

File Purpose When to touch it
utils/constants.ts RANKING_WEIGHTS, STABILITY_SCORES, LENGTH_NORM_TARGET Tune scoring weights
utils/locator-priority.ts LOCATOR_PRIORITY_TIERS (1–8) Change locator priority order
utils/scoring-utils.ts clamp01, lengthScore helpers Change scoring math
utils/regex-patterns.ts Regex for dynamic ID detection, hash detection Add new unstable ID patterns
utils/playwright-locator-parse.ts Parse page.getByTestId(...) strings Add new Playwright locator patterns
utils/errors.ts DomainError class Change error codes

🏆 Locator Priority Strategy

LIMS always evaluates candidates in this strict tier order. Lower tier number = tried first = preferred when stable.

┌─────┬──────────────────────┬────────────────────────────────────────────┬────────────┐
│Tier │ Strategy             │ Examples                                   │ Stability  │
├─────┼──────────────────────┼────────────────────────────────────────────┼────────────┤
│  1  │ Test attributes      │ data-testid="submit"                       │ ██████████ │
│     │                      │ data-test="login-btn"                      │ Highest    │
│     │                      │ data-qa="email-field"                      │            │
├─────┼──────────────────────┼────────────────────────────────────────────┼────────────┤
│  2  │ Accessibility        │ aria-label="Close dialog"                  │ █████████░ │
│     │                      │ role="button" + name="Submit"              │ Very high  │
│     │                      │ getByRole('textbox', {name:'Email'})       │            │
├─────┼──────────────────────┼────────────────────────────────────────────┼────────────┤
│  3  │ Structural anchors   │ id="login-form"  (non-dynamic only)        │ ████████░░ │
│     │                      │ name="email"                               │ High       │
│     │                      │ Dynamic IDs auto-rejected (hash/uuid/ts)  │            │
├─────┼──────────────────────┼────────────────────────────────────────────┼────────────┤
│  4  │ Form hints           │ placeholder="Enter your email"             │ ███████░░░ │
│     │                      │ type="submit"                              │ Medium-high│
│     │                      │ label[for=...] associations                │            │
├─────┼──────────────────────┼────────────────────────────────────────────┼────────────┤
│  5  │ Visible text         │ getByText('Login')  — STATIC text only     │ ██████░░░░ │
│     │                      │ SEMI_DYNAMIC → lower confidence            │ Medium     │
│     │                      │ HIGHLY_DYNAMIC → ❌ rejected automatically │            │
├─────┼──────────────────────┼────────────────────────────────────────────┼────────────┤
│  6  │ Relative locators    │ near('Email label')                        │ █████░░░░░ │
│     │                      │ above('Password field')                    │ Medium-low │
│     │                      │ right-of('Submit')                        │            │
├─────┼──────────────────────┼────────────────────────────────────────────┼────────────┤
│  7  │ XPath fallback       │ //input[@type='email']                     │ ███░░░░░░░ │
│     │                      │ (constrained, not absolute paths)          │ Low        │
├─────┼──────────────────────┼────────────────────────────────────────────┼────────────┤
│  8  │ CSS class (last)     │ .btn-primary  .submit-button               │ █░░░░░░░░░ │
│     │                      │ Utility classes (.flex, .p-4) rejected     │ Lowest     │
└─────┴──────────────────────┴────────────────────────────────────────────┴────────────┘

Dynamic text classification — automatically applied before any text-based locator is used:

STATIC          → safe to use as locator signal
                  e.g. "Login", "Submit", "Email address"

SEMI_DYNAMIC    → used with reduced confidence
                  e.g. "Welcome, John" (changes per user)

HIGHLY_DYNAMIC  → never used as locator signal ❌
                  e.g. "$1,234.56", "00:03:42", "Loading 87%..."

To change the priority order: edit src/utils/locator-priority.ts To change dynamic text rules: edit src/domain/dynamic/index.ts


📊 Confidence Score Explained

Every locator LIMS returns has a confidence between 0.0 and 1.0. Here is what that number means and how it is calculated.

What the number means

1.00 ──── Perfect. Unique, visible, interactable, test-attribute based.
│         Passes all runtime checks. Will not break on normal UI changes.
│
0.90 ──── Excellent. Aria or structural anchor, runtime validated.
│
0.80 ──── Good. Stable attribute but no test-id. Passes DOM uniqueness.
│
0.70 ──── Acceptable. Visible text or relative locator. Stable enough.
│
0.60 ──── Use with caution. Placeholder or weak anchor.
│
0.50 ──── Fragile. May break on minor UI refactor.
│
0.30 ──── Last resort. XPath or class-based. High break risk.
│
0.00 ──── Rejected. Not unique (matches >1 element) or not visible.

How confidence is calculated

LIMS fuses three signals into one final score:

Final Confidence = (DOM score × 0.50)
                 + (Visual score × 0.20)   ← only if screenshot provided
                 + (Runtime score × 0.30)  ← only if browser validation ran

DOM Score — from the ranking engine (5 weighted factors)

┌─────────────────────┬────────┬───────────────────────────────────────────┐
│ Factor              │ Weight │ What it measures                          │
├─────────────────────┼────────┼───────────────────────────────────────────┤
│ Uniqueness          │  0.35  │ Matches exactly 1 element = 1.0           │
│                     │        │ Matches >1 element = 0.0 (hard gate)      │
├─────────────────────┼────────┼───────────────────────────────────────────┤
│ Attribute stability │  0.25  │ STABLE attribute (testid, aria) = 1.0     │
│                     │        │ SEMI_STABLE (id, name) = 0.55             │
│                     │        │ UNSTABLE (dynamic class, index) = 0.0     │
├─────────────────────┼────────┼───────────────────────────────────────────┤
│ Readability         │  0.15  │ Human-readable selector = higher score    │
│                     │        │ Long XPath chain = lower score            │
├─────────────────────┼────────┼───────────────────────────────────────────┤
│ Maintainability     │  0.15  │ No complex regex = 0.55 base              │
│                     │        │ No long chain (< 6 hops) = +0.45         │
├─────────────────────┼────────┼───────────────────────────────────────────┤
│ Length              │  0.10  │ Shorter locator = higher score            │
│                     │        │ Normalised against 120-char target        │
└─────────────────────┴────────┴───────────────────────────────────────────┘

Runtime Score — from live browser validation

┌─────────────────────┬────────┬───────────────────────────────────────────┐
│ Check               │ Points │ What it means                             │
├─────────────────────┼────────┼───────────────────────────────────────────┤
│ executed            │  +0.20 │ Browser validation actually ran           │
│ unique              │  +0.25 │ locator.count() === 1 in real browser     │
│ visible             │  +0.25 │ element.isVisible() === true              │
│ interactable        │  +0.20 │ click({trial:true}) did not throw         │
│ success             │  +0.10 │ All above passed together                 │
└─────────────────────┴────────┴───────────────────────────────────────────┘
Max runtime score = 1.0 (all five checks pass)

Visual Score — from screenshot + OCR (when screenshot provided)

0.0 – 1.0  based on how closely the OCR-extracted text near the element
           matches the target description. Higher = better visual match.

Example: how a score of 0.94 is built

Element: Login button  (data-testid="login-btn", visible, interactable)

DOM score:
  uniqueness        1.0 × 0.35 = 0.350
  attribute stab.   1.0 × 0.25 = 0.250   ← data-testid = STABLE
  readability       0.9 × 0.15 = 0.135
  maintainability   1.0 × 0.15 = 0.150
  length            0.9 × 0.10 = 0.090
  ─────────────────────────────────────
  DOM total                    = 0.975

Runtime score:
  executed+unique+visible+interactable+success = 1.0

Final confidence:
  (0.975 × 0.50) + (1.0 × 0.30) = 0.487 + 0.300 = 0.787
  → normalised → 0.94

⚖️ Ranking Weights

All weights live in one file: src/utils/constants.ts

export const RANKING_WEIGHTS = {
  uniqueness:         0.35,   // ← most important: must match exactly 1 element
  attributeStability: 0.25,   // ← second: is the attribute type stable?
  readability:        0.15,   // ← human-readable selectors preferred
  maintainability:    0.15,   // ← avoid regex chains and long XPath
  length:             0.10,   // ← shorter is better
}

export const STABILITY_SCORES = {
  STABLE:      1.00,   // data-testid, aria-label, role
  SEMI_STABLE: 0.55,   // id, name, placeholder
  UNSTABLE:    0.00,   // dynamic classes, index-based, hash IDs
}

export const LENGTH_NORM_TARGET = 120   // chars — locator longer than this scores 0 on length

To make uniqueness even more dominant: increase uniqueness weight and decrease others (all must sum to 1.0). To favour shorter locators more: increase length weight. To treat id as stable (not semi-stable): change SEMI_STABLE to 1.00 — but only if your app uses consistent IDs.


⚙️ Customisation Guide

Where to change what — quick reference

WHAT YOU WANT TO CHANGE                    WHERE TO CHANGE IT
──────────────────────────────────────────────────────────────────────
Add/change config env variable             src/infrastructure/config/app-config.ts
Change locator priority order              src/utils/locator-priority.ts
Tune confidence/ranking weights            src/utils/constants.ts
Change dynamic text classification         src/domain/dynamic/index.ts
Add a new locator provider (AG Grid etc.)  src/domain/locator/providers/
                                           + register in src/di/container.ts
Change healing similarity logic            src/domain/similarity-engine/similarity-engine.ts
Change generated file templates            src/domain/framework-sync/playwright-framework-codegen.ts
Add a new MCP tool                         src/mcp/schemas.ts
                                           + src/mcp/register-tools.ts
                                           + new service in src/application/
Change Playwright connection mode          src/infrastructure/config/app-config.ts
                                           (LIMS_PLAYWRIGHT_MCP_URL or COMMAND)
Change artifact storage location          LIMS_ARTIFACTS_DIR env var
Change learning store location            LIMS_LEARNING_STORE_PATH env var

All environment variables

Variable Default What it controls
LIMS_PLAYWRIGHT_MCP_URL (none) HTTP URL of a shared playwright-mcp server (e.g. http://localhost:8931/mcp)
LIMS_PLAYWRIGHT_MCP_COMMAND (none) Command to spawn playwright-mcp as subprocess (e.g. playwright-mcp)
LIMS_PLAYWRIGHT_MCP_ARGS [] JSON array of args for subprocess (e.g. ["--headless","--isolated"])
LIMS_PLAYWRIGHT_MCP_TIMEOUT_MS 7000 Timeout per playwright-mcp call in ms
LIMS_PLAYWRIGHT_VALIDATOR_URL (none) URL of a custom HTTP validation endpoint
LIMS_PLAYWRIGHT_AUTO_BRIDGE true Auto-start local HTTP validation bridge when no MCP
LIMS_PLAYWRIGHT_BRIDGE_PORT 4010 Port for the auto bridge
LIMS_LEARNING_ENABLED true Record pass/fail outcomes for future ranking bias
LIMS_LEARNING_STORE_PATH .lims/locator-learning.json Path to learning history file
LIMS_ARTIFACTS_ENABLED true Save DOM + locator snapshots for healing
LIMS_ARTIFACTS_DIR .lims/artifacts Directory for artifact JSON files
LIMS_LOG_LEVEL info Log verbosity: debug, info, warn, error
LIMS_CACHE_TTL_MS 60000 In-memory DOM cache TTL in ms
LIMS_CACHE_MAX_ENTRIES 500 Max entries in in-memory DOM cache
LIMS_HEALTH_PROFILE balanced Health check mode: balanced, dom-first, screenshot-first

🔌 Runtime Modes

LIMS picks a runtime validation mode automatically based on what is configured. Priority: URL > command > standalone.

┌─────┬──────────────────────────────┬───────────────────────────────────────────────┐
│ Pri │ Mode                         │ How to activate                               │
├─────┼──────────────────────────────┼───────────────────────────────────────────────┤
│  1  │ HTTP — shared server         │ Set LIMS_PLAYWRIGHT_MCP_URL                   │
│     │ One browser for Cursor+LIMS  │ Run: npx @playwright/mcp --headless --port 8931│
│     │ Most efficient               │ Cursor: { "url": "http://localhost:8931/mcp" }│
├─────┼──────────────────────────────┼───────────────────────────────────────────────┤
│  2  │ stdio — LIMS subprocess      │ Set LIMS_PLAYWRIGHT_MCP_COMMAND="npx"         │
│     │ LIMS owns its browser        │ LIMS_PLAYWRIGHT_MCP_ARGS='["-y",              │
│     │ Fully self-contained         │  "@playwright/mcp@latest"]'                   │
│     │ ✅ Recommended default       │ Use same version as Cursor (e.g. @0.0.70)     │
├─────┼──────────────────────────────┼───────────────────────────────────────────────┤
│  3  │ Standalone — local DOM       │ Set neither of the above                      │
│     │ No browser needed            │ Works offline, works in CI, less accurate     │
│     │ Always available             │ Uses Cheerio + XPath on static HTML           │
└─────┴──────────────────────────────┴───────────────────────────────────────────────┘

Common mistake: Setting LIMS_PLAYWRIGHT_MCP_COMMAND="playwright-mcp" (bare binary name) fails unless playwright-mcp is installed globally via npm install -g @playwright/mcp. Use npx instead — it works everywhere without a global install.

If Playwright MCP is configured but unreachable (wrong command, timeout, crash), LIMS catches the error and falls back to Mode 3 automatically. It never crashes on startup.


📱 Platform Support

Platform Locator Generation Self-Healing Live Capture Framework File Sync
Playwright (web) ✅ Full ✅ Full ✅ Full — Chromium .spec.ts + .page.ts + .locator.ts
Selenium (web) ✅ CSS + XPath output ✅ Full Snapshot-based Manual wiring
Appium Android ✅ From UIAutomator XML ✅ Snapshot-based Snapshot-based Not yet
Appium iOS ✅ From XCUI XML ✅ Snapshot-based Snapshot-based Not yet

📚 Documentation Index

Document What it covers
docs/END_TO_END_GUIDE.md Start here. Complete walkthrough with every step explained, backend internals, common questions
docs/API_SPEC.md Every MCP tool — exact inputs, exact outputs, scope notes
docs/ARCHITECTURE.md Layer boundaries, dependency rules, main flows
docs/WORKFLOW_DIAGRAM.md Mermaid sequence diagrams of capture → generate → sync → heal
docs/MCP_WORKING_GUIDE.md Quick daily reference — which tool to call when
docs/PLAYWRIGHT_INTEGRATION.md Playwright MCP configuration and integration details

🚀 Using LIMS with Your Playwright Framework

This section shows how to use LIMS inside an existing Playwright JS/TS project to generate locators and write framework files directly into your folder structure.

Step 1 — Confirm LIMS is active

In Cursor chat, type:

Call health_check on LIMS

You must see "status": "LIMS_ACTIVE" before doing anything else. If you don't — fully quit Cursor (Cmd+Q / Alt+F4) and reopen it.


Step 2 — Generate a locator and write files to your framework

Paste this prompt in Cursor chat (fill in your values):

Use LIMS for my Playwright JS automation framework.

Step 1: browser_navigate to https://your-app.com/page
Step 2: browser_snapshot to capture the DOM
Step 3: call generate_locator with the captured DOM, platform "web", 
        target "<describe the element, e.g. Login button>"
Step 4: call sync_playwright_framework with:
  feature: "login"
  language: "js"
  outputDir: "/absolute/path/to/your-framework/tests"
  specDir: "specs"
  pageDir: "pages"
  locatorDir: "locators"
  pageUrl: "https://your-app.com/page"
  testCases: ["User can log in with valid credentials"]

LIMS will create exactly these files:

tests/
├── locators/
│   └── login.locator.js    ← generated selectors
├── pages/
│   └── login.page.js       ← page object with methods
└── specs/
    └── login.spec.js       ← ready-to-run test

Step 3 — Run your tests

npx playwright test tests/specs/login.spec.js

Step 4 — Report result back to LIMS (closes the learning loop)

Call report_locator_result on LIMS:
  locator: "<bestLocator from Step 3 response>"
  status: "passed"
  platform: "web"
  artifactRef: "<ref returned by LIMS in Step 3>"

If the test failed — LIMS automatically heals the locator, regenerates it, and updates the file. You just re-run the test.


sync_playwright_framework — Path Parameters Reference

Parameter What it controls Example
outputDir Root of your framework /Users/you/my-framework/tests
specDir Sub-folder for spec files specs
pageDir Sub-folder for page objects pages
locatorDir Sub-folder for locator files locators
language "js" or "ts" "js"
feature Base name for all three files "login"login.spec.js etc.

All three directories are created automatically if they don't exist. Custom code you add outside the <lims:spec> / <lims:page> / <lims:locator> markers is never overwritten on re-sync.


Node.js Version Requirement

node --version   # must be v20.x.x or v22.x.x

LIMS depends on @modelcontextprotocol/sdk which uses the File Web API.
This API is only available in Node 20+. Node 18 is not supported.

If you are on Node 18:

nvm install 20 && nvm use 20 && nvm alias default 20

🧪 Verification

npm run build   # must exit 0
npm test        # 67 tests, all must pass

from github.com/imran-imz7/lims-mcp

Установка Locator Intelligence

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/imran-imz7/lims-mcp

FAQ

Locator Intelligence MCP бесплатный?

Да, Locator Intelligence MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Locator Intelligence?

Нет, Locator Intelligence работает без API-ключей и переменных окружения.

Locator Intelligence — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Locator Intelligence в Claude Desktop, Claude Code или Cursor?

Открой Locator Intelligence на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Locator Intelligence with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории design