JSの実行時エラーとかコンパイルエラーの検出をやってみた。
ちなみにconsole.logとかを検出するのはconsoleイベントpage.on('console', (msg) => {}) でできるけど、補足されていない実行時例外なんかはconsoleイベントでは取得できなかった。
こんな感じのHTMLを用意する。
JSには以下の問題点がある。
- constの変数に再代入している
 - ボタンを押したらErrorを投げている
 
<html>
<body>
<p>JSにエラーがあるのでそれを検出します<p>
<script>
    const message = "this is a pen.";
    message = "that is a cholk."
</script>
<button id="raise">例外が起きるよ</button>
<script>
    const el = document.getElementById("raise");
    el.addEventListener('click', () => {
        throw new Error('raise itself.');
    });
</script>
</body>
</html>
Playwrightのテスト側のポイントは2つ
- CDPSessionを使う
 - 
Runtime.enableを呼び出して、Runtimeドメイン機能を使えるようにする - 
Runtime.exceptionThrownを指定して、例外イベントを受け取るようにする 
参考 : https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#event-exceptionThrown
import { test, expect } from '@playwright/test';
test('JSのエラーを検出する',async ({page}) => {
  const messages: Array<string> = [];
  const client = await page.context().newCDPSession(page);
  await client.send('Runtime.enable');
  client.on('Runtime.exceptionThrown', payload => {
    messages.push(payload.exceptionDetails.exception?.description || "no description");
  });
  
  await page.goto('/invalid_js.html', { waitUntil: "load"});
  await page.waitForTimeout(2000);
  expect.soft(messages.length).toEqual(1);
  expect.soft(messages[0]).toMatch(/Assignment to constant variable/);
  await page.click('#raise');
  expect.soft(messages.length).toEqual(2);
  expect.soft(messages[1]).toMatch(/itself/);
});
const変数への再代入のときのpayloadは以下のようになっている。
{
  "timestamp": 1685954423868.76,
  "exceptionDetails": {
    "exceptionId": 1,
    "text": "Uncaught",
    "lineNumber": 41,
    "columnNumber": 12,
    "scriptId": "4",
    "url": "http://127.0.0.1:4000/invalid_js.html",
    "stackTrace": {
      "callFrames": [
        {
          "functionName": "",
          "scriptId": "4",
          "url": "http://127.0.0.1:4000/invalid_js.html",
          "lineNumber": 41,
          "columnNumber": 12
        }
      ]
    },
    "exception": {
      "type": "object",
      "subtype": "error",
      "className": "TypeError",
      "description": "TypeError: Assignment to constant variable.\n    at http://127.0.0.1:4000/invalid_js.html:42:13",
      "objectId": "3140245142211784158.3.1",
      "preview": {
        "type": "object",
        "subtype": "error",
        "description": "TypeError: Assignment to constant variable.\n    at http://127.0.0.1:4000/invalid_js.html:42:13",
        "overflow": false,
        "properties": [
          {
            "name": "stack",
            "type": "string",
            "value": "TypeError: Assignment to constant variable.\n    at http://127.0.0.1:4000/invalid_js.html:42:13"
          },
          {
            "name": "message",
            "type": "string",
            "value": "Assignment to constant variable."
          }
        ]
      }
    },
    "executionContextId": 3
  }
}
今後の野望
https://github.com/microsoft/playwright/discussions/11690 とかを参考にうまくFixturesにまとめるとページで一通り操作を行ったときにエラーが出てないことを確認できそう。