Testen von KI-generierten Apps (Gen UX)

Gen UX-Apps sind KI-generierte Power Apps, die durch die Erfahrung mit natürlicher Sprache in Power Apps erstellt werden. Sie verwenden dieselbe Canvas-Runtime wie von Hand erstellte Canvas-Apps, sodass die gleiche iframe-Bereichsdefinition und data-control-name-muster gelten. Die GenUxPage Klasse stellt Hilfsprogramme bereit, die für die generierte Steuerelementstruktur abgestimmt sind.

Unterschiede zwischen Gen-UX-Apps und Canvas-Apps

Gen UX-Apps teilen die Canvas-Laufzeit und den iframe[name="fullscreen-app-host"] Host-Frame. Die Hauptunterschiede sind:

  • Steuerelementnamen werden automatisch generiert (z. B. Button1, TextInput1) und können sich ändern, wenn Sie die App neu generieren.
  • Die KI-Eingabeaufforderung steuert das App-Layout, sodass die Struktur zwischen Apps variiert.
  • Die Klasse GenUxPage stellt Hilfsfunktionen bereit, die auf semantische Rollen und ARIA-Labels statt auf Kontrollnamen basieren, wodurch die Tests widerstandsfähiger gegenüber einer Neugenerierung werden.

Starten einer Gen-UX-App

Verwenden Sie die AppProvider klasse, um eine Gen-UX-App im Abspielmodus zu starten, und dabei eine direkte URL übergeben, um das Maker-Portal zu überspringen und direkt mit der Canvas-Runtime zu verbinden.

import { test, expect } from '@playwright/test';
import {
  AppProvider,
  AppType,
  AppLaunchMode,
  buildCanvasAppUrlFromEnv,
} from 'power-platform-playwright-toolkit';

const GEN_UX_APP_URL = buildCanvasAppUrlFromEnv();

test.beforeEach(async ({ page, context }) => {
  const app = new AppProvider(page, context);

  await app.launch({
    app: 'My AI App',
    type: AppType.Canvas,
    mode: AppLaunchMode.Play,
    skipMakerPortal: true,
    directUrl: GEN_UX_APP_URL,
  });
});

Tip

Verwenden Sie skipMakerPortal: true mit directUrl, um Power Apps zu umgehen und die Startzeit um 10 bis 20 Sekunden zu reduzieren.

Bereichslocatoren für den Canvas-Frame

Alle Interaktionen auf das iFrame der Zeichenfläche beschränken.

const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');

Warten, bis die App geladen wird

Gen-UX-Apps können 30 bis 60 Sekunden dauern, um Dataverse-Daten zu laden. Warten Sie vor der Interaktion auf ein bekanntes Element:

// Wait for a gallery or any visible UI element
await canvasFrame
  .locator('[data-control-part="gallery-item"]')
  .first()
  .waitFor({ state: 'visible', timeout: 60000 });

Interagieren mit Steuerelementen mit der ARIA-Bezeichnung

Gen-UX-Apps generieren Steuerelemente mit von Ihrer Eingabeaufforderung abgeleiteten ARIA-Bezeichnungen. Verwenden Sie ARIA-Bezeichnungsselektoren, um die Resilienz zu erhöhen:

Ausfüllen einer Texteingabe

Wählen Sie Texteingabefelder anhand ihres aria-label-Attributs aus, das mit dem Anzeigenamen der Dataverse-Spalte übereinstimmt, und verwenden Sie die fill()-Methode von Playwright, um Werte einzugeben.

await canvasFrame.locator('input[aria-label="Name"]').fill('Contoso Ltd');
await canvasFrame.locator('input[aria-label="Phone"]').fill('555-9000');

Klicken Sie auf eine Schaltfläche

Suchen Sie Schaltflächen, indem Sie den role="button"-Selektor mit dem von der KI basierend auf Ihrem Prompt zugewiesenen aria-label kombinieren.

