UNPKG

rabbit-browser

Version:

Browser automation tool for detecting interactive elements on web pages

187 lines 7.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.simpleRabbitBrowser = exports.SimpleRabbitBrowser = void 0; const logger_1 = require("./utils/logger"); const puppeteer_1 = require("./browser/puppeteer"); const elementDetector_1 = require("./highlighting/elementDetector"); const highlighter_1 = require("./highlighting/highlighter"); /** * Simple API to detect and highlight interactive elements on web pages */ class SimpleRabbitBrowser { /** * Create a new SimpleRabbitBrowser instance */ constructor(options = {}) { this.browser = null; this.page = null; this.elements = []; this.textBlocks = []; this.pageContext = null; // Default options this.options = { focusOnConsent: options.focusOnConsent ?? false, waitTime: options.waitTime ?? 3000, logDetails: options.logDetails ?? false, earlyReturn: options.earlyReturn ?? true, includePageContext: options.includePageContext ?? true, includeFormInputs: options.includeFormInputs ?? true, includeTextBlocks: options.includeTextBlocks ?? true, highlightAllText: options.highlightAllText ?? true, }; } /** * Navigate to a URL and detect elements * @param url The URL to navigate to * @returns Promise resolving when navigation and detection are complete */ async go(url) { try { // Launch browser if not already running if (!this.browser) { this.browser = await (0, puppeteer_1.setupBrowser)(); } // Create a new page if needed if (!this.page) { this.page = await (0, puppeteer_1.setupPage)(this.browser); } // Clear previous elements this.elements = []; this.textBlocks = []; this.pageContext = null; // Navigate to URL await (0, puppeteer_1.navigateTo)(this.page, url); // Initialize components await (0, highlighter_1.initializeHighlighter)(this.page); await (0, elementDetector_1.initializeElementDetector)(this.page, { focusOnConsent: this.options.focusOnConsent, includeFormInputs: this.options.includeFormInputs, highlightAllText: this.options.highlightAllText, }); // Start detecting elements await this.page.evaluate(() => { window.processedElements = new Set(); window.processedTextBlocks = new Set(); window.highlightedElements = window.highlightedElements || []; window.highlightedTextBlocks = window.highlightedTextBlocks || []; window.startObservingNewElements(); }); // Log if enabled if (this.options.logDetails) { (0, logger_1.log)("Detecting interactive elements and text blocks..."); } // Progressive checking for elements const checkIntervals = [300, 500, 700, 1000, 1500]; let totalWaitTime = 0; // Check at increasing intervals for (const interval of checkIntervals) { if (totalWaitTime >= this.options.waitTime) break; await new Promise((resolve) => setTimeout(resolve, interval)); totalWaitTime += interval; // Collect elements and text blocks const data = await (0, highlighter_1.collectElementData)(this.page); this.elements = data.elements; this.textBlocks = data.textBlocks; // Early return if we found elements if (this.options.earlyReturn && this.elements.length > 0) { if (this.options.logDetails) { (0, logger_1.log)(`Found ${this.elements.length} elements and ${this.textBlocks.length} text blocks after ${totalWaitTime}ms - returning early`); } break; } } // Final wait if needed if (this.elements.length === 0 && totalWaitTime < this.options.waitTime) { const remainingTime = this.options.waitTime - totalWaitTime; if (this.options.logDetails) { (0, logger_1.log)(`Waiting additional ${remainingTime}ms for elements...`); } await new Promise((resolve) => setTimeout(resolve, remainingTime)); const data = await (0, highlighter_1.collectElementData)(this.page); this.elements = data.elements; this.textBlocks = data.textBlocks; } // Collect page context if requested if (this.options.includePageContext) { if (this.options.logDetails) { (0, logger_1.log)("Collecting page text context for AI analysis..."); } const contextData = await (0, highlighter_1.collectPageTextContext)(this.page); this.pageContext = contextData.pageContext; } // Log results if enabled if (this.options.logDetails) { if (this.elements.length === 0) { (0, logger_1.log)("WARNING: No interactive elements were detected"); } else { (0, logger_1.log)(`Detected ${this.elements.length} elements and ${this.textBlocks.length} text blocks`); } } } catch (error) { // Clean up on error if (this.browser) { try { await this.browser.close(); } catch (e) { // Ignore errors when closing } this.browser = null; this.page = null; } (0, logger_1.log)(`Error detecting elements: ${error}`); throw error; } } /** * Get detected elements * @returns Array of detected elements */ getElements() { return this.elements; } /** * Get text blocks * @returns Array of text blocks */ getTextBlocks() { return this.textBlocks; } /** * Get page context information including text content * @returns Page context object with text content */ getPageContext() { return this.pageContext; } /** * Get complete data with both elements and page context * @returns Object containing elements and page context */ getCompleteData() { return { elements: this.elements, textBlocks: this.textBlocks, pageContext: this.pageContext, }; } /** * Close the browser if it's open */ async close() { if (this.browser) { await this.browser.close(); this.browser = null; this.page = null; } } } exports.SimpleRabbitBrowser = SimpleRabbitBrowser; /** * Global instance for simple use */ exports.simpleRabbitBrowser = new SimpleRabbitBrowser(); //# sourceMappingURL=SimpleRabbitBrowser.js.map