Skip to main content
Glama
element_exists.ts3.35 kB
import { ToolHandler, ToolMetadata, SessionConfig } from '../../common/types.js'; import { BrowserToolBase } from '../base.js'; import type { ToolContext, ToolResponse } from '../../common/types.js'; export interface ElementExistsArgs { selector: string; } export class ElementExistsTool extends BrowserToolBase implements ToolHandler { static getMetadata(sessionConfig?: SessionConfig): ToolMetadata { return { name: "element_exists", description: "Quick check if an element exists on the page. Ultra-lightweight alternative to query_selector_all when you only need existence confirmation. Returns simple exists/not found status. Most common check before attempting interaction. Supports testid shortcuts.", outputs: [ "Returns one line:", "- ✓ exists: <tag id/class> (N matches) when found (N optional)", "- ✗ not found: <original selector> when none", ], examples: [ "element_exists({ selector: 'testid:submit' })", "element_exists({ selector: '#does-not-exist' })", ], exampleOutputs: [ { call: "element_exists({ selector: 'testid:submit' })", output: `✓ exists: <button data-testid=\"submit\">` }, { call: "element_exists({ selector: '.card' })", output: `✓ exists: <div .card> (3 matches)` }, { call: "element_exists({ selector: '#does-not-exist' })", output: `✗ not found: #does-not-exist` }, ], inputSchema: { type: "object", properties: { selector: { type: "string", description: "CSS selector, text selector, or testid shorthand (e.g., 'testid:submit-button', '#main')" } }, required: ["selector"], }, }; } async execute(args: ElementExistsArgs, context: ToolContext): Promise<ToolResponse> { return this.safeExecute(context, async (page) => { const normalizedSelector = this.normalizeSelector(args.selector); const locator = page.locator(normalizedSelector); const count = await locator.count(); if (count === 0) { return { content: [ { type: 'text', text: `✗ not found: ${args.selector}` } ], isError: false }; } // Get element info for better output const element = locator.first(); const elementInfo = await element.evaluate((el) => { const tag = el.tagName.toLowerCase(); const parts: string[] = [tag]; if (el.id) parts.push(`#${el.id}`); if (el.className && typeof el.className === 'string') { const classes = el.className.split(' ').filter(c => c).slice(0, 2); if (classes.length) { classes.forEach(c => parts.push(`.${c}`)); } } return parts.join(''); }).catch(() => args.selector); if (count === 1) { return { content: [ { type: 'text', text: `✓ exists: <${elementInfo}>` } ], isError: false }; } // Multiple matches return { content: [ { type: 'text', text: `✓ exists: <${elementInfo}> (${count} matches)` } ], isError: false }; }); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/antonzherdev/mcp-web-inspector'

If you have feedback or need assistance with the MCP directory API, please join our Discord server