clawdbot-workspace/reonomy-explore-after-login.js

187 lines
6.6 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* Reonomy Post-Login Explorer
*
* This script starts from an already logged-in state and explores
* the dashboard to find where leads/properties are located.
*/
const puppeteer = require('puppeteer');
const fs = require('fs');
// Configuration
const START_URL = 'https://app.reonomy.com/#!/account'; // Will login first
const REONOMY_EMAIL = process.env.REONOMY_EMAIL || 'henry@realestateenhanced.com';
const REONOMY_PASSWORD = process.env.REONOMY_PASSWORD || '9082166532';
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function exploreAfterLogin() {
console.log('🚀 Starting Reonomy exploration...\n');
const browser = await puppeteer.launch({
headless: false, // Keep visible to see what's happening
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
await page.setViewport({ width: 1920, height: 1080 });
try {
// Step 1: Login
console.log('📍 Step 1: Logging in...');
await page.goto(START_URL, { waitUntil: 'networkidle2', timeout: 60000 });
await sleep(2000);
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 - use Auth0-specific selector
const loginButton = await page.$('button.auth0-lock-submit, button[type="submit"]');
if (loginButton) {
await loginButton.click();
} else {
// Fallback: 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.toLowerCase().includes('log in')) {
await btn.click();
break;
}
}
}
console.log('⏳ Waiting for login...');
await sleep(5000);
// Step 2: Check current state
const currentUrl = page.url();
console.log(`📍 Current URL: ${currentUrl}`);
// Take screenshot
await page.screenshot({ path: '/tmp/reonomy-dashboard.png', fullPage: true });
console.log('📸 Screenshot saved: /tmp/reonomy-dashboard.png');
// Step 3: Get page content for analysis
const html = await page.content();
fs.writeFileSync('/tmp/reonomy-html.html', html);
console.log('📄 HTML saved: /tmp/reonomy-html.html');
// Step 4: Extract visible text
const bodyText = await page.evaluate(() => document.body.innerText);
fs.writeFileSync('/tmp/reonomy-text.txt', bodyText);
console.log('📝 Text content saved: /tmp/reonomy-text.txt');
// Step 5: Look for links and navigation
console.log('\n🔍 Looking for links and navigation...');
const links = await page.evaluate(() => {
const linkElements = Array.from(document.querySelectorAll('a'));
return linkElements
.map(a => ({
text: a.innerText || a.textContent,
href: a.href,
className: a.className
}))
.filter(l => l.text && l.text.trim().length > 0 && l.text.length < 100)
.slice(0, 50); // Limit to first 50
});
console.log(`Found ${links.length} links:`);
links.forEach((link, i) => {
console.log(` ${i + 1}. "${link.text.trim()}" -> ${link.href}`);
});
// Step 6: Look for search/property-related elements
console.log('\n🔍 Looking for search elements...');
const searchElements = await page.evaluate(() => {
const inputs = Array.from(document.querySelectorAll('input'));
return inputs
.map(input => ({
type: input.type,
placeholder: input.placeholder,
name: input.name,
className: input.className
}))
.filter(i => i.placeholder && (i.placeholder.toLowerCase().includes('search') ||
i.placeholder.toLowerCase().includes('address') ||
i.placeholder.toLowerCase().includes('property')));
});
if (searchElements.length > 0) {
console.log('Found search inputs:');
searchElements.forEach((el, i) => {
console.log(` ${i + 1}. Type: ${el.type}, Placeholder: "${el.placeholder}"`);
});
} else {
console.log(' No obvious search inputs found');
}
// Step 7: Look for buttons and actions
console.log('\n🔍 Looking for action buttons...');
const buttonTexts = await page.evaluate(() => {
const buttons = Array.from(document.querySelectorAll('button, .btn, [role="button"]'));
return buttons
.map(b => (b.innerText || b.textContent).trim())
.filter(t => t && t.length > 0 && t.length < 50)
.slice(0, 30);
});
console.log(`Found ${buttonTexts.length} buttons:`);
buttonTexts.forEach((text, i) => {
console.log(` ${i + 1}. "${text}"`);
});
// Step 8: Check for data tables or lists
console.log('\n🔍 Looking for data containers...');
const dataSelectors = await page.evaluate(() => {
const selectors = ['table', '[role="grid"]', '.list', '.results', '.cards', '.grid', '[data-test*="list"]'];
const results = {};
selectors.forEach(sel => {
const elements = document.querySelectorAll(sel);
if (elements.length > 0) {
results[sel] = elements.length;
}
});
return results;
});
if (Object.keys(dataSelectors).length > 0) {
console.log('Found data containers:');
Object.entries(dataSelectors).forEach(([sel, count]) => {
console.log(` ${sel}: ${count} elements`);
});
}
console.log('\n✅ Exploration complete!');
console.log('💡 Review the saved files to understand the UI structure:');
console.log(' - /tmp/reonomy-dashboard.png (screenshot)');
console.log(' - /tmp/reonomy-html.html (page HTML)');
console.log(' - /tmp/reonomy-text.txt (visible text)');
console.log(' - /tmp/reonomy-links.json (links - saved below)');
// Save links to JSON
fs.writeFileSync('/tmp/reonomy-links.json', JSON.stringify(links, null, 2));
console.log('\n⏸ Browser kept open. Press Ctrl+C to close, or close manually to exit.');
// Keep browser open for manual inspection
await new Promise(() => {});
} catch (error) {
console.error('❌ Error:', error.message);
console.error(error.stack);
await page.screenshot({ path: '/tmp/reonomy-error.png', fullPage: true });
} finally {
await browser.close();
}
}
exploreAfterLogin().catch(error => {
console.error('Fatal error:', error);
process.exit(1);
});