はじめに
playwrightではなく、puppeteerでPDFを保存するということをやったことはあるのだが、playwrightではやったことはなかったので備忘録として残しておく。
環境
1
2
3
| Node.js 20.11.1
pnpm 8.15.4
playwright 1.42.1
|
準備
を使う。
node.js+expressの記事で作成したものを少し改造する。
変更点
package.json
にplaywright
をインストール後、Dockerfileを下記のように修正した。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| -FROM node:${NODE_VERSION}-alpine
+FROM node:${NODE_VERSION}
+# 目的のUID/GIDに変更する
+ARG USER_ID=1000
+ARG GROUP_ID=1000
# Install pnpm.
-RUN --mount=type=cache,target=/root/.npm \
- npm install -g pnpm@${PNPM_VERSION}
+RUN npm install -g pnpm@${PNPM_VERSION}
WORKDIR /usr/src/app
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
--mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --prod --frozen-lockfile
+RUN npx playwright install-deps
+# グループとユーザを作成し、所有権を変更する
+RUN groupmod --gid $GROUP_ID node && \
+ usermod --uid $USER_ID --gid $GROUP_ID node && \
+ chown -R node:node /usr/src/app
# Run the application as a non-root user.
USER node
+RUN npx playwright install
|
Dockerfile
の全体は下記
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| # syntax=docker/dockerfile:1
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/
# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7
ARG NODE_VERSION=20.11.1
ARG PNPM_VERSION=8.15.4
FROM node:${NODE_VERSION}
# 目的のUID/GIDに変更する
ARG USER_ID=1000
ARG GROUP_ID=1000
# Use production node environment by default.
ENV NODE_ENV production
# Install pnpm.
RUN npm install -g pnpm@${PNPM_VERSION}
WORKDIR /usr/src/app
# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.local/share/pnpm/store to speed up subsequent builds.
# Leverage a bind mounts to package.json and pnpm-lock.yaml to avoid having to copy them into
# into this layer.
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
--mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --prod --frozen-lockfile
RUN npx playwright install-deps
# グループとユーザを作成し、所有権を変更する
RUN groupmod --gid $GROUP_ID node && \
usermod --uid $USER_ID --gid $GROUP_ID node && \
chown -R node:node /usr/src/app
# Run the application as a non-root user.
USER node
RUN npx playwright install
# Copy the rest of the source files into the image.
COPY . .
# Expose the port that the application listens on.
EXPOSE 3000
# Run the application.
#CMD ["tail", "-f", "/dev/null"]
CMD node index.js
|
PDFを作成するjsは下記になる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
// ウェブページを開く
await page.goto('https://www.google.com');
// PDF を保存する
await page.pdf({ path: 'google.pdf' });
await browser.close();
})();
|
動作確認
1
| docker compose exec server bash
|
で、コンテナに入り
1
| node simple-capture-pdf.js
|
で実行する。
実行結果を確認すると、google.pdf
が作成できていることがわかる。
1
2
3
| node@4f740afe5daf:/usr/src/app$ node simple-pdf-capture.js
node@4f740afe5daf:/usr/src/app$ ls
README.Docker.md google.pdf index.js node_modules package.json playwright-test.js pnpm-lock.yaml simple-pdf-capture.js
|
PDFの確認
ホストとコンテナ間でソースコードに関してはボリュームをマウントしていないのでdocker cp
でコピーをする。
なので、docker cp
でコンテナIDを確認する。
1
2
3
4
| docker cp
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4f740afe5daf nodejs-express-handson-server "docker-entrypoint.s…" 30 minutes ago Up 30 minutes 0.0.0.0:3000->3000/tcp nodejs-express-handson-server-1
|
ホスト側にgoogle.pdf
をコピーする。
1
| docker cp 4f740afe5daf:/usr/src/app/google.pdf .
|
できたもの↓
google.pdf
参考
おわりに
playwrightでPDFの保存というのをやってみた。
playwrightはE2Eテストが主な目的だが、WebページのPDFを保存するということもできることを知れた。
今度はE2Eテストとして使えるように試してみたい。
特に業務ではテストデータを手作業で作るのが面倒なので、playwrightを使って自動化してみたいなあ。