Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add E2E tests for chromium and firefox #1121

Merged
merged 11 commits into from
Jan 17, 2023
59 changes: 59 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: e2e
on:
workflow_dispatch:
inputs:
firefox-version:
description: The version of selenium/standalone-firefox image to use
default: latest
required: true
galargh marked this conversation as resolved.
Show resolved Hide resolved
chromium-version:
description: The version of selenium/standalone-chrome image to use
default: latest
required: true
SgtPooki marked this conversation as resolved.
Show resolved Hide resolved
kubo-version:
description: The version of ipfs/kubo image to use
default: latest
required: true
galargh marked this conversation as resolved.
Show resolved Hide resolved
ipfs-companion-version:
description: The version of ipfs-companion extension to use (defaults to building the extension from source)
default: ''
required: false

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v3
- name: Set up node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Download ipfs-companion
if: inputs.ipfs-companion-version != ''
run: ./ci/download-release-artifacts.sh
env:
IPFS_COMPANION_VERSION: ${{ inputs.ipfs-companion-version }}
galargh marked this conversation as resolved.
Show resolved Hide resolved
- name: Build ipfs-companion
if: inputs.ipfs-companion-version == ''
run: npm run release-build
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should eventually upload the built docker image (ipfs-companion-release-build) and reuse that if possible.. (hash of source or non-docker build artifacts to determine if we want to use the same image?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a write-up recently on docker publishing/caching in CI for build speed-up. See https://filecoinproject.slack.com/archives/C03KLC57LKB/p1673517809976679?thread_ts=1673468796.401379&cid=C03KLC57LKB

I'd say it's a little bit beyond the scope of this PR though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created #1132 for this

- name: Prepare E2E env
run: npm run compose:e2e:prepare
env:
FIREFOX_VERSION: ${{ inputs.firefox-version }}
CHROMIUM_VERSION: ${{ inputs.chromium-version }}
KUBO_VERSION: ${{ inputs.kubo-version }}
- name: Start E2E env
run: npm run compose:e2e:up
env:
FIREFOX_VERSION: ${{ inputs.firefox-version }}
CHROMIUM_VERSION: ${{ inputs.chromium-version }}
KUBO_VERSION: ${{ inputs.kubo-version }}
- name: Wait for E2E env set up to complete
run: sleep 60
- name: Run E2E tests
run: npm run compose:e2e:test
env:
IPFS_COMPANION_VERSION: ${{ inputs.ipfs-companion-version }}
- name: Stop E2E env
run: npm run compose:e2e:down
14 changes: 9 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ ARG GROUP_ID
RUN curl -s https://ipfs.io/ipfs/QmbukYcmtyU6ZEKt6fepnvrTNa9F6VqsUPMUgNxQjEmphH > /usr/local/bin/jq && chmod +x /usr/local/bin/jq

RUN mkdir -p /home/node/app
WORKDIR /home/node/app

RUN if [ ${USER_ID:-0} -ne 0 ] && [ ${GROUP_ID:-0} -ne 0 ]; then \
userdel -f node && \
if getent group node ; then groupdel node; fi && \
if getent passwd ${USER_ID} ; then userdel -f $(getent passwd ${USER_ID} | cut -d: -f1); fi && \
if getent group ${GROUP_ID} ; then groupdel $(getent group ${GROUP_ID} | cut -d: -f1); fi && \
groupadd -g ${GROUP_ID} node && \
useradd -l -u ${USER_ID} -g node node && \
chown -fhR ${USER_ID}:${GROUP_ID} /home/node; fi
useradd -l -u ${USER_ID} -g node node; fi
RUN chown -fhR node:node /home/node

COPY --chown=${USER_ID}:${GROUP_ID} . /home/node/app
WORKDIR /home/node/app

COPY --chown=node:node ./package.json ./package-lock.json /home/node/app/

USER node

RUN npm run ci:install

COPY --chown=node:node . /home/node/app

ENV PATH="/home/node/app/node_modules/.bin:${PATH}"
5 changes: 5 additions & 0 deletions ci/access-control-allow-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh
set -ex

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "${ACCESS_CONTROL_ALLOW_ORIGIN:-[\"*\"]}"
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods "${ACCESS_CONTROL_ALLOW_METHODS:-[\"*\"]}"
15 changes: 15 additions & 0 deletions ci/download-release-artifacts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh
set -ex

IPFS_COMPANION_VERSION=${IPFS_COMPANION_VERSION:-$(jq -r '.version' ./add-on/manifest.common.json)}

id="$(curl --retry 5 --no-progress-meter "https://api.github.com/repos/ipfs/ipfs-companion/releases/tags/v$IPFS_COMPANION_VERSION" | jq '.id')"
assets="$(curl --retry 5 --no-progress-meter --location "https://api.github.com/repos/ipfs/ipfs-companion/releases/$id/assets" | jq -r '.[].name')"

if [[ ! -d build ]]; then
mkdir build
fi

for asset in $assets; do
curl --retry 5 --no-progress-meter --location --output "build/$asset" "https://github.com/ipfs/ipfs-companion/releases/download/v$IPFS_COMPANION_VERSION/$asset"
done
39 changes: 39 additions & 0 deletions docker-compose.e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: "3.9"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we should be able to set hostname and domain name for these containers, which would make addressing https://github.com/ipfs/ipfs-companion/pull/1121/files#r1053853150 much easier. We would know the hostname, protocol, and port

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how exactly setting hostname and domainname works. Could you elaborate on how they could affect the setup?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you asking about how hostname and domainname are set inside the container? I'm not fully aware of the implementation details but I believe the etc/hostname file (and docker configs) are updated appropriately.

Ultimately, setting domainname and hostname would allow you to address the CORS concerns brought up by @whizzzkid, because you would be able to specify the origins set via hostname/domainname and port.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got confused a bit and though these were global settings for the compose file 🤦

Back to the matter, we're already "using" hostname. If the value is not specified, then the hostname defaults to the service name. We already use this fact to communicate between services. E.g. that's how browsers know they can find Kubo at http://kubo.

Domainname, I'm not so familiar with, but apparently it's not that useful - https://stackoverflow.com/questions/70741780/what-is-the-domainname-option-used-for-in-docker

Anyway, I tried to be more explicit about access control and limit the origins to http://chromium and http://firefox but, apparently, that's not enough.

You can now set access control values through env - https://github.com/ipfs/ipfs-companion/blob/25a4760138ac21fdfdf198a6476a88b92bd09c4c/ci/access-control-allow-all.sh. This should allow for easier experimentation in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created an issue for this at #1130

services:
firefox:
image: ${FIREFOX_IMAGE:-selenium/standalone-firefox}:${FIREFOX_VERSION:-latest}
shm_size: 2g
ports:
- 4444
- 7900
chromium:
# WARN: `standalone-chrome` does NOT work on ARM-based machines;
# see https://github.com/SeleniumHQ/docker-selenium#experimental-mult-arch-aarch64armhfamd64-images;
# try using `seleniarm/standalone-chromium` instead
Comment on lines +10 to +12
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. thanks for this

# export CHROMIUM_IMAGE=seleniarm/standalone-chromium
image: ${CHROMIUM_IMAGE:-selenium/standalone-chrome}:${CHROMIUM_VERSION:-latest}
shm_size: 2g
ports:
- 4444
- 7900
kubo:
image: ipfs/kubo:${KUBO_VERSION:-latest}
ports:
- 4001
- 5001
- 8080
volumes:
- ./ci/access-control-allow-all.sh:/container-init.d/001-access-control-allow-all.sh
e2e:
build:
dockerfile: ./Dockerfile
environment:
- SELENIUM_REMOTE_CHROMIUM_URL=http://chromium:4444
- SELENIUM_REMOTE_FIREFOX_URL=http://firefox:4444
- IPFS_API_URL=http://kubo:5001
- CUSTOM_GATEWAY_URL=http://kubo:8080
- TEST_E2E=true
- TEST_HEADLESS=${TEST_HEADLESS:-false}
- IPFS_COMPANION_VERSION=${IPFS_COMPANION_VERSION}
volumes:
- ./build:/home/node/app/build
2 changes: 1 addition & 1 deletion docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ If you want to download translations from Transifex and run them locally, make s

## Writing Code

**If you plan to write code make sure to read [Developer Notes](./docs/DEVELOPER-NOTES.md) to get familiar with tools and commands that will make your work easier.**
**If you plan to write code make sure to read [Developer Notes](DEVELOPER-NOTES.md) to get familiar with tools and commands that will make your work easier.**

## How to Help with Things Beyond Browser Extension?

Expand Down
88 changes: 88 additions & 0 deletions docs/DEVELOPER-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,94 @@ Release build shortcuts:
- `npm run dev-build`: All-in-one: fast dependency install, build with yarn (updates `yarn.lock` if needed)
- `npm run release-build`: Reproducible release build in docker with frozen `yarn.lock`

E2E tests:

- `npm run compose:e2e:prepare`: Pull and build docker images for e2e tests
- `npm run compose:e2e:up`: Start e2e test docker environment
- `npm run compose:e2e:test`: Run e2e tests in the docker environment
- `npm run compose:e2e:down`: Stop e2e test docker environment

## Running E2E tests

E2E tests are run in a docker environment, so you need to have docker installed.

### Preparing extension builds

You can run the tests against either release or dev builds of the extension.

To download release builds of the extension, run:

```sh
./ci/e2e/download-release-builds.sh
```

_NOTE_: When using release builds, you can control the version of the extension by setting the `IPFS_COMPANION_VERSION` environment variable:

```sh
export IPFS_COMPANION_VERSION=x.y.z
```

To build dev versions of the extension, run:

```sh
npm run build
```

or (to perform the build inside a docker container):

```sh
npm run release-build
```

### Preparing the docker environment

You need to pull docker images for [Kubo](https://github.com/ipfs/kubo), [Chromium](https://hub.docker.com/r/selenium/standalone-chrome/) and [Firefox](https://hub.docker.com/r/selenium/standalone-firefox/) before running the tests.

You also need to build the docker image containing the e2e tests.

To do all of this, run:

```sh
npm run compose:e2e:prepare
```

_NOTE_: You can control the versions of Kubo, Chromium and Firefox by setting the following environment variables:

```sh
export KUBO_VERSION=x.y.z
export CHROMIUM_VERSION=x.y.z
export FIREFOX_VERSION=x.y.z
```

**IMPORTANT**: If you are running the tests on a ARM machine, you need to use a different Chromium image. To do this, run:

```sh
export CHROMIUM_IMAGE=seleniarm/standalone-chromium
galargh marked this conversation as resolved.
Show resolved Hide resolved
export FIREFOX_IMAGE=seleniarm/standalone-firefox
```

### Running the tests

To run the tests, run:

```sh
npm run compose:e2e:test
```

_NOTE_: You can control whether the browsers operate in headless mode as follows:

```sh
export TEST_HEADLESS=true
```

### Stopping the docker environment

To stop the docker environment, run:

```sh
npm run compose:e2e:down
```

## Other tips

- You can switch to an alternative Firefox version by overriding your `PATH`:
Expand Down
69 changes: 69 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading