Skip to content

Commit

Permalink
Webviz testing fixture (#615)
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKallekleiv authored Aug 29, 2022
1 parent 7b5d93a commit f65576b
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 0 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def get_long_description() -> str:
"TablePlotter = webviz_config.generic_plugins._table_plotter:TablePlotter",
"PivotTable = webviz_config.generic_plugins._pivot_table:PivotTable",
],
"pytest11": ["webviz = webviz_config.testing._plugin"],
},
install_requires=[
"bleach[css]>=5",
Expand Down
22 changes: 22 additions & 0 deletions tests/test_example_wlf_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import webviz_config
from webviz_config.generic_plugins._example_wlf_plugin import ExampleWlfPlugin2


def test_example_wlf_plugin2(
_webviz_duo: webviz_config.testing._composite.WebvizComposite,
) -> None:

plugin = ExampleWlfPlugin2(title="hello")

_webviz_duo.start_server(plugin)

_webviz_duo.toggle_webviz_drawer()

component_id = _webviz_duo.view_settings_group_unique_component_id(
view_id="plot-view",
settings_group_id="plot-settings",
component_unique_id="coordinates-selector",
)

_webviz_duo.wait_for_contains_text(component_id, "x - y")
assert _webviz_duo.get_logs() == []
Empty file.
96 changes: 96 additions & 0 deletions webviz_config/testing/_composite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from typing import Any

import pathlib

from dash.testing.composite import Browser
import dash
import webviz_core_components as wcc

from webviz_config.common_cache import CACHE
from webviz_config.themes import default_theme
from webviz_config.webviz_factory_registry import WEBVIZ_FACTORY_REGISTRY
from webviz_config.webviz_instance_info import WEBVIZ_INSTANCE_INFO, WebvizRunMode
from webviz_config import WebvizPluginABC

from ._webviz_ids import WebvizIds


class WebvizComposite(Browser):
def __init__(self, server: Any, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.app = dash.Dash(__name__)
self.server = server
self.plugin: WebvizPluginABC
self.init_app()

def init_app(self) -> None:
WEBVIZ_INSTANCE_INFO.initialize(
dash_app=self.app,
run_mode=WebvizRunMode.NON_PORTABLE,
theme=default_theme,
storage_folder=pathlib.Path(__file__).resolve().parent,
)
try:
WEBVIZ_FACTORY_REGISTRY.initialize(None)
except RuntimeError:
pass

self.app.css.config.serve_locally = True
self.app.scripts.config.serve_locally = True
self.app.config.suppress_callback_exceptions = True
CACHE.init_app(self.app.server)

def start_server(self, plugin: WebvizPluginABC, **kwargs: Any) -> None:
"""Start the local server with app."""

self.app.layout = dash.html.Div(
className=WebvizIds.LAYOUT_WRAPPER,
children=[
wcc.WebvizContentManager(
id=WebvizIds.CONTENT_MANAGER,
children=[
wcc.WebvizSettingsDrawer(
id=WebvizIds.SETTINGS_DRAWER,
children=plugin.get_all_settings(),
),
wcc.WebvizPluginsWrapper(
id=WebvizIds.PLUGINS_WRAPPER,
children=plugin.plugin_layout(),
),
],
),
],
)
self.plugin = plugin
# start server with app and pass Dash arguments
self.server(self.app, **kwargs)

# set the default server_url, it implicitly call wait_for_page
self.server_url = self.server.url

def toggle_webviz_drawer(self) -> None:
"""Open the plugin settings drawer"""
self.wait_for_element(WebvizIds.SETTINGS_DRAWER_TOGGLE_OPEN).click()

def shared_settings_group_unique_component_id(
self, settings_group_id: str, component_unique_id: str
) -> str:
"""Returns the element id of a component in a shared settings group"""
unique_id = (
self.plugin.shared_settings_group(settings_group_id)
.component_unique_id(component_unique_id)
.to_string()
)
return f"#{unique_id}"

def view_settings_group_unique_component_id(
self, view_id: str, settings_group_id: str, component_unique_id: str
) -> str:
"""Returns the element id of a component in a view settings group"""
unique_id = (
self.plugin.view(view_id)
.settings_group(settings_group_id)
.component_unique_id(component_unique_id)
.to_string()
)
return f"#{unique_id}"
35 changes: 35 additions & 0 deletions webviz_config/testing/_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from typing import Any, Generator

import pytest

# pylint: disable=too-few-public-methods
class MissingWebvizTesting:
def __init__(self, **kwargs: Any) -> None:
raise RuntimeError(
"webviz_config[tests] was not installed. "
"Please install to use the webviz testing fixtures."
)


try:
from webviz_config.testing._composite import WebvizComposite
except ImportError:

WebvizComposite = MissingWebvizTesting # type: ignore


@pytest.fixture
def _webviz_duo(request: Any, dash_thread_server: Any, tmpdir: Any) -> Generator:
with WebvizComposite(
dash_thread_server,
browser=request.config.getoption("webdriver"),
remote=request.config.getoption("remote"),
remote_url=request.config.getoption("remote_url"),
headless=request.config.getoption("headless"),
options=request.config.hook.pytest_setup_options(),
download_path=tmpdir.mkdir("download").strpath,
percy_assets_root=request.config.getoption("percy_assets"),
percy_finalize=request.config.getoption("nopercyfinalize"),
pause=request.config.getoption("pause"),
) as duo:
yield duo
9 changes: 9 additions & 0 deletions webviz_config/testing/_webviz_ids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from enum import Enum


class WebvizIds(str, Enum):
LAYOUT_WRAPPER = "layoutWrapper"
CONTENT_MANAGER = "webviz-content-manager"
SETTINGS_DRAWER = "settings-drawer"
PLUGINS_WRAPPER = "plugins-wrapper"
SETTINGS_DRAWER_TOGGLE_OPEN = ".WebvizSettingsDrawer__ToggleOpen"

0 comments on commit f65576b

Please sign in to comment.