Skip to content

Within Blocks

Basic syntax

Within blocks define a context for actions. The syntax requires the the keyword between Within and the block name:

Within the Browser (plugin: playwright-python, type: browser)
go to "https://example.com"

Blocks must be indented with consistent whitespace. All statements inside the block are scoped to that context.

Required modifiers

The root within block must specify:

  • plugin: - which plugin to use
  • type: - which type from that plugin
Within the Browser (plugin: playwright-python, type: browser)

Both modifiers are required at the root level. The plugin: modifier selects which plugin processes actions; the type: modifier selects the type definition within that plugin.

Nested blocks

Blocks can be nested. Child blocks inherit the parent’s plugin but must still specify their own type:

Within the Browser (plugin: playwright-python, type: browser)
go to "https://example.com"
Within the Login Form (type: element)
type "user@example.com" into "Email"

Nesting constraints

Not all types can be nested inside all other types. Each type in a plugin defines an allowed_children list that specifies which types can be nested within it.

For example, in the playwright-python plugin:

  • browser allows children: element, failure_block
  • element allows children: element, failure_block

Attempting to nest an invalid type results in an error:

Block 'invalid_type' cannot nest inside 'browser'

Modifier syntax

Two equivalent syntaxes are supported for modifiers:

Parentheses syntax:

Within the Browser (plugin: playwright-python, type: browser, url: 'http://localhost')

With syntax:

Within the Browser with plugin: playwright-python, type: browser, url: 'http://localhost'

Both syntaxes accept comma-separated key-value pairs. The with syntax is single-line only, while parentheses can span multiple lines (though this is discouraged).

Block names

Block names are freeform text between the and the opening parenthesis (or with keyword):

Within the My Custom Name Here (type: browser)

The name is used for:

  • Generating variable names in the output code
  • Diagnostic messages and error reporting
  • Documentation purposes in the test

Scope rules

Definitions created with Define and variables captured with Capture share a single flat scope across the entire script. This means:

  • A Define in one block is accessible in sibling and child blocks
  • A Capture in one block creates a variable usable in later blocks

To share a variable explicitly between blocks, use Export:

Within the Orders API (plugin: python-requests, type: api, base: 'http://orders.internal')
POST "/orders" body '{"item": "widget"}'
capture "$.id" as order_id
Export order_id
Within the Notifications API (plugin: python-requests, type: api, base: 'http://notifications.internal')
GET "/notifications/{order_id}"
expect status 200

Multi-plugin scripts

A single vanya file can use multiple plugins. Each root-level Within block specifies its own plugin:

Within the API (plugin: python-requests, type: api, base: 'http://api.local')
GET "/health"
expect status 200
Within the Browser (plugin: playwright-python, type: browser, url: 'http://localhost:3000')
go to "/login"
Within the Login Form (type: element, id: 'login_form')
type "user@example.com" into input (label: 'Email')
click button (testid: 'submit')

Case sensitivity

The Within keyword must be written with a capital W. This is consistent with other vanya keywords (Script, Define, Export, Capture).