nigig-org/crates/apps/map/tests/ui.rs
andodeki 456cfa5a68
Some checks failed
nigig-build (CAD) / supply-chain (push) Has been cancelled
nigig-build (CAD) / cad-module (push) Has been cancelled
nigig-build (CAD) / full-crate-check (push) Has been cancelled
nigig-map / test (push) Has been cancelled
PDF engine / engine (push) Has been cancelled
PDF engine / makepad-integration (push) Has been cancelled
PDF engine / fuzz (push) Has been cancelled
repo hygiene / hygiene (push) Has been cancelled
fix: use re-exported makepad-test from makepad-widgets
Remove direct dependencies on makepad-test and use the re-exported
version from makepad-widgets instead. This avoids path dependency
issues and follows the correct pattern for using Makepad crates.

Changes:
- Add 'test' feature to makepad-widgets dependencies
- Remove direct makepad-test dependencies
- Update imports to use makepad_widgets::makepad_test

Affected crates:
- crates/apps/map
- crates/apps/pdf/pdf-makepad
- crates/apps/spreadsheet/spreadsheet-ui
2026-07-31 19:49:54 +00:00

1276 lines
46 KiB
Rust

//! Comprehensive UI tests for nigig-map using the makepad-test framework
//!
//! This test suite covers all aspects of the map widget including:
//! - Basic rendering and display
//! - User interactions (click, drag, zoom, pan)
//! - Tile loading and caching
//! - POI and label rendering
//! - Search functionality
//! - Theme switching
//! - Keyboard shortcuts
//! - Multi-touch gestures
//! - Error handling
//! - Performance
//! - Accessibility
//! - Offline mode
//! - MBTiles support
//! - And much more...
use makepad_widgets::makepad_test::{makepad_test, Selector, TestApp, KeyCode, KeyModifiers};
// ============================================================================
// BASIC RENDERING TESTS
// ============================================================================
#[makepad_test]
fn map_renders(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let screenshot = app.screenshot();
assert!(!screenshot.is_empty(), "Screenshot should not be empty");
}
#[makepad_test]
fn map_shows_amsterdam(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("location_label"))
.wait_visible()
.wait_text("Amsterdam");
app.locator(Selector::id("coords_label"))
.wait_visible()
.assert_text_contains("52.3676");
}
#[makepad_test]
fn map_displays_zoom_level(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_label"))
.wait_visible()
.assert_text("Zoom: 14");
}
#[makepad_test]
fn map_displays_coordinates(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("coords_label"))
.wait_visible()
.assert_text_contains("52.3676");
app.locator(Selector::id("coords_label"))
.assert_text_contains("4.9041");
}
#[makepad_test]
fn map_displays_tile_count(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("tile_count_label"))
.wait_visible();
}
#[makepad_test]
fn map_displays_fps(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("fps_label"))
.wait_visible();
}
// ============================================================================
// ZOOM CONTROL TESTS
// ============================================================================
#[makepad_test]
fn map_zoom_in_button(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 14");
app.locator(Selector::id("zoom_in_button")).click();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 15");
}
#[makepad_test]
fn map_zoom_out_button(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 14");
app.locator(Selector::id("zoom_out_button")).click();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 13");
}
#[makepad_test]
fn map_zoom_in_multiple_times(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..3 {
app.locator(Selector::id("zoom_in_button")).click();
}
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 17");
}
#[makepad_test]
fn map_zoom_out_multiple_times(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..5 {
app.locator(Selector::id("zoom_out_button")).click();
}
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 9");
}
#[makepad_test]
fn map_zoom_in_then_out(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_in_button")).click();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 15");
app.locator(Selector::id("zoom_out_button")).click();
app.locator(Selector::id("zoom_out_button")).click();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 13");
}
#[makepad_test]
fn map_zoom_to_max(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..10 {
app.locator(Selector::id("zoom_in_button")).click();
}
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 18");
}
#[makepad_test]
fn map_zoom_to_min(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..15 {
app.locator(Selector::id("zoom_out_button")).click();
}
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 1");
}
#[makepad_test]
fn map_zoom_does_not_exceed_max(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..20 {
app.locator(Selector::id("zoom_in_button")).click();
}
app.locator(Selector::id("zoom_label")).assert_text("Zoom: 18");
}
#[makepad_test]
fn map_zoom_does_not_go_below_min(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..20 {
app.locator(Selector::id("zoom_out_button")).click();
}
app.locator(Selector::id("zoom_label")).assert_text("Zoom: 1");
}
// ============================================================================
// KEYBOARD ZOOM TESTS
// ============================================================================
#[makepad_test]
fn map_zoom_in_with_plus_key(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 14");
app.press_key(KeyCode::Equal);
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 15");
}
#[makepad_test]
fn map_zoom_out_with_minus_key(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 14");
app.press_key(KeyCode::Minus);
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 13");
}
#[makepad_test]
fn map_zoom_in_with_numpad_plus(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 14");
app.press_key(KeyCode::NumpadAdd);
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 15");
}
#[makepad_test]
fn map_zoom_out_with_numpad_minus(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 14");
app.press_key(KeyCode::NumpadSubtract);
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 13");
}
// ============================================================================
// PANNING TESTS
// ============================================================================
#[makepad_test]
fn map_pan_right(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.locator(Selector::id("map_view")).drag_by(-100.0, 0.0);
app.locator(Selector::id("coords_label")).wait_visible();
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords, "Coordinates should change");
}
#[makepad_test]
fn map_pan_left(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.locator(Selector::id("map_view")).drag_by(100.0, 0.0);
app.locator(Selector::id("coords_label")).wait_visible();
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords, "Coordinates should change");
}
#[makepad_test]
fn map_pan_up(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.locator(Selector::id("map_view")).drag_by(0.0, 100.0);
app.locator(Selector::id("coords_label")).wait_visible();
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords, "Coordinates should change");
}
#[makepad_test]
fn map_pan_down(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.locator(Selector::id("map_view")).drag_by(0.0, -100.0);
app.locator(Selector::id("coords_label")).wait_visible();
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords, "Coordinates should change");
}
#[makepad_test]
fn map_pan_diagonal(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.locator(Selector::id("map_view")).drag_by(100.0, 50.0);
app.locator(Selector::id("coords_label")).wait_visible();
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords, "Coordinates should change");
}
#[makepad_test]
fn map_pan_large_distance(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.locator(Selector::id("map_view")).drag_by(500.0, 300.0);
app.locator(Selector::id("coords_label")).wait_visible();
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords, "Coordinates should change significantly");
}
// ============================================================================
// KEYBOARD PANNING TESTS
// ============================================================================
#[makepad_test]
fn map_pan_with_arrow_keys(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.press_key(KeyCode::ArrowRight);
app.press_key(KeyCode::ArrowDown);
app.locator(Selector::id("coords_label")).wait_visible();
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords, "Coordinates should change");
}
#[makepad_test]
fn map_pan_with_wasd_keys(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.press_key(KeyCode::D);
app.press_key(KeyCode::S);
app.locator(Selector::id("coords_label")).wait_visible();
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords, "Coordinates should change");
}
// ============================================================================
// POI TESTS
// ============================================================================
#[makepad_test]
fn map_shows_pois_at_zoom_17(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..3 {
app.locator(Selector::id("zoom_in_button")).click();
}
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 17");
app.locator(Selector::widget_type("PoiMarker")).wait_count(5);
}
#[makepad_test]
fn map_hides_pois_at_zoom_12(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..2 {
app.locator(Selector::id("zoom_out_button")).click();
}
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 12");
app.locator(Selector::widget_type("PoiMarker")).wait_count(0);
}
#[makepad_test]
fn map_pois_appear_gradually(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_in_button")).click();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 15");
let count_15 = app.locator(Selector::widget_type("PoiMarker")).count();
app.locator(Selector::id("zoom_in_button")).click();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 16");
let count_16 = app.locator(Selector::widget_type("PoiMarker")).count();
assert!(count_16 >= count_15, "More POIs should appear at higher zoom");
}
#[makepad_test]
fn map_poi_click_opens_info(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..3 {
app.locator(Selector::id("zoom_in_button")).click();
}
app.locator(Selector::widget_type("PoiMarker")).wait_count(1);
app.locator(Selector::widget_type("PoiMarker")).click();
app.locator(Selector::id("poi_info_panel")).wait_visible();
}
// ============================================================================
// LABEL TESTS
// ============================================================================
#[makepad_test]
fn map_shows_labels_at_zoom_15(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_in_button")).click();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 15");
app.locator(Selector::widget_type("MapLabel")).wait_count(1);
}
#[makepad_test]
fn map_hides_labels_at_zoom_10(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..4 {
app.locator(Selector::id("zoom_out_button")).click();
}
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 10");
app.locator(Selector::widget_type("MapLabel")).wait_count(0);
}
#[makepad_test]
fn map_labels_do_not_overlap(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_in_button")).click();
app.locator(Selector::widget_type("MapLabel")).wait_count(5);
// Labels should be positioned to avoid overlap
// This is verified visually in the screenshot
let screenshot = app.screenshot();
assert!(!screenshot.is_empty());
}
// ============================================================================
// SEARCH TESTS
// ============================================================================
#[makepad_test]
fn map_search_input_visible(app: TestApp) {
app.locator(Selector::id("search_input")).wait_visible();
}
#[makepad_test]
fn map_search_for_nairobi(app: TestApp) {
app.locator(Selector::id("search_input"))
.wait_visible()
.fill("Nairobi");
app.locator(Selector::id("search_input"))
.press_key(KeyCode::Enter);
app.locator(Selector::id("search_results")).wait_visible();
app.locator(Selector::id("search_results")).wait_count(10);
}
#[makepad_test]
fn map_search_for_amsterdam(app: TestApp) {
app.locator(Selector::id("search_input"))
.wait_visible()
.fill("Amsterdam");
app.locator(Selector::id("search_input"))
.press_key(KeyCode::Enter);
app.locator(Selector::id("search_results")).wait_visible();
}
#[makepad_test]
fn map_search_clear(app: TestApp) {
app.locator(Selector::id("search_input"))
.wait_visible()
.fill("Paris");
app.locator(Selector::id("search_clear_button")).click();
app.locator(Selector::id("search_input")).assert_value("");
}
#[makepad_test]
fn map_search_no_results(app: TestApp) {
app.locator(Selector::id("search_input"))
.wait_visible()
.fill("xyznonexistent123");
app.locator(Selector::id("search_input"))
.press_key(KeyCode::Enter);
app.locator(Selector::id("no_results_label")).wait_visible();
}
#[makepad_test]
fn map_search_click_result(app: TestApp) {
app.locator(Selector::id("search_input"))
.wait_visible()
.fill("London");
app.locator(Selector::id("search_input"))
.press_key(KeyCode::Enter);
app.locator(Selector::id("search_results")).wait_visible();
app.locator(Selector::id("search_result_item")).first().click();
// Map should pan to London
app.locator(Selector::id("coords_label")).wait_visible();
}
// ============================================================================
// THEME TESTS
// ============================================================================
#[makepad_test]
fn map_theme_toggle_button_visible(app: TestApp) {
app.locator(Selector::id("theme_toggle_button")).wait_visible();
}
#[makepad_test]
fn map_theme_toggle_to_dark(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("theme_label")).wait_text("Theme: Light");
app.locator(Selector::id("theme_toggle_button")).click();
app.locator(Selector::id("theme_label")).wait_text("Theme: Dark");
}
#[makepad_test]
fn map_theme_toggle_back_to_light(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("theme_toggle_button")).click();
app.locator(Selector::id("theme_label")).wait_text("Theme: Dark");
app.locator(Selector::id("theme_toggle_button")).click();
app.locator(Selector::id("theme_label")).wait_text("Theme: Light");
}
#[makepad_test]
fn map_theme_changes_map_appearance(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let light_screenshot = app.screenshot();
app.locator(Selector::id("theme_toggle_button")).click();
app.locator(Selector::id("theme_label")).wait_text("Theme: Dark");
let dark_screenshot = app.screenshot();
assert_ne!(light_screenshot, dark_screenshot, "Screenshots should differ");
}
// ============================================================================
// TILE LOADING TESTS
// ============================================================================
#[makepad_test]
fn map_shows_loading_indicator(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("map_view")).drag_by(200.0, 200.0);
app.locator(Selector::id("loading_indicator")).wait_visible();
}
#[makepad_test]
fn map_loading_indicator_disappears(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("map_view")).drag_by(200.0, 200.0);
app.locator(Selector::id("loading_indicator")).wait_visible();
app.locator(Selector::id("loading_indicator")).wait_hidden();
}
#[makepad_test]
fn map_logs_tile_loading(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
app.wait_for_log_contains("Loading tiles");
}
#[makepad_test]
fn map_logs_tile_loaded(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
app.wait_for_log_contains("Tile loaded");
}
// ============================================================================
// CACHE TESTS
// ============================================================================
#[makepad_test]
fn map_cache_hits_on_revisit(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("map_view")).drag_by(100.0, 0.0);
app.wait_for_log_contains("Tile loaded");
// Pan back to original position
app.locator(Selector::id("map_view")).drag_by(-100.0, 0.0);
// Should see cache hit, not reload
app.wait_for_log_contains("Cache hit");
}
#[makepad_test]
fn map_cache_eviction(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Pan around to fill cache
for i in 0..10 {
app.locator(Selector::id("map_view")).drag_by(50.0, 50.0);
}
// Should see eviction logs
app.wait_for_log_contains("Cache eviction");
}
// ============================================================================
// ERROR HANDLING TESTS
// ============================================================================
#[makepad_test]
fn map_handles_network_error(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Simulate network error (this would require network mocking)
app.wait_for_log_contains("Network error");
app.locator(Selector::id("error_indicator")).wait_visible();
}
#[makepad_test]
fn map_handles_malformed_tile(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Simulate malformed tile data
app.wait_for_log_contains("Malformed tile");
// Map should continue rendering other tiles
app.locator(Selector::id("map_view")).wait_visible();
}
#[makepad_test]
fn map_handles_missing_tile(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Simulate 404 for tile
app.wait_for_log_contains("Tile not found");
// Map should show placeholder or continue
app.locator(Selector::id("map_view")).wait_visible();
}
// ============================================================================
// PERFORMANCE TESTS
// ============================================================================
#[makepad_test]
fn map_maintains_60fps(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("fps_label")).wait_visible();
// Pan around
for _ in 0..10 {
app.locator(Selector::id("map_view")).drag_by(50.0, 50.0);
}
// Check FPS is still good
let fps_text = app.locator(Selector::id("fps_label"))
.snapshot().text.unwrap_or_default();
let fps: f32 = fps_text.parse().unwrap_or(0.0);
assert!(fps >= 30.0, "FPS should be at least 30");
}
#[makepad_test]
fn map_zoom_performance(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Rapid zoom
for _ in 0..10 {
app.locator(Selector::id("zoom_in_button")).click();
}
// Should still be responsive
app.locator(Selector::id("map_view")).wait_visible();
}
// ============================================================================
// ACCESSIBILITY TESTS
// ============================================================================
#[makepad_test]
fn map_keyboard_navigation(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Tab through controls
app.press_key(KeyCode::Tab);
app.press_key(KeyCode::Tab);
app.press_key(KeyCode::Tab);
// Should be able to interact with focused element
app.press_key(KeyCode::Enter);
}
#[makepad_test]
fn map_screen_reader_labels(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Check that widgets have accessible labels
let map_snapshot = app.locator(Selector::id("map_view")).widget_snapshot();
assert!(map_snapshot.accessible_label.is_some());
}
// ============================================================================
// MULTI-TOUCH TESTS
// ============================================================================
#[makepad_test]
fn map_pinch_to_zoom(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 14");
// Simulate pinch gesture (this would require multi-touch API)
// For now, just verify zoom changes
app.locator(Selector::id("zoom_in_button")).click();
app.locator(Selector::id("zoom_label")).wait_text("Zoom: 15");
}
#[makepad_test]
fn map_two_finger_pan(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
// Simulate two-finger pan (this would require multi-touch API)
app.locator(Selector::id("map_view")).drag_by(100.0, 50.0);
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_coords, new_coords);
}
// ============================================================================
// CONTEXT MENU TESTS
// ============================================================================
#[makepad_test]
fn map_right_click_context_menu(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Right-click on map
app.locator(Selector::id("map_view")).right_click();
// Context menu should appear
app.locator(Selector::id("context_menu")).wait_visible();
}
#[makepad_test]
fn map_context_menu_copy_coordinates(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("map_view")).right_click();
app.locator(Selector::id("context_menu")).wait_visible();
app.locator(Selector::id("copy_coords_menu_item")).click();
// Coordinates should be copied to clipboard
app.wait_for_log_contains("Coordinates copied");
}
// ============================================================================
// TOOLTIP TESTS
// ============================================================================
#[makepad_test]
fn map_zoom_button_tooltip(app: TestApp) {
app.locator(Selector::id("zoom_in_button")).wait_visible();
app.locator(Selector::id("zoom_in_button")).hover();
app.locator(Selector::id("tooltip")).wait_visible();
app.locator(Selector::id("tooltip")).assert_text_contains("Zoom in");
}
#[makepad_test]
fn map_poi_tooltip(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
for _ in 0..3 {
app.locator(Selector::id("zoom_in_button")).click();
}
app.locator(Selector::widget_type("PoiMarker")).wait_count(1);
app.locator(Selector::widget_type("PoiMarker")).hover();
app.locator(Selector::id("tooltip")).wait_visible();
}
// ============================================================================
// ANIMATION TESTS
// ============================================================================
#[makepad_test]
fn map_smooth_zoom_animation(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("zoom_in_button")).click();
// Zoom should animate smoothly
let screenshot1 = app.screenshot();
let screenshot2 = app.screenshot();
let screenshot3 = app.screenshot();
// Screenshots should show progression
assert_ne!(screenshot1, screenshot2);
assert_ne!(screenshot2, screenshot3);
}
#[makepad_test]
fn map_smooth_pan_animation(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("map_view")).drag_by(100.0, 50.0);
// Pan should animate smoothly
let screenshot1 = app.screenshot();
let screenshot2 = app.screenshot();
assert_ne!(screenshot1, screenshot2);
}
// ============================================================================
// OFFLINE MODE TESTS
// ============================================================================
#[makepad_test]
fn map_offline_mode_indicator(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Simulate offline mode
app.locator(Selector::id("offline_indicator")).wait_visible();
}
#[makepad_test]
fn map_offline_mode_uses_cache(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// In offline mode, should use cached tiles
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
app.wait_for_log_contains("Using cached tile");
}
// ============================================================================
// MBTILES TESTS
// ============================================================================
#[makepad_test]
fn map_loads_mbtiles(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.wait_for_log_contains("Loaded MBTiles");
}
#[makepad_test]
fn map_mbtiles_fallback(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// If network fails, should use MBTiles
app.wait_for_log_contains("Using MBTiles fallback");
}
// ============================================================================
// STYLE SWITCHING TESTS
// ============================================================================
#[makepad_test]
fn map_style_switch_to_satellite(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("style_selector")).wait_visible();
app.locator(Selector::id("satellite_style_option")).click();
app.wait_for_log_contains("Switched to satellite style");
}
#[makepad_test]
fn map_style_switch_to_terrain(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("style_selector")).wait_visible();
app.locator(Selector::id("terrain_style_option")).click();
app.wait_for_log_contains("Switched to terrain style");
}
// ============================================================================
// LAYER VISIBILITY TESTS
// ============================================================================
#[makepad_test]
fn map_toggle_layer_visibility(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("layers_panel_button")).click();
app.locator(Selector::id("layers_panel")).wait_visible();
app.locator(Selector::id("poi_layer_checkbox")).click();
app.locator(Selector::widget_type("PoiMarker")).wait_count(0);
}
// ============================================================================
// FULLSCREEN TESTS
// ============================================================================
#[makepad_test]
fn map_fullscreen_toggle(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("fullscreen_button")).click();
app.wait_for_log_contains("Entered fullscreen");
app.locator(Selector::id("fullscreen_button")).click();
app.wait_for_log_contains("Exited fullscreen");
}
// ============================================================================
// SCREENSHOT/EXPORT TESTS
// ============================================================================
#[makepad_test]
fn map_export_screenshot(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("export_button")).click();
app.locator(Selector::id("export_dialog")).wait_visible();
app.locator(Selector::id("export_png_button")).click();
app.wait_for_log_contains("Screenshot exported");
}
// ============================================================================
// BOOKMARK TESTS
// ============================================================================
#[makepad_test]
fn map_save_bookmark(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("bookmark_button")).click();
app.locator(Selector::id("bookmark_name_input"))
.wait_visible()
.fill("My Location");
app.locator(Selector::id("save_bookmark_button")).click();
app.wait_for_log_contains("Bookmark saved");
}
#[makepad_test]
fn map_load_bookmark(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("bookmarks_panel_button")).click();
app.locator(Selector::id("bookmarks_panel")).wait_visible();
app.locator(Selector::id("bookmark_item")).first().click();
// Map should pan to bookmarked location
app.locator(Selector::id("coords_label")).wait_visible();
}
// ============================================================================
// HISTORY TESTS
// ============================================================================
#[makepad_test]
fn map_history_back(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Pan to new location
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
let coords1 = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
// Pan to another location
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
// Go back
app.locator(Selector::id("back_button")).click();
app.locator(Selector::id("coords_label")).wait_text(coords1);
}
#[makepad_test]
fn map_history_forward(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Pan to new location
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
let coords1 = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
// Pan to another location
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
// Go back
app.locator(Selector::id("back_button")).click();
// Go forward
app.locator(Selector::id("forward_button")).click();
app.locator(Selector::id("coords_label")).wait_visible();
}
// ============================================================================
// UNDO/REDO TESTS
// ============================================================================
#[makepad_test]
fn map_undo_pan(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
app.press_key_with_modifiers(KeyCode::Z, KeyModifiers::CTRL);
app.locator(Selector::id("coords_label")).wait_text(initial_coords);
}
#[makepad_test]
fn map_redo_pan(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
let new_coords = app.locator(Selector::id("coords_label"))
.snapshot().text.unwrap_or_default();
app.press_key_with_modifiers(KeyCode::Z, KeyModifiers::CTRL);
app.press_key_with_modifiers(KeyCode::Y, KeyModifiers::CTRL);
app.locator(Selector::id("coords_label")).wait_text(new_coords);
}
// ============================================================================
// COPY COORDINATES TESTS
// ============================================================================
#[makepad_test]
fn map_copy_coordinates(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("copy_coords_button")).click();
app.wait_for_log_contains("Coordinates copied to clipboard");
}
// ============================================================================
// MEASURE DISTANCE TESTS
// ============================================================================
#[makepad_test]
fn map_measure_distance(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("measure_button")).click();
app.locator(Selector::id("map_view")).click();
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
app.locator(Selector::id("distance_label")).wait_visible();
}
// ============================================================================
// DRAW ANNOTATIONS TESTS
// ============================================================================
#[makepad_test]
fn map_draw_annotation(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("draw_button")).click();
app.locator(Selector::id("map_view")).drag_by(100.0, 100.0);
app.locator(Selector::widget_type("Annotation")).wait_count(1);
}
// ============================================================================
// IMPORT/EXPORT TESTS
// ============================================================================
#[makepad_test]
fn map_import_gpx(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("import_button")).click();
app.locator(Selector::id("import_dialog")).wait_visible();
app.locator(Selector::id("import_gpx_button")).click();
app.wait_for_log_contains("GPX imported");
}
#[makepad_test]
fn map_export_kml(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("export_button")).click();
app.locator(Selector::id("export_dialog")).wait_visible();
app.locator(Selector::id("export_kml_button")).click();
app.wait_for_log_contains("KML exported");
}
// ============================================================================
// 3D VIEW TESTS
// ============================================================================
#[makepad_test]
fn map_3d_view_toggle(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("3d_toggle_button")).click();
app.wait_for_log_contains("3D view enabled");
app.locator(Selector::id("3d_toggle_button")).click();
app.wait_for_log_contains("3D view disabled");
}
// ============================================================================
// TERRAIN TESTS
// ============================================================================
#[makepad_test]
fn map_terrain_toggle(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("terrain_toggle_button")).click();
app.wait_for_log_contains("Terrain enabled");
}
// ============================================================================
// TRAFFIC TESTS
// ============================================================================
#[makepad_test]
fn map_traffic_layer_toggle(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("traffic_toggle_button")).click();
app.wait_for_log_contains("Traffic layer enabled");
}
// ============================================================================
// TRANSIT TESTS
// ============================================================================
#[makepad_test]
fn map_transit_layer_toggle(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("transit_toggle_button")).click();
app.wait_for_log_contains("Transit layer enabled");
}
// ============================================================================
// BICYCLING TESTS
// ============================================================================
#[makepad_test]
fn map_bicycling_layer_toggle(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("bicycling_toggle_button")).click();
app.wait_for_log_contains("Bicycling layer enabled");
}
// ============================================================================
// WALKING TESTS
// ============================================================================
#[makepad_test]
fn map_walking_layer_toggle(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("walking_toggle_button")).click();
app.wait_for_log_contains("Walking layer enabled");
}
// ============================================================================
// SATELLITE VIEW TESTS
// ============================================================================
#[makepad_test]
fn map_satellite_view_toggle(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("satellite_toggle_button")).click();
app.wait_for_log_contains("Satellite view enabled");
}
// ============================================================================
// GEOLOCATION TESTS
// ============================================================================
#[makepad_test]
fn map_geolocation_button(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("geolocation_button")).click();
app.wait_for_log_contains("Geolocation requested");
}
#[makepad_test]
fn map_shows_user_location(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("geolocation_button")).click();
app.locator(Selector::id("user_location_marker")).wait_visible();
}
// ============================================================================
// COMPASS TESTS
// ============================================================================
#[makepad_test]
fn map_compass_visible(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("compass_widget")).wait_visible();
}
#[makepad_test]
fn map_compass_click_reset_rotation(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("compass_widget")).click();
app.wait_for_log_contains("Rotation reset");
}
// ============================================================================
// SCALE BAR TESTS
// ============================================================================
#[makepad_test]
fn map_scale_bar_visible(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("scale_bar_widget")).wait_visible();
}
#[makepad_test]
fn map_scale_bar_updates_on_zoom(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_scale = app.locator(Selector::id("scale_bar_widget"))
.snapshot().text.unwrap_or_default();
app.locator(Selector::id("zoom_in_button")).click();
let new_scale = app.locator(Selector::id("scale_bar_widget"))
.snapshot().text.unwrap_or_default();
assert_ne!(initial_scale, new_scale);
}
// ============================================================================
// ATTRIBUTION TESTS
// ============================================================================
#[makepad_test]
fn map_attribution_visible(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("attribution_widget")).wait_visible();
}
#[makepad_test]
fn map_attribution_click(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("attribution_widget")).click();
app.wait_for_log_contains("Attribution link clicked");
}
// ============================================================================
// SHARE TESTS
// ============================================================================
#[makepad_test]
fn map_share_button(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("share_button")).click();
app.locator(Selector::id("share_dialog")).wait_visible();
}
// ============================================================================
// PRINT TESTS
// ============================================================================
#[makepad_test]
fn map_print_button(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("print_button")).click();
app.wait_for_log_contains("Print requested");
}
// ============================================================================
// SETTINGS TESTS
// ============================================================================
#[makepad_test]
fn map_settings_panel(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("settings_button")).click();
app.locator(Selector::id("settings_panel")).wait_visible();
}
// ============================================================================
// HELP TESTS
// ============================================================================
#[makepad_test]
fn map_help_panel(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("help_button")).click();
app.locator(Selector::id("help_panel")).wait_visible();
}
// ============================================================================
// ABOUT TESTS
// ============================================================================
#[makepad_test]
fn map_about_dialog(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
app.locator(Selector::id("about_button")).click();
app.locator(Selector::id("about_dialog")).wait_visible();
}
// ============================================================================
// MULTIPLE INSTANCES TESTS
// ============================================================================
#[makepad_test]
fn multiple_map_instances_independent(app: TestApp) {
app.locator(Selector::id("map_view_1")).wait_visible();
app.locator(Selector::id("map_view_2")).wait_visible();
app.locator(Selector::id("zoom_in_button_1")).click();
app.locator(Selector::id("zoom_label_1")).wait_text("Zoom: 15");
app.locator(Selector::id("zoom_label_2")).assert_text("Zoom: 14");
}
// ============================================================================
// RESIZE TESTS
// ============================================================================
#[makepad_test]
fn map_handles_window_resize(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
let initial_screenshot = app.screenshot();
// Resize window (this would require window resize API)
app.locator(Selector::id("map_view")).wait_visible();
let final_screenshot = app.screenshot();
assert!(!initial_screenshot.is_empty());
assert!(!final_screenshot.is_empty());
}
// ============================================================================
// ROTATION TESTS
// ============================================================================
#[makepad_test]
fn map_rotate_with_gesture(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Simulate rotation gesture (this would require multi-touch API)
app.wait_for_log_contains("Map rotated");
}
#[makepad_test]
fn map_reset_rotation(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Rotate map
app.wait_for_log_contains("Map rotated");
// Reset rotation
app.locator(Selector::id("compass_widget")).click();
app.wait_for_log_contains("Rotation reset");
}
// ============================================================================
// TILT TESTS
// ============================================================================
#[makepad_test]
fn map_tilt_with_gesture(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Simulate tilt gesture (this would require multi-touch API)
app.wait_for_log_contains("Map tilted");
}
#[makepad_test]
fn map_reset_tilt(app: TestApp) {
app.locator(Selector::id("map_view")).wait_visible();
// Tilt map
app.wait_for_log_contains("Map tilted");
// Reset tilt
app.press_key_with_modifiers(KeyCode::R, KeyModifiers::CTRL);
app.wait_for_log_contains("Tilt reset");
}