Power Appsテスト エンジンは、特殊なテスト ホストに対して実行される YAML ベースのテスト定義を使用します。 Power Platform Playwright サンプルでは、TypeScript と標準の Playwright テスト ランナーを使用して、完全な Playwright API、エコシステム ツール、CI/CD 統合にアクセスできます。
このガイドでは、テスト エンジンの概念をプレイライトの同等の概念にマップし、具体的な移行の例について説明します。
概念マッピング
次の表は、テスト エンジンの概念が Playwright の概念にどのように対応するかを示しています。
| テストエンジンの概念 | プレイライトに相当する |
|---|---|
| YAML テスト ファイル | TypeScript テスト ファイル (*.test.ts) |
testSuite.testCases |
test.describe() ブロック |
testStep |
test() 関数 |
appLogicalName |
directUrl の AppProvider.launch() |
onTestCaseStart |
test.beforeEach() |
Assert |
expect() から @playwright/test |
Select (制御インタラクション) |
canvasFrame.locator('[data-control-name="..."]').click() |
SetProperty |
canvasFrame.locator('input[...]').fill() |
Screenshot |
page.screenshot() または toHaveScreenshot() |
environmentVariables |
.env ファイル変数 |
| YAML の Power Fx 数式 | TypeScript 式 |
始める前の準備
移行を開始する前に、これらの前提条件を完了してください。
リポジトリを複製し、依存関係をインストールします。
git clone https://github.com/microsoft/power-platform-playwright-samples.git cd power-platform-playwright-samples node common/scripts/install-run-rush.js installテスト エンジンの YAML
appLogicalNameまたは Power Apps make ポータルからアプリの URL をコピーします。認証を設定する - 認証ガイドを参照してください。
手順 1: アプリの種類を特定する
テスト エンジンでは、キャンバス アプリがサポートされています。 移行する場合:
- キャンバス アプリのテスト → テスト キャンバス アプリに従います。
- カスタム ページ テスト → テスト カスタム ページに従います。
- モデル駆動アプリのテスト → モデル駆動アプリをテストします。
手順 2: テスト構造をマップする
テスト エンジン YAML
一般的なテスト エンジンのテスト定義は次のようになります。
testSuite:
testSuiteName: OrdersTests
testCases:
- testCaseName: CreateOrder
testSteps: |
Select(AddButton);
SetProperty(OrderNumberInput, "ORD-TEST");
Select(SaveButton);
Assert(Label1.Text = "Saved");
Playwright TypeScript に相当する
Playwright と Power Platform ツールキットを使用して書き換えたのと同じテストを次に示します。
import { test, expect } from '@playwright/test';
import { AppProvider, AppType, AppLaunchMode, buildCanvasAppUrlFromEnv } from 'power-platform-playwright-toolkit';
test.describe('OrdersTests', () => {
test('CreateOrder', async ({ page, context }) => {
const app = new AppProvider(page, context);
await app.launch({
app: 'Orders App',
type: AppType.Canvas,
mode: AppLaunchMode.Play,
skipMakerPortal: true,
directUrl: buildCanvasAppUrlFromEnv(),
});
const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
// Wait for app to load
await canvasFrame
.locator('[data-control-part="gallery-item"]')
.first()
.waitFor({ state: 'visible', timeout: 60000 });
// Select(AddButton)
await canvasFrame.locator('[data-control-name="AddButton"] [role="button"]').click();
// SetProperty(OrderNumberInput, "ORD-TEST")
await canvasFrame.locator('input[aria-label="Order Number"]').fill('ORD-TEST');
// Select(SaveButton)
await canvasFrame.locator('[data-control-name="SaveButton"] [role="button"]').click();
// Assert(Label1.Text = "Saved")
await expect(canvasFrame.locator('[data-control-name="Label1"]')).toHaveText('Saved');
});
});
手順 3: コントロール セレクターをマップする
テスト エンジンでは、Power Apps Studio のコントロール名が YAML で直接使用されます。 Playwright では、同じ値 data-control-name 属性を使用します。
| テストエンジン | Playwright |
|---|---|
Select(MyButton) |
canvasFrame.locator('[data-control-name="MyButton"] [role="button"]').click() |
SetProperty(MyInput, "text") |
canvasFrame.locator('input[aria-label="My Label"]').fill("text") |
Assert(MyLabel.Text = "x") |
expect(canvasFrame.locator('[data-control-name="MyLabel"]')).toHaveText("x") |
Select(GalleryItem) |
canvasFrame.locator('[data-control-part="gallery-item"]').filter({ hasText: 'x' }).click() |
ヒント
コントロールの data-control-name 値を見つけるには、再生モードでアプリを開き、DevTools (F12) を開き、要素を調べます。 この値は、Power Apps Studio で設定したコントロール名と一致します。
手順 4: 環境変数をマップする
テスト エンジンでは、YAML の environmentVariables セクションを使用します。 これらの値を .env ファイルに移動します。
# Test Engine YAML
environmentVariables:
- name: appUrl
value: https://apps.powerapps.com/play/...
# packages/e2e-tests/.env
CANVAS_APP_URL=https://apps.powerapps.com/play/...
手順 5: マップのセットアップと破棄
テスト エンジンのライフサイクル フックを Playwright の組み込みの beforeEach および afterEach 関数に変換します。
# Test Engine
testSuite:
onTestCaseStart: |
Navigate(HomeScreen);
// Playwright
test.beforeEach(async ({ page, context }) => {
// Re-launch the app for each test (equivalent to onTestCaseStart navigation)
const app = new AppProvider(page, context);
await app.launch({ ... });
});
手順 6: Power Fx アサーションを置き換える
テスト エンジンは、 Assert()で Power Fx 式を使用します。 Playwright expect() アサーションを使って置き換えます。
| Power Fx | Playwright |
|---|---|
Assert(Label1.Text = "Done") |
expect(frame.locator('[data-control-name="Label1"]')).toHaveText('Done') |
Assert(CountRows(Gallery1.AllItems) > 0) |
expect(await frame.locator('[data-control-part="gallery-item"]').count()).toBeGreaterThan(0) |
Assert(IsVisible(ErrorLabel)) |
expect(frame.locator('[data-control-name="ErrorLabel"]')).toBeVisible() |
Assert(!IsVisible(Spinner)) |
expect(frame.locator('[data-control-name="Spinner"]')).not.toBeVisible() |
注意すべき主な違い
テストを移行するときは、これらの動作の違いに留意してください。
| 面積 | テストエンジン | Playwright |
|---|---|---|
| 待機 | 自動 (テストエンジンがタイミングを管理) | 明示的な waitFor() が必要です |
| ギャラリーのタイムアウト | 内部的に処理される | Dataverse ギャラリーに 60 秒のタイムアウトを使用する |
| 分離のテスト | 各テストでアプリの状態がリセットされる |
beforeEachを使用してホームを再起動または移動する |
| スクリーンショット | 組み込みの Screenshot ステップ |
page.screenshot() または toHaveScreenshot() |
| エラー報告 | YAMLレベル | Playwright HTML レポート + トレース ビューアー |
移行されたテストを実行する
テストを移行した後、これらのコマンドを使用してテストを認証して実行します。
cd packages/e2e-tests
npm run auth:headful # authenticate
npx playwright test # run all tests
npx playwright test --ui # run with interactive UI
移行に関する問題のトラブルシューティング
移行に関する一般的な問題とその解決策については、次の表を参照してください。
| 症状: | Resolution |
|---|---|
| ギャラリーが読み込まれない | 対話する前に waitFor({ timeout: 60000 }) を追加する |
| コントロールが見つかりません | DevTools で data-control-name を確認する - Power Fx 名と異なる場合があります |
| セレクターが複数の要素と一致する |
.filter()または.nth(0)を使用して選択範囲を絞り込む |
| テストは実行されますが、アサーションはすぐに失敗します | アサートする前に明示的な waitFor または toBeVisible を追加する |