Back to Repositories

Testing Todo List Task Management Workflow in Gradio

This test suite validates the functionality of a todo list application in Gradio, focusing on task management operations including adding, completing, and deleting tasks. The test ensures proper state management and UI updates across different task status tabs.

Test Coverage Overview

The test suite provides comprehensive coverage of core todo list functionality.

  • Task addition and validation of counter updates
  • Task completion state management
  • Task deletion functionality
  • Tab content verification
  • UI state consistency checks

Implementation Analysis

The test implements a page-based testing approach using the @self/tootils framework. It employs async/await patterns for handling UI interactions and assertions, with systematic verification of both UI elements and application state.

Key patterns include locator-based element selection, content verification through expectations, and sequential task operation validation.

Technical Details

  • Testing Framework: @self/tootils
  • Page Object Model implementation
  • Locator strategies: label, text content, and element type
  • Async test execution
  • Element interaction methods: fill, press, click
  • Assertion patterns: toContainText, toHaveValue

Best Practices Demonstrated

The test exhibits strong testing practices through systematic validation of component state changes.

  • Atomic test structure with clear progression
  • Comprehensive state verification after each action
  • Robust element selection strategies
  • Explicit waiting patterns for async operations
  • Clear test scenario organization

gradio-app/gradio

js/spa/test/todo_list.spec.ts

            
import { test, expect } from "@self/tootils";

test("clicking through tabs shows correct content", async ({ page }) => {
	await expect(page.locator("body")).toContainText("Incomplete Tasks (0)");
	await expect(page.locator("body")).toContainText("Complete Tasks (0)");

	const input_text = page.getByLabel("Task Name");

	await input_text.fill("eat");
	await input_text.press("Enter");

	await expect(page.locator("body")).not.toContainText("Incomplete Tasks (0)");
	await expect(page.locator("body")).toContainText("Incomplete Tasks (1)");
	await expect(page.locator("body")).toContainText("Complete Tasks (0)");
	await expect(page.locator("textarea").nth(1)).toHaveValue("eat");

	await input_text.fill("pray");
	await input_text.press("Enter");

	await expect(page.locator("body")).toContainText("Incomplete Tasks (2)");
	await expect(page.locator("body")).toContainText("Complete Tasks (0)");
	await expect(page.locator("textarea").nth(2)).toHaveValue("pray");

	await input_text.fill("love");
	await input_text.press("Enter");

	await expect(page.locator("body")).toContainText("Incomplete Tasks (3)");
	await expect(page.locator("body")).toContainText("Complete Tasks (0)");
	await expect(page.locator("textarea").nth(1)).toHaveValue("eat");
	await expect(page.locator("textarea").nth(2)).toHaveValue("pray");
	await expect(page.locator("textarea").nth(3)).toHaveValue("love");

	const done_btn_for_eat = page
		.locator("button")
		.filter({ hasText: "Done" })
		.first();
	await done_btn_for_eat.click();

	await expect(page.locator("body")).toContainText("Incomplete Tasks (2)");
	await expect(page.locator("body")).toContainText("Complete Tasks (1)");

	const delete_btn_for_love = page
		.locator("button")
		.filter({ hasText: "Delete" })
		.last();
	await delete_btn_for_love.click();

	await expect(page.locator("body")).toContainText("Incomplete Tasks (1)");
	await expect(page.locator("body")).toContainText("Complete Tasks (1)");
});