Six colonnes et rien pour s'y retrouver : au-delà de vingt salariés, l'effectif se parcourait au défilement. Recherche par prénom, nom ou matricule, et quatre filtres — établissement, rôle, type de contrat, présence — plus le tri. Les critères vivent dans l'adresse et non dans le composant : un effectif filtré s'envoie par lien, et le retour arrière défait le dernier choix plutôt que de vider la page. Ils sont appliqués en base, pas après lecture : plusieurs centaines de dossiers ne se filtrent pas en mémoire à chaque affichage. Le tri par nom reste en mémoire, lui : Postgres range « Étienne » après « Etchegaray », un lecteur français avant. Les colonnes suivent : rôle, mobile, rattachement et état de l'invitation remplacent le matricule, qui ne s'affiche plus que sous le nom des salariés sans compte applicatif — ceux pour qui c'est la seule adresse. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
81 lines
3.6 KiB
TypeScript
81 lines
3.6 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
|
|
/**
|
|
* Registre de paramétrage et création d'un salarié sans accès applicatif.
|
|
*
|
|
* Ces parcours n'éprouvent pas l'authentification : ils réutilisent la session
|
|
* commune plutôt que d'ouvrir la leur. La direction porte un second facteur, et
|
|
* un code TOTP ne sert qu'une fois — deux connexions parallèles sur ce compte
|
|
* échoueraient, à raison.
|
|
*/
|
|
|
|
test('la direction lit et alimente le registre de paramétrage', async ({
|
|
page,
|
|
}) => {
|
|
await page.goto('/reglages/registre');
|
|
|
|
await expect(
|
|
page.getByRole('heading', { name: 'Registre de paramétrage juridique' }),
|
|
).toBeVisible();
|
|
|
|
const parameter = `Durée quotidienne maximale ${Date.now()}`;
|
|
// Ciblage par attribut `name` : les libellés portent un texte d'aide, et
|
|
// celui de « Source » contient lui-même le mot « valeur », ce qui rend la
|
|
// correspondance par libellé ambiguë.
|
|
const form = page.locator('form').filter({ hasText: 'Consigner' });
|
|
await form.locator('input[name="key"]').fill(parameter);
|
|
await form.locator('input[name="value"]').fill('10 h');
|
|
await form
|
|
.locator('input[name="source"]')
|
|
.fill('IDCC 1517 — texte consolidé Legifrance');
|
|
await form.locator('input[name="population"]').fill('Tous les salariés');
|
|
await page.getByRole('button', { name: 'Consigner' }).click();
|
|
|
|
const row = page.getByRole('row', { name: new RegExp(parameter) });
|
|
await expect(row).toBeVisible();
|
|
|
|
// Consigné n'est pas approuvé : la matrice exige un approbateur nommé.
|
|
await row.getByRole('button', { name: 'Approuver' }).click();
|
|
await expect(row.getByText(/Approuvé le/)).toBeVisible();
|
|
});
|
|
|
|
test('un salarié sans compte applicatif est créable', async ({ page }) => {
|
|
await page.goto('/equipe');
|
|
|
|
await expect(page.getByRole('heading', { name: 'Équipe' })).toBeVisible();
|
|
// L'effectif vient de la base, pas du module de démonstration : un annuaire
|
|
// fabriqué à l'écran ne se filtrerait pas par matricule.
|
|
await page
|
|
.getByPlaceholder('Rechercher par prénom, nom ou matricule.')
|
|
.fill('E0001');
|
|
await expect(page.getByText(/^1 sur \d+ salariés$/)).toBeVisible();
|
|
await page.goto('/equipe');
|
|
|
|
// Nom unique par exécution : la base de test n'est pas remise à zéro entre
|
|
// deux passages, et un nom fixe finirait par désigner plusieurs salariés.
|
|
const matricule = `E9${Date.now() % 100000}`;
|
|
const nom = `Sanscompte${matricule}`;
|
|
const form = page.locator('form').filter({ hasText: 'Ajouter' });
|
|
await form.locator('input[name="firstName"]').fill('Sans');
|
|
await form.locator('input[name="lastName"]').fill(nom);
|
|
await form.locator('input[name="employeeNumber"]').fill(matricule);
|
|
await page.getByRole('button', { name: 'Ajouter' }).click();
|
|
await expect(page.getByText('Salarié ajouté.')).toBeVisible();
|
|
|
|
// Rechargement explicite : ce qui est vérifié ici est la persistance et la
|
|
// présence dans l'annuaire, pas le moment exact où la revalidation atteint
|
|
// le rendu courant.
|
|
await page.reload();
|
|
|
|
// Un salarié sans adresse doit exister : la plupart des équipes de vente ne
|
|
// se connectent jamais à l'outil.
|
|
// Sans compte applicatif, l'annuaire affiche le matricule sous le nom : c'est
|
|
// la seule adresse à laquelle on désigne ce salarié.
|
|
await expect(page.getByText(`Matricule ${matricule}`)).toBeVisible();
|
|
// Le nom vit sur le dossier, pas sur le compte : un salarié sans accès
|
|
// applicatif doit tout de même figurer nommément au registre du personnel.
|
|
await expect(
|
|
page.getByRole('link', { name: new RegExp(`Sans ${nom}`) }),
|
|
).toBeVisible();
|
|
});
|