Skip to content

Commit

Permalink
✅ Do not integrate test code inside images as default CMD
Browse files Browse the repository at this point in the history
  • Loading branch information
zigarn committed May 30, 2024
1 parent 6c71499 commit 9e30a1f
Show file tree
Hide file tree
Showing 19 changed files with 70 additions and 70 deletions.
51 changes: 26 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,13 @@ Command (with no-sandbox): `` docker container run -u `id -u $USER` -it --rm -v

Go the deno `src` folder. Build your image using this command:

```
```shell
docker image build -t zenika/alpine-chrome:with-deno-sample .
```

Then launch the container:

```
```shell
docker container run -it --rm zenika/alpine-chrome:with-deno-sample
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts
Expand All @@ -148,7 +148,7 @@ docker container run -it --rm zenika/alpine-chrome:with-deno-sample

With your own file, use this command:

```
```shell
docker container run -it --rm -v $(pwd):/usr/src/app zenika/alpine-chrome:with-deno-sample run helloworld.ts
Compile file:///usr/src/app/helloworld.ts
Download https://deno.land/std/fmt/colors.ts
Expand All @@ -162,18 +162,18 @@ With tool like ["Puppeteer"](https://pptr.dev/#?product=Puppeteer&version=v1.15.

With some code in NodeJS, we can improve and make some tests.

See the ["with-puppeteer"](https://github.com/Zenika/alpine-chrome/blob/master/with-puppeteer) folder for more details. We have to [follow the mapping of Chromium => Puppeteer described here](https://github.com/puppeteer/puppeteer/blob/main/versions.js).
See the [`with-puppeteer`](./with-puppeteer) folder for more details. We have to [follow the mapping of Chromium => Puppeteer described here](https://github.com/puppeteer/puppeteer/blob/main/versions.js).

If you have a NodeJS/Puppeteer script in your `src` folder named `pdf.js`, you can launch it using the following command:

```
```shell
docker container run -it --rm -v $(pwd)/src:/usr/src/app/src --cap-add=SYS_ADMIN zenika/alpine-chrome:with-puppeteer node src/pdf.js
```

