次の方法で共有


Power Apps テスト エンジンからの移行

Power Appsテスト エンジンは、特殊なテスト ホストに対して実行される YAML ベースのテスト定義を使用します。 Power Platform Playwright サンプルでは、TypeScript と標準の Playwright テスト ランナーを使用して、完全な Playwright API、エコシステム ツール、CI/CD 統合にアクセスできます。

このガイドでは、テスト エンジンの概念をプレイライトの同等の概念にマップし、具体的な移行の例について説明します。

概念マッピング

次の表は、テスト エンジンの概念が Playwright の概念にどのように対応するかを示しています。

テストエンジンの概念 プレイライトに相当する
YAML テスト ファイル TypeScript テスト ファイル (*.test.ts)
testSuite.testCases test.describe() ブロック
testStep test() 関数
appLogicalName directUrlAppProvider.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 式

始める前の準備

移行を開始する前に、これらの前提条件を完了してください。

  1. リポジトリを複製し、依存関係をインストールします。

    git clone https://github.com/microsoft/power-platform-playwright-samples.git
    cd power-platform-playwright-samples
    node common/scripts/install-run-rush.js install
    
  2. テスト エンジンの YAML appLogicalName または Power Apps make ポータルからアプリの URL をコピーします。

  3. 認証を設定する - 認証ガイドを参照してください。

手順 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 を追加する

次のステップ

こちらも参照ください