Not static OCR
Vision finds controls by label, role and layout, live, rather than matching stored image snippets. Nothing to recapture when a theme, font or resolution changes.
The automation core of Qventis One, built for the systems that run your business. Write the step in plain English. It compiles once and runs the same way every time on your runners, with no model in the loop.
Check that 'Total' shows '42.00'
{"verb":"check","target":{"label":"Total","role":"field"},"expect":"42.00"}Resolved viaWeb DOM, cross-checked by vision
Order summary
Set cell 'Qty' to '5' on the 'Approved' row
{"verb":"set-cell","target":{"grid":"Orders","column":"Qty","row":{"Status":"Approved"}},"value":"5"}Resolved viaLive vision: the grid exposes no cells
Type '{{po.number}}' into 'PO NUMBER' and press Enter
{"verb":"type","target":{"label":"PO NUMBER","screen":"PO INQUIRY"},"value":"{{po.number}}","then":"enter"}Resolved viaTerminal data stream
PO INQUIRY SCREEN 04
PO NUMBER . . . 4500017731
VENDOR . . . . 120044
STATUS . . . . OPEN
F3=EXIT F5=REFRESH ENTER=INQUIRE
Run 'Create sales order' and check that 'Status' shows 'Created'
{"verb":"run","target":{"task":"Create sales order"},"then":{"verb":"check","target":"Status","expect":"Created"}}Resolved viaDOM and accessibility tree
Send POST to '/orders' and check status '201'
{"verb":"send","method":"POST","path":"/orders","expect":{"status":201}}Resolved viaHTTP contract
POST /orders
{
"customer": "acme-retail",
"lines": 3
}201 Created
{ "id": "ord_10422" }Compare 'staging.orders' with 'dw.fact_orders' on 'order_id'
{"verb":"compare","left":"staging.orders","right":"dw.fact_orders","key":"order_id"}Resolved viaSQL connection
staging.orders
104211042210423dw.fact_orders
104211042210423For each control, Qventis Core uses the richest signal the screen offers: the DOM, accessibility and UI Automation trees, native control APIs or terminal data streams. When a layer is missing, custom-drawn or remote, live vision takes over automatically in the same step, and both signals cross-check each other wherever both exist.
| Layer | Checkout pageWeb | Custom-drawn gridWinForms desktop | Order entryCitrix session |
|---|---|---|---|
| Web DOM and shadow DOM | Resolved | None | None |
| Accessibility and UI Automation trees | Cross-checked | Grid only, no cells | None |
| Native control APIs (Java, SAP GUI, .NET) | Not needed | Partial | None |
| Terminal data streams | Not needed | Not needed | None |
| Live vision | Confirms | Resolved | Resolved |
Vision finds controls by label, role and layout, live, rather than matching stored image snippets. Nothing to recapture when a theme, font or resolution changes.
One step can resolve a field from the DOM and the next from vision. No separate script, no mode to set.
Every step records which layer resolved it, so reviewers can see exactly how each control was found.
Image and OCR tools, object-only frameworks, cloud screenshot vision and runtime model lookups each stop somewhere. Qventis Core uses every layer first and live vision when a layer runs out, on your own runners.
| Approach | How it finds a control | What it means for you |
|---|---|---|
| Image matching and OCR | Stored image snippets matched against pixels, text read by OCR; no awareness of the objects underneath | Breaks when theme, resolution, scaling or font changes; an image library to maintain per environment |
| Object-only frameworks | Selectors and accessibility IDs from the DOM or UI tree | Stops at custom-drawn controls, canvas, terminals and remote sessions |
| Cloud screenshot vision | Screenshots go to a vendor-run cloud service that resolves each element | Screens leave your network and every step waits on a round trip |
| Runtime model lookups | A language model is asked to find the element during the run | Cost on every step, and results can vary between runs |
| Qventis Core | Every technical layer first, then live vision per control, switched automatically and cross-checked | The richest signal for every control, nothing stored to maintain, screens stay in your network |
Choose a step and see what it compiles to for each channel. Nothing is interpreted at run time.
Step you write
Check that 'Total' shows '42.00'
await expect(page.getByLabel('Total')).toHaveText('42.00');expect(body.total).toBe('42.00');engine.check(Label("Total"), TextEquals("42.00"))expect(await $('~Total').getText()).toBe('42.00');SELECT total FROM orders WHERE order_id = :order_id; -- expect '42.00'People read and edit the sentence. Qventis Core versions and compiles the structure underneath, so plain English never drifts into prose nobody can run. Select a highlighted part to see what it means.
Select a highlighted part of the sentence.
The same verbs mean the same thing on web, desktop, mobile, API and data. Targets are labels people recognize, never selectors.
Select 'Express' in 'Shipping method'
Remember 'Order number' as {{order.id}}
Send GET to '/orders/{{order.id}}'
Qventis Core reads every layer a Windows app exposes, then switches to live vision for custom-drawn controls that object-based tools see as one blank pane.
Step 4 could not find the 'Total' field. A field labeled 'Order total' now sits in the same place.
Evidence: before and after screenshots and every other test affected.
# run a suite and fail the pipeline on errors qventis run --suite smoke --env test # take your web tests with you qventis export --to playwright ./exported
Runtime-AI tools send a model the page and the step on every run. Estimate the model spend compile-once execution avoids.
Illustrative defaults. Enter your own figures on a basic model.
Bring the app your current tools cannot see. We will record it with you.