# Tester l’Interactivity API et les block bindings de WordPress 6.5

> WordPress 6.5 a introduit l'Interactivity API et les block bindings. Deux fonctionnalités récentes qui demandent une approche de test différente de celle utilisée pour un bloc classique.

- Auteur : Clément Hadrot
- Publié le : 2024-06-13
- Mis à jour le : 2024-06-13
- Catégorie : Tests
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tests/tester-interactivity-api-block-bindings/

## L’essentiel

- Des directives data-wp- à couvrir en priorité dans vos tests
- Un store JavaScript testable indépendamment du rendu
- Les block bindings à vérifier côté PHP et côté affichage

WordPress 6.5, sorti en avril, a introduit deux nouveautés qui changent la façon d'écrire des blocs interactifs : l'Interactivity API, un système standardisé pour ajouter de l'interactivité côté front sans dépendre de React complet, et les block bindings, qui permettent de connecter dynamiquement un attribut de bloc à une source de données (une métadonnée d'article, un champ personnalisé) sans écrire de PHP de rendu spécifique. Ces deux fonctionnalités, encore jeunes, demandent d'adapter la stratégie de test habituelle des blocs Gutenberg.

Cet article détaille comment tester un bloc qui utilise l'Interactivity API, avec ses directives `data-wp-*` et son store JavaScript, ainsi que la vérification des block bindings à la fois côté PHP et côté rendu final.

## Comprendre ce qu'il y a à tester dans l'Interactivity API

Un bloc interactif construit avec cette API repose sur trois éléments distincts, qui appellent chacun une stratégie de test différente : le balisage HTML enrichi de directives (`data-wp-interactive`, `data-wp-on--click`, `data-wp-bind--*`), un store JavaScript qui contient l'état et la logique, et le rendu final observable dans le navigateur une fois le script d'hydratation exécuté.

```
<div
    data-wp-interactive="mon-plugin"
    data-wp-context='{ "compteur": 0 }'
>
    <button data-wp-on--click="actions.incrementer">
        Cliquer
    </button>
    <span data-wp-text="state.texteAffiche"></span>
</div>
```

## Tester le store en isolation avec Jest

Le store JavaScript, déclaré via `store()` depuis `@wordpress/interactivity`, contient généralement de la logique pure (calculs, dérivations d'état) qui se teste très bien avec Jest, sans avoir besoin de monter le DOM complet :

```
import { store } from '@wordpress/interactivity';

const { state, actions } = store( 'mon-plugin', {
    state: {
        compteur: 0,
        get texteAffiche() {
            return `Compteur : ${ state.compteur }`;
        },
    },
    actions: {
        incrementer() {
            state.compteur++;
        },
    },
} );

export { state, actions };
```

```
import { state, actions } from '../view';

describe( 'Store du compteur', () => {
    beforeEach( () => {
        state.compteur = 0;
    } );

    it( 'incrémente le compteur', () => {
        actions.incrementer();
        expect( state.compteur ).toBe( 1 );
    } );

    it( 'met à jour le texte affiché', () => {
        actions.incrementer();
        expect( state.texteAffiche ).toBe( 'Compteur : 1' );
    } );
} );
```

> L'essentiel à retenir : Des directives data-wp- à couvrir en priorité dans vos tests ; Un store JavaScript testable indépendamment du rendu ; Les block bindings à vérifier côté PHP et côté affichage

## Vérifier le rendu réel avec un test E2E ciblé

La logique testée en Jest ne garantit pas que les directives `data-wp-*` sont correctement câblées dans le HTML, ni que le script d'hydratation s'exécute sans erreur dans un vrai navigateur. Un test E2E ciblé, avec Playwright et `@wordpress/e2e-test-utils-playwright`, reste nécessaire pour ce niveau de vérification :

```
test( 'le clic incrémente le compteur affiché', async ( { page, editor, admin } ) => {
    await admin.createNewPost();
    await editor.insertBlock( { name: 'mon-plugin/compteur' } );
    await editor.publishPost();

    const url = page.url();
    await page.goto( url );

    await page.click( 'button' );

    await expect( page.locator( 'span' ) ).toHaveText( 'Compteur : 1' );
} );
```

Ce test valide l'ensemble de la chaîne : sérialisation correcte des directives dans le HTML publié, chargement du module d'interactivité côté front, et exécution effective de l'action au clic.

## Tester les block bindings côté PHP

Les block bindings permettent de connecter un attribut de bloc, comme le contenu d'un paragraphe ou la source d'une image, à une valeur dynamique via un callback enregistré avec `register_block_bindings_source()`. Ce callback PHP se teste comme n'importe quelle fonction, avec `WP_UnitTestCase` :

```
register_block_bindings_source( 'mon-plugin/prix-produit', array(
    'label'              => __( 'Prix du produit', 'mon-plugin' ),
    'get_value_callback' => 'mon_plugin_get_prix_binding',
) );

function mon_plugin_get_prix_binding( $source_args, $block_instance ) {
    $prix = get_post_meta( $block_instance->context['postId'], '_prix', true );
    return $prix ? number_format_i18n( (float) $prix, 2 ) . ' €' : '';
}
```

```
class Test_Binding_Prix extends WP_UnitTestCase {

    public function test_formate_le_prix_en_euros() {
        $post_id = $this->factory()->post->create();
        update_post_meta( $post_id, '_prix', '19.9' );

        $bloc_instance = new stdClass();
        $bloc_instance->context = array( 'postId' => $post_id );

        $resultat = mon_plugin_get_prix_binding( array(), $bloc_instance );

        $this->assertStringContainsString( '19,90', $resultat );
    }
}
```

Ce test vérifie la logique de formatage isolément, sans avoir besoin de publier réellement le bloc dans l'éditeur.

## Une répartition claire des responsabilités de test

- **Jest** pour la logique pure du store d'interactivité : dérivations d'état, actions qui ne touchent pas le DOM.
- **PHPUnit** pour les callbacks de block bindings et toute logique serveur associée.
- **E2E ciblé** pour vérifier que les directives sont bien câblées et que l'hydratation fonctionne réellement dans un navigateur, sur un nombre restreint de scénarios critiques.

> Sur nos premiers projets utilisant l'Interactivity API, nous avons appris à ne pas sur-tester le store en E2E : ce que Jest peut vérifier en quelques millisecondes n'a pas besoin d'un navigateur complet. Le E2E doit se concentrer sur ce que lui seul peut prouver, le câblage réel entre le balisage et le comportement observé.

## En résumé

Tester un bloc qui exploite l'Interactivity API et les block bindings de WordPress 6.5 demande de répartir l'effort sur trois couches distinctes plutôt que de tout pousser en E2E : Jest pour la logique du store, PHPUnit pour les callbacks de binding côté serveur, et un E2E ciblé pour valider l'hydratation réelle dans le navigateur. Cette répartition, encore en train de se stabiliser dans les pratiques de la communauté, garde les suites de tests rapides tout en couvrant ce qui compte vraiment sur ces fonctionnalités encore jeunes.
