diff --git a/docs/api/index.md b/docs/api/index.md
index 99d614fee..4f8256bdc 100644
--- a/docs/api/index.md
+++ b/docs/api/index.md
@@ -11,6 +11,7 @@ servers
 sessions
 windows
 panes
+snapshot
 constants
 common
 exceptions
diff --git a/docs/api/snapshot.md b/docs/api/snapshot.md
new file mode 100644
index 000000000..60582510e
--- /dev/null
+++ b/docs/api/snapshot.md
@@ -0,0 +1,111 @@
+(snapshot)=
+
+# Snapshots
+
+The snapshot module provides functionality for capturing and analyzing the state of tmux panes.
+
+## Core Classes
+
+```{eval-rst}
+.. autoclass:: libtmux.snapshot.PaneSnapshot
+    :members:
+    :inherited-members:
+    :show-inheritance:
+    :member-order: bysource
+
+.. autoclass:: libtmux.snapshot.PaneRecording
+    :members:
+    :inherited-members:
+    :show-inheritance:
+    :member-order: bysource
+```
+
+## Output Adapters
+
+```{eval-rst}
+.. autoclass:: libtmux.snapshot.SnapshotOutputAdapter
+    :members:
+    :inherited-members:
+    :show-inheritance:
+    :member-order: bysource
+
+.. autoclass:: libtmux.snapshot.TerminalOutputAdapter
+    :members:
+    :inherited-members:
+    :show-inheritance:
+    :member-order: bysource
+
+.. autoclass:: libtmux.snapshot.CLIOutputAdapter
+    :members:
+    :inherited-members:
+    :show-inheritance:
+    :member-order: bysource
+
+.. autoclass:: libtmux.snapshot.PytestDiffAdapter
+    :members:
+    :inherited-members:
+    :show-inheritance:
+    :member-order: bysource
+
+.. autoclass:: libtmux.snapshot.SyrupySnapshotAdapter
+    :members:
+    :inherited-members:
+    :show-inheritance:
+    :member-order: bysource
+```
+
+## Examples
+
+### Basic Snapshot
+
+```python
+>>> pane = session.active_window.active_pane
+>>> snapshot = pane.snapshot()
+>>> print(snapshot.content_str)
+$ echo "Hello World"
+Hello World
+$
+```
+
+### Recording Activity
+
+```python
+>>> recording = pane.record()
+>>> recording.add_snapshot(pane)
+>>> pane.send_keys("echo 'Hello'")
+>>> recording.add_snapshot(pane)
+>>> print(recording.latest.content_str)
+$ echo 'Hello'
+Hello
+$
+```
+
+### Using Output Adapters
+
+```python
+>>> from libtmux.snapshot import TerminalOutputAdapter
+>>> print(snapshot.format(TerminalOutputAdapter()))
+=== Pane Snapshot ===
+Pane: %1
+Window: @1
+Session: $1
+Server: default
+Timestamp: 2024-01-01T12:00:00Z
+=== Content ===
+$ echo "Hello World"
+Hello World
+$
+```
+
+### Custom Adapter
+
+```python
+>>> from libtmux.snapshot import SnapshotOutputAdapter
+>>> class MyAdapter(SnapshotOutputAdapter):
+...     def format(self, snapshot):
+...         return f"Content: {snapshot.content_str}"
+>>> print(snapshot.format(MyAdapter()))
+Content: $ echo "Hello World"
+Hello World
+$
+```
diff --git a/docs/topics/index.md b/docs/topics/index.md
index 0653bb57b..478c1c683 100644
--- a/docs/topics/index.md
+++ b/docs/topics/index.md
@@ -10,4 +10,5 @@ Explore libtmux’s core functionalities and underlying principles at a high lev
 
 context_managers
 traversal
