Skip to content

Run Emscripten tests in a browser #294

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/deploy-github-page.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
pushd build

export BUILD_PREFIX=$MAMBA_ROOT_PREFIX/envs/xeus-cpp-wasm-build
echo "BUILD_PREFIX=$BUILD_PREFIX" >> $GITHUB_ENV
export PREFIX=$MAMBA_ROOT_PREFIX/envs/xeus-cpp-wasm-host
echo "PREFIX=$PREFIX" >> $GITHUB_ENV
export SYSROOT_PATH=$BUILD_PREFIX/opt/emsdk/upstream/emscripten/cache/sysroot
Expand All @@ -64,6 +65,60 @@ jobs:
..
emmake make -j ${{ env.ncpus }} install

- name: Test xeus-cpp C++ Emscripten
shell: bash -l {0}
run: |
set -e
micromamba create -n xeus-lite-host jupyterlite-core
micromamba activate xeus-lite-host
cd build/test
os="${{ matrix.os }}"
if [[ "${os}" == "macos"* ]]; then
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The reason we install a fresh install of Firefox and Chome is to follow what is done in the Emscripten repo (for example here with Firefox https://github.com/emscripten-core/emscripten/blob/38e16464cffc8f886364fe4919a712131a4c9456/.circleci/config.yml#L363 ). It has the added advantage by not using the users installed versions of these browsers (if they have them installed), that there are no add ons, etc that could be causing issues with the tests running. I have made the instructions, such that a developer without admin privileges on there machine can install them.

# Install Firefox
wget "https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US" -O Firefox-latest.dmg
hdiutil attach Firefox-latest.dmg
cp -r /Volumes/Firefox/Firefox.app $PWD
hdiutil detach /Volumes/Firefox
cd ./Firefox.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd –

# Install Google Chrome
wget https://dl.google.com/chrome/mac/stable/accept_tos%3Dhttps%253A%252F%252Fwww.google.com%252Fintl%252Fen_ph%252Fchrome%252Fterms%252F%26_and_accept_tos%3Dhttps%253A%252F%252Fpolicies.google.com%252Fterms/googlechrome.pkg
pkgutil --expand-full googlechrome.pkg google-chrome
cd ./google-chrome/GoogleChrome.pkg/Payload/Google\ Chrome.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd –

# Run tests in browsers
echo "Running test_xeus_cpp in Firefox"
python ${{ env.BUILD_PREFIX }}/bin/emrun.py --browser="firefox" --kill_exit --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python ${{ env.BUILD_PREFIX }}/bin/emrun.py --browser="Google Chrome" --kill_exit --browser-args="--headless" test_xeus_cpp.html
else
# Install Google Chrome
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
dpkg-deb -x google-chrome-stable_current_amd64.deb $PWD/chrome
cd ./chrome/opt/google/chrome/
export PATH="$PWD:$PATH"
cd -

# Install Firefox
wget https://ftp.mozilla.org/pub/firefox/releases/138.0.1/linux-x86_64/en-GB/firefox-138.0.1.tar.xz
tar -xJf firefox-138.0.1.tar.xz
cd ./firefox
export PATH="$PWD:$PATH"
cd -

# Run tests in browsers
echo "Running test_xeus_cpp in Firefox"
python ${{ env.BUILD_PREFIX }}/bin/emrun.py --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" test_xeus_cpp.html
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Given emrun is not on our PATH, I have to reference the exact path to emrun.py . I could add ${{ env.BUILD_PREFIX }}/bin/ to PATH, but not sure if this would be wanted.

--kill_exit makes it so that when emrun finishes, that the headless browser we create is killed along with it
--timeout 60 is such that emrun is killed after 60 seconds if still running. emrun should have finished long before then, so if it is still running, something went wrong (such as a test which crashed the html file). This will cause the ci to fail, as a non 0 value of will be returned.

echo "Running test_xeus_cpp in Google Chrome"
python ${{ env.BUILD_PREFIX }}/bin/emrun.py --browser="google-chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" test_xeus_cpp.html
fi
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In the case of Chrome we have the extra --no-sandbox flag, as on Ubuntu Chrome will refuse to run otherwise, as it expects to have been installed with admin privileges. This flag allows it to run in userspace.

node test_xeus_cpp.js
timeout-minutes: 4

- name: Jupyter Lite integration
shell: bash -l {0}
run: |
Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ jobs:
pushd build

export BUILD_PREFIX=$MAMBA_ROOT_PREFIX/envs/xeus-cpp-wasm-build
echo "BUILD_PREFIX=$BUILD_PREFIX" >> $GITHUB_ENV
export PREFIX=$MAMBA_ROOT_PREFIX/envs/xeus-cpp-wasm-host
echo "PREFIX=$PREFIX" >> $GITHUB_ENV
export SYSROOT_PATH=$BUILD_PREFIX/opt/emsdk/upstream/emscripten/cache/sysroot
Expand All @@ -250,10 +251,55 @@ jobs:
- name: Test xeus-cpp C++ Emscripten
shell: bash -l {0}
run: |
export BUILD_PREFIX=$MAMBA_ROOT_PREFIX/envs/xeus-cpp-wasm-build
set -e
micromamba create -n xeus-lite-host jupyterlite-core
micromamba activate xeus-lite-host
cd build/test
os="${{ matrix.os }}"
if [[ "${os}" == "macos"* ]]; then
# Install Firefox
wget "https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US" -O Firefox-latest.dmg
hdiutil attach Firefox-latest.dmg
cp -r /Volumes/Firefox/Firefox.app $PWD
hdiutil detach /Volumes/Firefox
cd ./Firefox.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd -

# Install Google Chrome
wget https://dl.google.com/chrome/mac/stable/accept_tos%3Dhttps%253A%252F%252Fwww.google.com%252Fintl%252Fen_ph%252Fchrome%252Fterms%252F%26_and_accept_tos%3Dhttps%253A%252F%252Fpolicies.google.com%252Fterms/googlechrome.pkg
pkgutil --expand-full googlechrome.pkg google-chrome
cd ./google-chrome/GoogleChrome.pkg/Payload/Google\ Chrome.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd -

# Run tests in browsers
echo "Running test_xeus_cpp in Firefox"
python ${{ env.BUILD_PREFIX }}/bin/emrun.py --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python ${{ env.BUILD_PREFIX }}/bin/emrun.py --browser="Google Chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" test_xeus_cpp.html
else
# Install Google Chrome
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
dpkg-deb -x google-chrome-stable_current_amd64.deb $PWD/chrome
cd ./chrome/opt/google/chrome/
export PATH="$PWD:$PATH"
cd -

# Install Firefox
wget https://ftp.mozilla.org/pub/firefox/releases/138.0.1/linux-x86_64/en-GB/firefox-138.0.1.tar.xz
tar -xJf firefox-138.0.1.tar.xz
cd ./firefox
export PATH="$PWD:$PATH"
cd -

# Run tests in browsers
echo "Running test_xeus_cpp in Firefox"
python ${{ env.BUILD_PREFIX }}/bin/emrun.py --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python ${{ env.BUILD_PREFIX }}/bin/emrun.py --browser="google-chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" test_xeus_cpp.html
fi
node test_xeus_cpp.js
timeout-minutes: 4

Expand Down
57 changes: 51 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,57 @@ emcmake cmake \
emmake make install
```

To test the lite build you can execute the following to run the C++ tests built against emscripten in node

```bash
cd test
node test_xeus_cpp.js
```

It is possible to run the Emscripten tests in a headless browser. We will run our tests in a fresh installed browser. Installing the browsers, and running the tests within the installed browsers will be platform dependent. To do this on MacOS execute the following

```bash
wget "https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US" -O Firefox-latest.dmg
hdiutil attach Firefox-latest.dmg
cp -r /Volumes/Firefox/Firefox.app $PWD
hdiutil detach /Volumes/Firefox
cd ./Firefox.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd –

wget https://dl.google.com/chrome/mac/stable/accept_tos%3Dhttps%253A%252F%252Fwww.google.com%252Fintl%252Fen_ph%252Fchrome%252Fterms%252F%26_and_accept_tos%3Dhttps%253A%252F%252Fpolicies.google.com%252Fterms/googlechrome.pkg
pkgutil --expand-full googlechrome.pkg google-chrome
cd ./google-chrome/GoogleChrome.pkg/Payload/Google\ Chrome.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd –

echo "Running test_xeus_cpp in Firefox"
python $BUILD_PREFIX/bin/emrun.py --browser="firefox" --kill_exit --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python $BUILD_PREFIX/bin/emrun.py --browser="Google Chrome" --kill_exit --browser-args="--headless --no-sandbox" test_xeus_cpp.html
```

To do this on Ubuntu x86 execute the following

```bash
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
dpkg-deb -x google-chrome-stable_current_amd64.deb $PWD/chrome
cd ./chrome/opt/google/chrome/
export PATH="$PWD:$PATH"
cd -

wget https://ftp.mozilla.org/pub/firefox/releases/138.0.1/linux-x86_64/en-GB/firefox-138.0.1.tar.xz
tar -xJf firefox-138.0.1.tar.xz
cd ./firefox
export PATH="$PWD:$PATH"
cd -

echo "Running test_xeus_cpp in Firefox"
python $BUILD_PREFIX/bin/emrun.py --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python $BUILD_PREFIX/bin/emrun.py --browser="google-chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" test_xeus_cpp.html
```

To build Jupyter Lite with this kernel without creating a website you can execute the following
```bash
micromamba create -n xeus-lite-host jupyterlite-core -c conda-forge
Expand All @@ -106,9 +157,3 @@ Once the Jupyter Lite site has built you can test the website locally by executi
```bash
jupyter lite serve --XeusAddon.prefix=$PREFIX
```

To test the lite build you can execute the following to run the C++ tests built against emscripten
```bash
cd test
node test_xeus_cpp.js
```
57 changes: 51 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,57 @@ emcmake cmake \
emmake make install
```

To test the lite build you can execute the following to run the C++ tests built against emscripten in node

```bash
cd test
node test_xeus_cpp.js
```

It is possible to run the Emscripten tests in a headless browser. We will run our tests in a fresh installed browser. Installing the browsers, and running the tests within the installed browsers will be platform dependent. To do this on MacOS execute the following

```bash
wget "https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US" -O Firefox-latest.dmg
hdiutil attach Firefox-latest.dmg
cp -r /Volumes/Firefox/Firefox.app $PWD
hdiutil detach /Volumes/Firefox
cd ./Firefox.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd -

wget https://dl.google.com/chrome/mac/stable/accept_tos%3Dhttps%253A%252F%252Fwww.google.com%252Fintl%252Fen_ph%252Fchrome%252Fterms%252F%26_and_accept_tos%3Dhttps%253A%252F%252Fpolicies.google.com%252Fterms/googlechrome.pkg
pkgutil --expand-full googlechrome.pkg google-chrome
cd ./google-chrome/GoogleChrome.pkg/Payload/Google\ Chrome.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd -

echo "Running test_xeus_cpp in Firefox"
python $BUILD_PREFIX/bin/emrun.py --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python python $BUILD_PREFIX/bin/emrun.py --browser="Google Chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" test_xeus_cpp.html
```

To do this on Ubuntu x86 execute the following

```bash
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
dpkg-deb -x google-chrome-stable_current_amd64.deb $PWD/chrome
cd ./chrome/opt/google/chrome/
export PATH="$PWD:$PATH"
cd -

wget https://ftp.mozilla.org/pub/firefox/releases/138.0.1/linux-x86_64/en-GB/firefox-138.0.1.tar.xz
tar -xJf firefox-138.0.1.tar.xz
cd ./firefox
export PATH="$PWD:$PATH"
cd -

echo "Running test_xeus_cpp in Firefox"
python $BUILD_PREFIX/bin/emrun.py --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python $BUILD_PREFIX/bin/emrun.py --browser="google-chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" test_xeus_cpp.html
```

To build Jupyter Lite with this kernel without creating a website you can execute the following
```bash
micromamba create -n xeus-lite-host jupyterlite-core -c conda-forge
Expand All @@ -108,12 +159,6 @@ Once the Jupyter Lite site has built you can test the website locally by executi
jupyter lite serve --XeusAddon.prefix=$PREFIX
```

To test the lite build you can execute the following to run the C++ tests built against emscripten
```bash
cd test
node test_xeus_cpp.js
```

## Trying it online

To try out xeus-cpp interactively in your web browser, just click on the binder link:
Expand Down
51 changes: 51 additions & 0 deletions docs/source/InstallationAndUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,57 @@ You are now in a position to build the xeus-cpp kernel. You build it by executin
emmake make install


To test the lite build you can execute the following to run the C++ tests built against emscripten in node

.. code-block:: bash

cd test
node test_xeus_cpp.js

It is possible to run the Emscripten tests in a headless browser. We will run our tests in a fresh installed browser. Installing the browsers, and running the tests within the installed browsers will be platform dependent. To do this on MacOS execute the following

.. code-block:: bash

wget "https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US" -O Firefox-latest.dmg
hdiutil attach Firefox-latest.dmg
cp -r /Volumes/Firefox/Firefox.app $PWD
hdiutil detach /Volumes/Firefox
cd ./Firefox.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd -

wget https://dl.google.com/chrome/mac/stable/accept_tos%3Dhttps%253A%252F%252Fwww.google.com%252Fintl%252Fen_ph%252Fchrome%252Fterms%252F%26_and_accept_tos%3Dhttps%253A%252F%252Fpolicies.google.com%252Fterms/googlechrome.pkg
pkgutil --expand-full googlechrome.pkg google-chrome
cd ./google-chrome/GoogleChrome.pkg/Payload/Google\ Chrome.app/Contents/MacOS/
export PATH="$PWD:$PATH"
cd -

echo "Running test_xeus_cpp in Firefox"
python $BUILD_PREFIX/bin/emrun.py --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python $BUILD_PREFIX/bin/emrun.py --browser="Google Chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" test_xeus_cpp.html

To do this on Ubuntu x86 execute the following

.. code-block:: bash

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
dpkg-deb -x google-chrome-stable_current_amd64.deb $PWD/chrome
cd ./chrome/opt/google/chrome/
export PATH="$PWD:$PATH"
cd -

wget https://ftp.mozilla.org/pub/firefox/releases/138.0.1/linux-x86_64/en-GB/firefox-138.0.1.tar.xz
tar -xJf firefox-138.0.1.tar.xz
cd ./firefox
export PATH="$PWD:$PATH"
cd -

echo "Running test_xeus_cpp in Firefox"
python $BUILD_PREFIX/bin/emrun.py --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" test_xeus_cpp.html
echo "Running test_xeus_cpp in Google Chrome"
python $BUILD_PREFIX/bin/emrun.py --browser="google-chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" test_xeus_cpp.html

To build Jupyter Lite with this kernel without creating a website you can execute the following

.. code-block:: bash
Expand Down
6 changes: 5 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ if(EMSCRIPTEN)
target_compile_options(test_xeus_cpp
PUBLIC "SHELL: -fexceptions"
)

set_target_properties(test_xeus_cpp PROPERTIES
SUFFIX ".html"
)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So that we create a html file, as well as the javascript file.

target_link_options(test_xeus_cpp
PUBLIC "SHELL: -fexceptions"
PUBLIC "SHELL: -s MAIN_MODULE=1"
Expand All @@ -69,6 +71,8 @@ if(EMSCRIPTEN)
PUBLIC "SHELL: --preload-file ${SYSROOT_PATH}/include@/include"
PUBLIC "SHELL: --preload-file ../${XEUS_CPP_DATA_DIR}@/share/xeus-cpp"
PUBLIC "SHELL: --preload-file ../${XEUS_CPP_CONF_DIR}@/etc/xeus-cpp"
PUBLIC "SHELL: --emrun"
Copy link
Collaborator Author

@mcbarton mcbarton May 2, 2025

Choose a reason for hiding this comment

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

Rebuild your Emscripten application and add the --emrun [linker flag](https://emscripten.org/docs/tools_reference/emcc.html#emcc-emrun).

This flag injects code into the generated [Module object](https://emscripten.org/docs/api_reference/module.html#module) to enable capture of stdout, stderr and exit().

Note

If you skip this step, you can still run any .html file with emrun, but the capture will not work.

The above is taken from emruns documentation https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html

PUBLIC "SHELL: -s MINIFY_HTML=0"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Without this MINIFY_HTML=0 flag you end up with the situation where the creation of the test_xeus_cpp.html file breaks on MacOS, but not Ubuntu as can be seen here https://github.com/compiler-research/xeus-cpp/actions/runs/14780201517

)

target_include_directories(test_xeus_cpp PRIVATE ${XEUS_CPP_INCLUDE_DIR})
Expand Down
Loading