Gen UX アプリは、Power Apps の自然言語エクスペリエンスを通じて作成された AI 生成Power Appsです。 それらは、手書きのキャンバス アプリと同じキャンバス ランタイムを使用するため、同じ iframe スコープと data-control-name パターンが適用されます。
GenUxPage クラスは、生成されたコントロール構造用にチューニングされたヘルパーを提供します。
Gen UX アプリとキャンバス アプリの違い
Gen UX アプリは、キャンバス ランタイムと iframe[name="fullscreen-app-host"] ホスト フレームを共有します。 主な違いは次のとおりです。
- コントロール名は自動生成され (
Button1、TextInput1など)、アプリを再生成すると変更される可能性があります。 - AI プロンプトによってアプリのレイアウトが促進されるため、構造はアプリによって異なります。
-
GenUxPageクラスは、コントロール名ではなくセマンティック ロールと ARIA ラベルに対して動作するヘルパーを公開し、テストの再生成に対する回復性を高めます。
Gen UX アプリを起動する
AppProvider クラスを使用して、Gen UX アプリを再生モードで起動し、直接 URL を渡してメーカー ポータルをスキップし、キャンバス ランタイムに直接接続します。
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,
});
});
ヒント
skipMakerPortal: true で directUrl を使用して、Power Appsをバイパスし、起動時間を 10 ~ 20 秒短縮します。
キャンバスフレームに対してロケーターを設定する
すべての操作のスコープをキャンバス iframe に設定します。
const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
アプリが読み込まれるのを待つ
Gen UX アプリは、Dataverse データの読み込みに 30 ~ 60 秒かかる場合があります。 次の操作を行う前に、既知の要素を待ちます。
// Wait for a gallery or any visible UI element
await canvasFrame
.locator('[data-control-part="gallery-item"]')
.first()
.waitFor({ state: 'visible', timeout: 60000 });
ARIAラベルを使用したコントロールとのインタラクション
Gen UX アプリは、プロンプトから派生した ARIA ラベルを含むコントロールを生成します。 回復性のために ARIA ラベル セレクターを使用します。
テキスト入力欄に入力する
Dataverse 列の表示名と一致する aria-label 属性でテキスト入力をターゲットとし、Playwright の fill() メソッドを使用して値を入力します。
await canvasFrame.locator('input[aria-label="Name"]').fill('Contoso Ltd');
await canvasFrame.locator('input[aria-label="Phone"]').fill('555-9000');
ボタンをクリックする
role="button" セレクターと、プロンプトに基づいて AI によって割り当てられたaria-labelを組み合わせて、ボタンを見つけます。
await canvasFrame.locator('[role="button"][aria-label="Save"]').click();
await canvasFrame.locator('[role="button"][aria-label="New record"]').click();
ドロップダウンから選択する
ドロップダウンリストをクリックしてオプションリストを展開し、表示されているテキストと一致させて目的のオプションを選択します。
const dropdown = canvasFrame.locator('[aria-label="Category"]');
await dropdown.click();
await canvasFrame.locator('[role="option"]:has-text("Enterprise")').click();
ギャラリーを操作する
Gen UX ギャラリーでは、キャンバス アプリ ギャラリーと同じ属性が使用されます。
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();
完全なテスト例: レコードを作成して検索する
次のエンド ツー エンドテストでは、Gen UX アプリを起動し、フォームを使用して新しいレコードを作成し、ギャラリーに表示されることを確認します。
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 });
});
生成されたコントロール名を検出する
Gen UX コントロール名は、アプリを再生成すると変更されます。 現在のコントロール名を検索するには:
- ブラウザーで再生モードでアプリを開きます。
- ブラウザー DevTools (F12) を開きます。
- インスペクターを使用してコントロールにカーソルを合わせます。
- 要素の属性で
data-control-nameを探します。
ヒント
Gen UX アプリのaria-labelよりも、data-control-nameとロールベースのセレクターを優先します。 ARIA ラベルは Dataverse 列の表示名から取得され、アプリを再生成しても変更されません。
認証
Gen UX アプリでは、Power Apps ドメインが使用されます。 Standard Storage の状態を使用します。
import { getStorageStatePath } from 'power-platform-playwright-toolkit';
test.use({
storageState: getStorageStatePath(process.env.MS_AUTH_EMAIL!),
});