controller

Defines the interface between View & Model.

source

App


def App(
    
):

Initialize self. See help(type(self)) for accurate signature.


source

open_gui


def open_gui(
    
):

Start the interactive widgets interface for NeuralActivityCubic

GUI Tests Dependencies

import os
import uuid
import sys
import subprocess
import ipykernel
import requests

from time import sleep
from pathlib import Path
from playwright.async_api import expect
from playwright.async_api import ViewportSize
from playwright.async_api import async_playwright
from jupyter_server import serverapp
from jupyter_server.services.contents.filemanager import FileContentsManager
from contextlib import contextmanager
from contextlib import asynccontextmanager
from nbformat import v4 as nbformat
def get_kernel_id() -> str | None:
    try:
        connection_file = ipykernel.get_connection_file()
        return Path(connection_file).stem.split('-', 1).pop(-1)
    except RuntimeError:
        return None


def find_server_info_by_kernel_id(kernel_id: str):
    servers = list(serverapp.list_running_servers())
    for server in servers:
        try:
            response = requests.get(f"{server['url']}api/sessions", headers={'Authorization': f"token {server['token']}"})
            for session in response.json():
                if session['kernel']['id'] == kernel_id:
                    return server
        except Exception as e:
            continue

    return None


def find_server_info_by_process_id(process_id: int):
    servers = list(serverapp.list_running_servers())
    for server in servers:
        if server['pid'] == process_id:
            return server

    return None


@contextmanager
def run_jupyter_server_app(project_root: str):
    jupyter_process = subprocess.Popen([sys.executable, '-m', 'jupyter', 'server', f'--ServerApp.root_dir={project_root}', '--ServerApp.open_browser=false'])

    sleep(10)  # Wait for the server to start

    yield find_server_info_by_process_id(jupyter_process.pid)

    jupyter_process.terminate()


@contextmanager
def get_jupyter_server():
    kernel_id = get_kernel_id()

    if kernel_id:
        yield find_server_info_by_kernel_id(kernel_id)
    else:
        with run_jupyter_server_app(project_root=Path.cwd().parent) as server_info:
            yield server_info
@contextmanager
def create_temporary_notebook(cells: list[str], kernel_name: str = 'python3'):
    fcm = FileContentsManager()
    name = f"test-{uuid.uuid4()}.ipynb"
    try:
        notebook = nbformat.new_notebook()
        notebook['metadata'] = {'kernelspec': {'name': kernel_name, 'display_name': kernel_name}}
        for cell in cells:
            notebook['cells'].append(nbformat.new_code_cell(source=cell))
        fcm.save({'type': 'notebook', 'content': notebook}, name)
        yield name
    finally:
        fcm.delete(name)


@asynccontextmanager
async def provide_playwright_page(headless: bool):
    browser = 'chromium'
    if headless:
        browser = 'chromium-headless-shell'
    subprocess.run([sys.executable, '-m', 'playwright', 'install', '--with-deps', browser])

    async with async_playwright() as playwright:
        browser_type = playwright.chromium
        browser = await browser_type.launch(headless=headless)
        page = await browser.new_page(viewport=ViewportSize(width=1280, height=1024))

        yield page

        await browser.close()


@asynccontextmanager
async def provide_na3_gui(visible: bool = True):
    with get_jupyter_server() as server_info, create_temporary_notebook(cells=['import neuralactivitycubic as na3; na3.open_gui()']) as notebook_name:
        token = server_info['token']
        lab_url = server_info['url'] + 'lab/tree/nbs'

        async with provide_playwright_page(headless=not visible) as page:
            await page.goto(f'{lab_url}/{notebook_name}?token={token}')

            await expect(page.get_by_role('main')).to_contain_text(notebook_name)

            selected_tab_id = await page.get_by_role('main').get_by_role('tab', selected=True).first.get_attribute('data-id')
            selected_tab = page.locator(f'#{selected_tab_id}').first
            await expect(selected_tab).to_be_visible()

            try:
                await expect(page.locator('#filebrowser')).to_be_visible(timeout=1)
                await page.locator('li[data-id="filebrowser"]').click()
            except AssertionError:
                pass

            kernel_status = selected_tab.locator('.jp-Notebook-ExecutionIndicator')
            await expect(kernel_status).to_have_attribute('data-status', 'idle')
            await page.wait_for_timeout(timeout=1000)

            run_menu = page.get_by_role('menuitem').filter(has=page.get_by_text('Run')).first
            await run_menu.click()

            run_all_cells_option = page.get_by_role('menuitem').filter(has=page.get_by_text('Run All Cells')).first
            await expect(run_all_cells_option).to_be_visible()
            await run_all_cells_option.click()

            na3_gui = selected_tab.locator('.box-na3-gui')
            await expect(na3_gui).to_be_visible()

            yield na3_gui
visible = os.environ.get('CI') != 'true'

async with provide_na3_gui(visible=visible) as gui:
    general_settings = gui.locator('.box-general-settings')
    assert not await general_settings.get_by_role("button", name="Select").is_disabled()
    assert await general_settings.get_by_role("button", name="Load Data").is_disabled()

    analysis_settings = gui.locator('.box-analysis-settings')

    buttons = await analysis_settings.locator("button").all()
    assert buttons
    for button in buttons:
        assert await button.is_disabled()

    inputs = await analysis_settings.locator("input").all()
    assert inputs
    for input in inputs:
        assert await input.is_disabled()