Skip to main content
Glama

browser_scroll_to_element

Scroll the browser viewport to make a specific web element visible using locator strategies like ID, CSS, or XPath for automated web testing and interaction.

Instructions

Scroll to an element

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
byYesLocator strategy to find element
timeoutNoMaximum time to wait for element in milliseconds
valueYesValue for the locator strategy

Implementation Reference

  • Registers the 'browser_scroll_to_element' MCP tool with input schema based on locatorSchema and an inline handler function that creates an ActionService instance and calls its scrollToElement method.
    server.tool( 'browser_scroll_to_element', 'Scroll to an element', { ...locatorSchema }, async ({ by, value, timeout = 15000 }) => { try { const driver = stateManager.getDriver(); const actionService = new ActionService(driver); await actionService.scrollToElement({ by, value, timeout }); return { content: [{ type: 'text', text: `Scrolled to element` }], }; } catch (e) { return { content: [ { type: 'text', text: `Error scrolling to element: ${(e as Error).message}`, }, ], }; } } );
  • Core handler logic for scrolling to an element: creates locator, waits for element, and executes JavaScript to scroll it into view using Selenium WebDriver.
    async scrollToElement(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const element = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); await this.driver.executeScript('arguments[0].scrollIntoView();', element); }
  • Zod schema definition for element locator parameters (by, value, timeout), spread into the tool's input schema.
    export const locatorSchema = { by: z .enum(['id', 'css', 'xpath', 'name', 'tag', 'class', 'link', 'partialLink']) .describe('Locator strategy to find element'), value: z.string().describe('Value for the locator strategy'), timeout: z.number().optional().describe('Maximum time to wait for element in milliseconds'), };
  • TypeScript interface defining the LocatorParams type used in the tool handler and service method.
    export interface LocatorParams { by: LocatorStrategy; value: string;
  • No, wait, better not. Actually, skipping LocatorFactory for now.
    import { LocatorFactory } from '../utils/locators.js'; import { LocatorParams } from '../types/index.js'; export class ActionService { constructor(private driver: WebDriver) {} async hoverOverElement(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const element = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); const actions = this.driver.actions({ bridge: true }); await actions.move({ origin: element }).perform(); } async waitForElement(params: LocatorParams): Promise<WebElement> { const locator = LocatorFactory.createLocator(params.by, params.value); return this.driver.wait(until.elementLocated(locator), params.timeout || 15000); } async dragAndDrop(sourceParams: LocatorParams, targetParams: LocatorParams): Promise<void> { const sourceLocator = LocatorFactory.createLocator(sourceParams.by, sourceParams.value); const targetLocator = LocatorFactory.createLocator(targetParams.by, targetParams.value); const sourceElement = await this.driver.wait(until.elementLocated(sourceLocator), sourceParams.timeout || 15000); const targetElement = await this.driver.wait(until.elementLocated(targetLocator), targetParams.timeout || 15000); const actions = this.driver.actions({ bridge: true }); await actions.dragAndDrop(sourceElement, targetElement).perform(); } async doubleClickElement(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const element = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); const actions = this.driver.actions({ bridge: true }); await actions.doubleClick(element).perform(); } async rightClickElement(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const element = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); const actions = this.driver.actions({ bridge: true }); await actions.contextClick(element).perform(); } async selectDropdownByText(params: LocatorParams & { text: string }): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const selectElement = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); const select = new Select(selectElement); await select.selectByVisibleText(params.text); } async selectDropdownByValue(params: LocatorParams & { value: string }): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const selectElement = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); const select = new Select(selectElement); await select.selectByValue(params.value); } async pressKey(key: string): Promise<void> { const actions = this.driver.actions({ bridge: true }); await actions.keyDown(key).keyUp(key).perform(); } async executeScript(script: string, args = []): Promise<any> { return this.driver.executeScript(script, ...args); } async scrollToElement(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const element = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); await this.driver.executeScript('arguments[0].scrollIntoView();', element); } async scrollToTop(): Promise<void> { await this.driver.executeScript('window.scrollTo(0, 0);'); } async scrollToBottom(): Promise<void> { await this.driver.executeScript('window.scrollTo(0, document.body.scrollHeight);'); } async scrollToCoordinates(x: number, y: number): Promise<void> { await this.driver.executeScript(`window.scrollTo(${x}, ${y});`); } async scrollByPixels(x: number, y: number): Promise<void> { await this.driver.executeScript(`window.scrollBy(${x}, ${y});`); } async submitForm(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const form = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); await form.submit(); } async focusElement(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const element = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); await this.driver.executeScript('arguments[0].focus();', element); } async blurElement(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const element = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); await this.driver.executeScript('arguments[0].blur();', element); } async selectCheckbox(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const checkbox = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); if (!(await checkbox.isSelected())) { await checkbox.click(); } } async unselectCheckbox(params: LocatorParams): Promise<void> { const locator = LocatorFactory.createLocator(params.by, params.value); const checkbox = await this.driver.wait(until.elementLocated(locator), params.timeout || 15000); if (await checkbox.isSelected()) { await checkbox.click(); } } async takeScreenshot(): Promise<string> { return this.driver.takeScreenshot(); } }

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/pshivapr/selenium-mcp'

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