defmodule AprsmeWeb.HistoricalLoadingIntegrationTest do @moduledoc """ Integration tests for historical packet loading using Wallaby Tests the complete user experience including initial page load behavior """ use ExUnit.Case, async: false use Wallaby.Feature import Aprsme.PacketsFixtures import Wallaby.Browser import Wallaby.Query alias Aprsme.Repo alias Ecto.Adapters.SQL.Sandbox setup do :ok = Sandbox.checkout(Repo) # Use shared mode for Wallaby tests Sandbox.mode(Repo, {:shared, self()}) # Use real Packets module for integration tests Application.put_env(:aprsme, :packets_module, Aprsme.Packets) on_exit(fn -> # Restore mock for other tests Application.put_env(:aprsme, :packets_module, Aprsme.PacketsMock) end) {:ok, %{}} end describe "historical packet loading on page load" do @describetag :integration @describetag timeout: 60_000 feature "displays historical packets immediately after map loads", %{session: session} do # Create test packets with known positions # Make sure they're recent enough to be loaded now = DateTime.utc_now() packet1 = packet_fixture(%{ sender: "INTTEST1", base_callsign: "INTTEST1", ssid: "0", lat: Decimal.new("40.7128"), lon: Decimal.new("-74.0060"), received_at: DateTime.add(now, -20 * 60, :second), comment: "Integration test station 1", symbol_code: "k", symbol_table_id: "/", has_position: true, data_type: "position" }) packet2 = packet_fixture(%{ sender: "INTTEST2", base_callsign: "INTTEST2", ssid: "0", lat: Decimal.new("40.7580"), lon: Decimal.new("-73.9855"), received_at: DateTime.add(now, -10 * 60, :second), comment: "Integration test station 2", symbol_code: "-", symbol_table_id: "/", has_position: true, data_type: "position" }) # Debug: Verify packets were created IO.puts("Created packets: #{inspect([packet1.id, packet2.id])}") # Navigate to the map with the test location in view # Center on New York area where our test packets are located session |> visit("/?lat=40.735&lon=-73.996&zoom=11") |> assert_has(css("#aprs-map")) # Wait for map container to be present assert_has(session, css(".leaflet-container")) # Wait for map to fully initialize Process.sleep(2000) # Execute script to check map state and manually trigger historical loading execute_script(session, """ // Check if map is initialized if (!window.aprsMap || !window.aprsMap.map) { console.error('Map not initialized'); return false; } // Get the LiveView hook const mapElement = document.getElementById('aprs-map'); if (!mapElement || !mapElement.__hook__) { console.error('Map hook not found'); return false; } // Manually push a bounds_changed event mapElement.__hook__.pushEvent('bounds_changed', { north: 40.9, south: 40.6, east: -73.8, west: -74.2, zoom: 11 }); return true; """) # Wait for packets to load and render Process.sleep(5000) # Try to find markers with a more specific selector # Leaflet markers have specific classes markers = all(session, css(".leaflet-marker-icon")) marker_count = length(markers) if marker_count == 0 do # Take screenshot for debugging take_screenshot(session, name: "no_markers_found") # Check if there are any error messages page_text = Wallaby.Browser.text(session) IO.puts("Page text: #{page_text}") end # Check that markers are present on the map assert marker_count > 0, "Expected to find markers on the map, but found #{marker_count}" # Verify at least 2 markers are present (our test packets) marker_count = session |> all(css(".leaflet-marker-icon")) |> length() assert marker_count >= 2, "Expected at least 2 markers, found #{marker_count}" # Click on a marker to verify it's one of our test packets click(session, css(".leaflet-marker-icon", at: 0)) # Wait for popup to appear Process.sleep(1000) # Verify popup contains one of our test callsigns assert_has(session, css(".leaflet-popup-content", text: ~r/INTTEST[12]/)) end feature "loads packets within specified historical time range", %{session: session} do now = DateTime.utc_now() # Create packets at different times _old_packet = packet_fixture(%{ sender: "OLDTEST", base_callsign: "OLDTEST", ssid: "0", lat: 40.7128, lon: -74.0060, # 3 hours ago received_at: DateTime.add(now, -3 * 60 * 60, :second), comment: "Old packet - should not appear with hist=1" }) _recent_packet = packet_fixture(%{ sender: "RECENTTEST", base_callsign: "RECENTTEST", ssid: "0", lat: 40.7128, lon: -74.0060, # 30 minutes ago received_at: DateTime.add(now, -30 * 60, :second), comment: "Recent packet - should appear" }) # Navigate to map with 1 hour historical range (default) session |> visit("/?hist=1&lat=39.8283&lon=-98.5795&zoom=6") |> assert_has(css("#aprs-map")) # Wait for historical loading Process.sleep(3000) # Click on the marker (should be the recent one) click(session, css(".leaflet-marker-icon", at: 0)) Process.sleep(1000) # Verify it's the recent packet, not the old one assert_has(session, css(".leaflet-popup-content", text: "RECENTTEST")) refute_has(session, css(".leaflet-popup-content", text: "OLDTEST")) # Now test with extended historical range session # 6 hours |> visit("/?hist=6&lat=39.8283&lon=-98.5795&zoom=6") |> assert_has(css("#aprs-map")) Process.sleep(3000) # Now both packets should be visible marker_count = session |> all(css(".leaflet-marker-icon")) |> length() assert marker_count >= 2, "Expected at least 2 markers with 6-hour range" end feature "updates historical packets when bounds change", %{session: session} do now = DateTime.utc_now() # Create packets in different locations _nyc_packet = packet_fixture(%{ sender: "NYC1", base_callsign: "NYC1", ssid: "0", lat: 40.7128, lon: -74.0060, received_at: DateTime.add(now, -30 * 60, :second), comment: "NYC packet" }) _la_packet = packet_fixture(%{ sender: "LA1", base_callsign: "LA1", ssid: "0", lat: 34.0522, lon: -118.2437, received_at: DateTime.add(now, -30 * 60, :second), comment: "LA packet" }) # Start focused on NYC session |> visit("/?lat=40.7128&lng=-74.0060&z=10") |> assert_has(css("#aprs-map")) Process.sleep(3000) # Should see NYC packet click(session, css(".leaflet-marker-icon", at: 0)) Process.sleep(1000) assert_has(session, css(".leaflet-popup-content", text: "NYC1")) # Close popup send_keys(session, [:escape]) # Pan to LA (this would be done via map interaction in real usage) # For testing, we'll navigate to new URL visit(session, "/?lat=34.0522&lng=-118.2437&z=10") Process.sleep(3000) # Should now see LA packet instead click(session, css(".leaflet-marker-icon", at: 0)) Process.sleep(1000) assert_has(session, css(".leaflet-popup-content", text: "LA1")) end end describe "historical loading with tracked callsigns" do @describetag :integration feature "loads all packets for tracked callsign regardless of bounds", %{session: session} do now = DateTime.utc_now() # Create packets for tracked station at different locations _packet1 = packet_fixture(%{ sender: "TRACK1-9", base_callsign: "TRACK1", ssid: "9", lat: 40.7128, lon: -74.0060, received_at: DateTime.add(now, -45 * 60, :second), comment: "NYC position" }) _packet2 = packet_fixture(%{ sender: "TRACK1-9", base_callsign: "TRACK1", ssid: "9", lat: 41.8781, lon: -87.6298, received_at: DateTime.add(now, -30 * 60, :second), comment: "Chicago position" }) _packet3 = packet_fixture(%{ sender: "TRACK1-9", base_callsign: "TRACK1", ssid: "9", lat: 34.0522, lon: -118.2437, received_at: DateTime.add(now, -15 * 60, :second), comment: "LA position" }) # Navigate to tracked callsign URL session |> visit("/TRACK1-9?lat=39.8283&lon=-98.5795&zoom=4") |> assert_has(css("#aprs-map")) # Wait for map to load and center on latest position Process.sleep(3000) # Should see trail connecting all positions # Verify we have markers (latest position + trail points) marker_count = session |> all(css(".leaflet-marker-icon")) |> length() # Should have at least 1 marker for current position assert marker_count >= 1, "Expected markers for tracked station" # Verify polyline trail exists assert_has(session, css(".leaflet-pane .leaflet-overlay-pane polyline")) end end end