ラベル Playwright の投稿を表示しています。 すべての投稿を表示
ラベル Playwright の投稿を表示しています。 すべての投稿を表示

2025年4月1日火曜日

ChainlitのアプリケーションよりPlaywright MCPを呼び出してOracle APEXのアプリケーションを操作する

以前の記事で、Claude DesktopにPlaywright MCPを組み込んでOracle APEXのアプリケーションを操作してみました。MCPサーバーの組み込みがClaude Desktopに限定されている点で、自由度が今ひとつと思っていたところ、株式会社ヘッドウォータース様が公開している以下の記事を見つけました。

Azure OpenAIでMCPを使ったデモアプリを試す
https://zenn.dev/headwaters/articles/223f212b4c1cd6

Microsoftから公開されているAzure OpenAIのサンプルのひとつにMCPとのインテグレーションが含まれていて、それを動かしたことを記事にされています。

記事に含まれるスクリーンショットより、デモアプリケーションはChainlitで作成していることが分かります。ChainlitであればPythonが動けばどこでも実行できそうです。Azure OpenAI向けですが、少し修正してOpenAIで動作させました。

Azure OpenAI MCP Integration
https://github.com/monuminu/AOAI_Samples/tree/main/mcp_aoai

以前の記事と同じ操作を行なっています。サインイン後にダッシュボードのページに移動しなかったり、ユーザー名の入力がうまくできなかったりしましたが、概ねアプリケーションの操作はできています。


以下、作業の手順を紹介します。作業はmacOS 15.3.2で行なっています。

最初に作業ディレクトリを作成して、移動します。

mkdir mcp_aoai
cd mcp_aoai

% mkdir mcp_aoai

% cd mcp_aoai

mcp_aoai % 


必須の作業ではありませんが、仮想環境を作成します。このサンプル・アプリケーションのPrerequisitesは、Python 3.8以上になっています。

python3 -V
python3 -m venv mcp_aoai
source mcp_aoai/bin/activate

mcp_aoai % python3 -V            

Python 3.13.2

mcp_aoai % python3 -m venv mcp_aoai

mcp_aoai % source mcp_aoai/bin/activate

(mcp_aoai) mcp_aoai % 


必要なパッケージをインストールします。

pip install chainlit openai python-dotenv aiohttp

(mcp_aoai) mcp_aoai % pip install chainlit openai python-dotenv aiohttp


Collecting chainlit

  Using cached chainlit-2.4.400-py3-none-any.whl.metadata (6.3 kB)

Collecting openai

  Using cached openai-1.70.0-py3-none-any.whl.metadata (25 kB)

Collecting python-dotenv

  Using cached python_dotenv-1.1.0-py3-none-any.whl.metadata (24 kB)

Collecting aiohttp

  Using cached aiohttp-3.11.12-cp313-cp313-macosx_11_0_arm64.whl.metadata (7.7 kB)

Collecting aiofiles<25.0.0,>=23.1.0 (from chainlit)

  Using cached aiofiles-24.1.0-py3-none-any.whl.metadata (10 kB)

Collecting asyncer<0.0.8,>=0.0.7 (from chainlit)

  Using cached asyncer-0.0.7-py3-none-any.whl.metadata (6.6 kB)

Collecting click<9.0.0,>=8.1.3 (from chainlit)


[中略]


o-5.12.1 pyyaml-6.0.2 regex-2024.11.6 requests-2.32.3 simple-websocket-1.1.0 six-1.17.0 sniffio-1.3.1 sse-starlette-2.2.1 starlette-0.41.3 syncer-2.0.3 tenacity-8.5.0 tiktoken-0.9.0 tokenizers-0.21.1 tomli-2.2.1 tqdm-4.67.1 traceloop-sdk-0.39.0 typing-extensions-4.13.0 typing-inspect-0.9.0 typing-inspection-0.4.0 uptrace-1.31.0 urllib3-2.3.0 uvicorn-0.34.0 watchfiles-0.20.0 wrapt-1.17.2 wsproto-1.2.0 yarl-1.18.3 zipp-3.21.0


[notice] A new release of pip is available: 25.0 -> 25.0.1

[notice] To update, run: pip install --upgrade pip

(mcp_aoai) mcp_aoai % 


Azure OpenAI MCP Integrationのリポジトリに含まれるapp.pyをダウンロードします。


