Test d’API via le contexte de formulaire

La méthode FormComponent.execute() exécute un code JavaScript arbitraire à l’intérieur du contexte de formulaire Dynamics 365, directement sur l’API Xrm. Cette approche permet une approche de test hybride. Utilisez playwright pour accéder à un enregistrement, puis utilisez-le execute() pour valider ou manipuler des données par programmation. Cette approche remplace les interactions de l’interface utilisateur qui sont lentes ou non fiables.

Fonctionnement

Lorsque vous ouvrez un enregistrement d’application piloté par modèle dans le navigateur, l’objet Xrm est disponible sur window.Xrm. La execute() méthode relie le contexte Playwright Node.js et le contexte de la page du navigateur. Il injecte votre fonction dans le navigateur et retourne le résultat :

const result = await modelDrivenApp.form.execute(async (formContext) => {
  // This code runs inside the browser, with access to the full Xrm API
  return formContext.getAttribute('nwind_ordernumber')?.getValue();
});

console.log(`Order number from Xrm: ${result}`);

formContext est l’objet Dynamics 365 Xrm.Form.FormContext standard. Vous pouvez utiliser n’importe quelle méthode d’API clientE Xrm.

Lire les valeurs de champ via Xrm

Permet execute() de lire les valeurs de champ sans compter sur les sélecteurs DOM :

// Read a text field
const orderNumber = await mda.form.execute(
  (ctx) => ctx.getAttribute('nwind_ordernumber')?.getValue()
);

// Read a lookup field
const customer = await mda.form.execute((ctx) => {
  const lookup = ctx.getAttribute('nwind_customerid')?.getValue();
  return lookup?.[0]?.name ?? null;
});

// Read a choice/option set
const statusCode = await mda.form.execute(
  (ctx) => ctx.getAttribute('nwind_orderstatusid')?.getValue()
);

Conseil / Astuce

La lecture via l’API Xrm est plus fiable que la lecture des valeurs d’entrée DOM. L’API Xrm retourne la valeur typée interne, quel que soit le rendu du champ.

Écrire des valeurs de champ via Xrm

Définissez des valeurs de champ par programmation sans remplir d’éléments d’entrée :

await mda.form.execute((ctx) => {
  ctx.getAttribute('nwind_ordernumber')?.setValue('ORD-API-001');
  ctx.getAttribute('nwind_notes')?.setValue('Updated via Xrm API');
});

Note

La définition de valeurs via execute() contourne les événements d’entrée du navigateur. Pour les champs avec onChange des règles métier, cette approche équivaut à ce qu’un plug-in ou un script ferait. Pour les champs qui dépendent du focus d’entrée du navigateur ou des événements flous, utilisez mda.form.setAttribute(), ce qui déclenche le chemin d’interface utilisateur.

Valider des règles de logique métier

Testez si les règles métier au niveau du champ ou au niveau du formulaire s'activent correctement.

// Open a record
await mda.grid.openRecord({ rowNumber: 0 });

// Trigger a field change
await mda.form.setAttribute('nwind_orderstatusid', 'Shipped');

// Validate that a business rule made the tracking field required
const requiredLevel = await mda.form.execute(
  (ctx) => ctx.getAttribute('nwind_trackingnumber')?.getRequiredLevel()
);

expect(requiredLevel).toBe('required');

Vérifier la validité du formulaire et l’état modifié

Utilisez les méthodes isDirty(), isValid() et save() pour vérifier que les modifications du formulaire sont suivies correctement et que la validation passe avant et après l’enregistrement.

// After making changes, verify the form is dirty
const isDirty = await mda.form.isDirty();
expect(isDirty).toBe(true);

// Save and verify no validation errors
await mda.form.save();
expect(await mda.form.isValid()).toBe(true);
expect(await mda.form.isDirty()).toBe(false);

Exécuter des appels Xrm WebApi

L’api Xrm.WebApi complète est disponible à l’intérieur execute(). Utilisez-le pour interroger ou muter des enregistrements Dataverse directement.

// Query Dataverse records without navigating the grid
const result = await mda.form.execute(async (formContext) => {
  const response = await (window as any).Xrm.WebApi.retrieveMultipleRecords(
    'nwind_orders',
    '?$filter=nwind_orderstatus eq 1&$select=nwind_ordernumber&$top=5'
  );
  return response.entities.map((e: any) => e.nwind_ordernumber);
});

expect(result.length).toBeGreaterThan(0);

Important

Xrm.WebApi les appels s’exécutent dans le contexte du navigateur et sont soumis aux limites de l’API Dataverse et au rôle de sécurité de l’utilisateur de test. Ils sont déduits de votre quota d'appels API.

Tester les effets secondaires du plugin

Après avoir enregistré un enregistrement, utilisez cette option execute() pour vérifier qu’un plug-in a correctement mis à jour un champ associé.

// Create a new order via UI
await mda.navigateToFormView('nwind_orders');
await page.locator('input[data-id="nwind_ordernumber.fieldControl-text-box-text"]').fill('ORD-PLUGIN-TEST');
await mda.form.save();

// Wait for plugin async processing
await page.waitForTimeout(3000);

// Verify the plugin set the calculated total
const calculatedTotal = await mda.form.execute(
  (ctx) => ctx.getAttribute('nwind_calculatedtotal')?.getValue()
);

expect(calculatedTotal).toBeGreaterThan(0);

Combiner la navigation de l’interface utilisateur avec des assertions d’API

Un modèle courant consiste à parcourir l’interface utilisateur et à valider l’état via l’API. L’exemple suivant ouvre une commande à partir de la grille, clique sur le bouton Barre de commande Envoyer une commande , puis utilise l’API Xrm pour affirmer que l’état de la commande a été mis à jour en attente.

test('submit order sets status to Pending', async ({ page, context }) => {
  const app = new AppProvider(page, context);
  await app.launch({ ... });
  const mda = app.getModelDrivenAppPage();

  // Navigate to the order via the grid (UI path)
  await mda.navigateToGridView('nwind_orders');
  await mda.grid.filterByKeyword('ORD-001');
  await mda.grid.waitForGridLoad();
  await mda.grid.openRecord({ rowNumber: 0 });

  // Click Submit via the command bar (UI path)
  await mda.commanding.clickButton('Submit Order');
  await page.waitForTimeout(2000);

  // Validate the status via Xrm API (API assertion)
  const status = await mda.form.execute(
    (ctx) => ctx.getAttribute('nwind_orderstatusid')?.getValue()
  );

  expect(status).toBe(100000001); // Pending option set value
});

Informations de référence sur l’API de contexte de formulaire

Le rappel execute() reçoit un objet de contexte de formulaire standard Dynamics 365 . Méthodes clés :

Méthode Description
getAttribute(name) Récupérer un attribut de formulaire par nom de schéma
getAttribute(name).getValue() Lire la valeur de champ actuelle
getAttribute(name).setValue(v) Définir la valeur du champ
getAttribute(name).getRequiredLevel() Lire 'none', 'recommended' ou 'required'
getAttribute(name).setRequiredLevel(level) Définir le niveau requis
getControl(name).setVisible(bool) Afficher ou masquer un champ
getControl(name).setDisabled(bool) Activer ou désactiver un champ
ui.tabs.get(name).setVisible(bool) Afficher ou masquer un onglet
data.entity.getId() Obtenir le GUID de l'enregistrement en cours
data.entity.getEntityName() Obtenir le nom de l’entité logique
data.save() Enregistrer le formulaire par voie de programmation

Pour obtenir la référence complète de l’API client Xrm, consultez la référence de l’API client Microsoft Dataverse.

Étapes suivantes

Voir également