Component
createComponent permet de décrire un fragment d'interface réutilisable.
Un composant définit où il se trouve, quels éléments il expose, quelles méthodes il fournit et quels sous-composants il embarque.
En pratique, c'est la brique de base pour éviter de répéter des sélecteurs et des helpers partout dans les tests.
Exemple simple
ts
import { Actions, createComponent, createWebsite, type Website } from "@duplojs/playwright";
import test from "playwright/test";
interface TestFixtures {
website: Website;
}
const testClient = test.extend<TestFixtures>({
async website({ page, context }, use) {
const website = createWebsite({
playwrightPage: page,
playwrightBrowserContext: context,
envConfig: {
baseUrl: "https://example.com",
},
});
await use(website);
},
});
const searchForm = createComponent(
"searchForm",
{
getMainElement({ body }) {
return body.locator("[data-search-form]");
},
getElements({ mainElement }) {
return {
input: mainElement.locator("input"),
submitButton: mainElement.locator("button[type='submit']"),
};
},
getMethods({ elements }) {
return {
async fillSearch(value: string) {
await elements.input.fill(value);
},
};
},
},
);
testClient("component example", async({ website }) => {
const component = searchForm(website);
await component.methods.fillSearch("duplojs");
await Actions.click(component, "submitButton");
});Ce qui se passe ici
- l'exemple montre un client Playwright étendu, puis la définition du composant.
createComponent(...)décrit un composantsearchForm.getMainElement(...)définit son élément racine.getElements(...)expose des locators nommés réutilisables.getMethods(...)permet de regrouper une action métier simple dans le composant.
Paramètres
name- le nom public du composant dans le modèle de test.params.getMainElement- retourne le locator racine du composant.params.getElements?- expose des éléments nommés à partir du composant.params.getMethods?- expose des méthodes construites à partir du contexte du composant.params.components?- enregistre des sous-composants accessibles depuis le composant.
Syntaxe
ts
interface CreateComponentParams {
getMainElement(params: {
body: Locator;
}): Locator;
getElements?(params: {
mainElement: Locator;
body: Locator;
}): Record<string, Locator>;
getMethods?(params: {
mainElement: Locator;
body: Locator;
elements: Record<string, Locator> | undefined;
website: Website;
}): Record<string, (...args: any[]) => any>;
components?: ComponentEngine[];
}
type ComponentEngine = (website: Website) => Component;
interface Component {
name: string;
mainElement: Locator;
elements: Record<string, Locator> | undefined;
methods: Record<string, (...args: any[]) => any> | undefined;
iWantToSeeComponent(componentName: string): Promise<Component>;
}À quoi ça sert ?
Component sert à centraliser dans un même endroit :
- les sélecteurs d'un bloc d'interface
- les petites actions métier réutilisables
- la composition entre plusieurs fragments d'interface
Autrement dit, il permet d'écrire des tests plus lisibles et plus stables quand une même zone d'interface revient souvent.
Voir aussi
Website- pour instancier un composant dans un contexte de test.Page- pour construire une page sur le même modèle qu'un composant, avec en plusmakePath(...).Component Interaction- pour créer des interactions réutilisables sur les éléments d'un composant.Actions- pour les actions prêtes à l'emploi sur les composants.Assertions- pour les assertions prêtes à l'emploi sur les composants.