+snapshots
 ```
diff --git a/docs/topics/snapshots.md b/docs/topics/snapshots.md
new file mode 100644
index 000000000..e1ee8dacd
--- /dev/null
+++ b/docs/topics/snapshots.md
@@ -0,0 +1,162 @@
+(snapshots)=
+
+# Snapshots and Recordings
+
+libtmux provides functionality to capture and analyze the state of tmux panes through snapshots and recordings.
+
+## Taking Snapshots
+
+A snapshot captures the content and metadata of a pane at a specific point in time:
+
+```python
+>>> pane = session.active_window.active_pane
+>>> snapshot = pane.snapshot()
+>>> print(snapshot.content_str)
+$ echo "Hello World"
+Hello World
+$
+```
+
+Snapshots are immutable and include:
+- Pane content
+- Timestamp (in UTC)
+- Pane, window, session, and server IDs
+- All tmux pane metadata
+
+You can also capture specific ranges of the pane history:
+
+```python
+>>> # Capture lines 1-3 only
+>>> snapshot = pane.snapshot(start=1, end=3)
+
+>>> # Capture from start of history
+>>> snapshot = pane.snapshot(start="-")
+
+>>> # Capture up to current view
+>>> snapshot = pane.snapshot(end="-")
+```
+
+## Recording Pane Activity
+
+To track changes in a pane over time, use recordings:
+
+```python
+>>> recording = pane.record()
+>>> recording.add_snapshot(pane)
+>>> pane.send_keys("echo 'Hello'")
+>>> recording.add_snapshot(pane)
+>>> pane.send_keys("echo 'World'")
+>>> recording.add_snapshot(pane)
+
+>>> # Access snapshots
+>>> print(recording[0].content_str)  # First snapshot
+>>> print(recording.latest.content_str)  # Most recent
+
+>>> # Filter by time
+>>> recent = recording.get_snapshots_between(
+...     start_time=datetime.datetime.now() - datetime.timedelta(minutes=5),
+...     end_time=datetime.datetime.now(),
+... )
+```
+
+## Output Formats
+
+Snapshots can be formatted in different ways for various use cases:
+
+### Terminal Output
+
+```python
+>>> from libtmux.snapshot import TerminalOutputAdapter
+>>> print(snapshot.format(TerminalOutputAdapter()))
+=== Pane Snapshot ===
+Pane: %1
+Window: @1
+Session: $1
+Server: default
+Timestamp: 2024-01-01T12:00:00Z
+=== Content ===
+$ echo "Hello World"
+Hello World
+$
+```
+
+### CLI Output (No Colors)
+
+```python
+>>> from libtmux.snapshot import CLIOutputAdapter
+>>> print(snapshot.format(CLIOutputAdapter()))
+=== Pane Snapshot ===
+Pane: %1
+Window: @1
+Session: $1
+Server: default
+Timestamp: 2024-01-01T12:00:00Z
+=== Content ===
+$ echo "Hello World"
+Hello World
+$
+```
+
+### Pytest Assertion Diffs
+
+```python
+>>> from libtmux.snapshot import PytestDiffAdapter
+>>> expected = """
+... PaneSnapshot(
+...     pane_id='%1',
+...     window_id='@1',
+...     session_id='$1',
+...     server_name='default',
+...     timestamp='2024-01-01T12:00:00Z',
+...     content=[
+...         '$ echo "Hello World"',
+...         'Hello World',
+...         '$',
+...     ],
+...     metadata={
+...         'pane_height': '24',
+...         'pane_width': '80',
+...     },
+... )
+... """
+>>> assert snapshot.format(PytestDiffAdapter()) == expected
+```
+
+### Syrupy Snapshot Testing
+
+```python
+>>> from libtmux.snapshot import SyrupySnapshotAdapter
+>>> snapshot.format(SyrupySnapshotAdapter())
+{
+  "pane_id": "%1",
+  "window_id": "@1",
+  "session_id": "$1",
+  "server_name": "default",
+  "timestamp": "2024-01-01T12:00:00Z",
+  "content": [
+    "$ echo \"Hello World\"",
+    "Hello World",
+    "$"
+  ],
+  "metadata": {
+    "pane_height": "24",
+    "pane_width": "80"
+  }
+}
+```
+
+## Custom Output Formats
+
+You can create custom output formats by implementing the `SnapshotOutputAdapter` interface:
+
+```python
+from libtmux.snapshot import SnapshotOutputAdapter
+
+class MyCustomAdapter(SnapshotOutputAdapter):
+    def format(self, snapshot: PaneSnapshot) -> str:
+        # Format snapshot data as needed
+        return f"Custom format: {snapshot.content_str}"
+
+# Use custom adapter
+print(snapshot.format(MyCustomAdapter()))
+```
diff --git a/src/libtmux/pane.py b/src/libtmux/pane.py
index a60bb36f6..aba12795c 100644
--- a/src/libtmux/pane.py
+++ b/src/libtmux/pane.py
@@ -22,6 +22,7 @@
 )
 from libtmux.formats import FORMAT_SEPARATOR
 from libtmux.neo import Obj, fetch_obj
+from libtmux.snapshot import PaneRecording, PaneSnapshot
 
 from . import exc
 
@@ -342,6 +343,43 @@ def capture_pane(
             cmd.extend(["-E", str(end)])
         return self.cmd(*cmd).stdout
 
+    def snapshot(
+        self,
+        start: t.Literal["-"] | int | None = None,
+        end: t.Literal["-"] | int | None = None,
+    ) -> PaneSnapshot:
+        """Create a snapshot of the pane's current state.
+
+        This is a convenience method that creates a :class:`PaneSnapshot` instance
+        from the current pane state.
+
+        Parameters
+        ----------
+        start : int | "-" | None
+            Start line for capture_pane
+        end : int | "-" | None
+            End line for capture_pane
+
+        Returns
+        -------
+        PaneSnapshot
+            A frozen snapshot of the pane's current state
+        """
+        return PaneSnapshot.from_pane(self, start=start, end=end)
+
+    def record(self) -> PaneRecording:
+        """Create a new recording for this pane.
+
+        This is a convenience method that creates a :class:`PaneRecording` instance
+        for recording snapshots of this pane.
+
+        Returns
+        -------
+        PaneRecording
+            A new recording instance for this pane
+        """
+        return PaneRecording()
+
     def send_keys(
         self,
         cmd: str,
diff --git a/src/libtmux/snapshot.py b/src/libtmux/snapshot.py
new file mode 100644
index 000000000..99841a45f
--- /dev/null
+++ b/src/libtmux/snapshot.py
@@ -0,0 +1,387 @@
+"""Snapshot and recording functionality for tmux panes."""
+
+from __future__ import annotations
+
+import dataclasses
+import datetime
+import json
+import typing as t
+from abc import ABC, abstractmethod
+
+from typing_extensions import Self
+
+from libtmux.formats import PANE_FORMATS
+
+if t.TYPE_CHECKING:
+    from collections.abc import Iterator, Sequence
+
+    from libtmux.pane import Pane
+
+
+class SnapshotOutputAdapter(ABC):
+    """Base class for snapshot output adapters.
+
+    This class defines the interface for converting a PaneSnapshot
+    into different output formats.
+    """
+
+    @abstractmethod
+    def format(self, snapshot: PaneSnapshot) -> str:
+        """Format the snapshot for output.
+
+        Parameters
+        ----------
+        snapshot : PaneSnapshot
+            The snapshot to format
+
+        Returns
+        -------
+        str
+            The formatted output
+        """
+
+
+class TerminalOutputAdapter(SnapshotOutputAdapter):
+    """Format snapshot for terminal output with ANSI colors."""
+
+    def format(self, snapshot: PaneSnapshot) -> str:
+        """Format snapshot with ANSI colors for terminal display.
+
+        Parameters
+        ----------
+        snapshot : PaneSnapshot
+            The snapshot to format
+
+        Returns
+        -------
+        str
+            ANSI-colored terminal output
+        """
+        header = (
+            f"\033[1;34m=== Pane Snapshot ===\033[0m\n"
+            f"\033[1;36mPane:\033[0m {snapshot.pane_id}\n"
+            f"\033[1;36mWindow:\033[0m {snapshot.window_id}\n"
+            f"\033[1;36mSession:\033[0m {snapshot.session_id}\n"
+            f"\033[1;36mServer:\033[0m {snapshot.server_name}\n"
+            f"\033[1;36mTimestamp:\033[0m {snapshot.timestamp.isoformat()}\n"
+            f"\033[1;33m=== Content ===\033[0m\n"
+        )
+        return header + snapshot.content_str
+
+
+class CLIOutputAdapter(SnapshotOutputAdapter):
+    """Format snapshot for plain text CLI output."""
+
+    def format(self, snapshot: PaneSnapshot) -> str:
+        """Format snapshot as plain text.
+
+        Parameters
+        ----------
+        snapshot : PaneSnapshot
+            The snapshot to format
+
+        Returns
+        -------
+        str
+            Plain text output suitable for CLI
+        """
+        header = (
+            f"=== Pane Snapshot ===\n"
+            f"Pane: {snapshot.pane_id}\n"
+            f"Window: {snapshot.window_id}\n"
+            f"Session: {snapshot.session_id}\n"
+            f"Server: {snapshot.server_name}\n"
+            f"Timestamp: {snapshot.timestamp.isoformat()}\n"
+            f"=== Content ===\n"
+        )
+        return header + snapshot.content_str
+
+
+class PytestDiffAdapter(SnapshotOutputAdapter):
+    """Format snapshot for pytest assertion diffs."""
+
+    def format(self, snapshot: PaneSnapshot) -> str:
+        """Format snapshot for optimal pytest diff output.
+
+        Parameters
+        ----------
+        snapshot : PaneSnapshot
+            The snapshot to format
+
+        Returns
+        -------
+        str
+            Pytest-friendly diff output
+        """
+        lines = [
+            "PaneSnapshot(",
+            f"    pane_id={snapshot.pane_id!r},",
+            f"    window_id={snapshot.window_id!r},",
+            f"    session_id={snapshot.session_id!r},",
+            f"    server_name={snapshot.server_name!r},",
+            f"    timestamp={snapshot.timestamp.isoformat()!r},",
+            "    content=[",
+            *(f"        {line!r}," for line in snapshot.content),
+            "    ],",
+            "    metadata={",
+            *(f"        {k!r}: {v!r}," for k, v in sorted(snapshot.metadata.items())),
+            "    },",
+            ")",
+        ]
+        return "\n".join(lines)
+
+
+class SyrupySnapshotAdapter(SnapshotOutputAdapter):
+    """Format snapshot for syrupy snapshot testing."""
+
+    def format(self, snapshot: PaneSnapshot) -> str:
+        """Format snapshot for syrupy compatibility.
+
+        Parameters
+        ----------
+        snapshot : PaneSnapshot
+            The snapshot to format
+
+        Returns
+        -------
+        str
+            JSON-serialized snapshot data
+        """
+        data = {
+            "pane_id": snapshot.pane_id,
+            "window_id": snapshot.window_id,
+            "session_id": snapshot.session_id,
+            "server_name": snapshot.server_name,
+            "timestamp": snapshot.timestamp.isoformat(),
+            "content": snapshot.content,
+            "metadata": snapshot.metadata,
+        }
+        return json.dumps(data, indent=2, sort_keys=True)
+
+
+@dataclasses.dataclass(frozen=True)
+class PaneSnapshot:
+    """A frozen snapshot of a pane's state at a point in time.
+
+    This class captures both the content and metadata of a tmux pane,
+    making it suitable for testing and debugging purposes.
+
+    Attributes
+    ----------
+    content : list[str]
+        The captured content of the pane
+    timestamp : datetime.datetime
+        When the snapshot was taken (in UTC)
+    pane_id : str
+        The ID of the pane
+    window_id : str
+        The ID of the window containing the pane
+    session_id : str
+        The ID of the session containing the window
+    server_name : str
+        The name of the tmux server
+    metadata : dict[str, str]
+        Additional pane metadata from tmux formats
+    """
+
+    content: list[str]
+    timestamp: datetime.datetime
+    pane_id: str
+    window_id: str
+    session_id: str
+    server_name: str
+    metadata: dict[str, str]
+
+    @classmethod
+    def from_pane(
+        cls,
+        pane: Pane,
+        start: t.Literal["-"] | int | None = None,
+        end: t.Literal["-"] | int | None = None,
+    ) -> Self:
+        """Create a snapshot from a pane.
+
+        Parameters
+        ----------
+        pane : Pane
+            The pane to snapshot
+        start : int | "-" | None
+            Start line for capture_pane
+        end : int | "-" | None
+            End line for capture_pane
+
+        Returns
+        -------
+        PaneSnapshot
+            A frozen snapshot of the pane's state
+        """
+        metadata = {
+            fmt: getattr(pane, fmt)
+            for fmt in PANE_FORMATS
+            if hasattr(pane, fmt) and getattr(pane, fmt) is not None
+        }
+
+        content = pane.capture_pane(start=start, end=end)
+        if isinstance(content, str):
+            content = [content]
+
+        return cls(
+            content=content,
+            timestamp=datetime.datetime.now(datetime.timezone.utc),
+            pane_id=str(pane.pane_id),
+            window_id=str(pane.window.window_id),
+            session_id=str(pane.session.session_id),
+            server_name=str(pane.server.socket_name),
+            metadata=metadata,
+        )
+
+    def format(self, adapter: SnapshotOutputAdapter | None = None) -> str:
+        """Format the snapshot using the specified adapter.
+
+        If no adapter is provided, uses the default string representation.
+
+        Parameters
+        ----------
+        adapter : SnapshotOutputAdapter | None
+            The adapter to use for formatting
+
+        Returns
+        -------
+        str
+            The formatted output
+        """
+        if adapter is None:
+            return str(self)
+        return adapter.format(self)
+
+    def __str__(self) -> str:
+        """Return a string representation of the snapshot.
+
+        Returns
+        -------
+        str
+            A formatted string showing the snapshot content and metadata
+        """
+        return (
+            f"PaneSnapshot(pane={self.pane_id}, window={self.window_id}, "
+            f"session={self.session_id}, server={self.server_name}, "
+            f"timestamp={self.timestamp.isoformat()}, "
+            f"content=\n{self.content_str})"
+        )
+
+    @property
+    def content_str(self) -> str:
+        """Get the pane content as a single string.
+
+        Returns
+        -------
+        str
+            The pane content with lines joined by newlines
+        """
+        return "\n".join(self.content)
+
+
+@dataclasses.dataclass
+class PaneRecording:
+    """A time-series recording of pane snapshots.
+
+    This class maintains an ordered sequence of pane snapshots,
+    allowing for analysis of how a pane's content changes over time.
+
+    Attributes
+    ----------
+    snapshots : list[PaneSnapshot]
+        The sequence of snapshots in chronological order
+    """
+
+    snapshots: list[PaneSnapshot] = dataclasses.field(default_factory=list)
+
+    def add_snapshot(
+        self,
+        pane: Pane,
+        start: t.Literal["-"] | int | None = None,
+        end: t.Literal["-"] | int | None = None,
+    ) -> None:
+        """Add a new snapshot to the recording.
+
+        Parameters
+        ----------
+        pane : Pane
+            The pane to snapshot
+        start : int | "-" | None
+            Start line for capture_pane
+        end : int | "-" | None
+            End line for capture_pane
+        """
+        self.snapshots.append(PaneSnapshot.from_pane(pane, start=start, end=end))
+
+    def __len__(self) -> int:
+        """Get the number of snapshots in the recording.
+
+        Returns
+        -------
+        int
+            The number of snapshots
+        """
+        return len(self.snapshots)
+
+    def __iter__(self) -> Iterator[PaneSnapshot]:
+        """Iterate through snapshots in chronological order.
+
+        Returns
+        -------
+        Iterator[PaneSnapshot]
+            Iterator over the snapshots
+        """
+        return iter(self.snapshots)
+
+    def __getitem__(self, index: int) -> PaneSnapshot:
+        """Get a snapshot by index.
+
+        Parameters
+        ----------
+        index : int
+            The index of the snapshot to retrieve
+
+        Returns
+        -------
+        PaneSnapshot
+            The snapshot at the specified index
+        """
+        return self.snapshots[index]
+
+    @property
+    def latest(self) -> PaneSnapshot | None:
+        """Get the most recent snapshot.
+
+        Returns
+        -------
+        PaneSnapshot | None
+            The most recent snapshot, or None if no snapshots exist
+        """
+        return self.snapshots[-1] if self.snapshots else None
+
+    def get_snapshots_between(
+        self,
+        start_time: datetime.datetime,
+        end_time: datetime.datetime,
+    ) -> Sequence[PaneSnapshot]:
+        """Get snapshots between two points in time.
+
+        Parameters
+        ----------
+        start_time : datetime.datetime
+            The start of the time range
+        end_time : datetime.datetime
+            The end of the time range
+
+        Returns
+        -------
+        Sequence[PaneSnapshot]
+            Snapshots within the specified time range
+        """
+        return [
+            snapshot
+            for snapshot in self.snapshots
+            if start_time <= snapshot.timestamp <= end_time
+        ]
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
new file mode 100644
index 000000000..f226c8157
--- /dev/null
+++ b/tests/test_snapshot.py
@@ -0,0 +1,233 @@
+"""Tests for libtmux snapshot functionality."""
+
+from __future__ import annotations
+
+import datetime
+import json
+import shutil
+import time
+import typing as t
+
+from libtmux.snapshot import (
+    CLIOutputAdapter,
+    PaneRecording,
+    PaneSnapshot,
+    PytestDiffAdapter,
+    SyrupySnapshotAdapter,
+    TerminalOutputAdapter,
+)
+
+if t.TYPE_CHECKING:
+    from libtmux.session import Session
+
+
+def test_pane_snapshot(session: Session) -> None:
+    """Test creating a PaneSnapshot from a pane."""
+    env = shutil.which("env")
+    assert env is not None, "Cannot find usable `env` in PATH."
+
+    session.new_window(
+        attach=True,
+        window_name="snapshot_test",
+        window_shell=f"{env} PS1='$ ' sh",
+    )
+    pane = session.active_window.active_pane
+    assert pane is not None
+
+    # Take initial snapshot
+    snapshot = PaneSnapshot.from_pane(pane)
+    assert snapshot.content == ["$"]
+    assert snapshot.pane_id == pane.pane_id
+    assert snapshot.window_id == pane.window.window_id
+    assert snapshot.session_id == pane.session.session_id
+    assert snapshot.server_name == pane.server.socket_name
+    assert isinstance(snapshot.timestamp, datetime.datetime)
+    assert snapshot.timestamp.tzinfo == datetime.timezone.utc
+
+    # Verify metadata
+    assert "pane_id" in snapshot.metadata
+    assert "pane_width" in snapshot.metadata
+    assert "pane_height" in snapshot.metadata
+
+    # Test string representation
+    str_repr = str(snapshot)
+    assert "PaneSnapshot" in str_repr
+    assert snapshot.pane_id in str_repr
+    assert snapshot.window_id in str_repr
+    assert snapshot.session_id in str_repr
+    assert snapshot.server_name in str_repr
+    assert snapshot.timestamp.isoformat() in str_repr
+    assert "$" in str_repr
+
+
+def test_pane_recording(session: Session) -> None:
+    """Test creating and managing a PaneRecording."""
+    env = shutil.which("env")
+    assert env is not None, "Cannot find usable `env` in PATH."
+
+    session.new_window(
+        attach=True,
+        window_name="recording_test",
+        window_shell=f"{env} PS1='$ ' sh",
+    )
+    pane = session.active_window.active_pane
+    assert pane is not None
+
+    recording = PaneRecording()
+    assert len(recording) == 0
+    assert recording.latest is None
+
+    # Take initial snapshot
+    recording.add_snapshot(pane)
+    assert len(recording) == 1
+    assert recording.latest is not None
+    assert recording.latest.content == ["$"]
+
+    # Send some commands and take more snapshots
+    pane.send_keys("echo 'Hello'")
+    time.sleep(0.1)  # Give tmux time to update
+    recording.add_snapshot(pane)
+
+    pane.send_keys("echo 'World'")
+    time.sleep(0.1)  # Give tmux time to update
+    recording.add_snapshot(pane)
+
+    assert len(recording) == 3
+
+    # Test iteration
+    snapshots = list(recording)
+    assert len(snapshots) == 3
+    assert snapshots[0].content == ["$"]
+    assert "Hello" in snapshots[1].content_str
+    assert "World" in snapshots[2].content_str
+
+    # Test indexing
+    assert recording[0].content == ["$"]
+    assert "Hello" in recording[1].content_str
+    assert "World" in recording[2].content_str
+
+    # Test time-based filtering
+    start_time = snapshots[0].timestamp
+    mid_time = snapshots[1].timestamp
+    end_time = snapshots[2].timestamp
+
+    assert len(recording.get_snapshots_between(start_time, end_time)) == 3
+    assert len(recording.get_snapshots_between(mid_time, end_time)) == 2
+
+
+def test_snapshot_output_adapters(session: Session) -> None:
+    """Test the various output adapters for PaneSnapshot."""
+    env = shutil.which("env")
+    assert env is not None, "Cannot find usable `env` in PATH."
+
+    session.new_window(
+        attach=True,
+        window_name="adapter_test",
+        window_shell=f"{env} PS1='$ ' sh",
+    )
+    pane = session.active_window.active_pane
+    assert pane is not None
+
+    # Create a snapshot with some content
+    pane.send_keys("echo 'Test Content'")
+    time.sleep(0.1)
+    snapshot = pane.snapshot()
+
+    # Test Terminal Output
+    terminal_output = snapshot.format(TerminalOutputAdapter())
+    assert "\033[1;34m=== Pane Snapshot ===\033[0m" in terminal_output
+    assert "\033[1;36mPane:\033[0m" in terminal_output
+    assert "Test Content" in terminal_output
+
+    # Test CLI Output
+    cli_output = snapshot.format(CLIOutputAdapter())
+    assert "=== Pane Snapshot ===" in cli_output
+    assert "Pane: " in cli_output
+    assert "\033" not in cli_output  # No ANSI codes
+    assert "Test Content" in cli_output
+
+    # Test Pytest Diff Output
+    pytest_output = snapshot.format(PytestDiffAdapter())
+    assert "PaneSnapshot(" in pytest_output
+    assert "    pane_id=" in pytest_output
+    assert "    content=[" in pytest_output
+    assert "    metadata={" in pytest_output
+    assert "'Test Content'" in pytest_output
+
+    # Test Syrupy Output
+    syrupy_output = snapshot.format(SyrupySnapshotAdapter())
+    data = json.loads(syrupy_output)
+    assert isinstance(data, dict)
+    assert "pane_id" in data
+    assert "content" in data
+    assert "metadata" in data
+    assert "Test Content" in str(data["content"])
+
+    # Test default format (no adapter)
+    default_output = snapshot.format()
+    assert default_output == str(snapshot)
+
+
+def test_pane_snapshot_convenience_method(session: Session) -> None:
+    """Test the Pane.snapshot() convenience method."""
+    env = shutil.which("env")
+    assert env is not None, "Cannot find usable `env` in PATH."
+
+    session.new_window(
+        attach=True,
+        window_name="snapshot_convenience_test",
+        window_shell=f"{env} PS1='$ ' sh",
+    )
+    pane = session.active_window.active_pane
+    assert pane is not None
+
+    # Take snapshot using convenience method
+    snapshot = pane.snapshot()
+    assert snapshot.content == ["$"]
+    assert snapshot.pane_id == pane.pane_id
+    assert snapshot.window_id == pane.window.window_id
+    assert snapshot.session_id == pane.session.session_id
+    assert snapshot.server_name == pane.server.socket_name
+
+    # Test with start/end parameters
+    pane.send_keys("echo 'Line 1'")
+    time.sleep(0.1)
+    pane.send_keys("echo 'Line 2'")
+    time.sleep(0.1)
+    pane.send_keys("echo 'Line 3'")
+    time.sleep(0.1)
+
+    snapshot_partial = pane.snapshot(start=1, end=2)
+    assert len(snapshot_partial.content) == 2
+    assert "Line 1" in snapshot_partial.content_str
+    assert "Line 2" in snapshot_partial.content_str
+    assert "Line 3" not in snapshot_partial.content_str
+
+
+def test_pane_record_convenience_method(session: Session) -> None:
+    """Test the Pane.record() convenience method."""
+    env = shutil.which("env")
+    assert env is not None, "Cannot find usable `env` in PATH."
+
+    session.new_window(
+        attach=True,
+        window_name="record_convenience_test",
+        window_shell=f"{env} PS1='$ ' sh",
+    )
+    pane = session.active_window.active_pane
+    assert pane is not None
+
+    # Create recording using convenience method
+    recording = pane.record()
+    assert isinstance(recording, PaneRecording)
+    assert len(recording) == 0
+
+    # Add snapshots to recording
+    recording.add_snapshot(pane)
+    pane.send_keys("echo 'Test'")
+    time.sleep(0.1)
+    recording.add_snapshot(pane)
+
+    assert len(recording) == 2
+    assert recording[0].content == ["$"]
+    assert "Test" in recording[1].content_str