"""
Before running this script make sure you have
```bash
git pull
pip install -e . -U
python setup.py develop
```
Then run the script to create/ update the notebooks for Panelite
```bash
python scripts/generate_panelite_content.py
```
Follow the steps in the Panel Jupyterlite guide including
```bash
cd lite
pip install -r requirements.txt -U
jupyter lite build --output-dir ./dist
```
Start the http server
```bash
cd dist
python -m http.server
```
Reset your files as described in https://github.com/jupyterlite/jupyterlite/issues/9#issuecomment-875870620
Run the tests
```bash
pytest scripts/test_panelite/test_panelite.py --headed
```
"""
import pathlib
import pytest
from playwright.sync_api import Page, expect
from scripts.test_panelite.notebooks_with_panelite_issues import (
NOTEBOOK_ISSUES,
)
from scripts.test_panelite.utils import Retrier
URL = "https://panelite.holoviz.org"
URL = "http://localhost:8000"
PANEL_BASE = pathlib.Path(__file__).parent.parent.parent
FILES = PANEL_BASE / 'lite' / 'files'
def get_panelite_nb_paths():
nbs = list(FILES.glob('*/*/*.ipynb')) + list(FILES.glob('*/*.*'))
for nb in nbs:
path = str(nb).replace("\\", "/").split("files/")[-1]
if path.endswith(".ipynb") and ".ipynb_checkpoints" not in path:
yield path
PATHS_WITH_NOTHING_TO_TEST = [
"gallery/demos/attractors.ipynb",
"gallery/demos/gapminders.ipynb",
"gallery/demos/glaciers.ipynb",
"gallery/demos/nyc_taxi.ipynb",
"gallery/demos/portfolio-optimizer.ipynb",
]
PATHS = list(path for path in get_panelite_nb_paths() if path not in PATHS_WITH_NOTHING_TO_TEST)
PATHS_WITHOUT_ISSUES = list(path for path in PATHS if path not in NOTEBOOK_ISSUES)
PATHS_WITH_ISSUES = list(path for path in PATHS if path in NOTEBOOK_ISSUES)
def _wait_for_notebook_tab(page, notebook):
tabs = page.get_by_role("tablist")
tabs.get_by_text(notebook)
def _select_kernel(page):
page.get_by_role("button", name="Python (Pyodide)").click()
page.get_by_role("button", name="Select").filter(has_text="Select").click()
def _run_all_cells(page):
page.get_by_role("menuitem", name="Run").get_by_text("Run").click()
page.get_by_text("Run All Cells").nth(2).click()
class RunCells(Exception):
"""Raised if an exception is raised while running all cells"""
def run_notebook(path, page):
"""Opens the notebook and runs all cells"""
url =URL + f"/lab/index.html?path={path}"
notebook = path.split("/")[-1]
retrier = Retrier(retries=3, delay=1)
while not retrier.accomplished:
with retrier:
page.goto(url)
_wait_for_notebook_tab(page, notebook)
_select_kernel(page)
_run_all_cells(page)
busy_cells = page.get_by_text("[*]:")
expect(busy_cells).not_to_have_count(0)
execution_indicator = page.locator('.jp-Notebook-ExecutionIndicator')
expect(execution_indicator).to_have_attribute("data-status", "unknown", timeout=10000)
expect(execution_indicator).to_have_attribute("data-status", "busy", timeout=10000)
expect(execution_indicator).to_have_attribute("data-status", "idle", timeout=45000)
@pytest.mark.parametrize(["path"], [(path,) for path in PATHS_WITHOUT_ISSUES])
def test_notebooks_without_issues(path, page: Page):
run_notebook(path, page)
cells_with_err = page.locator('div[data-mime-type="application/vnd.jupyter.stderr"]')
if cells_with_err.count()>0:
raise RunCells(cells_with_err.first.inner_text())
@pytest.mark.xfail
@pytest.mark.parametrize(["path"], [(path,) for path in PATHS_WITH_ISSUES])
def test_notebooks_with_issues(path, page: Page):
run_notebook(path, page)
cells_with_err = page.locator('div[data-mime-type="application/vnd.jupyter.stderr"]')
if cells_with_err.count()>0:
raise RunCells(cells_with_err.first.inner_text())