Beeeat’s log

Beeeat’s log

プログラミングで出くわした知識やツール、日常生活、働き方その他色々なことをメモしていくブログ

「ゆるWeb勉強会@札幌 OnLine #9」で Jest + Puppeteer で E2E テストを導入した話をしました

この記事は マイナビ Advent Calendar 2020 の1日目の記事となります. (なんか去年も1日目だった気がする...)

今年の10月頃になりますが「ゆるWeb勉強会@札幌 OnLine #9」という勉強会で登壇しました.

mild-web-sap.connpass.com

私の地元は札幌で前々からゆるWeb勉強会に参加してみたかったのですが.帰省する日が盆と正月でいつも参加のタイミングを逃していましたが, 今回はオンラインでの参加ができるとのことなので,思い切って参加してみました.

オンラインでの登壇のためいつもと勝手が違い緊張しましたがオンライン上で参加者の皆さんと交流ができ,充実したイベントとなりました.

このイベントでは,私が業務で担当しているニュースメディアに Jest + Puppeteer で E2Eテストを導入した話をしました. 今回は登壇した資料についての補足や発表時にあまり話せていなかった内容を書いていこうと思います.

登壇資料

広告の表示確認を目視で確認している

f:id:bake0937:20201201223558p:plain

担当しているニュースメディアでは Google Ad Manager(以下,GAM) などを利用してネットワーク広告を表示するようにしています.

初回は GAM で発行されたタグをWebアプリ(Rails)の View に設定する必要があるのですが,どんな種類の広告が表示されるかはGAM側の設定になるため, 基本的には社内のネットワーク広告のチームのメンバーが表示を確認していました.

表示の確認なら簡単じゃん...と思うじゃん!

f:id:bake0937:20201201223641p:plain

1つ2つの広告タグの追加や変更くらいならパッと目視で確認ができるのですが,変更数が多かったりページ全体をリニューアルする時は確認作業って結構大変になります.

f:id:bake0937:20201201204415p:plain

確認作業は慣れてはいきますが,その分ヒューマンエラーも発生するリスクもあります.

f:id:bake0937:20201201204731p:plain

PC版に加えて,スマホ版のチェックもあったりと結局,広告チームのメンバーは確認作業で約半日掛かったようです.

回数を重ねれば,慣れてはいきますが,全体に関わるような変更を都度行ってしまうとその都度すべてのパターンを確認することになるのでかなり消耗します.

E2Eテストを導入して自動できそう!?

f:id:bake0937:20201201210555p:plain

E2Eテストの存在は前職で RSpec + Capybara + Poltergeist でE2Eテストを実装した経験もあり,導入してネットワーク広告のチームのメンバーの確認作業の負担を減らせそうと思いトライしてみました.

技術選定は色々なパターンを検討しましたが結果的には Jest + Puppeteer の構成にしました.

選定理由はスライドにも書いてありますが,さらに補足すると Poltergeist を使って操作することができる PhantomJS は現在では EOL になってしまい,その代替として Headless Chrome が話題になっていたことがずっと気になっており,いつか使ってみたいという気持ちがあったからというのもありました.

jser.info

導入手順とディレクトリ構成

f:id:bake0937:20201201223728p:plain

元々ローカル開発環境が Docker で作られていたため,それに併せて Puppeteer 用の Dockerfile を作成しました.(GtiHub にサンプルを後日アップします.)

結構...というかかなり Docker の勉強もすることもできて良かったです. ディレクトリ構成としてはフロントエンド用のディレクトリをすでに作っていたためそこにE2Eテストを導入するような構成しました.

実装例

f:id:bake0937:20201201211548p:plain

基本的にはbeforeAllで特定のページにアクセスし,GAM で発行したタグを取得できるか・できないかを確認のためテストの内容自体は簡単でした. しかし,タグが何十個もあるためその分のテストケースを書く必要がありました.

全テストを実行してみた

f:id:bake0937:20201201212027p:plain

