clawdbot-workspace/reonomy-explorer.js

197 lines
6.2 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* Reonomy UI Explorer
*
* This script explores the Reonomy UI to understand:
* - Login process
* - Navigation structure
* - Where lead data is located
* - How to access property/owner information
*/
const puppeteer = require('puppeteer');
const { execSync } = require('child_process');
// Configuration - Use environment variables for credentials
const REONOMY_EMAIL = process.env.REONOMY_EMAIL || 'henry@realestateenhanced.com';
const REONOMY_PASSWORD = process.env.REONOMY_PASSWORD || '9082166532';
// Google Sheets configuration
const SHEET_TITLE = process.env.REONOMY_SHEET_TITLE || 'Reonomy Leads';
async function explore() {
console.log('🔍 Starting Reonomy UI exploration...');
const browser = await puppeteer.launch({
headless: process.env.HEADLESS === 'true' ? 'new' : false, // Show browser for debugging unless HEADLESS=true
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--window-size=1920,1080'
]
});
const page = await browser.newPage();
// Set viewport
await page.setViewport({ width: 1920, height: 1080 });
try {
// Navigate to login page
console.log('📍 Navigating to login page...');
await page.goto('https://app.reonomy.com/#!/account', {
waitUntil: 'networkidle2',
timeout: 60000
});
// Wait for email input
await page.waitForSelector('input[type="email"], input[placeholder*="example"]', { timeout: 10000 });
console.log('✅ Login page loaded');
// Take screenshot
await page.screenshot({ path: '/tmp/reonomy-01-login.png' });
// Fill email
console.log('🔑 Entering credentials...');
await page.type('input[type="email"], input[placeholder*="example"]', REONOMY_EMAIL, { delay: 100 });
await page.type('input[type="password"], input[placeholder*="password"]', REONOMY_PASSWORD, { delay: 100 });
// Click login button - try multiple methods
console.log('🔘 Looking for login button...');
// Method 1: Try type="submit"
let loginButton = await page.$('button[type="submit"]');
if (loginButton) {
await loginButton.click();
} else {
// Method 2: Look for button with text "Log In"
const buttons = await page.$$('button');
for (const btn of buttons) {
const text = await btn.evaluate(e => e.innerText || e.textContent);
if (text && text.includes('Log In')) {
await btn.click();
break;
}
}
}
console.log('⏳ Waiting for login to complete...');
// Wait for navigation - check for dashboard
await page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 30000 }).catch(() => {
console.log('⚠️ No automatic navigation detected, checking current state...');
});
// Take screenshot after login
await page.screenshot({ path: '/tmp/reonomy-02-after-login.png' });
// Check URL to see where we are
const currentUrl = page.url();
console.log(`📍 Current URL: ${currentUrl}`);
// Wait a bit for any dynamic content
await new Promise(resolve => setTimeout(resolve, 5000));
// Get page title
const title = await page.title();
console.log(`📄 Page title: ${title}`);
// Look for navigation elements
console.log('\n🔎 Looking for navigation elements...');
// Common selectors for navigation
const navSelectors = [
'nav',
'[role="navigation"]',
'.navbar',
'.nav',
'header nav',
'.sidebar',
'.menu',
'ul.menu',
'[data-test="navigation"]',
'[data-testid="navigation"]'
];
for (const selector of navSelectors) {
const elements = await page.$$(selector);
if (elements.length > 0) {
console.log(` ✅ Found ${elements.length} elements with selector: ${selector}`);
// Try to extract navigation text
for (const el of elements) {
try {
const text = await el.evaluate(e => e.innerText);
if (text && text.length < 500) {
console.log(` Content: ${text.substring(0, 200)}...`);
}
} catch (err) {
// Ignore errors
}
}
}
}
// Look for common lead-related keywords in the page
console.log('\n🔎 Scanning for lead-related content...');
const keywords = ['search', 'property', 'owner', 'leads', 'listings', 'buildings', 'properties'];
const pageContent = await page.content();
for (const keyword of keywords) {
const regex = new RegExp(keyword, 'gi');
const matches = pageContent.match(regex);
if (matches && matches.length > 0) {
console.log(` ✅ Found "${keyword}" (${matches.length} occurrences)`);
}
}
// Look for data tables or lists
console.log('\n🔎 Looking for data tables/lists...');
const tableSelectors = ['table', '[role="grid"]', '.table', '.data-table', '.list', '.results'];
for (const selector of tableSelectors) {
const elements = await page.$$(selector);
if (elements.length > 0) {
console.log(` ✅ Found ${elements.length} elements with selector: ${selector}`);
}
}
// Try to find search functionality
console.log('\n🔎 Looking for search functionality...');
const searchSelectors = [
'input[type="search"]',
'input[placeholder*="search"]',
'input[placeholder*="Search"]',
'.search-input',
'[data-test="search"]',
'[data-testid="search"]'
];
for (const selector of searchSelectors) {
const elements = await page.$$(selector);
if (elements.length > 0) {
console.log(` ✅ Found ${elements.length} search inputs with selector: ${selector}`);
}
}
// Save a screenshot of the final state
await page.screenshot({ path: '/tmp/reonomy-03-exploration.png', fullPage: true });
console.log('\n✅ Exploration complete!');
console.log('📸 Screenshots saved to /tmp/reonomy-*.png');
} catch (error) {
console.error('❌ Error during exploration:', error.message);
await page.screenshot({ path: '/tmp/reonomy-error.png' });
} finally {
console.log('\n🔚 Closing browser...');
await browser.close();
}
}
// Run exploration
explore().catch(error => {
console.error('Fatal error:', error);
process.exit(1);
});