UNPKG

chromancer

Version:

A powerful command-line interface for automating Chrome browser using Playwright. Perfect for web scraping, automation, testing, and browser workflows.

118 lines (117 loc) 4.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("@oclif/core"); const base_js_1 = require("../base.js"); const evaluation_js_1 = require("../utils/evaluation.js"); class Evaluate extends base_js_1.BaseCommand { static description = 'Execute JavaScript in the page context'; static examples = [ '<%= config.bin %> <%= command.id %> "document.title"', '<%= config.bin %> <%= command.id %> "document.querySelectorAll(\'a\').length" --return-result', '<%= config.bin %> <%= command.id %> "localStorage.getItem(\'token\')" --json', ]; static flags = { ...base_js_1.BaseCommand.baseFlags, 'return-result': core_1.Flags.boolean({ description: 'Print the result of the evaluation', default: true, }), json: core_1.Flags.boolean({ description: 'Output result as raw JSON', default: false, }), selector: core_1.Flags.string({ description: 'Evaluate within the context of a specific element', }), }; static args = { script: core_1.Args.string({ description: 'JavaScript code to execute', required: true, }), }; async run() { const { args, flags } = await this.parse(Evaluate); await this.connectToChrome(flags.port, flags.host, flags.launch, flags.profile, flags.headless, flags.verbose, flags.keepOpen); if (!this.page) { this.error('No page available'); } try { this.log(`🔧 Evaluating JavaScript...`); this.logVerbose('Script to evaluate', { script: args.script }); let result; if (flags.selector) { // Evaluate within element context this.log(`📍 Using element context: ${flags.selector}`); const element = await this.page.$(flags.selector); if (!element) { this.error(`Element not found: ${flags.selector}`); } result = await element.evaluate((el, script) => { // Create a function that has 'el' in scope const fn = new Function('el', `return ${script}`); return fn(el); }, args.script); } else { // Evaluate in page context result = await (0, evaluation_js_1.safeEvaluate)(this.page, args.script); } if (flags['return-result']) { if (flags.json) { // Raw JSON output for scripting console.log(JSON.stringify(result)); } else { // Pretty formatted output this.log('📤 Result:'); if (result === undefined) { this.log('undefined'); } else if (result === null) { this.log('null'); } else if (typeof result === 'object') { this.log(JSON.stringify(result, null, 2)); } else { this.log(String(result)); } } // Log type information if verbose if (flags.verbose && !flags.json) { this.logVerbose('Result type', { type: typeof result, isArray: Array.isArray(result), constructor: result?.constructor?.name, }); } } else { this.log('✅ JavaScript executed successfully'); } // Log performance metrics if verbose if (flags.verbose) { const metrics = await this.page.evaluate(() => { if (typeof performance !== 'undefined' && performance.memory) { return { usedJSHeapSize: Math.round(performance.memory.usedJSHeapSize / 1024 / 1024) + 'MB', totalJSHeapSize: Math.round(performance.memory.totalJSHeapSize / 1024 / 1024) + 'MB', }; } return null; }); if (metrics) { this.logVerbose('Memory usage', metrics); } } } catch (error) { if (error.name === 'SyntaxError' || error.message.includes('SyntaxError')) { this.error(`JavaScript syntax error: ${error.message}`); } this.error(`Failed to evaluate JavaScript: ${error.message}`); } } } exports.default = Evaluate;