適宜リファクタリングもし,全テストを実行してみたところ確認作業がなんと半日から約2分間まで短縮できました. この結果にはかなり驚き,とても達成感が溢れていた記憶があります.

とはいえ課題はある

f:id:bake0937:20201201212249p:plain

確認作業の大幅な時間短縮を期待できそうではあるのですが,メンテナンスコストや CI で回すかどうかなど色々と課題はありました.

E2Eテストはページの読み込みが上手く行かなったりすると,「たまに落ちる」が起きてしまうためあまり細かい粒度で書いてしまうと苦労するような話をよく聞きました.

今回はネットワーク広告という収益に大きく関わる内容だったため,E2Eテストを書く価値があると判断しましたが他の種類のテストケースを書く時はその都度検討したほうが良いと思いました.

発表中

発表中は Twitterハッシュタグや, Youtube のコメント,質疑応答を通してたくさんのコメントやフォードバックを頂きました.ありがとうございます.

当日の様子は「ゆるWeb勉強会@札幌 OnLine #9」あたりのツイートのリンクをざっくりではありますが,作ってみたの良ければこちらからどうぞ.

mobile.twitter.com

追記

tacck さんがまとめてくださってました.ありがとうございます!

togetter.com

まとめと所感

「ゆるWeb勉強会@札幌 OnLine #9」で登壇しました. オンラインでの登壇ははじめてでしたが,久しぶりに地元の勉強会に参加できてとても楽しかったです.

E2Eテストについては今回の登壇を通してフィードバッグをたくさん頂いたため,それらを基に引き続き頑張っていこうと思います.

来月も「ゆるWeb勉強会@札幌 OnLine #11」が開催されるとのことなので5分 LT で参加しようと思います💪

mild-web-sap.connpass.com

「Tab Limiter」を使ってブラウザのタブを開きすぎないようにする

情報収集をしている時にあとで読むページをとりあえず新規タブで開いておくようにしている.

しかし,そうするとブラウザのタブが30個以上になり,次第に PC のファンが急激に回りフリーズする...なんてことが度々ある.

そのため,タブを開きすぎないようにしようと思うにも中々守ることができないため色々探してみると「Tab Limiter」という Chrome 拡張が便利そうだと思い使ってみた.

使い方

ここからインストールする.

chrome.google.com

オプションへ移動する.

f:id:bake0937:20201130183326p:plain

ここでタブ数の制限を設定できる.私は10で設定している. こうすると11タブ目を開こうとした時に一番左のタブが閉じられるようになる.

f:id:bake0937:20201130183940p:plain

実際に11タブ目を開いてみると一番左のタブが閉じられる.もし閉じたくないタブだった場合は閉じたタイミングで通知が表示されるため, 記事タイトル周辺をクリックすると固定された状態で再び表示されるので安心.しかし,入力途中のタブだった場合はデータが消える可能性が高いため注意が必要. f:id:bake0937:20201130184916p:plain

f:id:bake0937:20201130184837p:plain

まとめと所感

今回は「Tab Limiter」について紹介した.タブはついつい沢山開いてしまうと途端に PC のファンが急激に周って困っていたため今回の拡張機能を使って強制的に10タブにで運用してみたところ. 今の所良い感じに運用できている.

しかし,ウィンドウを複数開いて10タブ開いてしまうと元の子もないためそこに関しては注意が必要である.

サブディレクトリで vue プロジェクトを作成し,VSCode 上で ESLint が動かない場合の対応方法

vue-cli を使ってサブディレクトリに vue プロジェクトを作成したところ VSCode 上で ESLint が上手く動かなくなり,少し詰まってしまった. 今回はその対応方法についてまとめてみる.

内容

以下のような階層で vue プロジェクトを作った場合とする.

