# Fixtures Backmarket

Ce dossier contient des fichiers HTML réels capturés depuis Backmarket.fr pour les tests.

## ⚠️ Note importante sur Backmarket

Backmarket utilise une **protection anti-bot**:
- HTTP simple retourne **403 Forbidden**
- **Playwright est OBLIGATOIRE** pour récupérer le contenu
- Temps de chargement: ~2-3 secondes

## Spécificité Backmarket

Backmarket vend des **produits reconditionnés**:
- Prix variable selon la **condition** (Correct, Bon, Excellent, etc.)
- Chaque produit a plusieurs offres avec des états différents
- Le prix extrait correspond à l'offre sélectionnée par défaut

## Fichiers

### backmarket_iphone15pro.html
- **Produit**: iPhone 15 Pro (reconditionné)
- **SKU**: iphone-15-pro
- **URL**: https://www.backmarket.fr/fr-fr/p/iphone-15-pro
- **Taille**: ~1.5 MB
- **Date capture**: 2026-01-13
- **Prix capturé**: 571 EUR (prix de l'offre par défaut)
- **Usage**: Test complet parsing smartphone reconditionné

## Structure HTML Backmarket

### JSON-LD Schema.org ✓
Backmarket utilise **JSON-LD structuré** (contrairement à Cdiscount):
```json
{
  "@type": "Product",
  "name": "iPhone 15 Pro",
  "offers": {
    "@type": "Offer",
    "price": "571.00",
    "priceCurrency": "EUR"
  }
}
```

### Sélecteurs identifiés

#### Titre
```css
h1.heading-1
```
Classes stables, simple et propre.

#### Prix
Priorité: **JSON-LD** (source la plus fiable)
Fallback: `div[data-test='price']`

#### Images
```css
img[alt]
```
URLs CDN: `https://d2e6ccujb3mkqf.cloudfront.net/...`

#### SKU
Extraction depuis l'URL:
```regex
/p/([a-z0-9-]+)
```
Exemple: `/p/iphone-15-pro` → SKU = "iphone-15-pro"

#### Condition (État du reconditionné)
```css
button[data-test='condition-button']
div[class*='condition']
```
Valeurs possibles: Correct, Bon, Très bon, Excellent, Comme neuf

## Comparaison avec autres stores

| Aspect | Amazon | Cdiscount | Backmarket |
|--------|--------|-----------|------------|
| **Anti-bot** | Faible | Fort | Fort |
| **Méthode** | HTTP OK | Playwright | Playwright |
| **JSON-LD** | Partiel | ✗ Non | ✓ Oui (complet) |
| **Sélecteurs** | Stables (IDs) | Instables | Stables (classes) |
| **SKU format** | `/dp/{ASIN}` | `/f-{cat}-{SKU}` | `/p/{slug}` |
| **Particularité** | - | Prix dynamiques | Reconditionné (condition) |

## Utilisation dans les tests

```python
@pytest.fixture
def backmarket_fixture_iphone15pro():
    fixture_path = Path(__file__).parent.parent.parent / \
        "pricewatch/app/stores/backmarket/fixtures/backmarket_iphone15pro.html"
    with open(fixture_path, "r", encoding="utf-8") as f:
        return f.read()

def test_parse_real_fixture(store, backmarket_fixture_iphone15pro):
    url = "https://www.backmarket.fr/fr-fr/p/iphone-15-pro"
    snapshot = store.parse(backmarket_fixture_iphone15pro, url)

    assert snapshot.title == "iPhone 15 Pro"
    assert snapshot.price == 571.0
    assert snapshot.reference == "iphone-15-pro"
    assert snapshot.currency == "EUR"
```

## Points d'attention pour les tests

1. **JSON-LD prioritaire** - Le prix vient du JSON-LD, pas du HTML visible
2. **Prix variable** - Change selon la condition sélectionnée
3. **Ne pas tester le prix exact** - Il varie avec les offres disponibles
4. **Tester le format** et la présence des données
5. Backmarket = **produits reconditionnés** uniquement

## Comment capturer une nouvelle fixture

```python
from pricewatch.app.scraping.pw_fetch import fetch_playwright

url = "https://www.backmarket.fr/fr-fr/p/..."
result = fetch_playwright(url, headless=True, timeout_ms=60000)

if result.success:
    with open("fixture.html", "w", encoding="utf-8") as f:
        f.write(result.html)
```

⚠️ **N'utilisez JAMAIS** `fetch_http()` pour Backmarket - cela retournera 403!

## Avantages de Backmarket

✓ **JSON-LD structuré** → Parsing très fiable
✓ **Classes CSS stables** → Moins de casse que Cdiscount
✓ **URL propre** → SKU facile à extraire
✓ **Schema.org complet** → Prix, nom, images dans JSON

## Inconvénients

✗ **Protection anti-bot** → Playwright obligatoire (lent)
✗ **Prix multiples** → Un produit = plusieurs offres selon état
✗ **Stock complexe** → Dépend de l'offre et de la condition
