Files
cannaiq/backend/test-puppeteer-click.ts
2025-11-28 19:45:44 -07:00

168 lines
5.6 KiB
TypeScript

import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
puppeteer.use(StealthPlugin());
async function testPuppeteerClick() {
let browser;
try {
console.log('🌐 Testing with REAL Puppeteer clicks...');
console.log('');
browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
const url = 'https://curaleaf.com/stores/curaleaf-dispensary-phoenix-airport/brands';
console.log('Going to:', url);
await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
await page.waitForTimeout(3000);
console.log('Current URL:', page.url());
if (page.url().includes('/age-gate')) {
console.log('\n═══ GATE 1: STATE SELECTOR ═══');
// Wait for and click the dropdown button using REAL Puppeteer click
await page.waitForSelector('button[role="combobox"]', { timeout: 10000 });
await page.click('button[role="combobox"]');
console.log('✅ Clicked dropdown with Puppeteer click');
await page.waitForTimeout(2000);
// Take screenshot of dropdown open
await page.screenshot({ path: '/tmp/dropdown-open.png' });
console.log('📸 Screenshot: /tmp/dropdown-open.png');
// Wait for options to appear
await page.waitForSelector('[role="option"]', { timeout: 5000 });
// Get all options and find Arizona
const options = await page.$$('[role="option"]');
console.log(`Found ${options.length} options`);
let arizonaClicked = false;
for (const option of options) {
const text = await option.evaluate(el => el.textContent?.toLowerCase().trim());
if (text === 'arizona') {
console.log('Found Arizona option, clicking with REAL Puppeteer click...');
await option.click();
arizonaClicked = true;
break;
}
}
if (arizonaClicked) {
console.log('✅ Clicked Arizona with Puppeteer click');
// Wait for React to update
await page.waitForTimeout(5000);
// Screenshot after click
await page.screenshot({ path: '/tmp/after-real-click.png' });
console.log('📸 Screenshot: /tmp/after-real-click.png');
console.log('URL after click:', page.url());
// Check what buttons are now visible
const buttons = await page.evaluate(() => {
const allButtons = Array.from(document.querySelectorAll('button, a'));
return allButtons.map(btn => ({
text: btn.textContent?.trim() || '',
visible: (btn as HTMLElement).offsetParent !== null,
ariaLabel: btn.getAttribute('aria-label') || '',
role: btn.getAttribute('role') || ''
})).filter(b => b.visible && b.text.length > 0 && b.text.length < 100);
});
console.log('\n📋 VISIBLE BUTTONS:');
console.log(JSON.stringify(buttons, null, 2));
// Look for age confirmation button
console.log('\n═══ GATE 2: AGE CONFIRMATION ═══');
const ageButton = buttons.find(btn => {
const text = btn.text.toLowerCase();
return text.includes("i'm") ||
text.includes('21') ||
text.includes('yes') ||
text.includes('enter') ||
text.includes('continue');
});
if (ageButton) {
console.log('✅ Found age button:', ageButton.text);
// Click it with Puppeteer
const ageButtonClicked = await page.evaluate((btnText) => {
const buttons = Array.from(document.querySelectorAll('button, a'));
const btn = buttons.find(b => b.textContent?.trim() === btnText) as HTMLElement;
if (btn) {
btn.click();
return true;
}
return false;
}, ageButton.text);
if (ageButtonClicked) {
console.log('✅ Clicked age button');
// Wait for potential navigation or page update
await page.waitForTimeout(5000);
console.log('Final URL:', page.url());
// Try to scrape brands
console.log('\n═══ SCRAPING BRANDS ═══');
const brands = await page.evaluate(() => {
const selectors = [
'[data-testid*="brand"]',
'[class*="Brand"]',
'[class*="brand"]',
'a[href*="/brand/"]'
];
const found = new Set<string>();
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(el => {
const text = el.textContent?.trim();
if (text && text.length > 0 && text.length < 50) {
found.add(text);
}
});
});
return Array.from(found);
});
console.log(`Found ${brands.length} brands`);
if (brands.length > 0) {
console.log('─'.repeat(60));
brands.forEach((b, i) => console.log(` ${i + 1}. ${b}`));
console.log('─'.repeat(60));
}
}
} else {
console.log('⚠️ No age confirmation button found');
console.log('Available buttons:', buttons.map(b => b.text));
}
} else {
console.log('❌ Could not find Arizona option');
}
}
} catch (error: any) {
console.error('❌ Error:', error.message);
} finally {
if (browser) await browser.close();
}
}
testPuppeteerClick();