sample_project
├── vue_app
│   ├── .browserslistrc
│   ├── .eslintrc.js
│   ├── .gitignore
│   ├── .prettierrc.js
│   ├── Dockerfile
│   ├── README.md
│   ├── babel.config.js
│   ├── cypress.json
│   ├── docker-compose.yml
│   ├── jest.config.js
│   ├── node_modules
│   ├── package.json
│   ├── public
│   ├── src
│   ├── stylelint.config.js
│   ├── tests
│   ├── tsconfig.json
│   └── yarn.lock
└──.vscode
    └── settings.json

単一ファイルコンポーネントを修正し,保存しても ESLint の警告が表示されない...

f:id:bake0937:20201123230501p:plain

「出力」を ESLint に選択し,内容を見てみると以下のような Error が表示された.

[Error - 22:51:22] Request textDocument/codeAction failed.
  Message: Request textDocument/codeAction failed with message: Cannot read config file: /Users/hoge_user/projects/sample_project/.eslintrc.js
Error: Cannot find module '/Users/hoge_user/projects/sample_project/.eslintrc.js'
Require stack:
- /Users/hoge_user/projects/sample_project/vue_app/node_modules/eslint/lib/cli-engine/noop.js
  Code: -32603 
(node:16876) UnhandledPromiseRejectionWarning: Error: Cannot read config file: /Users/hoge_user/projects/sample_project/.eslintrc.js
Error: Cannot find module '/Users/hoge_user/projects/sample_project/.eslintrc.js'
Require stack:
- /Users/hoge_user/projects/sample_project/vue_app/node_modules/eslint/lib/cli-engine/noop.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:844:17)
    at resolveFileName (/Users/hoge_user/projects/sample_project/vue_app/node_modules/import-fresh/node_modules/resolve-from/index.js:29:39)
    at resolveFrom (/Users/hoge_user/projects/sample_project/vue_app/node_modules/import-fresh/node_modules/resolve-from/index.js:43:9)
    at module.exports (/Users/hoge_user/projects/sample_project/vue_app/node_modules/import-fresh/node_modules/resolve-from/index.js:46:41)
    at module.exports (/Users/hoge_user/projects/sample_project/vue_app/node_modules/import-fresh/index.js:14:19)
    at loadJSConfigFile (/Users/hoge_user/projects/sample_project/vue_app/node_modules/eslint/lib/cli-engine/config-array-factory.js:201:16)
    at loadConfigFile (/Users/hoge_user/projects/sample_project/vue_app/node_modules/eslint/lib/cli-engine/config-array-factory.js:284:20)
    at ConfigArrayFactory._loadConfigData (/Users/hoge_user/projects/sample_project/vue_app/node_modules/eslint/lib/cli-engine/config-array-factory.js:496:13)
    at ConfigArrayFactory.loadFile (/Users/hoge_user/projects/sample_project/vue_app/node_modules/eslint/lib/cli-engine/config-array-factory.js:416:18)
    at createCLIConfigArray (/Users/hoge_user/projects/sample_project/vue_app/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js:157:35)
(node:16876) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 8)

原因

調べてみたところ VSCode で開いたプロジェクトの直下に .eslintrc.js が無いことが原因だった.

そのためプロジェクトの直下に .eslintrc.js を置くようにすれば良いのだが,今回のようなサブディレクトリに vue プロジェクトを作った場合の構成は, .vscode/settings.jsoneslint.workingDirectoriesを設定をする必要がある.

++  // .vscode/settings.json
++  "eslint.workingDirectories": [
++    "./vue_app"
++  ],

再び単一ファイルコンポーネントを修正し保存すると,期待通りに ESLint が警告を出ることを確認できた.

f:id:bake0937:20201123231857p:plain

まとめと所感

今回はサブディレクトリで vue プロジェクトを作成し,VSCode で ESLint が動かない場合の対応方法についてまとめた. 知ってしまえば簡単だが,ここで詰まると Linter が動かないまま開発を進めることになるため非常に辛い状況になる.

勉強時はルートディレクトリに vue プロジェクトを作ってコードを書いていくのが普通だったため中々気づきにくかった内容ではある.

