2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Node.jsからLighthouseを使用して認証付きサイトを検証する方法

Posted at

目的

Node.jsからLighthouseを使って認証付きサイトの測定を自動化しようとして色々調べていたが、情報が散らばっていて構築するのにすごく手間がかかったので、メモがてら残しておく

環境

nodeがインストールされていることが前提
node v16.13.1

準備

まずはLighthouseとブラウザ操作をするためにPuppeteer、パスワードなど環境変数を使用するためにdotenvをインストールする

npm install lighthouse
npm install puppeteer
npm install dotenv

Node.jsで動かすためのコード

.envやコンフィグファイルを使用して、ユーザー名やパスワードをフォームに入力し、狙いのURLをLighthouseで検証するコードは以下となる。
Basic認証を通している。

lighthouse.js
const fs = require("fs");
const puppeteer = require("puppeteer");
const lighthouse = require("lighthouse");
const { URL } = require("url");
const config = require("./custom-config.js");
require('dotenv').config();

(async () => {

  // ブラウザを立ち上げる
  const browser = await puppeteer.launch({
    headless: false,
    defaultViewport: null,
  });
  const page = await browser.newPage();

  // Basic認証の設定   
  await page.setExtraHTTPHeaders({
    Authorization: `Basic ${Buffer.from(`${process.env.BASIC_USERNAME}:${process.env.BASIC_PASSWORD}`).toString("base64")}`,
  });

  // ログインページに遷移
  await page.goto(loginUrl, {
    waitUntil: "domcontentloaded",
  });
  // ユーザーメイトパスワードを入力してログインボタンを押す
  await page.type("ユーザー名のフォームを指定", process.env.USER_NAME);
  await page.type("パスワードのフォームを指定", process.env.USER_PASSWORD);
  await page.click("ログインボタンを指定");
  await page.waitForNavigation({
    timeout: 20000,
    waitUntil: "domcontentloaded",
  });

  // 測定したいページに遷移
  await page.goto(process.env.TARGET_URL, {
    waitUntil: "domcontentloaded",
  });

  // BASIC認証を入れてLighthouseを起動する
  const runnerResult = await lighthouse(
    targetUrl,
    {
      port: new URL(browser.wsEndpoint()).port,
      logLevel: "info",
      output: "html",
      disableStorageReset: true,
      extraHeaders: {
        Authorization: `Basic ${Buffer.from(`${process.env.BASIC_USERNAME}:${process.env.BASIC_PASSWORD}`).toString("base64")}`,
      },
    },
    config
  );

  // Lighthouseのレポートを保存する
  const reportHtml = runnerResult.report;
  fs.writeFileSync("./reports/" + nameReport, reportHtml);

  // スコアをコンソールに表示
  console.log(
    `Lighthouse scores: ${Object.values(runnerResult.lhr.categories)
      .map((c) => c.score * 100)
      .join(", ")}`
  );

  await browser.close();

})();

Lighthouseに設定値を使用するためにコンフィグファイルを使用している。

custom-config.js
module.exports = {
    extends: "lighthouse:default",
    settings: {
      formFactor: "desktop",
      screenEmulation: {
        mobile: false,
        width: 1366,
        height: 768,
        deviceScaleFactor: 1,
        disabled: false,
      },
      emulatedUserAgent:
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4143.7 Safari/537.36 Chrome-Lighthouse",
    },
  };

さらに、パスワードなどの変数を使用するために.envファイルを使用する。

.env
BASIC_USERNAME = ""
BASIC_PASSWORD = ""
USER_NAME = ""
USER_PASSWORD = ""

動かし方

コマンドラインで以下を実行する
node lighthouse.js

ブラウザが自動で立ち上がりユーザー名やパスワードを入れてページ遷移をして、Lighthouseの計測が始まる

所感

1.Node.jsで計測したLighthouseの結果とChrome開発者ツールで測定した結果があまりにも違いすぎる

Node.jsで計測した結果
image.png

Chrome開発者ツールで測定した結果
image.png

2.3回に1回くらい失敗する
 →これはChrome開発者ツールで測定しても失敗することがある(セッションが絡むと上手くいかないことがある)

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?