With the ["font-wqy-zenhei"](https://pkgs.alpinelinux.org/package/edge/testing/x86/font-wqy-zenhei) library, you could also manipulate asian pages like in ["screenshot-asia.js"](https://github.com/Zenika/alpine-chrome/blob/master/with-puppeteer/src/screenshot-asia.js)
With the ["font-wqy-zenhei"](https://pkgs.alpinelinux.org/package/edge/community/x86/font-wqy-zenhei) library, you could also manipulate asian pages like in [`with-puppeteer/test/screenshot-asia.js`](./with-puppeteer/test/screenshot-asia.js)

```
docker container run -it --rm -v $(pwd)/src:/usr/src/app/src --cap-add=SYS_ADMIN zenika/alpine-chrome:with-puppeteer node src/screenshot-asia.js
```shell
docker container run -it --rm -v $(pwd)/with-puppeteer/test:/usr/src/app/test --cap-add=SYS_ADMIN zenika/alpine-chrome:with-puppeteer node test/screenshot-asia.js
```

These websites are tested with the following supported languages:
Expand All @@ -183,29 +183,30 @@ These websites are tested with the following supported languages:
- Korean (with `https://www.naver.com/`)

# How to use with Puppeteer to test a Chrome Extension
[According to puppeteer official doc](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#working-with-chrome-extensions) you can not test a Chrome Extension in headleass mode. You need a display available, that's where Xvfb comes in.

See the ["with-puppeteer-xvfb"](https://github.com/Zenika/alpine-chrome/blob/master/with-puppeteer-xvfb) folder for more details. We have to [follow the mapping of Chromium => Puppeteer described here](https://github.com/puppeteer/puppeteer/blob/main/versions.js).
[According to puppeteer official doc](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#working-with-chrome-extensions) you can not test a Chrome Extension in headless mode. You need a display available, that's where Xvfb comes in.

Assuming you have a NodeJS/Puppeteer script in your `src` folder named `extension.js`, and the unpacked extension in the `chrome-extension` folder, you can launch it using the following command:
See the [`with-puppeteer-xvfb`](./with-puppeteer-xvfb) folder for more details. We have to [follow the mapping of Chromium => Puppeteer described here](https://github.com/puppeteer/puppeteer/blob/main/versions.js).

```
Assuming you have a NodeJS/Puppeteer script in your `src` folder named `extension.js`, and the [unpacked extension](./with-puppeteer-xvfb/test/chrome-extension/) in the `src/chrome-extension` folder, you can launch it using the following command:

```shell
docker container run -it --rm -v $(pwd)/src:/usr/src/app/src --cap-add=SYS_ADMIN zenika/alpine-chrome:with-puppeteer-xvfb node src/extension.js
```

The extension provided will change the page background in red for every website visited. This demo will load the extension and take a screenshot of the icanhazip.com website.
The extension provided will change the page background in red for every website visited. This test `test/test.js` will load the extension and take a screenshot of the https://example.com website.

# How to use with Playwright

Like ["Puppeteer"](https://pptr.dev/#?product=Puppeteer&version=v6.0.0&show=api-class-browser), we can do a lot things using ["Playwright"](https://playwright.dev/docs/core-concepts/#browser) with our Chrome Headless.

Go to the `with-playwright` folder and launch the following command:
Go to the [`with-playwright`](./with-playwright) folder and launch the following command:

```
docker container run -it --rm -v $(pwd)/src:/usr/src/app/src --cap-add=SYS_ADMIN zenika/alpine-chrome:with-playwright node src/useragent.js
```shell
docker container run -it --rm -v $(pwd)/test:/usr/src/app/test --cap-add=SYS_ADMIN zenika/alpine-chrome:with-playwright node test/test.js
```

A `example-chromium.png` file will be created in your `with-playwright/src` folder.
An `example.png` file will be created in the [`with-playwright/test`](./with-playwright/test) folder.

# How to use with WebGL

Expand All @@ -230,7 +231,7 @@ Even if it used to run browsers in docker containers, it can be quite useful as

You can run it with following command:

```
```shell
docker container run -it --rm --cap-add=SYS_ADMIN -p 4444:4444 zenika/alpine-chrome:with-selenoid -capture-driver-logs
```

Expand All @@ -246,7 +247,7 @@ See more [selenoid docs](https://aerokube.com/selenoid/latest/#_using_selenoid_w

We can run the container as root with this command:

```
```shell
docker container run --rm -it --entrypoint "" --user root zenika/alpine-chrome sh
```

Expand All @@ -272,23 +273,23 @@ Some examples are available on the `examples` [directory](examples):

## Alpine version

```
```shell
docker container run -it --rm --entrypoint "" zenika/alpine-chrome cat /etc/alpine-release
3.19.1
# 3.19.1
```

## Chrome version

```
```shell
docker container run -it --rm --entrypoint "" zenika/alpine-chrome chromium-browser --version
Chromium 121.0.6167.85 Alpine Linux
# Chromium 121.0.6167.85 Alpine Linux
```

## Image disk size

```
```shell
docker image inspect zenika/alpine-chrome --format='{{.Size}}'
663644797 # 633 MB
# 663644797 # 633 MB
```

# ✨ Contributors
Expand Down
1 change: 1 addition & 0 deletions with-playwright/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
test/
test.sh
2 changes: 0 additions & 2 deletions with-playwright/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ ENV PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium-browser
WORKDIR /usr/src/app
COPY --chown=chrome package.json package-lock.json ./
RUN npm install
COPY --chown=chrome . ./
ENTRYPOINT ["tini", "--"]
CMD ["node", "/usr/src/app/src/useragent"]
6 changes: 1 addition & 5 deletions with-playwright/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
{
"name": "zenika-alpinechrome-withplaywright",
"version": "1.0.0",
"description": "Tests with playwright",
"scripts": {
"start": "node src/useragent",
"test": "echo \"Error: no test specified\" && exit 1"
},
"description": "Alpine chrome with playwright",
"repository": {
"type": "git",
"url": "git+https://github.com/zenika/alpine-chrome.git"
Expand Down
10 changes: 5 additions & 5 deletions with-playwright/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ DIR=$(cd $(dirname $0) && pwd)
${DIR}/../test.sh

echo "# Playwright test"
WORK_DIR=$(mktemp --directory)
trap "rm -rf ${WORK_DIR}" EXIT
mkdir ${WORK_DIR}/src/ && chmod a+rwX -R ${WORK_DIR}
docker container run --rm --volume ${WORK_DIR}:/work --workdir /work ${IMAGE_NAME:-zenika/alpine-chrome:with-playwright}
[ -f ${WORK_DIR}/src/example-chromium.png ]
EXPECTED_SCREENSHOT="${DIR}/test/example.png"
rm -f "${EXPECTED_SCREENSHOT}"
chmod a+rwX -R ${DIR}/test
docker container run --rm --volume ${DIR}/test:/usr/src/app/test ${IMAGE_NAME} node test/test.js
[ -f "${EXPECTED_SCREENSHOT}" ] && echo "Screenshot created" || { echo "Missing screenshot" 2>&1; exit 1; }
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { chromium } = require("playwright-chromium");
exec(
process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH + " --version",
function callback(error, stdout, stderr) {
console.log(stdout);
console.log(stdout.replace(/\n$/, ""));
}
);
})();
Expand All @@ -20,7 +20,7 @@ const { chromium } = require("playwright-chromium");
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto("https://icanhazip.com/");
await page.screenshot({ path: `src/example-chromium.png` });
await page.goto("https://example.com/");
await page.screenshot({ path: "test/example.png" });
await browser.close();
})();
1 change: 1 addition & 0 deletions with-puppeteer-xvfb/.dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
test.sh
test/
3 changes: 1 addition & 2 deletions with-puppeteer-xvfb/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ USER chrome

ENV DISPLAY :99

COPY --chown=chrome . ./
COPY --chown=chrome docker-entrypoint.sh ./
RUN chmod +x docker-entrypoint.sh
ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"]
CMD ["node", "/usr/src/app/src/extension.js"]
10 changes: 5 additions & 5 deletions with-puppeteer-xvfb/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ DIR=$(cd $(dirname $0) && pwd)
${DIR}/../test.sh

echo "# Puppeteer-Xvfb test"
WORK_DIR=$(mktemp --directory)
trap "rm -rf ${WORK_DIR}" EXIT
mkdir ${WORK_DIR}/src/ && chmod a+rwX -R ${WORK_DIR}
docker container run --rm --volume ${WORK_DIR}:/work --workdir /work --cap-add=SYS_ADMIN ${IMAGE_NAME:-zenika/alpine-chrome:with-puppeteer-xvfb}
[ -f ${WORK_DIR}/src/screenshot.png ]
EXPECTED_PNG="${DIR}/test/example.png"
rm -f ${EXPECTED_PNG}
chmod a+rwX -R ${DIR}/test
docker container run --rm --volume ${DIR}/test:/usr/src/app/test --cap-add=SYS_ADMIN ${IMAGE_NAME} node test/test.js
[ -f "${EXPECTED_PNG}" ] && echo "Screenshot created" || { echo "Missing screenshot" 2>&1; exit 1; }
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ const path = require("path");
]
});
const page = await browser.newPage();
await page.goto("http://icanhazip.com/", {
waitUntil: "networkidle2"
});
await page.screenshot({ path: "src/screenshot.png" });
await page.goto("https://example.com/", { waitUntil: "networkidle2" });
await page.screenshot({ path: "test/example.png" });
await browser.close();
})();
1 change: 1 addition & 0 deletions with-puppeteer/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
test/
test.sh
2 changes: 0 additions & 2 deletions with-puppeteer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ ENV PUPPETEER_EXECUTABLE_PATH /usr/bin/chromium-browser
WORKDIR /usr/src/app
COPY --chown=chrome package.json package-lock.json ./
RUN npm install
COPY --chown=chrome . ./
ENTRYPOINT ["tini", "--"]
CMD ["node", "/usr/src/app/src/pdf"]
6 changes: 1 addition & 5 deletions with-puppeteer/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
{
"name": "zenika-alpinechrome-withpuppeteer",
"version": "1.0.0",
"description": "Tests with puppeteer",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"description": "Alpine chrome with puppeteer",
"repository": {
"type": "git",
"url": "git+https://github.com/zenika/alpine-chrome.git"
Expand Down
16 changes: 11 additions & 5 deletions with-puppeteer/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ DIR=$(cd $(dirname $0) && pwd)
${DIR}/../test.sh

echo "# Puppeteer test"
WORK_DIR=$(mktemp --directory)
trap "rm -rf ${WORK_DIR}" EXIT
mkdir ${WORK_DIR}/src/ && chmod a+rwX -R ${WORK_DIR}
docker container run --rm --volume ${WORK_DIR}:/work --workdir /work --cap-add=SYS_ADMIN ${IMAGE_NAME:-zenika/alpine-chrome:with-puppeteer}
[ -f ${WORK_DIR}/src/devfest.pdf ]
EXPECTED_PDF="${DIR}/test/example.pdf"
EXPECTED_CN_PNG="${DIR}/test/baidu_cn.png"
EXPECTED_JP_PNG="${DIR}/test/yahoo_jp.png"
EXPECTED_KR_PNG="${DIR}/test/naver_kr.png"
rm -f ${EXPECTED_PDF} ${EXPECTED_CN_PNG} ${EXPECTED_JP_PNG} ${EXPECTED_KR_PNG}
chmod a+rwX -R ${DIR}/test
docker container run --rm --volume ${DIR}/test:/usr/src/app/test --cap-add=SYS_ADMIN ${IMAGE_NAME} node test/test.js
[ -f "${EXPECTED_PDF}" ] && echo "PDF created" || { echo "Missing PDF" 2>&1; exit 1; }
[ -f "${EXPECTED_CN_PNG}" ] && echo "Screenshot CN created" || { echo "Missing screenshot CN" 2>&1; exit 1; }
[ -f "${EXPECTED_JP_PNG}" ] && echo "Screenshot JP created" || { echo "Missing screenshot JP" 2>&1; exit 1; }
[ -f "${EXPECTED_KR_PNG}" ] && echo "Screenshot KR created" || { echo "Missing screenshot KR" 2>&1; exit 1; }
6 changes: 2 additions & 4 deletions with-puppeteer/src/pdf.js → with-puppeteer/test/pdf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ const puppeteer = require("puppeteer");
]
});
const page = await browser.newPage();
await page.goto("https://devfest.gdgnantes.com/", {
waitUntil: "networkidle2"
});
await page.goto("https://example.com/", { waitUntil: "networkidle2" });
await page.pdf({
path: "src/devfest.pdf",
path: "test/example.pdf",
printBackground: true,
format: "A4"
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const puppeteer = require("puppeteer");
const page = await browser.newPage();
await page.setViewport({ width: 412, height: 732 });
await page.goto("https://m.baidu.com", { waitUntil: "networkidle2" });
await page.screenshot({ path: "src/baidu_cn.png" });
await page.screenshot({ path: "test/baidu_cn.png" });
await page.goto("https://www.yahoo.co.jp/", { waitUntil: "networkidle2" });
await page.screenshot({ path: "src/yahoo_jp.png" });
await page.screenshot({ path: "test/yahoo_jp.png" });
await page.goto("https://www.naver.com/", { waitUntil: "networkidle2" });
await page.screenshot({ path: "src/naver_kr.png" });
await page.screenshot({ path: "test/naver_kr.png" });
await browser.close();
})();
7 changes: 7 additions & 0 deletions with-puppeteer/test/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const events = require("events");
const child_process = require("child_process");

(async () => {
await events.once(child_process.fork('test/pdf.js'), 'close');
await events.once(child_process.fork('test/screenshot-asia.js'), 'close');
})();

0 comments on commit 9e30a1f

Please sign in to comment.