Skip to main content

Vocabulary System

The playwright-praman/vocabulary sub-path provides a controlled vocabulary system for SAP S/4HANA business term resolution. It maps natural-language terms to UI5 selectors with fuzzy matching, synonym resolution, and cross-domain search.

Overview​

import { createVocabularyService } from 'playwright-praman/vocabulary';

const svc = createVocabularyService();
await svc.loadDomain('procurement');
const results = await svc.search('vendor');

SAP Domain JSON Files​

The vocabulary system ships with 6 SAP domain JSON files in src/vocabulary/domains/:

FileDomainSAP ModuleDescription
procurement.jsonprocurementMMMaterials Management -- vendors, POs, GR
sales.jsonsalesSDSales & Distribution -- customers, SOs, deliveries
finance.jsonfinanceFIFinancial Accounting -- GL, AP, AR
manufacturing.jsonmanufacturingPPProduction Planning -- orders, BOMs, routings
warehouse.jsonwarehouseWM/EWMWarehouse Management -- storage, picking
quality.jsonqualityQMQuality Management -- inspections, lots

Each JSON file contains vocabulary terms with synonyms and optional UI5 selectors:

{
"supplier": {
"name": "supplier",
"synonyms": ["vendor", "vendorId", "supplierId", "LIFNR"],
"domain": "procurement",
"sapField": "LIFNR",
"selector": {
"controlType": "sap.m.Input",
"properties": { "labelFor": "Supplier" }
}
}
}

VocabularyService API​

Creating the Service​

import { createVocabularyService } from 'playwright-praman/vocabulary';
import type { VocabularyService } from 'playwright-praman/vocabulary';

const svc: VocabularyService = createVocabularyService();

Loading Domains​

Domains are loaded lazily on demand:

await svc.loadDomain('procurement');
await svc.loadDomain('finance');
// Only procurement and finance terms are in memory

Searching Terms​

// Search across all loaded domains
const results = await svc.search('vendor');

// Search within a specific domain
const results = await svc.search('vendor', 'procurement');

Returns VocabularySearchResult[] sorted by confidence descending:

interface VocabularySearchResult {
readonly term: string; // 'supplier'
readonly synonyms: string[]; // ['vendor', 'vendorId', 'supplierId']
readonly confidence: number; // 0.0 to 1.0
readonly domain: SAPDomain; // 'procurement'
readonly sapField?: string; // 'LIFNR'
readonly selector?: UI5Selector;
}

Resolving Field Selectors​

When a term matches with high enough confidence (>= 0.85), you can get its UI5 selector directly:

const selector = await svc.getFieldSelector('vendor', 'procurement');
if (selector) {
// { controlType: 'sap.m.Input', properties: { labelFor: 'Supplier' } }
await ui5.fill(selector, '100001');
}

Returns undefined when:

  • No match reaches the 0.85 confidence threshold.
  • Multiple matches score above 0.7 but below 0.85 (ambiguous).

Getting Suggestions​

For autocomplete and disambiguation:

const suggestions = await svc.getSuggestions('sup');
// ['supplier', 'supplierName', 'supplyPlant', ...]

// Limit results
const top3 = await svc.getSuggestions('sup', 3);

Service Statistics​

const stats = svc.getStats();
// {
// loadedDomains: ['procurement', 'sales'],
// totalTerms: 142,
// cacheHits: 37,
// cacheMisses: 5,
// }

Normalization and Matching Algorithm​

The vocabulary matcher uses a tiered scoring system:

Match Tiers​

TierConfidenceCriteria
Exact1.0Query exactly matches term name or synonym (case-insensitive)
Prefix0.9Term name starts with the query string
Partial0.7Term name contains the query string
Fuzzy0.5Levenshtein distance <= 3 characters

Normalization​

Before matching, both the query and term names are normalized:

  • Converted to lowercase
  • Leading/trailing whitespace trimmed

Levenshtein Distance​

The fuzzy matching tier uses Levenshtein edit distance (standard DP matrix approach). Terms within 3 edits of the query are considered fuzzy matches:

levenshtein('vendor', 'vendro') = 2  --> Fuzzy match (0.5)
levenshtein('vendor', 'vend') = 2 --> Fuzzy match (0.5)
levenshtein('vendor', 'xyz') = 6 --> No match

Scoring Priority​

When multiple terms match, results are sorted by:

  1. Confidence score (descending)
  2. Within the same confidence tier, exact matches on synonyms score the same as exact matches on the canonical name

Disambiguation​

The getFieldSelector() method includes disambiguation logic. If there are multiple high-confidence matches (0.7-0.85 range) without a clear winner, the method returns undefined rather than guessing, allowing the caller to present options to the user or AI agent.

Integration with Intents​

The vocabulary system integrates with the intent API through the VocabLookup interface:

import { fillField } from 'playwright-praman/intents';
import { createVocabularyService } from 'playwright-praman/vocabulary';

const vocab = createVocabularyService();
await vocab.loadDomain('procurement');

// fillField uses vocab to resolve 'Vendor' to a UI5 selector
await fillField(ui5, vocab, 'Vendor', '100001', { domain: 'procurement' });

Supported Domain Types​

type SAPDomain =
| 'procurement' // MM - Materials Management
| 'sales' // SD - Sales & Distribution
| 'finance' // FI - Financial Accounting
| 'manufacturing' // PP - Production Planning
| 'warehouse' // WM/EWM - Warehouse Management
| 'quality'; // QM - Quality Management

Extending the Vocabulary​

To add terms to an existing domain, edit the corresponding JSON file in src/vocabulary/domains/. Each term must have:

  • name -- canonical term name (used as the Map key)
  • synonyms -- array of alternative names
  • domain -- must match one of the 6 SAPDomain values
  • sapField (optional) -- the underlying ABAP field name
  • selector (optional) -- UI5 selector for direct control discovery