work in progress with deno

This commit is contained in:
2025-08-08 17:57:42 +02:00
parent 8bdc03a221
commit f4d450c75a
7 changed files with 3122 additions and 38 deletions

View File

@@ -5,6 +5,7 @@ import login from "./scripts/login.ts";
import companySetup, { Company } from "./scripts/admin/companySetup.ts";
import path from "node:path";
import displaySetup from "./scripts/admin/displaySetup.ts";
import moduleSetup from "./scripts/admin/moduleSetup.ts";
/*
Initialisation
@@ -69,7 +70,10 @@ const globalCtx = {
// await companySetup.setupCompany(globalCtx, company);
try {
await displaySetup.setupDisplay(globalCtx);
// await displaySetup.setupDisplay(globalCtx);
await moduleSetup.configureModule(globalCtx, {moduleName: 'TIERS' ,enabled: false, onConfiguration: async () => {
await globalCtx.page.screenshot({path: 'save.png'})
}});
} catch (error) {
console.error(error);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 104 KiB

View File

@@ -61,7 +61,23 @@ async function setupLoginPage(
]),
1,
);
}
async function setGlobalCSS(
{ page, dolibarrAddress, imgFolderPath }: {
page: Page;
dolibarrAddress: string;
imgFolderPath: string;
}, cssStyleSheet: string) {
await page.goto(`${dolibarrAddress}/admin/ihm.php?mode=css`);
await forms.fillForm(
{page, imgFolderPath},
{cssStyleSheet},
new Map([
["cssStyleSheet","MAIN_IHM_CUSTOM_CSSaceeditorid:ace"]
]),
1,
)
}
async function setupDisplay(
@@ -73,17 +89,22 @@ async function setupDisplay(
},
): Promise<void> {
await login.doAdminLogin(globalCtx);
await removeLoginForgottenPasswordLink(globalCtx);
await setupLoginPage(globalCtx, {
removeHelpLink: true,
HTMLMessage: `
<div style="text-align:center"><span style="color:#000000">Bienvenue chez </span><span style="color:#2c3e50"><em>Gabriel Radureau</em></span><br />
<span style="color:#000000"><em>l&#39;</em></span><span style="color:#e74c3c"><em>ar</em></span><span style="color:#c0392b"><em>change</em></span><span style="color:#000000"><em> du </em></span><span style="color:#2ecc71"><em>code</em></span><br />
<span style="color:#000000">🏹💻🪽<br />
<em><span style="font-size:8px">Pariez sur le bon sagitaire</span></em></span></div>
`.trim(),
backgroundImage: "$IMG/loginBackground.jpeg",
});
// await removeLoginForgottenPasswordLink(globalCtx);
// await setupLoginPage(globalCtx, {
// removeHelpLink: true,
// HTMLMessage: `
// <div style="text-align:center"><span style="color:#000000">Bienvenue chez </span><span style="color:#2c3e50"><em>Gabriel Radureau</em></span><br />
// <span style="color:#000000"><em>l&#39;</em></span><span style="color:#e74c3c"><em>ar</em></span><span style="color:#c0392b"><em>change</em></span><span style="color:#000000"><em> du </em></span><span style="color:#2ecc71"><em>code</em></span><br />
// <span style="color:#000000">🏹💻🪽<br />
// <em><span style="font-size:8px">Pariez sur le bon sagitaire</span></em></span></div>
// `.trim(),
// backgroundImage: "$IMG/loginBackground.jpeg",
// });
await setGlobalCSS(globalCtx, `
body {
color: black;
}
`.trim());
}
export default {

View File

@@ -0,0 +1,47 @@
// info-box
import { 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"]
async function configureModule(
globalCtx: {
page: Page;
dolibarrAddress: string;
adminCredentials: { username: string; password: string };
},
{
moduleName,
enabled,
onConfiguration,
}: {
moduleName: string;
enabled: boolean;
onConfiguration?: CallableFunction;
}
): Promise<void> {
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();
}
}
export default {
configureModule,
}

View File

@@ -0,0 +1,4 @@
# Divers
## Modèle de génération et contrôle des codes tiers (client ou fournisseur)

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,52 @@
import type { Page } from "playwright";
import type { Locator, Page } from "playwright";
async function toggleOnOff({page}:{page:Page}, label: string, on: boolean) : Promise<void>{
/*
CKEditor - The WYSIWYG Editor https://ckeditor.com/wysiwyg-editor-open-source/
*/
async function CKEditor(
{ page }: { page: Page },
inputName: string,
value: string,
): Promise<void> {
const col = page.locator("td", {
has: page.locator(`textarea[name="${inputName}"]`),
});
// const htmlEditor = col.frameLocator('iframe').locator('body');
const rawHTMLEditor = col.locator("textarea.cke_editable");
const row = page.locator("tr").filter({
has: page.locator("td", { hasText: label }),
});
const hideBtn = row.locator(`[title="Désactivé"]`);
const showBtn = row.locator(`[title="Actif"]`);
if (!await hideBtn.isVisible() && !await showBtn.isVisible()) {
throw new Error("Show/Hide button not found");
}
if (on && await hideBtn.isVisible()) await hideBtn.click();
if (!on && await showBtn.isVisible()) await showBtn.click();
const htmlToggleBtn = col.getByRole("button").filter({ hasText: /Source/ });
await htmlToggleBtn.click();
await rawHTMLEditor.fill(value);
await htmlToggleBtn.click();
}
/*
Ace - The High Performance Code Editor for the Web https://ace.c9.io/
*/
async function ACE(
{ page }: { page: Page },
inputName: string,
value: string,
): Promise<void> {
const input = page.locator(`pre[id="${inputName}"]`).locator("textarea");
await input.focus();
const CtrlKey = Deno.build.os === 'darwin' ? 'Meta' : 'Control';
await page.keyboard.press(CtrlKey+"+A")
await page.keyboard.press("Backspace")
await input.fill(value);
}
async function toggleOnOff(
containerLocator: Locator,
on: boolean,
): Promise<void> {
const hideBtn = containerLocator.locator(`[title="Désactivé"]`);
const showBtn = containerLocator.locator(`[title="Actif"], [title="Activé"]`);
if (!await hideBtn.isVisible() && !await showBtn.isVisible()) {
throw new Error("Show/Hide button not found");
}
if (on && await hideBtn.isVisible()) await hideBtn.click();
if (!on && await showBtn.isVisible()) await showBtn.click();
}
// Fonction générique `fillForm` pour remplir des formulaires
@@ -19,7 +54,7 @@ async function fillForm<T>(
{ page, imgFolderPath }: { page: Page; imgFolderPath: string },
data: T,
inputNames: Map<keyof T, string>,
submit: number = 0,
submit: number = 0, // submit is a number to specify which submit buttton to use, 0 means no submit
) {
for (const [attr, input] of inputNames) {
const attrValue = data[attr];
@@ -43,20 +78,19 @@ async function fillForm<T>(
);
break;
}
case "cke": { // CKEditor https://ckeditor.com/wysiwyg-editor-open-source/
const col = page.locator("td", {has: page.locator(`textarea[name="${inputName}"]`)});
const htmlEditor = col.frameLocator('iframe').locator('body');
const rawHTMLEditor = col.locator('textarea.cke_editable');
const htmlToggleBtn = col.getByRole("button").filter({hasText: /Source/});
await htmlToggleBtn.click();
await rawHTMLEditor.fill(attrValue as string);
await htmlToggleBtn.click();
await htmlEditor.screenshot({path: 'save.png'});
case "cke":
CKEditor({ page }, inputName, attrValue as string);
break;
case "ace":
await ACE({ page }, inputName, attrValue as string);
break;
}
case "toggle":
await toggleOnOff({page}, inputName, Boolean(JSON.parse(attrValue as string)))
await toggleOnOff(
page.locator("tr").filter({
has: page.locator("td", { hasText: inputName }),
}),
Boolean(JSON.parse(attrValue as string)),
);
break;
default:
await page.fill(
@@ -72,4 +106,7 @@ async function fillForm<T>(
export default {
fillForm,
toggleOnOff,
CKEditor,
ACE,
};