187 lines
6.6 KiB
JavaScript
187 lines
6.6 KiB
JavaScript
#!/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);
|
||
});
|