def wait_for_sync_completion(
    api_url: str,
    source_conn_id: str,
    job_id: str,
    timeout: int = 300,
    poll_interval: int = 5
) -> Dict[str, Any]:
    """Wait for a sync job to complete and return final status.

    Args:
        api_url: The API base URL
        source_conn_id: The source connection ID
        job_id: The sync job ID
        timeout: Maximum seconds to wait
        poll_interval: Seconds between status checks

    Returns:
        The final job status dictionary

    Raises:
        AssertionError: If job times out
    """
    elapsed = 0

    while elapsed < timeout:
        response = requests.get(
            f"{api_url}/source-connections/{source_conn_id}/jobs/{job_id}"
        )
        assert response.status_code == 200, f"Failed to get job status: {response.text}"

        job_status = response.json()
        current_status = job_status["status"].upper()

        if current_status == "COMPLETED":
            return job_status
        elif current_status == "FAILED":
            return job_status

        # Show progress
        entities = job_status.get("entities_encountered", 0)
        print(f"  Status: {current_status} | Entities: {entities} | Elapsed: {elapsed}s", end="\r")

        time.sleep(poll_interval)
        elapsed += poll_interval

    raise AssertionError(f"Sync job timed out after {timeout} seconds")
Wait for a sync job to complete and return final status.

    Args:
        api_url: The API base URL
        source_conn_id: The source connection ID
        job_id: The sync job ID
        timeout: Maximum seconds to wait
        poll_interval: Seconds between status checks

    Returns:
        The final job status dictionary

    Raises:
        AssertionError: If job times out
    
backend/tests/e2e/scenarios/test_sources.py