# Live Server Testing

Live server fixtures for integration testing with a running Django server. These fixtures provide a real HTTP server for testing client-server interactions, AJAX requests, and external API integrations.

## Capabilities

### Live Server

Fixture that provides a running Django test server for integration testing.

```python { .api }
def live_server(request: pytest.FixtureRequest):
    """
    Django live server for integration testing.
    
    Starts a real Django development server in a separate thread,
    allowing tests to make actual HTTP requests to the application.
    Useful for testing AJAX, external API interactions, or full
    integration scenarios.
    
    The server is automatically started before the test and stopped
    after test completion. Server address is configurable via
    --liveserver command line option.
    
    Args:
        request: pytest fixture request object
        
    Returns:
        LiveServer: Live server instance with URL and utilities
    """
```

Usage example:
```python
import requests

def test_live_server_integration(live_server):
    # Make real HTTP request to running Django server
    response = requests.get(f"{live_server.url}/api/data/")
    assert response.status_code == 200
    assert response.json()["status"] == "ok"
    
    # Test POST request
    data = {"name": "test", "value": 123}
    response = requests.post(f"{live_server.url}/api/submit/", json=data)
    assert response.status_code == 201

def test_ajax_functionality(live_server, selenium_driver):
    # Test with Selenium WebDriver
    selenium_driver.get(f"{live_server.url}/page-with-ajax/")
    
    # Click button that makes AJAX request
    button = selenium_driver.find_element("id", "ajax-button")
    button.click()
    
    # Wait for AJAX response and verify results
    result = selenium_driver.find_element("id", "ajax-result")
    assert result.text == "Success"

def test_websocket_connection(live_server):
    import websocket
    
    # Test WebSocket connection to live server
    ws_url = live_server.url.replace("http://", "ws://") + "/ws/chat/"
    ws = websocket.create_connection(ws_url)
    
    ws.send(json.dumps({"message": "hello"}))
    response = json.loads(ws.recv())
    assert response["status"] == "received"
    
    ws.close()
```

## Live Server Configuration

The live server can be configured via command line options:

```bash
# Use specific address and port
pytest --liveserver=127.0.0.1:8081

# Use specific port range
pytest --liveserver=127.0.0.1:8081-8089

# Use any available port
pytest --liveserver=127.0.0.1:0
```

## Live Server Types

```python { .api }
from typing import Optional, Tuple
import threading
from django.test.testcases import LiveServerTestCase

class LiveServer:
    """Live Django server for integration testing."""
    
    def __init__(self, addr: str, *, start: bool = True) -> None:
        """
        Initialize live server instance.
        
        Args:
            addr: Server address in format "host" or "host:port"
            start: Whether to start server immediately (default: True)
        """
    
    def start(self) -> None:
        """Start the live server thread."""
    
    def stop(self) -> None:
        """Stop the live server and clean up resources."""
    
    @property
    def url(self) -> str:
        """Full server URL (e.g., "http://127.0.0.1:8081")"""
    
    def __str__(self) -> str:
        """Return server URL as string."""
    
    def __add__(self, other) -> str:
        """Concatenate server URL with path."""
    
    def __repr__(self) -> str:
        """Return server representation."""

# Server configuration types
ServerAddress = str  # Format: "host:port" or "host:port_start-port_end"
HostAddress = str    # IP address or hostname
PortNumber = int     # Port number
PortRange = Tuple[int, int]  # (start_port, end_port)

# Threading types for server management
ServerThread = threading.Thread
```