ダウンロードしたapp.pyに以下の変更を加えます。インポートするモジュールをAzureOpenAI、AsyncAzureOpenAIからOpenAI、AsyncOpenAIに変更し、モデルの指定を環境変数OIPENAI_MODEL、APIキーを環境変数OPENAI_API_KEYとして与えるようにします。
8c8
< from openai import AzureOpenAI, AsyncAzureOpenAI
---
> from openai import OpenAI, AsyncOpenAI
17,21c17,19
<         self.deployment_name = os.environ["AZURE_OPENAI_MODEL"]
<         self.client = AsyncAzureOpenAI(
<                 azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
<                 api_key=os.environ["AZURE_OPENAI_API_KEY"],
<                 api_version=os.environ["OPENAI_API_VERSION"]
---
>         self.deployment_name = os.environ["OPENAI_MODEL"]
>         self.client = AsyncOpenAI(
>                 api_key=os.environ["OPENAI_API_KEY"]

環境変数OPENAI_MODELOPENAI_API_KEYを設定します。あまりお金がかからないように、使用するモデルは廉価版のgpt-4o-miniを選択しています。

export OPENAI_MODEL=gpt-4o-mini-2024-07-18
export OPENAI_API_KEY=OpenAIのAPIキー


(mcp_aoai) mcp_aoai % export OPENAI_MODEL=gpt-4o-mini-2024-07-18

(mcp_aoai) mcp_aoai % export OPENAI_API_KEY=OpenAIのAPIキー

(mcp_aoai) mcp_aoai %                                             


以上で準備は完了です。

アプリケーションを実行します。

chainlit run app.py

(mcp_aoai) mcp_aoai % chainlit run app.py

2025-04-01 11:12:09 - Your app is available at http://localhost:8000

2025-04-01 11:12:10 - Translated markdown file for ja not found. Defaulting to chainlit.md.


ブラウザが開きます。コンセントのアイコンをクリックして、MCPサーバーの設定を開きます。


MCPサーバーとしてPlaywright MCPを追加します。

NamePlaywright MCPTypestdioを選択します。Commandに以下を記述します。

npx -y @playwright/mcp@latest

確認をクリックします。


My MCPsにPlaywright MCPが追加されます。緑のインジケータが点いて、14個のツールが登録されます。


コンセントのアイコンにMCPサーバーが1個登録されていることが、アクセントとして表示されます。


あとはChainlitのチャット・インターフェースを通して、Oracle APEXのアプリケーションを操作します。


今回の記事は以上になります。

2025年3月29日土曜日

MicrosoftのPlaywrightを使ってAPEXアプリケーションのE2Eテストを行う

Microsoftから公開されているオープンソースのE2Eテスト自動化フレームワークのPlaywrightを使って、APEXアプリケーションのE2Eテストを実施してみます。

最終的には以下の作業を行います。作業環境には、macOSのpodmanでコンテナとして動作しているOracle APEXの環境を使っています。コード内の定数BASE_URLを変更することで、テスト対象とするアプリケーションは変えられます。PlaywrightのテストはPlaywrightをインストールした上で、VSCodeの拡張機能Playwright Test for VSCodeから実行しています。


以下より、作業について説明します。

最初にE2Eテストの対象とするAPEXアプリケーションを作成します。

サンプル・アプリケーションサンプル・データセットEMP/DEPTをインストールして、APEXアプリケーションを作成します。言語英語にします。テスト・コードではページのタイトルを参照しているため、言語を日本語にすると、確認のために指定している文字列も日本語にする必要があります。

SQLワークショップサンプル・データセットを開きます。

データ・セットEMP/DEPTインストール(すでにインストール済みであれば更新)をクリックします。


インストールする言語の指定を求められます。言語として英語を選択します。


すでに英語でインストール済みであれば、新規言語は選択しません(- 新しい言語の選択 -から変更しません)。

へ進みます。


新規であればデータセットのインストールをクリックします。


更新であれば既存のデータセットのリフレッシュをクリックします。


サンプル・データセットのロードが完了すると、そのデータを元にしたアプリケーションを作ることができます。

アプリケーションの作成をクリックします。


アプリケーション作成ウィザードが開きます。ダッシュボードファセット検索のページが追加済みです。テスト用のアプリケーションに沢山のページは不要なので、機能についてはすべてチェックを外します。

以上でアプリケーションの作成をクリックします。


アプリケーションが作成されます。


アプリケーションを実行し、今回のE2Eテストで行う操作を確認します。

アプリケーションにアクセスし、表示されるログイン・ページにて、以下の操作を行います。
  1. ユーザー名を入力する。
  2. パスワードを入力する。
  3. サインインをクリックする。

サインインが完了すると、ホーム・ページが開きます。

ホーム・ページ上で以下の操作を行います。
  1. Dashboardのカードをクリックし、Dashboardのページが開くことを確認します。
  2. Employeesのカードをクリックし、Employeesのファセット検索のページが開くことを確認します。
  3. Departmentsのカードをクリックし、Departmentsの対話モード・レポートのページが開くことを確認します。

Playwrightではセレクタを使って、操作する要素を特定します。

ログイン画面ではテキスト・フィールドにユーザー名とパスワードを入力し、ボタンのサインインをクリックしています。そのため、これらのテキスト・フィールドとボタンを特定するセレクタが必要です。

どのようなセレクタが適当か確認するために開発ツールの検証を呼び出し、それぞれの要素のHTMLを確認します。


タイプがテキスト・フィールドの場合は、以下のようなHTMLが生成されていました。
<input type="text" id="P9999_USERNAME" name="P9999_USERNAME" placeholder="ユーザー名" class="text_field apex-item-text apex-item-has-icon" autocomplete="username" value="admin" size="40" maxlength="100" data-enter-submit="false" data-is-page-item-type="true">
ページ・アイテムの名前がid属性として設定されているため、セレクタとしては#ページアイテム名、つまり#P9999_USERNAMEで特定できます。パスワードも同様に#P9999_PASSWORDで特定できます。

ボタンサインインについては、BUTTON要素を特定できる適当な属性がありません。
<button class="t-Button t-Button--hot lto18565948643221472_0" type="button" id="B18565948643221472" data-otel-label="LOGIN"><span class="t-Button-label">サインイン</span></button>
そのため、ボタンに静的IDとしてLOGIN設定します。


ボタンに設定した静的IDは属性idに設定されます。そのため、このボタンをセレクタ#LOGINで特定できます。
<button class="t-Button t-Button--hot lto18565948643221472_0" type="button" id="LOGIN" data-otel-label="LOGIN"><span class="t-Button-label">サインイン</span></button>
ホーム・ページのカードについても確認します。

カードに紐ずくA要素を特定するセレクタとして使える、これといった属性がありません。


<a href="/ords/r/apexdev/demonstration-emp-dept106/dashboard?session=8435741618687" class="t-Card-wrap" data-otel-label="">
      <div class="t-Card-icon u-color "><span class="t-Icon fa fa-dashboard"><span class="t-Card-initials" role="presentation"></span></span></div>
      <div class="t-Card-titleWrap">
        <h3 class="t-Card-title">Dashboard</h3>
        <h4 class="t-Card-subtitle"></h4>
      </div>
      <div class="t-Card-body">
        <div class="t-Card-desc"></div>
        <div class="t-Card-info"></div>
      </div>
      <span class="t-Card-colorFill u-color " aria-hidden="true"></span>
    </a>
ページの設定を確認します。

ページ・ナビゲーションのリージョンのタイプリストです。


左ペインでページ共有コンポーネントを開き、リストに適用されているテンプレートを見つけ(テンプレートCardsが適用されています)、コンポーネントの編集をクリックします。

このリージョンが参照しているHTMLのテンプレートが表示されます。


リスト・テンプレートCardsテンプレート定義を確認します。

A要素はテンプレート定義カレント・リスト・テンプレートおよび非カレント・リスト・テンプレートで、以下のように記述されています。
<a href="#LINK#" class="t-Card-wrap" #A05# data-otel-label="#A10#">

置換文字列#A05#に、セレクタとして利用可能な属性を設定することにします。

置換文字列#A05#に設定する文字列は、Dashboardのカードにid="menu-dashboard"Employeesid="menu-employees"Departmentsにはid="menu-departments"とします。

ページ・ナビゲーションのソースを確認します。

ソースとなるリストページ・ナビゲーションです。


リストのソースは共有コンポーネントとして作成されています。

共有コンポーネントリストを開きます。


リストの一覧にページ・ナビゲーションがあります。名前のリンクをクリックして、ページ・ナビゲーションを開きます。


リスト・エントリとしてDashboardEmployeesDepartmentsが含まれています。

最初にDashboardを開いて、属性を追加します。


テンプレート定義に含まれる置換文字列#A01#から#A10#は、ユーザー定義属性です。セクションのユーザー定義属性に移動し、置換文字列#A05#に対応している5. Link Attributesとしてid="menu-dashboard"を設定します。

変更の適用をクリックします。


同様にリスト・エントリEmployeesを開き、ユーザー定義属性5. Link Attributesとしてid="menu-employees"を設定します。


リスト・エントリDepartments5. Link Attributesid="menu-departments"を設定します。


以上で、Playwrightを使ってE2Eテストを行うために必要な、APEXアプリケーションの改変は完了です。

続いてPlaywrightをインストールします。PlaywrightのGetting StartedのInstallationの記述に従って、作業を行います。


いくつか方法がありますが、今回はnpmでインストールしました。

今回のE2Eテストを作成するディレクトリを作成します。本作業ではPlaywrightとしました。

mkdir Playwright

% mkdir Playwright

% 


作成したディレクトリに移動し、Playwrightをインストールします。

cd Playwright
npm init playwright@latest

プロジェクトの初期化に当たって、いくつか質問されます。今回はすべてデフォルトの設定で初期化しています。デフォルトではテスト・スクリプトの記述はTypeScriptで行い、テスト・スクリプトはサブフォルダのtestsに保存されます。

% cd Playwright

Playwright % npm init playwright@latest


> npx

> create-playwright


Getting started with writing end-to-end tests with Playwright:

Initializing project in '.'

Do you want to use TypeScript or JavaScript? · TypeScript

Where to put your end-to-end tests? · tests

Add a GitHub Actions workflow? (y/N) · false

Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) · true

Initializing NPM project (npm init -y)…

Wrote to /Users/ynakakoshi/Documents/Playwright/package.json:


{

  "name": "playwright",

  "version": "1.0.0",

  "main": "index.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "keywords": [],

  "author": "",

  "license": "ISC",

  "description": ""

}




Installing Playwright Test (npm install --save-dev @playwright/test)…


added 3 packages, and audited 4 packages in 1s


found 0 vulnerabilities

Installing Types (npm install --save-dev @types/node)…


added 3 packages, and audited 7 packages in 640ms


found 0 vulnerabilities

Writing playwright.config.ts.

Writing tests/example.spec.ts.

Writing tests-examples/demo-todo-app.spec.ts.

Writing package.json.

Downloading browsers (npx playwright install)…

✔ Success! Created a Playwright Test project at /Users/ynakakoshi/Documents/Playwright


Inside that directory, you can run several commands:


  npx playwright test

    Runs the end-to-end tests.


  npx playwright test --ui

    Starts the interactive UI mode.


  npx playwright test --project=chromium

    Runs the tests only on Desktop Chrome.


  npx playwright test example

    Runs the tests in a specific file.


  npx playwright test --debug

    Runs the tests in debug mode.


  npx playwright codegen

    Auto generate tests with Codegen.


We suggest that you begin by typing:


    npx playwright test


And check out the following files:

  - ./tests/example.spec.ts - Example end-to-end test

  - ./tests-examples/demo-todo-app.spec.ts - Demo Todo App end-to-end tests

  - ./playwright.config.ts - Playwright Test configuration


Visit https://playwright.dev/docs/intro for more information. ✨


Happy hacking! 🎭

 Playwright % 


VSCodeに拡張機能のPlaywright Test for VSCodeをインストールします。


VSCodeから先ほど作成したE2Eテストのプロジェクト・フォルダ(今回の作業ではPlaywrightとして作成)を開きます。プロジェクトが初期化されていて、雛形となるファイルが作成されています。


エクスプローラーからファイルplaywright.config.tsを選択し、以下の内容に置き換えます。chromiumのプロジェクトにviewportとstorageStateの設定を加えています。


テスト・スクリプトを配置するフォルダtestsに、以下のファイルfixtures.tsを作成します。このファイルに、APEXアプリケーションへサインインする手順を記述しています。

BASE_URLは、先ほど作成したAPEXアプリケーションを指すURLに変更します。


プロジェクトのフォルダの直下にフォルダ.authを作成します。認証情報を保存するファイルauth.jsonと、ブラウザの状態を保存するファイルstate.jsonを配置します。


フォルダ.auth直下にファイルauth.jsonを作成します。内容として、以下を記述します。usernamepasswordは環境に合わせて変更します。sessionIdはログイン後にテスト・スクリプトによって更新されるため、値はそのままで問題ありません。

{"username":"admin","password":"4fae#ae2ef3!!","sessionId":"17291688537780"}


フォルダ.auth直下にブラウザのステータスを保存するファイルstate.jsonを作成します。内容はとして{}を記述し、空のJSONオブジェクトが保存されている状態にします。


最後に今回実施するE2Eテストを記述したファイルapex.spec.tsを、フォルダtests以下に作成します。


以上でPlaywrightを使ってE2Eテストを実行する準備ができました。

作成したファイルをすべて保存し、Playwrightの拡張機能を開きます。

testsとして認識されているapex.spec.tsにある実行ボタンをクリックすることで、apex.spec.tsに記述されている一連のテストが実行されます。apex.spec.tsにはopen Dashboard、open Employees、open Departmentsの3つのテストが含まれています。

それぞれ個別に実行できますが、open Dashboardでユーザー認証を行なっている都合上、最初にopen Dashboardのテストを実行する必要があります。


今回の記事は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。