Back to Repositories

Testing Application Quit Functionality in MailCatcher

This test suite validates the quit functionality in MailCatcher, ensuring proper application shutdown through both UI interactions and system signals. It verifies clean exit behaviors and proper state management during the quit process.

Test Coverage Overview

The test suite provides comprehensive coverage of MailCatcher’s quit functionality, focusing on two primary exit paths.

  • UI-based quit functionality with confirmation dialog handling
  • System signal handling (SIGINT/Ctrl+C)
  • Process termination verification
  • Post-quit navigation behavior

Implementation Analysis

The implementation employs RSpec and Capybara to simulate user interactions and verify process states. The tests utilize JavaScript evaluation for WebSocket state verification and process management for signal handling.

Key patterns include:
  • Dialog interaction handling using accept_confirm and dismiss_confirm
  • Process state verification using Process.kill and Process.wait2
  • WebSocket connection state monitoring

Technical Details

Testing tools and configuration:
  • RSpec for test structure and assertions
  • Capybara for browser interaction simulation
  • Process module for system-level process management
  • JavaScript evaluation for WebSocket state checking
  • Feature-type tests for end-to-end verification

Best Practices Demonstrated

The test suite exemplifies several testing best practices in Ruby.

  • Comprehensive state verification before and after actions
  • Proper cleanup and process management
  • Clear separation of UI and system-level test cases
  • Effective use of RSpec expectations and matchers
  • Robust handling of asynchronous operations

sj26/mailcatcher

spec/quit_spec.rb

            
# frozen_string_literal: true

require "spec_helper"

RSpec.describe "Quit", type: :feature do
  it "quits cleanly via the Quit button" do
    # Quitting and cancelling ..
    dismiss_confirm do
      click_on "Quit"
    end

    # .. should not exit the process
    expect { Process.kill(0, @pid) }.not_to raise_error

    # Reload the page to be sure
    visit "/"
    wait.until { page.evaluate_script("MailCatcher.websocket.readyState") == 1 rescue false }

    # Quitting and confirming ..
    accept_confirm "Are you sure you want to quit?" do
      click_on "Quit"
    end

    # .. should exit the process ..
    _, status = Process.wait2(@pid)

    expect(status).to be_exited
    expect(status).to be_success

    # .. and navigate to the mailcatcher website
    expect(page).to have_current_path "https://mailcatcher.me"
  end

  it "quits cleanly on Ctrl+C" do
    # Sending a SIGINT (Ctrl+C) ...
    Process.kill(:SIGINT, @pid)

    # .. should cause the process to exit cleanly
    _, status = Process.wait2(@pid)

    expect(status).to be_exited
    expect(status).to be_success
  end
end