Introduction
@duplojs/playwright est une surcouche légère au-dessus de Playwright pour structurer une suite de tests autour du site testé.
L'idée n'est pas de remplacer Playwright, mais de lui ajouter un modèle plus lisible :
- un
Websitepour porter le contexte global du test - des
Pagepour les écrans navigables - des
Componentpour les fragments d'interface réutilisables - des helpers métier pour éviter de répéter les mêmes intentions partout
Ce que la lib apporte
- une manière stable d'organiser la suite de tests quand elle grossit
- un vocabulaire plus proche du site testé que d'une suite de locators
- des interactions et assertions réutilisables
- des steps Playwright plus parlants dans les rapports
La philosophie
Le but est de tester un site avec des objets métier, pas d'écrire tous les tests directement contre page.locator(...).
Concrètement, au lieu d'avoir des sélecteurs et des helpers dispersés dans chaque test, on cherche à :
- centraliser la structure du site
- réutiliser les comportements fréquents
- garder des tests orientés intention
Exemple minimal
ts
import { Actions, createComponent, createPage, 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']"),
};
},
},
);
const HomePage = createPage(
"home",
{
makePath() {
return "/";
},
getMainElement({ body }) {
return body.locator("main");
},
components: [SearchForm],
},
);
testClient("home page", async({ website }) => {
const homePage = await website.iNavigateTo(HomePage);
const searchForm = await homePage.iWantToSeeComponent("searchForm");
await Actions.fill(searchForm, "input", "superValue");
await Actions.click(searchForm, "submitButton");
});Ce qui se passe ici
- le client Playwright étendu prépare
createWebsite(...)une fois. createPage(...)décrit un écran navigable.- le test récupère
websitedepuis ce client. website.iNavigateTo(...)permet de parler en termes de page, pas seulement en termes d'URL.
