Skip to content
Merged
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
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
lib/
node_modules/
components/lib/
components/node_modules/
nbextension/lib/
nbextension/node_modules/
nbextension/diff_match_patch.js
lc_notebook_diff/labextension/
lc_notebook_diff/nbextension/diff_match_patch.js
lc_notebook_diff/nbextension/jupyter-notebook-diff.js
lc_notebook_diff/nbextension/jupyter-notebook-diff.js.map
*.tsbuildinfo
ui-tests/test-results/
ui-tests/playwright-report/
ui-tests/e2e-notebook/artifacts/
.git/
.github/
.eslintcache
.stylelintcache
__pycache__/
.DS_Store
101 changes: 101 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: E2E Tests

on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
workflow_dispatch:

jobs:
notebook-e2e:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('ui-tests/e2e-notebook/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install Python dependencies
run: |
set -euxo pipefail
pip install --upgrade pip
pip install -r ui-tests/e2e-notebook/requirements.txt

- name: Install Playwright browsers
run: |
set -euxo pipefail
python -m playwright install --with-deps

- name: Build Docker image
run: |
set -euxo pipefail
docker build -t lc_notebook_diff:test .

- name: Prepare test workspace
run: |
set -euxo pipefail
mkdir -p ui-tests/e2e-notebook/artifacts/jupyter-work
cp -r html/* ui-tests/e2e-notebook/artifacts/jupyter-work/
chmod -R a+w ui-tests/e2e-notebook/artifacts/jupyter-work

- name: Start lc_notebook_diff container
run: |
set -euxo pipefail
docker run -d \
--name lc-notebook-diff-test \
-p 8888:8888 \
-v $(pwd)/ui-tests/e2e-notebook/artifacts/jupyter-work:/home/jovyan/work \
lc_notebook_diff:test \
start-notebook.sh --ServerApp.token='test-token' --ServerApp.allow_origin='*' --ServerApp.root_dir='/home/jovyan/work'
sleep 30
# Health check
curl --retry 10 --retry-delay 5 --retry-connrefused --fail http://localhost:8888/lab?token=test-token || (docker logs lc-notebook-diff-test && exit 1)

- name: Run notebook E2E tests
env:
E2E_TRANSITION_TIMEOUT: '60000'
E2E_DEFAULT_DELAY: '200'
JUPYTERLAB_URL: 'http://localhost:8888/lab?token=test-token'
NOTEBOOK7_URL: 'http://localhost:8888/tree?token=test-token'
NBCLASSIC_URL: 'http://localhost:8888/nbclassic/tree?token=test-token'
JUPYTER_WORK_DIR: ${{ github.workspace }}/ui-tests/e2e-notebook/artifacts/jupyter-work
run: |
set -euxo pipefail
python ui-tests/e2e-notebook/run_notebooks.py --skip-failed-test

- name: Gather Docker logs
if: always()
run: |
set -euxo pipefail
mkdir -p ui-tests/e2e-notebook/artifacts
docker logs lc-notebook-diff-test > ui-tests/e2e-notebook/artifacts/lc-notebook-diff-container.log 2>&1 || true

- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: e2e-results
path: |
ui-tests/e2e-notebook/artifacts

- name: Shutdown container
if: always()
run: |
set -euxo pipefail
docker stop lc-notebook-diff-test || true
docker rm lc-notebook-diff-test || true
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ lc_notebook_diff/_version.py
# Integration tests
ui-tests/test-results/
ui-tests/playwright-report/
ui-tests/e2e-notebook/artifacts/

# Created by https://www.gitignore.io/api/python
# Edit at https://www.gitignore.io/?templates=python
Expand Down
21 changes: 17 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
FROM jupyter/scipy-notebook:latest
FROM quay.io/jupyter/scipy-notebook:notebook-7.4.7

USER root

### extensions for jupyter
# Install Node.js 20.x (required for Etherpad build)
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y nodejs && \
apt-get clean && \
mkdir -p /.npm && \
chown jovyan:users -R /.npm && \
rm -rf /var/lib/apt/lists/*
ENV NPM_CONFIG_PREFIX=/.npm
ENV PATH=/.npm/bin/:${PATH}

RUN pip install --no-cache jupyter_nbextensions_configurator

COPY . /tmp/notebook_diff
RUN pip --no-cache-dir install jupyter_nbextensions_configurator \
/tmp/notebook_diff
RUN cd /tmp/notebook_diff/components && npm install && npm run build && \
cd /tmp/notebook_diff/nbextension && npm install && npm run build && \
pip install --no-cache /tmp/notebook_diff

RUN jupyter labextension enable lc_notebook_diff

RUN jupyter nbclassic-extension install --py jupyter_nbextensions_configurator --sys-prefix && \
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ Jupyter-LC\_notebook\_diff is an extension that compares two or three Jupyter no

## Install

To install the extension, execute:
To install the extension, download the tar.gz file from the [latest release](https://github.com/NII-cloud-operation/Jupyter-LC_notebook_diff/releases) and execute:

```bash
$ pip install git+https://github.com/NII-cloud-operation/Jupyter-LC_notebook_diff.git
$ pip install lc_notebook_diff-*.tar.gz
```

To use the extension you will also need to install and enable, you can use Jupyter subcommand:
For nbclassic users, you will also need to install and enable the extension:

```
$ jupyter nbclassic-extension install --py lc_notebook_diff
$ jupyter nbclassic-extension enable --py lc_notebook_diff
```bash
$ jupyter nbclassic-extension install --py lc_notebook_diff --sys-prefix
$ jupyter nbclassic-extension enable --py lc_notebook_diff --sys-prefix
```

then restart Jupyter notebook.
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ exclude = [".github", "binder"]
[tool.hatch.build.targets.wheel.shared-data]
"lc_notebook_diff/labextension" = "share/jupyter/labextensions/lc_notebook_diff"
"install.json" = "share/jupyter/labextensions/lc_notebook_diff/install.json"
"lc_notebook_diff/nbextension" = "share/jupyter/nbextensions/notebook_diff"

[tool.hatch.build.hooks.version]
path = "lc_notebook_diff/_version.py"
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Empty file.
34 changes: 34 additions & 0 deletions ui-tests/e2e-notebook/notebooks/scripts/jupyterlab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Helper functions for LC Wrapper E2E tests."""


async def ensure_launcher_tab_opened(page):
"""Ensure launcher tab is opened and active."""
# Check if Launcher tab exists, if not create one
launcher_tab = page.locator('//*[contains(@class, "lm-TabBar-tabLabel") and text() = "Launcher"]')
if not await launcher_tab.is_visible():
# Click the "+" button to open a new launcher
await page.locator('//*[@data-command="launcher:create"]').click()

# Click on "Launcher" tab to make sure it's active
await page.locator('//*[contains(@class, "lm-TabBar-tabLabel") and text() = "Launcher"]').click()


async def get_notebook_panel_ids(page):
"""Get set of all notebook panel IDs."""
notebook_panels = page.locator('.jp-NotebookPanel')
count = await notebook_panels.count()
ids = []
for i in range(count):
panel = notebook_panels.nth(i)
panel_id = await panel.get_attribute('id')
ids.append(panel_id)
return set(ids)


def get_file_browser_item_locator(page, filename):
return page.locator(f'//*[contains(@class, "jp-DirListing-item") and contains(@title, "Name: {filename}")]')


def get_current_tab_closer_locator(page):
"""Get locator for current tab's close button."""
return page.locator('.jp-mod-current .lm-TabBar-tabCloseIcon')
Loading
Loading