Skip to main content
Glama
JMRMEDEV
by JMRMEDEV

wait_for_react_state

Monitor React applications for state changes, data loading completion, or navigation events during web scraping and testing workflows.

Instructions

Wait for React component state changes, data loading, or navigation

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
browserNoBrowser engine to usechromium
conditionYesType of condition to wait for
selectorNoCSS selector or testID to wait for (for custom condition)
timeoutNoMaximum time to wait in milliseconds
urlYesURL to monitor

Implementation Reference

  • The main handler function 'waitForReactState' that implements the core logic of the 'wait_for_react_state' tool. It launches a browser, navigates to the URL, and waits for the specified condition (hydration, navigation, data-loading, animation, or custom selector) using Playwright methods.
    async waitForReactState(args) { this.validateArgs(args, ['url', 'condition']); const { url, condition, selector, timeout = TIMEOUTS.HYDRATION, browser: browserType = 'chromium' } = args; const { browser, context } = await this.getBrowser(browserType); const page = await context.newPage(); try { await this.setupMobileViewport(page); await page.goto(url, { waitUntil: 'networkidle' }); const startTime = Date.now(); let result = ''; switch (condition) { case 'hydration': const hydrated = await this.waitForReactHydration(page, timeout); result = hydrated ? '✅ React hydration completed' : '❌ React hydration timeout'; break; case 'navigation': await page.waitForFunction(() => { return !document.querySelector('[aria-label*="loading"]') && !document.querySelector('[data-testid*="loading"]'); }, { timeout }); result = '✅ Navigation completed'; break; case 'data-loading': await page.waitForFunction(() => { const loadingElements = document.querySelectorAll( '[data-testid*="loading"], [aria-label*="loading"], .loading, .spinner' ); return loadingElements.length === 0; }, { timeout }); result = '✅ Data loading completed'; break; case 'animation': await page.waitForTimeout(2000); result = '✅ Animation wait completed'; break; case 'custom': if (!selector) throw new Error('Selector required for custom condition'); const { usedSelector } = await this.findElement(page, selector, timeout); result = `✅ Custom condition met: ${usedSelector}`; break; default: throw new Error(`Unknown condition: ${condition}`); } const waitTime = Date.now() - startTime; return { content: [{ type: 'text', text: `${result}\nWait time: ${waitTime}ms` }] }; } finally { await context.close(); await browser.close(); } }
  • server.js:242-275 (registration)
    Tool registration in the ListTools response, including the name, description, and inputSchema definition for 'wait_for_react_state'.
    { name: 'wait_for_react_state', description: 'Wait for React component state changes, data loading, or navigation', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'URL to monitor' }, condition: { type: 'string', enum: ['hydration', 'navigation', 'data-loading', 'animation', 'custom'], description: 'Type of condition to wait for' }, selector: { type: 'string', description: 'CSS selector or testID to wait for (for custom condition)' }, timeout: { type: 'number', default: 15000, description: 'Maximum time to wait in milliseconds' }, browser: { type: 'string', enum: ['chromium', 'firefox', 'webkit'], default: 'chromium', description: 'Browser engine to use' } }, required: ['url', 'condition'] } },
  • server.js:606-607 (registration)
    Registration/dispatch in the CallToolRequestSchema switch statement that maps the tool name to the handler method.
    case 'wait_for_react_state': return await this.waitForReactState(args);
  • Input schema definition specifying parameters: url (required), condition (required, enum: ['hydration', 'navigation', 'data-loading', 'animation', 'custom']), selector (optional), timeout (default 15000), browser (default 'chromium').
    inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'URL to monitor' }, condition: { type: 'string', enum: ['hydration', 'navigation', 'data-loading', 'animation', 'custom'], description: 'Type of condition to wait for' }, selector: { type: 'string', description: 'CSS selector or testID to wait for (for custom condition)' }, timeout: { type: 'number', default: 15000, description: 'Maximum time to wait in milliseconds' }, browser: { type: 'string', enum: ['chromium', 'firefox', 'webkit'], default: 'chromium', description: 'Browser engine to use' } }, required: ['url', 'condition'] }
  • Helper function 'waitForReactHydration' used by the handler (and others) to detect React hydration completion via checks for React global, devtools hook, data-reactroot, etc., and waits for loading indicators to detach.
    async waitForReactHydration(page, timeout = TIMEOUTS.HYDRATION) { try { await page.waitForFunction(() => { return window.React || window.__REACT_DEVTOOLS_GLOBAL_HOOK__ || document.querySelector('[data-reactroot]') || document.querySelector('#root [data-testid]') || document.querySelector('.expo-web-view'); }, { timeout }); await page.waitForTimeout(1000); const loadingSelectors = [ '[data-testid*="loading"]', '[data-testid*="spinner"]', '.loading', '.spinner', '[aria-label*="loading"]' ]; for (const selector of loadingSelectors) { try { await page.waitForSelector(selector, { state: 'detached', timeout: 5000 }); } catch (e) { // Loading indicator might not exist, continue } } return true; } catch (error) { console.warn('React hydration wait failed:', error.message); return 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/JMRMEDEV/amazon-q-web-scraper-mcp'

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