/// <reference ...>を用いてSincoを使ったE2E試験での型エラーを解決する
この記事は、Deno Advent Calendar 2021の21日目です。
Zennでは初めての記事になります。よろしくお願いします。
はじめに
DenoでE2E試験をするには、deno-puppeteerとSincoの大きく分けて2つがあると思います。
Chrome等を事前インストールをしない点で私はSincoを気に入っており、今回利用しました。
その中で、試験で発生した型エラーと、その回避策を共有します。
この記事で伝えたいこと
- TypeScriptでSincoを利用するときに、プロジェクトルートにtsconfig.jsonを使うことで起きる型エラーの解決と実装への影響
- トリプルスラッシュディレクティブ(
/// <reference ...>
)を利用することで実装への影響を回避する方法
Sincoで要素名などを取るときに起こる問題
Sincoで要素名を取るときは、Page.evaluate()
を利用して、以下のように書きます。
const sinco = await buildFor("chrome");
const page = await sinco.goTo("https://example.com/");
const pageTitle: string = await page.evaluate(() => {
return document.querySelector("h1")?.innerText;
});
このpageTitle
の中に今回のURLでいうとExample Domain
が入るはずですが、このままですとdocumentの下に赤い線が引かれ、documentの型が見当たらないという警告が出ます。
これは、Denoの型定義の中にdocumentが存在しないためです。
そこで、Page.evaluate()
の公式ドキュメントを参考に、プロジェクトルートにtsconfig.json
を作成します。
{
"compilerOptions": {
"lib": ["dom", "dom.asynciterable", "deno.ns"]
}
}
deno.ns
はDenoが提供するDenoネームスペースのNode.jsモジュールです。これをlib
に指定することで、Deno.test()
といったメソッドが利用可能になります。
なお、dom.asynciterable
は私の場合では必要だったのですが、人によってはいらないかもしれません。
これで、問題なく試験ができる環境になりました。
さぁ、これで解決! ……というわけではありません。
実装を開くと、例えばURL Pattern APIがany
になっていたり、人によっては他にもany
になっているものが出てくるかもしれません。
なぜ実装でanyが出るのか
これはあくまで推測になりますが、URL Pattern APIが一部のChromiumブラウザかDenoでしか実装されていない限定的なAPIであることで、tsconfig.jsonの設定では網羅できなかったのではないかと考えています。
DenoはWeb標準をいち早く実装する流れがあるため、こういった事例は一定数起こりうるのではないでしょうか。
これを解決するために、トリプルスラッシュディレクティブというものを利用します。
トリプルスラッシュディレクティブとは
TypeScirptが提供している型定義の反映方法です。ファイルの先頭行に/// <reference ...>
のように記述することで利用でき、Denoでも対応しています。
今回利用するトリプルスラッシュディレクティブは以下の2つです。
/// <reference lib="..." />
/// <reference no-default-lib="true"/>
/// <reference lib="..." />
はtsconfig.json
のlib
に相当するものです。たとえば/// <reference lib="dom" />
と入力すれば、DOMの型定義が適用されます。
/// <reference no-default-lib="true"/>
はtsconfig.jsonのnoLib
に相当するものです。/// <reference lib="..." />
より前に記述します。ライブラリファイルの自動インクルードを無効化するようです。
トリプルスラッシュディレクティブでエラーを解決する
それでは、E2E試験のファイルに実際に適用していきます。
ファイルの先頭行に、以下のように記述します。
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.asynciterable" />
/// <reference lib="deno.ns" />
E2E試験のために作成したtsconfig.json
は合わせて削除してください。
これで、実装にも試験にも型エラーはなくなったと思います。
最後に
この記事を思いついたのは、12月18日のことでした。たまたまURL Pattern APIのanyを見つけたのが起因です。
そこから記事の構想が固まるまでに時間がかかったため、急ピッチの記事作成となってしまいました。できるだけ資料を読んで書いたつもりですが、認識違いなどあればご指摘ください。
今回の記事作成にあたって、ミノ駆動さんの以下の記事を参考にさせていただきました。ありがとうございます。
最後になりますが、トリプルスラッシュディレクティブを利用した今回のテストファイルをGitHub Gistにあげているので、興味のある方はご覧ください。
以下のコマンドを実行することで、実際に走らせることもできます。
deno test --allow-net --allow-run https://gist.githubusercontent.com/windchime-yk/5d242d9e6a117a8f9215baabe79b109d/raw/4e534d8e7c7f5f4c1225b0ad1375917869b10720/deno.e2e.ts
誰かの開発の一助となれば幸いです。
お読みいただき、ありがとうございました。
Discussion