# Expedia — Browser Automation Field-tested against expedia.co.in on 2026-04-27 using `browser-harness` CDP helpers (`goto`, `js`, `click`, `type_text`, `screenshot`). --- ## TL;DR **Build your search via URL parameters, not the UI.** The date picker, destination autocomplete, and traveller widgets are fragile—coordinate clicks frequently dismiss them or mis-target. Encode everything you can into a `goto()` URL, then use JS clicks only for what the URL can't express (child ages, price filters). --- ## Hotel Search URL Template ``` https://www.expedia.co.in/Hotel-Search?destination={DEST}&startDate={YYYY-MM-DD}&endDate={YYYY-MM-DD}&rooms={N}&adults={N}&children={N}&childrenAges={age1,age2,...} ``` Example — 2 adults, 2 children (ages 5 and 7), Tokyo, June 2026: ```python goto("https://www.expedia.co.in/Hotel-Search?" "destination=Central+Tokyo,+Tokyo+Prefecture&" "startDate=2026-06-01&endDate=2026-06-07&" "rooms=1&adults=2&children=2&childrenAges=5,7") ``` **Note:** `childrenAges` in the URL may not always populate the age dropdowns on the results page. Verify with a screenshot and set them via JS if needed. --- ## Date Picker — DO NOT USE The calendar widget is extremely unreliable with coordinate-based clicks: - Clicking a date cell frequently **closes the entire picker** instead of selecting the date. - The picker has month-navigation arrows that are tiny targets. - "Flexible dates" mode has a different DOM structure with pill-shaped month selectors that also mis-fire. - Dozens of retry attempts across multiple strategies all failed. **Workaround:** Always pass dates via URL parameters (`startDate`, `endDate`). --- ## Travellers Widget The travellers stepper panel works with JS `.click()` on the increment/decrement buttons. ### Opening the panel ```python js(""" (()=>{ let btn = document.querySelector('button[data-testid="travelers-field-trigger"]') || [...document.querySelectorAll('button')].find(b => b.textContent.includes('traveller')); if(btn){ btn.click(); return 'opened'; } return 'not found'; })() """) ``` ### Incrementing children count ```python js(""" (()=>{ let span = [...document.querySelectorAll('span')].find(s => s.textContent.trim() === 'Children'); if(!span) return 'no Children label'; let container = span.closest('div').parentElement; let buttons = container.querySelectorAll('button'); let plus = buttons[buttons.length - 1]; // last button is "+" plus.click(); return 'incremented'; })() """) ``` ### Setting child ages Child age dropdowns are `