Safa Alai
Safa Alai

Reputation: 1277

Stenciljs e2e tests on Google Cloud Build

TL;DR: does anyone know how to make a valid stencil.js docker image to run stencil build & test?

Long form:

To run stencil.js e2e tests on Google Cloud Build you need a custom build step as a docker image.
Here's a sample Dockerfile:

# THESE STEPS GET STENCIL BUILD WORKING & SHOULD HAVE GOT TESTING WORKING
FROM node:10-jessie-slim
WORKDIR /
RUN npm init stencil app stencil
WORKDIR /stencil
COPY package*.json ./
RUN npm install
WORKDIR /stencil/node_modules/puppeteer
RUN npm install
WORKDIR /stencil

# STEPS ADDED BASED ON https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-in-docker
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl wget && rm -rf /var/lib/apt/lists/*
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
    && apt-get update \
    && apt-get install -y google-chrome-unstable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf \
      --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*
RUN npm i puppeteer \
    # Add user so we don't need --no-sandbox.
    # same layer as npm install to keep re-chowned files from using up several hundred MBs more space
    && groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
    && mkdir -p /stencil/home/pptruser/Downloads \
    && chown -R pptruser:pptruser /stencil/home/pptruser \
    && chown -R pptruser:pptruser /stencil/node_modules

ENTRYPOINT ["npm"]

Now you insert this into a cloud build.yaml file:

steps:
  #1 Build stencil project
  - name: 'gcr.io/$PROJECT_ID/stencil'
    args: ['run','build']
  #2 Test stencil project
  - name: 'gcr.io/$PROJECT_ID/stencil'
    args: ['test']

In this build file step #1 works, validating the stencil install. However, step #2 fails with error message:

[ ERROR ] Chromium revision is not downloaded. Run "npm install" or "yarn Step #2: install" Error: Chromium revision is not downloaded. Run "npm Step #2: install" or "yarn install" at Launcher.launch Step #2: (/workspace/node_modules/puppeteer/lib/Launcher.js:120:15)

The error above is about puppeteer not finding chromium (even though a local version is installed) and I have already ran the npm install on puppeteer and validated that the local chromium is installed. However Puppeteer documentation does mention running puppeteer in Docker is tricky and gives a solution, but their solution is for a docker container dedicated just to Puppeteer.

Does anyone have an idea how I can create a valid stencil.js docker image with a valid puppeteer setup?

Upvotes: 0

Views: 566

Answers (1)

Safa Alai
Safa Alai

Reputation: 1277

I finally managed to get stencil working in a container suitable for Google Cloud Build. The main problem was that puppeteer, which is needed for e2e test, does not work as installed because it does not have a chrome install with all necessary dependencies.

To fix you have to do three things:

  1. Install Chrome separately
  2. Point puppeteer to the installed Chrome
  3. Modify stencil config to invoke testing without a sandbox

1 & 2 are addressed with the following Dockerfile:

# Need jessie to install dependencies
FROM node:10-jessie-slim

# Copy files from stencil project
WORKDIR /
COPY package*.json ./
COPY node_modules/ ./node_modules

# Install wget & dependencies needed to install Chrome (next step)
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl wget && rm -rf /var/lib/apt/lists/*

# Install Chromium dev & dependencies
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
    && apt-get update \
    && apt-get install -y google-chrome-unstable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf \
      --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*

# Point puppeteer to the Chromium just installed
ENV PUPPETEER_EXECUTABLE_PATH '/usr/bin/google-chrome-unstable'

# Set entry point
ENTRYPOINT ["npm"]

Note that this Dockerfile must be placed in the same directory as your stencil project --i.e. it's in the same location as your stencil.config.ts and package.json.

Also note that this will only work if you have already run your tests in your local environment. Doing so ensures that the necessary testing dependencies are installed.

3 is fixed by modifying your stencil.config.ts as shown in stencil documentation so chrome runs without a sandbox:

export const config: Config = {
  namespace: 'Foo',
  testing: {
    // run chrome with no sandbox to have it work in a container
    browserArgs: ['--no-sandbox', '--disable-setuid-sandbox'],
  },
  outputTargets: [
    { type: 'dist' },
    {
      type: 'www',
    },
  ],
};

Upvotes: 0

Related Questions