// info-box import { Locator, Page } from "playwright"; import forms from "../forms.ts"; import login from "../login.ts"; // span.info-box-title has-text /moduleName/ // span.fa-cog[title="Configuration"] type ModuleCtx = { page: Page; dolibarrAddress: string; adminCredentials: { username: string; password: string }; }; async function configureModule( globalCtx: ModuleCtx, { moduleName, enabled, onConfiguration, }: { moduleName: string; enabled: boolean; onConfiguration?: CallableFunction; } ): Promise { const {page, dolibarrAddress}= globalCtx; await login.doAdminLogin(globalCtx); await page.goto(`${dolibarrAddress}/admin/modules.php?mode=commonkanban`); const moduleDiv = page.locator('.info-box', { has: page.locator('.info-box-title',{ hasText: new RegExp('^'+moduleName+'\n?$','i') }) }); await forms.toggleOnOff(moduleDiv, enabled); if(enabled && onConfiguration!==undefined) { await moduleDiv.locator(`span.fa-cog[title="Configuration"]`).click(); await onConfiguration(); } } /* Enable Dolibarr's REST API / Web services module. Activation maps to llx_const.MAIN_MODULE_API=1; in the UI this is the module card on /admin/modules.php (kanban mode). In fr_FR the card title is "API/Web services REST (serveur)" (family "Interfaces"). NOTE: confirm the exact card title on the first real run against an installed sandbox — the label has not been verified live here. To stay resilient we try the known fr_FR label first (anchored exact match, same as configureModule), and if that card is not present we fall back to matching ANY module card whose title contains "API ... REST" / "REST ... API" in either order. */ async function enableApiModule(globalCtx: ModuleCtx): Promise { const {page, dolibarrAddress}= globalCtx; // fr_FR label as observed in the module catalogue. Confirm on first real run. const knownLabel = "API/Web services REST (serveur)"; await login.doAdminLogin(globalCtx); await page.goto(`${dolibarrAddress}/admin/modules.php?mode=commonkanban`); const exactCard = page.locator('.info-box', { has: page.locator('.info-box-title',{ hasText: new RegExp('^'+knownLabel+'\n?$','i') }) }); if(await exactCard.count() > 0) { await forms.toggleOnOff(exactCard, true); return; } // Fallback: the exact fr_FR label was not found (different Dolibarr version, // locale, or wording). Match any card whose title looks like the REST API // module regardless of word order. const fuzzyCard = page.locator('.info-box', { has: page.locator('.info-box-title',{ hasText: /API.*REST|REST.*API/i }) }); if(await fuzzyCard.count() === 0) { throw new Error( `REST API module card not found on ${dolibarrAddress}/admin/modules.php `+ `(tried exact label "${knownLabel}" and /API.*REST|REST.*API/i). `+ `Confirm the card title in the running sandbox.`, ); } // If several cards match the fuzzy pattern, toggle the first one only. await forms.toggleOnOff(fuzzyCard.first() as Locator, true); } export default { configureModule, enableApiModule, }