しかし,ここを知ってしまえばルートディレクトリ直下にfrontendbackendといったサブディレクトリの構成でリポジトリを作った時の VSCode の設定がわかるようになったため,良い経験だと捉えて引き続き頑張っていく.

参考記事

blogenist.jp

qiita.com

「Microsoft Clarity」という行動分析ツールが無料で使えるようなので試してみる

チームメンバーと雑談している時に「Microsoft Clarity」という行動分析ツールがあることを教えてもらいました.

clarity.microsoft.com

どうやら無料でヒートマップやセッションのレコーディングを使うことができる優れもののようです.

なんか凄そうなツールだと思い,試しに自分のブログに導入してみたので今回はそれについてまとめようと思います.

使い方

まずは公式サイトから Sign In をします.

clarity.microsoft.com

Sign In すると「ADD NEW PROJECT」という項目があるのでクリックし,自分が導入したいサイトのURLとその情報を入れます.

f:id:bake0937:20201116230147p:plain

追加すると Setup 画面に遷移されます. この画面にはブログの<head>タグに埋め込むスクリプトが載っているので,それをコピーしておきます.

f:id:bake0937:20201116230509p:plain

ブログの<head>タグにコピーしたスクリプトを貼りつけます.

f:id:bake0937:20201116230806p:plain

これで導入は完了です.ここから Microsoft Clarity が情報取得する作業に入るため約2〜3時間待ちます.

f:id:bake0937:20201116231718p:plain

導入してから約2〜3時間後にアクセスすると,Pages per session やアクセスが多い記事(URL),閲覧ブラウザの比率などサイト分析に必要な情報がダッシュボードに表示されます.

f:id:bake0937:20201116231521p:plain

メイン機能の一つであるヒートマップはこんな感じ! すごい!自分が書いた記事を読者がどの部分に注目しているのかがわかるのはとても役に立ちますね!

f:id:bake0937:20201116231301p:plain

他にも Session のレコーディング機能で読者がどのように記事を読んでいるのかを見る機能もあって感動しました.

便利!ではあるのですが...

ここまで便利が機能があって無料なんてマイクロソフトすげーって感じにはなりましたが,動作が遅いことは気になりました. (複数タブで開くと結構な確率で落ちます...orz)

まぁまだβ版とのことなのでここに関して今後のアップデートに期待です.

追記: 2020/11/23

私が入れていた Chrome 拡張が原因で動作が遅くなっていたようです...🙇‍♂️ たまたま不要になったため Chrome 拡張をアンインストールしたところ Microsoft Clarity がサクサク動くようになりました🙇‍♂️ .

まとめと所感

Microsoft Clarity」という行動分析ツールを自分のブログに導入してみました.ヒートマップツールは自分の中で遠い存在のものなイメージで今回をきっかけに触ることができて良かったです.

またこの手のツールは有料なものしかないものだと思っていたので,無料で気軽に試せたのはありがたかったです. サイト改善に普通に役立つツールだと感じました.

特にヒートマップや Session のレコーディング機能は魅力的だと思いました.

今回をきっかけに色々調べてみたところ無料のヒートマップツールが何個かあるようなので,気が向いたら試してみようかとも思いました.

リダイレクトされているかをチェックする時は「Link Redirect Trace」を使うと便利

業務で nginx を使ってリダイレクトを設定することが定期的にある. その時にリダイレクトできているのかを実際にアクセスして確認することがあるが,証跡が欲しい時がある.

そんな時は「Link Redirect Trace」を使うと便利なので今回はこの拡張機能について紹介する.

使い方

ここからインストールできる.

chrome.google.com

インストールするとこんなアイコンが表示される

f:id:bake0937:20201109223418p:plain

実際にリダイレクトできるページで試してみる. 今回は自分のブログを http でアクセスしてリダイレクトできるかを試してみる.

f:id:bake0937:20201109223227p:plain

アイコンを見てみると,301 が表示されており,リダイレクトできているように見える.

f:id:bake0937:20201109223348p:plain

さらにクリックすると詳細が表示され,アクセス経路が表示される.

