On this page6 sections

Travel & Booking QA

Seat selection, availability calendars, dynamic pricing, and booking race conditions.

// OVERVIEW

Every booking is a time-locked promise. Time-zones make the 'when' uncertain, concurrent holds make the 'what' uncertain, and supplier integration lag can make both wrong simultaneously — after the customer has already paid.

// What makes Travel & Booking QA different

  • All availability is timezone-sensitive: a booking date is only correct relative to the departure timezone, not the user's browser timezone — a flight at 00:30 local time looks like the previous calendar day in UTC
  • Availability is a transient held-and-expiring lock, not a permanent stock decrement: a seat is held for a short checkout window; if payment does not complete before the hold expires, the seat is released back to inventory
  • Double-booking under concurrency: two sessions can hold the last available seat simultaneously, both proceed through checkout, and both receive a booking confirmation before the collision is detected
  • Cancellation cutoff math is calculated against departure-local time, not server UTC — DST crossings mean a straightforward time-subtraction can produce the wrong refund eligibility decision
  • Supplier availability is a cached snapshot: the live availability at the GDS can differ from the cached state shown to the user, causing confirmed bookings to be made against inventory that is no longer available

// Core user journeys

JourneyWhat to cover
Search, hold, and confirmSearch availability, select a seat, enter the hold, complete checkout and payment, and receive a booking confirmation with the correct departure date and timezone
Cancellation within refund windowCancel a booking with more than the policy-defined time remaining before departure; assert refund eligibility is calculated against departure-local time and the correct amount is returned
Booking modificationChange the departure date or seat on an existing booking; assert the original hold is released, the new hold is created, and any price difference is correctly applied
Seat selection and upgradeSelect a specific seat from the seat map; assert the seat is held for the authenticated user and not available to a concurrent session during the hold period
Supplier availability check and mismatch handlingTrigger a live availability query against the supplier API; assert that a mismatch between cached and live state is surfaced to the user before payment, not after confirmation

// RISKS & TEST AREAS

// Main risk areas

RiskWhy it matters
Double-booking last seat under concurrencyTwo concurrent sessions both hold the same last available seat and both complete checkout before the collision is detected; both receive PNR confirmations for a single physical seat
Timezone date shift in confirmationA flight at 00:30 local departure time booked from a browser in UTC+9 records the booking date in UTC, shifting it to the previous calendar day; the confirmation email shows the wrong departure date
Hold-expiry gapA user's payment takes 65 seconds on a 60-second hold; the hold expires and the seat is released and re-assigned at 60 seconds; the payment captures at 65 seconds but no booking is created because the seat is gone
Cancellation cutoff miscalculationPolicy is expressed as '24 hours before departure in local departure time', but the system calculates the cutoff in server UTC; a customer who cancels within the refund window in local time may be incorrectly denied a refund
DST breaks flight duration displayA flight crossing a daylight-saving spring-forward boundary is displayed as 1 hour instead of 2 hours; the scheduled block time is correct but the wall-clock duration calculation uses the incorrect timezone offset

// Functional areas to test

  • Availability search and calendar: seat availability, date-range search, and price display across timezones
  • Seat hold and expiry: transient lock creation, hold-window countdown, expiry release, and hold extension on payment retry
  • Checkout and payment: multi-step form, payment capture within the hold window, and booking creation on payment success
  • Cancellation and refund: cutoff calculation in departure-local time, refund amount calculation, and refund status updates
  • Supplier API sync: cached availability vs live GDS state, mismatch detection before payment, and fallback messaging
  • Timezone-aware date display: departure date, arrival date, and layover duration all expressed in the correct local timezone

// API & integration areas

  • GDS/supplier availability API: assert cached inventory is refreshed before checkout confirmation and that stale cache state is never the basis for a final booking
  • PNR and booking confirmation generation: assert the booking reference is created atomically with payment capture and that duplicate references are not generated under concurrent requests
  • Cancellation and refund endpoint: assert refund eligibility is computed in departure-local time and that the refund amount matches the policy at the cancellation timestamp
  • Booking-status webhook from supplier: assert status updates (e.g. airline cancellation) are reflected in the local booking state and that conflicting states are resolved deterministically
  • Hold-expiry callback: assert that when a hold expires the seat is released back to available inventory immediately and is bookable by the next session

// Data testing

  • Seed availability data spanning DST transition dates in multiple departure timezones — specifically spring-forward and fall-back boundary dates with departures near midnight
  • Seed inventory with exactly one seat remaining for concurrency tests; reset after each test run to avoid state bleed between scenarios
  • Seed bookings with cancellation deadlines that fall within 30 minutes of a DST transition to test edge-case cutoff calculations
  • Use a supplier sandbox or mock GDS for all availability tests; never run booking tests against live supplier inventory

// CROSS-CUTTING CONCERNS

// Security & privacy

  • PNR and booking reference entropy: references must not be sequentially guessable — assert that iterating adjacent IDs does not return other users' booking details
  • Passenger personal data (passport number, date of birth, full name) must not appear in application logs, error messages, or analytics payloads
  • Payment data is PCI-scoped: card numbers must never be stored or logged; assert payment capture uses tokenisation or a provider-hosted redirect
  • Booking modification must verify authenticated ownership: assert a user cannot modify or cancel another user's booking via a direct API call with a known booking reference

