pilot_element_state
Before interacting with an element, confirm its state (visible, enabled, checked, etc.) with a boolean response.
Instructions
Check the current state of an element — whether it is visible, hidden, enabled, disabled, checked, editable, or focused. Use when the user wants to verify an element's condition before interacting with it, check if a button is disabled, confirm a checkbox is checked, or debug why an interaction is failing.
Parameters:
ref: Element reference from snapshot (e.g., "@e3") or CSS selector
property: The state to check — "visible", "hidden", "enabled", "disabled", "checked", "editable", or "focused"
Returns: Boolean string "true" or "false" indicating the element's state for the requested property.
Errors:
"Element not found": The ref is stale. Run pilot_snapshot to get fresh refs.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes | Element ref or CSS selector | |
| property | Yes | State to check |
Implementation Reference
- src/tools/page.ts:232-265 (handler)The async handler function that executes the pilot_element_state tool logic. Checks element state (visible, hidden, enabled, disabled, checked, editable, focused) either via extension or Playwright locator methods.
async ({ ref, property }) => { await bm.ensureBrowser(); try { const ext = bm.getExtension(); if (ext) { const res = await bm.extSend<{ visible: boolean; enabled: boolean; checked: boolean | null; focused: boolean }>('element_state', { ref }); const stateMap: Record<string, boolean> = { visible: res.visible, hidden: !res.visible, enabled: res.enabled, disabled: !res.enabled, checked: res.checked ?? false, focused: res.focused, editable: res.enabled && res.visible, }; return { content: [{ type: 'text' as const, text: String(stateMap[property] ?? false) }] }; } const page = bm.getPage(); const resolved = await bm.resolveRef(ref); const locator = 'locator' in resolved ? resolved.locator : page.locator(resolved.selector); let result: boolean; switch (property) { case 'visible': result = await locator.isVisible(); break; case 'hidden': result = await locator.isHidden(); break; case 'enabled': result = await locator.isEnabled(); break; case 'disabled': result = await locator.isDisabled(); break; case 'checked': result = await locator.isChecked(); break; case 'editable': result = await locator.isEditable(); break; case 'focused': result = await locator.evaluate((el) => el === document.activeElement); break; } return { content: [{ type: 'text' as const, text: String(result) }] }; } catch (err) { return { content: [{ type: 'text' as const, text: wrapError(err) }], isError: true }; } } ); - src/tools/page.ts:228-231 (schema)Zod schema defining input parameters: ref (string) and property (enum of: visible, hidden, enabled, disabled, checked, editable, focused).
{ ref: z.string().describe('Element ref or CSS selector'), property: z.enum(['visible', 'hidden', 'enabled', 'disabled', 'checked', 'editable', 'focused']).describe('State to check'), }, - src/tools/page.ts:215-265 (registration)Registration of the 'pilot_element_state' tool via server.tool() within the registerPageTools function. Includes the full description and parameter schema.
server.tool( 'pilot_element_state', `Check the current state of an element — whether it is visible, hidden, enabled, disabled, checked, editable, or focused. Use when the user wants to verify an element's condition before interacting with it, check if a button is disabled, confirm a checkbox is checked, or debug why an interaction is failing. Parameters: - ref: Element reference from snapshot (e.g., "@e3") or CSS selector - property: The state to check — "visible", "hidden", "enabled", "disabled", "checked", "editable", or "focused" Returns: Boolean string "true" or "false" indicating the element's state for the requested property. Errors: - "Element not found": The ref is stale. Run pilot_snapshot to get fresh refs.`, { ref: z.string().describe('Element ref or CSS selector'), property: z.enum(['visible', 'hidden', 'enabled', 'disabled', 'checked', 'editable', 'focused']).describe('State to check'), }, async ({ ref, property }) => { await bm.ensureBrowser(); try { const ext = bm.getExtension(); if (ext) { const res = await bm.extSend<{ visible: boolean; enabled: boolean; checked: boolean | null; focused: boolean }>('element_state', { ref }); const stateMap: Record<string, boolean> = { visible: res.visible, hidden: !res.visible, enabled: res.enabled, disabled: !res.enabled, checked: res.checked ?? false, focused: res.focused, editable: res.enabled && res.visible, }; return { content: [{ type: 'text' as const, text: String(stateMap[property] ?? false) }] }; } const page = bm.getPage(); const resolved = await bm.resolveRef(ref); const locator = 'locator' in resolved ? resolved.locator : page.locator(resolved.selector); let result: boolean; switch (property) { case 'visible': result = await locator.isVisible(); break; case 'hidden': result = await locator.isHidden(); break; case 'enabled': result = await locator.isEnabled(); break; case 'disabled': result = await locator.isDisabled(); break; case 'checked': result = await locator.isChecked(); break; case 'editable': result = await locator.isEditable(); break; case 'focused': result = await locator.evaluate((el) => el === document.activeElement); break; } return { content: [{ type: 'text' as const, text: String(result) }] }; } catch (err) { return { content: [{ type: 'text' as const, text: wrapError(err) }], isError: true }; } } ); - src/tools/register.ts:6-8 (helper)Import of registerPageTools from './page.js' which contains the pilot_element_state tool registration.
import { registerPageTools } from './page.js'; import { registerInspectionTools } from './inspection.js'; import { registerVisualTools } from './visual.js';