f:id:bake0937:20201109223305p:plain

各ステータス番号が表示されている付近をクリックすると,HTTP Headers も表示されて便利.

f:id:bake0937:20201109224050p:plain

まとめと課題

今回は「Link Redirect Trace」について紹介した. この拡張機能はリダイレクトの設定が上手くいった時は勿論,上手く行かなかった時にどういう経路になってしまっているかを調査する時に便利だと感じている. 他にも確認できる項目があるので,リダイレクトの確認以外にも上手く活用していこうと思う.

daily.dev で海外の Tech メディアやブログを手軽にチェックする

技術周りの情報収集をする時は個人・企業のテックブログや QiitaZenn などの情報共有サービス,最近だと TechFeed Pro という便利なメディアが出てきている.

techfeed.io

しかし,Twitter を見てると海外の記事がちょくちょく話題になっていることがあり,「そもそも皆どうやって見つけてるんだ?」という気持ちになることがある.

勿論,海外の Tech 系の記事をどんどん見ているんだろうけどそもそも海外のブログやメディアをそこまで深く知らない状態である.

とりあえず Hacker News の拡張機能でも入れようかと思っていたら関連のところに「daily.dev」というサービスを見つけたため今回はこれについてまとめていく.

daily.dev

使い方

インストールは簡単.ここから拡張機能をインストールする.

chrome.google.com

新しいタブを開くと早速 daily.dev が表示される.そのため手軽に海外の技術情報に触れる機会が増えることになる

左にカーソルを合わせるとサイドバーが表示され,フィードに追加したいソース(メディアやブログ)が表示される.

確か最初は全部がフィードに追加された状態だった気がするので,私の場合は一旦全部のソースをフィードから消してから気になったソースだけを追加するようにした.

f:id:bake0937:20201102225233p:plain

タグの機能もあり,選択すると該当する記事が表示される.

f:id:bake0937:20201102225437p:plain

フィードに表示されている記事をブックマークすることができる. f:id:bake0937:20201102230512p:plain

フィードに追加したいソースが daily.dev 上に無い場合はこのように RSS を登録することができるが無料会員の場合は daily.dev リクエストまでで,有料会員になれば追加することができる.

f:id:bake0937:20201102225708p:plain

有料会員になれば,他にもさまざまなサービスと連携ができるようだ.

daily.dev

まとめと所感

今回は daily.dev についてまとめてみた.海外のメディアやブログは Medium, dev.to, GitHub Blog, あとは Twitter で流れた記事くらいしかそこまで気にしていなかったが, daily.dev を入れたことで,さまざまな海外のメディアやブログをまずは知ることができた.「というかこんなに沢山あるんですね」というのが正直な感想である.

加えて新規タブを開くとすぐにフィードが表示され,手軽にチェックができるのも良い. 日本に加えて海外の Tech メディアやブログにも手を伸ばしたいという人にはその取っ掛かりになる便利なサービスだと感じた.

Google スライドで図形を透過する方法

今まででめちゃくちゃ小ネタになるが,Google スライドで図形を透過する時,ほんの数年前は Keynote などを使う必要があった気がしていたのだが, いつの間にか簡単に透過できることがわかったため自分用に残しておく

方法

とりあえず適当に画像が入ったスライドを用意する.

f:id:bake0937:20201026233316p:plain

図形を覆いかぶせる.

f:id:bake0937:20201026233647p:plain

カスタムの「+」を選択する.

f:id:bake0937:20201026233802p:plain

透明度という項目があるので真ん中あたりに設定.

f:id:bake0937:20201026234100p:plain

これで透過ができた.

f:id:bake0937:20201026233448p:plain

白文字にしたらそれらしくなる.

f:id:bake0937:20201026233549p:plain

まとめと所感

今回は Google スライドで図形を透過する方法についてまとめてみた.いつからできるようになったのか...それとも前々からできていたのか...

とりあえず,上記のようなスライドはよく作るので Google スライドで透過できることを知ったのはとても良かった.