mod e2e;
use e2e::RatadoTest;
use expectrl::Expect;
use std::time::Duration;
#[test]
fn test_app_starts_and_shows_empty_state() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.expect_text("Ready for liftoff");
assert!(app.database_exists(), "Database file should exist");
let db = app.quit();
db.assert_task_count(0);
}
#[test]
fn test_add_single_task() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Buy groceries");
app.expect_text("Buy groceries");
let db = app.quit();
db.assert_task_count(1);
db.assert_task_exists("Buy groceries");
db.assert_task_pending("Buy groceries");
}
#[test]
fn test_add_multiple_tasks() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Task One");
app.expect_text("Task One");
app.add_task("Task Two");
app.expect_text("Task Two");
app.add_task("Task Three");
app.expect_text("Task Three");
let db = app.quit();
db.assert_task_count(3);
db.assert_task_exists("Task One");
db.assert_task_exists("Task Two");
db.assert_task_exists("Task Three");
db.assert_pending_count(3);
db.assert_completed_count(0);
}
#[test]
fn test_empty_task_not_created() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.press("a");
app.wait(Duration::from_millis(100));
app.press_enter();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_count(0);
}
#[test]
fn test_toggle_task_completion() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.set_filter_all();
app.add_task("Complete me");
app.expect_text("Complete me");
app.toggle_complete();
app.wait(Duration::from_millis(100));
app.toggle_complete();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_count(1);
db.assert_task_pending("Complete me");
}
#[test]
fn test_complete_single_task() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Finish report");
app.expect_text("Finish report");
app.toggle_complete();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_completed("Finish report");
db.assert_completed_count(1);
}
#[test]
fn test_complete_multiple_tasks() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.set_filter_all();
app.add_task("Task A");
app.add_task("Task B");
app.add_task("Task C");
app.press("g"); app.wait(Duration::from_millis(50));
app.toggle_complete();
app.wait(Duration::from_millis(100));
app.move_down();
app.toggle_complete();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_completed("Task A");
db.assert_task_completed("Task B");
db.assert_task_pending("Task C");
db.assert_completed_count(2);
db.assert_pending_count(1);
}
#[test]
fn test_delete_task() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Delete me");
app.expect_text("Delete me");
app.delete_task();
let db = app.quit();
db.assert_task_count(0);
db.assert_task_not_exists("Delete me");
}
#[test]
fn test_delete_one_of_multiple_tasks() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Keep me");
app.add_task("Delete me");
app.add_task("Keep me too");
app.press("g"); app.wait(Duration::from_millis(50));
app.move_down();
app.delete_task();
let db = app.quit();
db.assert_task_count(2);
db.assert_task_exists("Keep me");
db.assert_task_not_exists("Delete me");
db.assert_task_exists("Keep me too");
}
#[test]
fn test_cancel_delete() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Keep me");
app.expect_text("Keep me");
app.press("d");
app.wait(Duration::from_millis(100));
app.press("n");
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_count(1);
db.assert_task_exists("Keep me");
}
#[test]
fn test_navigation_with_vim_keys() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.set_filter_all();
app.add_task("First");
app.add_task("Second");
app.add_task("Third");
app.press("g");
app.wait(Duration::from_millis(50));
app.toggle_complete();
app.wait(Duration::from_millis(100));
app.move_down();
app.move_down();
app.toggle_complete();
app.wait(Duration::from_millis(100));
app.move_up();
app.toggle_complete();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_completed_count(3);
db.assert_task_completed("First");
db.assert_task_completed("Second");
db.assert_task_completed("Third");
}
#[test]
fn test_navigation_with_arrow_keys() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.set_filter_all();
app.add_task("Task A");
app.add_task("Task B");
app.press("g");
app.wait(Duration::from_millis(50));
app.press_arrow("down");
app.toggle_complete();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_pending("Task A");
db.assert_task_completed("Task B");
}
#[test]
fn test_search_dialog_opens_and_closes() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Searchable task");
app.expect_text("Searchable task");
app.open_search();
app.wait(Duration::from_millis(100));
app.expect_text("Search");
app.press_escape();
app.wait(Duration::from_millis(100));
app.add_task("Another task");
app.expect_text("Another task");
let db = app.quit();
db.assert_task_count(2);
}
#[test]
fn test_cycle_priority() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Priority test");
app.expect_text("Priority test");
app.press("p");
app.wait(Duration::from_millis(100));
app.press("p");
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_exists("Priority test");
}
#[test]
fn test_edit_dialog_opens_and_closes() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Original title");
app.expect_text("Original title");
app.edit_task();
app.wait(Duration::from_millis(100));
app.press_escape();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_exists("Original title");
}
#[test]
fn test_panel_switching() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Test task");
app.expect_text("Test task");
app.press("h"); app.wait(Duration::from_millis(100));
app.press("l"); app.wait(Duration::from_millis(100));
app.press_tab();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_count(1);
}
#[test]
fn test_special_characters_in_title() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Task with 'quotes' and numbers 123");
app.expect_text("Task with");
let db = app.quit();
db.assert_task_count(1);
}
#[test]
fn test_rapid_operations() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
for i in 1..=5 {
app.add_task(&format!("Rapid task {}", i));
}
for _ in 0..10 {
app.press("j");
}
for _ in 0..10 {
app.press("k");
}
let db = app.quit();
db.assert_task_count(5);
}
#[test]
fn test_full_task_lifecycle() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.set_filter_all();
app.add_task("Lifecycle test");
app.expect_text("Lifecycle test");
app.toggle_complete();
app.wait(Duration::from_millis(100));
app.toggle_complete();
app.wait(Duration::from_millis(100));
app.delete_task();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_task_count(0);
db.assert_task_not_exists("Lifecycle test");
}
#[test]
fn test_debug_view_toggle() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.add_task("Debug test");
app.expect_text("Debug test");
app.session.send("\x1b[24~").expect("Failed to send F12");
app.wait(Duration::from_millis(200));
app.session.send("\x1b[24~").expect("Failed to send F12");
app.wait(Duration::from_millis(200));
let db = app.quit();
db.assert_task_exists("Debug test");
}
#[test]
fn test_mixed_task_states() {
let mut app = RatadoTest::spawn();
app.wait_for_startup();
app.set_filter_all();
app.add_task("Pending task");
app.add_task("Completed task");
app.press("g"); app.wait(Duration::from_millis(50));
app.move_down();
app.toggle_complete();
app.wait(Duration::from_millis(100));
let db = app.quit();
db.assert_pending_count(1);
db.assert_completed_count(1);
db.assert_task_pending("Pending task");
db.assert_task_completed("Completed task");
}