Back to Repositories

Testing Page Unload Event Handling Implementation in Gradio

This test suite validates the page unload event handling and state management in a web application. It specifically tests the behavior of increment operations and cleanup when a user closes the page, ensuring proper event triggering and data persistence.

Test Coverage Overview

The test suite provides comprehensive coverage of page unload event handling and state management. It verifies:

  • Sequential increment operations
  • Event timing and processing
  • Unload event triggering
  • Data persistence verification
  • Cleanup operations during page closure

Implementation Analysis

The testing approach utilizes Playwright’s page object model for browser interaction and state verification. It implements controlled timing with waitForTimeout to ensure reliable event processing, and uses file system operations to verify persisted state changes.

Technical Details

  • Testing Framework: Custom (@self/tootils)
  • Browser Automation: Playwright
  • File Operations: Node.js fs module
  • Asynchronous Testing: Promise-based timing controls
  • State Verification: File-based logging and assertions

Best Practices Demonstrated

The test exhibits several testing best practices including:

  • Explicit wait times for event processing
  • Robust state verification through file system checks
  • Clear separation of setup, action, and verification steps
  • Comprehensive assertion coverage
  • Proper cleanup verification

gradio-app/gradio

js/spa/test/unload_event_test.spec.ts

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

test("when a user closes the page, the unload event should be triggered", async ({
	page
}) => {
	const increment = await page.locator("button", {
		hasText: /Increment/
	});

	// if you click too fast, the page may close before the event is processed
	await increment.click();
	await page.waitForTimeout(100);
	await increment.click();
	await page.waitForTimeout(100);
	await increment.click();
	await page.waitForTimeout(100);
	await increment.click();
	await expect(page.getByLabel("Number")).toHaveValue("4");
	await page.close();

	await new Promise((resolve) => setTimeout(resolve, 5000));

	const data = readFileSync(
		"../../demo/unload_event_test/output_log.txt",
		"utf-8"
	);
	expect(data).toContain("incremented 0");
	expect(data).toContain("incremented 1");
	expect(data).toContain("incremented 2");
	expect(data).toContain("incremented 3");
	expect(data).toContain("unloading");
	expect(data).toContain("deleted 4");
});