# Utilisation avec Lighthouse CI

# Objectifs

Utiliser le plugin lighthouse-ecoindex avec Lighthouse CI dans vos outils de CI/CD ou vos repositories CI/Cd.

Vous pourrez ainsi :

  • Publier les résultats des audits Lighthouse et EcoIndex® dans votre CI/CD ;
  • Publier les résultats des audits Lighthouse et EcoIndex® dans un serveur Lighthouse.

# Installation

npm install -g lighthouse lighthouse-plugin-ecoindex puppeteer --save-dev

# Utilisation

Vous devez utiliser le fichiers configuration de Lighthouse pour pouvoir utiliser le plugin lighthouse-ecoindex.

/**
 * @license
 * Copyright 2018 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
const path = require('path')
function getLighthouseConfig() {
  return path.join(
    require.resolve('lighthouse-plugin-ecoindex'),
    '../helpers/lhci/custom-config.cjs',
  )
}
function getPuppeteerConfig() {
  return 'node_modules/lighthouse-plugin-ecoindex/helpers/.puppeteerrc.cjs'
}
module.exports = {
  ci: {
    collect: {
      url: [
        'https://www.ecoindex.fr/',
        'https://www.ecoindex.fr/comment-ca-marche/',
      ],
      numberOfRuns: 1,
      settings: {
        // must adapte the path to the custom-config.js file, it must be an absolute path
        configPath: getLighthouseConfig(),
      },
      puppeteerLaunchOptions: {
        headless: 'new',
        args: [
          '--disable-gpu',
          '--disable-dev-shm-usage',
          '--disable-setuid-sandbox',
          '--no-sandbox',
        ],
      },
      puppeteerScript: getPuppeteerConfig(),
    },
    assert: {
      preset: 'lighthouse:default',
    },
    upload: {
      target: 'lhci',
      serverBaseUrl: 'http://localhost:9001', // The Lighthouse CI server URL
      token: 'xxx', // The Lighthouse CI server build token for the project
      ignoreDuplicateBuildFailure: true,
    },
  },
}

Tip Placer le fichier .lighthouserc.js à la racine de votre projet.

// https://pptr.dev/guides/configuration
// https://github.com/GoogleChrome/lighthouse-ci/blob/main/docs/configuration.md#puppeteerscript
/**
 * @param {puppeteer.Browser} browser
 * @param {{url: string, options: LHCI.CollectCommand.Options}} context
 */
module.exports = async (browser, context) => {
  // launch browser for LHCI
  const page = await browser.newPage(context.options)
  const session = await page.target().createCDPSession()
  await page.goto(context.url, { waitUntil: 'networkidle0' })
  await startEcoindexPageMesure(page, session)
  await endEcoindexPageMesure()
  // close session for next run
  await page.close()
}

async function startEcoindexPageMesure(page, session) {
  page.setViewport({
    width: 1920,
    height: 1080,
  })
  await new Promise(r => setTimeout(r, 3 * 1000))
  const dimensions = await page.evaluate(() => {
    var body = document.body,
      html = document.documentElement

    var height = Math.max(
      body.scrollHeight,
      body.offsetHeight,
      html.clientHeight,
      html.scrollHeight,
      html.offsetHeight,
    )
    return {
      width: document.documentElement.clientWidth,
      height: height,
      deviceScaleFactor: window.devicePixelRatio,
    }
  })
  // console.log('dimensions', dimensions)
  // We need the ability to scroll like a user. There's not a direct puppeteer function for this, but we can use the DevTools Protocol and issue a Input.synthesizeScrollGesture event, which has convenient parameters like repetitions and delay to somewhat simulate a more natural scrolling gesture.
  // https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-synthesizeScrollGesture
  await session.send('Input.synthesizeScrollGesture', {
    x: 100,
    y: 600,
    yDistance: -dimensions.height,
    speed: 1000,
  })
}

/**
 * End Ecoindex flow. Wait 3s.
 */
async function endEcoindexPageMesure() {
  await new Promise(r => setTimeout(r, 3 * 1000))
}

# Exemple

Projet example pour lighthouse-ci
https://github.com/cnumr/lighthouse-plugin-ecoindex/tree/main/examples/lhci

# Exemples à adapter suivant votre CI/CD

Informations

.github/workflows/ci.yml

name: CI
on: [push]
jobs:
  lighthouseci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
      - run: npm install && npm install -g @lhci/cli@0.12.x
      - run: npm run build
      - run: lhci autorun

.gitlab-ci.yml

image: cypress/browsers:node16.17.0-chrome106
lhci:
  script:
    - npm install
    - npm run build
    - npm install -g @lhci/cli@0.12.x
    - lhci autorun --upload.target=temporary-public-storage --collect.settings.chromeFlags="--no-sandbox" || echo "LHCI failed!"

.circleci/config.yml

version: 2.1
orbs:
  browser-tools: circleci/browser-tools@1.2.3
jobs:
  build:
    docker:
      - image: cimg/node:16.13-browsers
    working_directory: ~/your-project
    steps:
      - checkout
      - browser-tools/install-chrome
      - run: npm install
      - run: npm run build
      - run: sudo npm install -g @lhci/cli@0.12.x
      - run: lhci autorun

machine-setup.sh

#!/bin/bash

set -euxo pipefail

# Add Chrome's apt-key
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee -a /etc/apt/sources.list.d/google.list
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -

# Add Node's apt-key
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -

# Install NodeJS and Google Chrome
sudo apt-get update
sudo apt-get install -y nodejs google-chrome-stable

job.sh


#!/bin/bash

set -euxo pipefail

npm install
npm run build

export CHROME_PATH=$(which google-chrome-stable)
export LHCI_BUILD_CONTEXT__EXTERNAL_BUILD_URL="$BUILD_URL"

npm install -g @lhci/cli@0.12.x
lhci autorun

# Documentation externe des dépendances

Lighthouse CI
https://github.com/GoogleChrome/lighthouse-ci#readme

Puppeteer
https://pptr.dev/