// Accessibility

  • WCAG AA contrast and keyboard navigation on date picker components and seat selection maps, including focus management when a seat is selected or becomes unavailable
  • Full keyboard navigation through the multi-step booking flow: search → seat selection → passenger details → payment → confirmation
  • Screen reader on dynamic seat-availability updates: when a seat becomes unavailable during the hold period, assert the change is announced via an ARIA live region

// Performance

  • Availability search under concurrent load: simulate peak travel-season traffic patterns and assert search response latency stays within the defined SLA
  • Seat-hold expiry release: assert the seat becomes bookable by the next session within the defined window after the hold expires, measured under concurrent load
  • GDS latency graceful degradation: when the supplier API response exceeds the timeout threshold, assert the user sees a clear availability-check message, not a blank page or unhandled error

// Mobile & responsive

  • Mobile booking at 375 px: date pickers, seat maps, and multi-step form fields must be touch-usable with correct tap-target sizes across all booking steps
  • Push notification for supplier booking status change: assert the notification is delivered and correctly identifies the booking when the supplier confirms or rejects a pending booking

// BUGS & SCENARIOS

// Common bugs

BugScenario / repro
Double-booking last seatTwo concurrent browser sessions both hold the last available seat and both complete checkout; both receive booking confirmation emails with valid PNRs; the airline check-in system sees two PNRs assigned to one physical seat
Timezone date shift in confirmationUser in UTC+9 books a flight departing at 00:30 local airport time; the system stores the booking date in UTC (the previous calendar day); the confirmation email shows the wrong departure date, causing the passenger to arrive a day late
Hold-expiry gapUser's payment takes 65 seconds on a 60-second seat hold; the hold expires and the seat is released at 60 seconds; the payment provider captures at 65 seconds but no booking is created because the seat has already been re-assigned to another session
DST flight duration displayA flight departs at 01:30 on the morning clocks spring forward; the displayed duration is 2 hours (scheduled block time) but the actual wall-clock difference is 1 hour because the destination timezone moved forward during the flight
Cancellation refund miscalculationPolicy grants a full refund if cancelled more than 24 hours before departure in local departure time; system calculates the cutoff in server UTC; customer cancels when 23 hours remain in local time but 25 hours remain in UTC; system incorrectly grants a full refund

// Example test scenarios

  1. 01Open two browser sessions simultaneously; both select the last available seat and proceed through checkout; complete both payment flows — assert exactly one booking is confirmed and the other receives a seat-unavailable error
  2. 02Book a flight departing at 00:30 local airport time from a browser configured to UTC+9 — assert the confirmation email shows the correct local departure date, not the UTC date which is one calendar day earlier
  3. 03Complete checkout after the seat hold has expired using a test-mode short TTL — assert no payment is captured and the user receives a clear hold-expired message with an option to restart
  4. 04Search for a flight crossing a DST spring-forward boundary — assert the displayed flight duration matches the actual wall-clock difference between departure and arrival, not the scheduled block time
  5. 05Book a cancellable ticket; cancel at a point where 23 hours remain in local departure time (server UTC shows 25 hours) — assert refund eligibility uses departure-local time and the full refund is correctly denied per policy

// Edge cases

  • Airline cancels the flight after the user has completed checkout: the local booking stays 'confirmed' while the supplier marks it cancelled — assert the user receives a proactive notification and the booking state reflects the supplier update within the defined SLA
  • Booking created at exactly the cancellation cutoff boundary: assert refund eligibility is deterministic and does not flip based on millisecond timing differences between the cancellation request and the cutoff calculation
  • Multi-segment journey with legs crossing timezone boundaries: assert layover duration is expressed as clock time at the layover location, not as the arithmetic difference of two UTC timestamps
  • Availability search at midnight on a DST transition date: the datetime range spanning the clock change must not produce a zero-length or negative-length window that returns no results
  • Booking modification while hold expires: user initiates a seat change and the new hold expires during the modification form — assert the original booking is preserved intact and not cancelled

// AUTOMATION & TOOLS

// What to automate

  • Concurrent last-seat test: fire two simultaneous hold requests and checkout attempts for the same single-seat inventory; assert exactly one booking is confirmed and one receives a seat-unavailable error
  • Timezone parametrised matrix: book the same departure from N browser timezone configurations against M departure timezones; assert the confirmation date always uses departure-local time, not server UTC
  • DST date matrix: seed bookings spanning spring-forward and fall-back boundary dates in multiple departure timezones; assert duration calculation and cancellation cutoff are correct on all boundary dates
  • Hold-expiry test: create a hold with a test-mode short TTL; assert the seat becomes bookable again immediately after expiry and that no booking is created if payment arrives after the TTL

// SHIP & LEARN

// Release readiness checklist

  • Double-booking concurrency suite passes: only one booking is confirmed when two sessions compete for the last available seat
  • Timezone date display correct in all confirmation paths: departure date always expressed in departure-local time, not server UTC
  • Hold-expiry handled correctly: no payment is captured and no booking is created if payment arrives after the hold has expired
  • DST duration calculation correct on spring-forward and fall-back boundary dates across all departure timezones in scope
  • Cancellation cutoff uses departure-local time in all calculation paths: UTC-only calculation is blocked in code review and test
  • GDS degraded-mode tested: slow or unavailable supplier returns a clear user message within the defined timeout, not a blank page or unhandled error
  • Mobile booking flow validated at 375 px viewport: date pickers, seat maps, and payment form all usable with touch