await canvasFrame.locator('[role="button"][aria-label="Save"]').click();
await canvasFrame.locator('[role="button"][aria-label="New record"]').click();

Aus einer Dropdownliste auswählen

Klicken Sie auf das Dropdown, um die Optionsliste zu erweitern, und wählen Sie dann die gewünschte Option aus, indem Sie den sichtbaren Text abgleichen.

const dropdown = canvasFrame.locator('[aria-label="Category"]');
await dropdown.click();
await canvasFrame.locator('[role="option"]:has-text("Enterprise")').click();

Mit Katalogen arbeiten

Gen-UX-Kataloge verwenden dieselben Attribute wie Canvas-App-Kataloge:

const gallery = canvasFrame.locator('[data-control-part="gallery-item"]');

// Count items
const count = await gallery.count();
expect(count).toBeGreaterThan(0);

// Filter by text content
const item = gallery.filter({ hasText: 'Contoso Ltd' });
await item.waitFor({ state: 'visible', timeout: 30000 });
await item.click();

Vollständiges Testbeispiel: Erstellen und Finden eines Datensatzes

Der folgende End-to-End-Test startet eine Gen-UX-App, erstellt einen neuen Datensatz über das Formular und überprüft, ob er im Katalog angezeigt wird.

import { test, expect } from '@playwright/test';
import { AppProvider, AppType, AppLaunchMode, buildCanvasAppUrlFromEnv } from 'power-platform-playwright-toolkit';

const GEN_UX_APP_URL = buildCanvasAppUrlFromEnv();

test('should create a new record and find it in the list', async ({ page, context }) => {
  const app = new AppProvider(page, context);
  await app.launch({
    app: 'My AI App',
    type: AppType.Canvas,
    mode: AppLaunchMode.Play,
    skipMakerPortal: true,
    directUrl: GEN_UX_APP_URL,
  });

  const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');

  // Wait for the gallery to load
  await canvasFrame
    .locator('[data-control-part="gallery-item"]')
    .first()
    .waitFor({ state: 'visible', timeout: 60000 });

  // Click New record
  await canvasFrame.locator('[role="button"][aria-label="New record"]').click();

  // Fill the form
  const accountName = `AI Test ${Date.now()}`;
  await canvasFrame.locator('input[aria-label="Name"]').fill(accountName);
  await canvasFrame.locator('input[aria-label="Phone"]').fill('555-1234');

  // Save
  await canvasFrame.locator('[role="button"][aria-label="Save"]').click();
  await page.waitForTimeout(3000); // allow Dataverse write

  // Verify the new record appears in the gallery
  const newItem = canvasFrame
    .locator('[data-control-part="gallery-item"]')
    .filter({ hasText: accountName });

  await expect(newItem).toBeVisible({ timeout: 30000 });
});

Ermitteln der generierten Steuerelementnamen

Gen-UX-Steuerelementnamen ändern sich, wenn Sie die App neu generieren. So suchen Sie nach aktuellen Steuerelementnamen:

  1. Öffnen Sie die App im Wiedergabemodus in einem Browser.
  2. Öffnen Sie Browser DevTools (F12).
  3. Verwenden Sie den Inspektor , um mit dem Mauszeiger auf ein Steuerelement zu zeigen.
  4. Suchen Sie nach data-control-name in den Attributen des Elements.

Tip

Bevorzugen Sie aria-label und rollenbasierte Selektoren vor data-control-name für Gen-UX-Apps. ARIA-Bezeichnungen stammen aus ihren Dataverse-Spaltenanzeigenamen und ändern sich nicht, wenn Sie die App neu generieren.

Authentifizierung

Gen-UX-Apps verwenden die Domäne Power Apps. Verwenden Sie den Standardspeicherstatus:

import { getStorageStatePath } from 'power-platform-playwright-toolkit';

test.use({
  storageState: getStorageStatePath(process.env.MS_AUTH_EMAIL!),
});

Nächste Schritte

Siehe auch