Metadata-Version: 2.4
Name: browser-core
Version: 2.0.0
Summary: Um framework robusto e configurável para automação de navegadores, com gestão de perfis, sessões e uma CLI.
Author: gabigolo
License: MIT
Project-URL: Homepage, https://github.com/gabrielbarbosel/browser-core
Project-URL: Bug Tracker, https://github.com/gabrielbarbosel/browser-core/issues
Project-URL: Repository, https://github.com/gabrielbarbosel/browser-core
Keywords: automation,selenium,web,browser,framework
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: selenium>=4.15.0
Requires-Dist: webdriver-manager>=4.0.1
Requires-Dist: click>=8.0.0
Requires-Dist: typing-extensions>=4.0.0
Dynamic: license-file

# Browser-Core

[![PyPI version](https://badge.fury.io/py/browser-core.svg)](https://badge.fury.io/py/browser-core)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Browser-Core** é uma plataforma de orquestração de ambientes de navegador, projetada para automação web em escala, com
foco em eficiência, isolamento e reprodutibilidade total.

---

## Visão Geral

O Browser-Core evoluiu de uma simples biblioteca de automação para uma plataforma de orquestração completa. Ele permite
provisionar, gerir e executar frotas de "Workers" (navegadores) em paralelo, com uma arquitetura robusta e elegante.

A base do framework é um **sistema de snapshots em camadas**, análogo ao Docker e Git, que permite criar, derivar e
reutilizar estados de navegador (como sessões com login efetuado) de forma rápida, eficiente em disco e, crucialmente, *
*100% reprodutível**.

## Conceitos Fundamentais

* **Snapshots em Camadas**: Crie "imagens" do estado do seu navegador (com cookies, `localStorage`, etc.) e derive
  outras a partir delas. Diga adeus à necessidade de repetir o login a cada execução.
* **Workers Isolados**: Execute cada tarefa em um "Worker" limpo e isolado, instanciado a partir de um snapshot,
  garantindo que execuções paralelas não interfiram umas nas outras.
* **API Fluente e Intuitiva**: Interaja com os elementos da página de forma declarativa e legível com o método
  `worker.get()`, que torna a automação mais limpa e de fácil manutenção.
* **Gestão Automática de Drivers**: O `browser-core` faz o download e gere o cache da versão exata do WebDriver
  necessária para cada snapshot, eliminando problemas de compatibilidade.
* **CLI Integrada**: Uma ferramenta de linha de comando para listar, inspecionar e gerir seus snapshots e o
  armazenamento de objetos.

---

## Instalação

A forma recomendada de instalar o `browser-core` é através do PyPI:

```bash
pip install browser-core
```

---

## Um Fluxo de Trabalho Moderno

O uso do `browser-core` é dividido em duas fases lógicas: a **preparação de ambientes** (criação de snapshots) e a *
*execução de tarefas**.

### Fase 1: Criar os Snapshots Reutilizáveis

#### Passo 1.1: Criar um Snapshot Base (Raiz)

Primeiro, você precisa de um ponto de partida. Use a CLI para criar um "snapshot base", que representa um perfil de
navegador limpo. Este comando é executado apenas uma vez.

```bash
# Cria um snapshot base chamado 'chrome-base' usando a versão mais recente do Chrome.
browser-core snapshots create-base chrome-base
```

Você pode inspecionar os snapshots existentes a qualquer momento com `browser-core snapshots list`.

#### Passo 1.2: Criar um Snapshot com Estado (ex: Login)

Agora, a partir do `chrome-base`, crie um estado mais complexo, como uma sessão de usuário autenticada. Este processo é
automatizado pelo `WorkforceManager`.

```python
# scripts/create_login_snapshot.py
import os
from browser_core import WorkforceManager, Worker, create_selector, ConfigurationError
from browser_core.types import SelectorType

# De preferência, carregue credenciais como variáveis de ambiente.
# export APP_USER="meu_usuario@exemplo.com"
# export APP_PASSWORD="minha-senha-super-segura"
APP_USER = os.getenv("APP_USER")
APP_PASSWORD = os.getenv("APP_PASSWORD")


# 1. Defina a função que executa a lógica de setup
def perform_login(worker: Worker):
    """Esta função navega e realiza o login para criar o estado desejado."""
    if not APP_USER or not APP_PASSWORD:
        raise ConfigurationError("As variáveis de ambiente APP_USER e APP_PASSWORD devem ser definidas.")

    worker.logger.info("Iniciando processo de login para criar o snapshot...")
    worker.navigate_to("https://app.exemplo.com/login")

    EMAIL_INPUT = create_selector("input[name='email']", SelectorType.CSS)
    PASSWORD_INPUT = create_selector("input[name='password']", SelectorType.CSS)
    LOGIN_BUTTON = create_selector("//button[text()='Entrar']", SelectorType.XPATH)

    worker.get(EMAIL_INPUT).send_keys(APP_USER)
    worker.get(PASSWORD_INPUT).send_keys(APP_PASSWORD)
    worker.get(LOGIN_BUTTON).click()

    worker.get(create_selector("#dashboard-welcome-message", SelectorType.CSS))
    worker.logger.info("Login realizado com sucesso! Estado pronto para ser capturado.")


# 2. Execute o orquestrador para criar o snapshot
def main():
    workforce = WorkforceManager()

    # [ATUALIZADO] IDs de snapshot mais claros
    BASE_SNAPSHOT = "chrome-base"  # O snapshot que acabamos de criar com a CLI
    LOGGED_IN_SNAPSHOT = "app_logged_in"  # O novo snapshot que vamos criar

    try:
        workforce.create_snapshot_from_task(
            base_snapshot_id=BASE_SNAPSHOT,
            new_snapshot_id=LOGGED_IN_SNAPSHOT,
            setup_function=perform_login,
            metadata={
                "description": "Sessão autenticada no app.exemplo.com.",
                "user": APP_USER
            }
        )
        print(f"\nSnapshot '{LOGGED_IN_SNAPSHOT}' criado com sucesso!")
    except Exception as e:
        print(f"\n[!!!] Falha ao criar o snapshot: {e}")


if __name__ == "__main__":
    main()
```

### Fase 2: Executar Tarefas Usando o Snapshot

Com o snapshot `app_logged_in` pronto, você pode executar inúmeras tarefas que dependem de um usuário autenticado, de
forma massivamente paralela, e **sem nunca mais precisar fazer login**.

```python
# scripts/run_report_tasks.py
from browser_core import WorkforceManager, Worker, create_selector, default_settings
from browser_core.types import SelectorType


# --- Lógica da Tarefa ---
# Esta função já parte do princípio que o worker está logado.
def extract_report_data(worker: Worker, report_id: str):
    worker.logger.info(f"Iniciando extração para o relatório: {report_id}")
    worker.navigate_to(f"https://app.exemplo.com/reports/{report_id}")

    REPORT_TABLE = create_selector("#report-data-table", SelectorType.CSS)

    # A simples chamada a .text força o worker a aguardar o elemento aparecer
    table_data = worker.get(REPORT_TABLE).text

    # ... aqui você processaria os dados da tabela ...
    processed_data = {"report_id": report_id, "content_length": len(table_data)}
    worker.logger.info(f"Extração do relatório '{report_id}' concluída.")
    return processed_data


# --- Lógica de Setup do Worker (opcional) ---
def worker_session_setup(worker: Worker) -> bool:
    worker.logger.info(f"Worker {worker.logger.extra['task_id']} está pronto e online.")
    return True


# --- Execução em Lote ---
def main():
    settings = default_settings()
    settings["browser"]["headless"] = False  # Útil para depuração

    workforce = WorkforceManager(settings)

    reports_to_process = ["Q1-2024", "Q2-2024", "Q3-2024", "Q4-2024"]

    try:
        results = workforce.run_tasks_in_squad(
            squad_size=2,
            base_snapshot_id="app_logged_in",  # Usa o estado de login
            task_items=reports_to_process,
            worker_setup_function=worker_session_setup,
            item_processing_function=extract_report_data
        )
        print("\n--- Processamento Concluído ---")
        for res in results:
            print(res)

    except Exception as e:
        print(f"\n[!!!] Uma falha ocorreu durante a execução do esquadrão: {e}")


if __name__ == "__main__":
    main()
```

### Uso da CLI

Use o comando `browser-core` no seu terminal para gerir o ecossistema.

* **Criar um snapshot base:**
    ```bash
    browser-core snapshots create-base <snapshot-id>
    ```

* **Listar snapshots disponíveis:**
    ```bash
    browser-core snapshots list
    ```

* **Inspecionar os detalhes de um snapshot:**
    ```bash
    browser-core snapshots inspect app_logged_in
    ```

* **Limpar todo o armazenamento (cuidado, operação destrutiva!):**
    ```bash
    browser-core storage clean --force
    ```

---

## Desenvolvimento e Contribuição

Se pretende contribuir para o `browser-core`, siga estes passos para configurar seu ambiente.

1. **Clone o repositório:**
   ```bash
   git clone https://github.com/gabrielbarbosel/browser-core.git
   cd browser-core
   ```

2. **Crie e ative um ambiente virtual:**
   ```bash
   python -m venv .venv
   source .venv/bin/activate  # No Linux/macOS
   # .venv\Scripts\activate    # No Windows
   ```

3. **Instale o projeto em modo "editável" com as dependências de desenvolvimento:**
   ```bash
   pip install -e ".[dev]"
    
