Skip to content
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

[WIP] Unit Test for dashboard #672

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4456665
Added IDs to UI components
proy30 Aug 10, 2024
f4219ca
Added some more IDs to UI components
proy30 Aug 11, 2024
7f3bbbb
Added 'close' button in lattice settings
proy30 Aug 11, 2024
b067042
Removed functionality that converted user input
proy30 Aug 11, 2024
fd50751
Added unit test for running FODO simulation on dashboard
proy30 Aug 11, 2024
9fd2b54
Added subprocess to start up server with pytest
proy30 Aug 11, 2024
583f227
Attempt to fix flaky test
proy30 Aug 12, 2024
f7e0e83
Add seleniumbase dependency in CI workflows for testing
proy30 Aug 12, 2024
e5f9e94
Added dashboard dependencies in stubs.yml
proy30 Aug 12, 2024
91fa693
Added missing dashboard dependencies to stubs.yml
proy30 Aug 12, 2024
703d73c
Update CI & Requirements Files
ax3l Aug 12, 2024
c94b280
pytest: Graceful Skipping
ax3l Aug 12, 2024
962efe7
Merge remote-tracking branch 'mainline/development' into selenium
ax3l Aug 12, 2024
2e5588c
Unit test interacts with phase space projections
proy30 Aug 18, 2024
e3fec39
time adjustments
proy30 Aug 18, 2024
7bbf231
adjust format
proy30 Aug 18, 2024
e493deb
attempt to run headless
proy30 Aug 18, 2024
36c7928
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 18, 2024
42c5972
Fixed UnboundLocalError and PermissionError
proy30 Sep 19, 2024
52c1dda
Replace time.sleep() with alternative
proy30 Sep 19, 2024
8a1b787
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 19, 2024
fcd0138
Redid logic to show simulation is complete
proy30 Sep 19, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
python3 -m venv py-venv
source py-venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade build packaging setuptools wheel pytest
python3 -m pip install --upgrade build packaging setuptools wheel
python3 -m pip install --upgrade -r requirements_mpi.txt
python3 -m pip install --upgrade -r src/python/impactx/dashboard/requirements.txt
python3 -m pip install --upgrade -r examples/requirements.txt
Expand Down
4 changes: 3 additions & 1 deletion src/python/impactx/dashboard/Analyze/plotsMain.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ async def print_lines():
ctrl.terminal_print(line)
ctrl.terminal_print("Simulation complete.")


asyncio.create_task(print_lines())


Expand All @@ -175,6 +176,7 @@ def on_filtered_data_change(**kwargs):

@ctrl.add("run_simulation")
def run_simulation_and_store():
state.simulation_complete = True,
state.plot_options = available_plot_options(simulationClicked=True)
run_simulation_impactX()
update_plot()
Expand Down Expand Up @@ -228,7 +230,7 @@ def plot():
with vuetify.VCard(style="height: 50vh; width: 150vh;"):
with vuetify.VTabs(v_model=("active_tab", 0)):
vuetify.VTab("Plot")
vuetify.VTab("Interact")
vuetify.VTab("Interact", id="interact")
vuetify.VDivider()
with vuetify.VTabsItems(v_model="active_tab"):
with vuetify.VTabItem():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ def on_distribution_type_change(**kwargs):

@ctrl.add("updateDistributionParameters")
def on_distribution_parameter_change(parameter_name, parameter_value, parameter_type):
parameter_value, input_type = generalFunctions.determine_input_type(parameter_value)
error_message = generalFunctions.validate_against(parameter_value, parameter_type)

update_distribution_parameters(parameter_name, parameter_value, error_message)
Expand Down Expand Up @@ -175,13 +174,15 @@ def card():
with vuetify.VCol(cols=8):
vuetify.VCombobox(
label="Select Distribution",
id="selected_distribution",
v_model=("selectedDistribution",),
items=("listOfDistributions",),
dense=True,
)
with vuetify.VCol(cols=4):
vuetify.VSelect(
v_model=("selectedDistributionType",),
id="selected_distribution_type",
label="Type",
items=(["Native", "Twiss"],),
# change=(ctrl.kin_energy_unit_change, "[$event]"),
Expand All @@ -199,6 +200,7 @@ def card():
):
vuetify.VTextField(
label=("parameter.parameter_name",),
id=("parameter.parameter_name",),
v_model=("parameter.parameter_default_value",),
change=(
ctrl.updateDistributionParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def card(self):
vuetify.VCombobox(
v_model=("particle_shape",),
label="Particle Shape",
id="particle_shape",
items=([1, 2, 3],),
dense=True,
)
Expand All @@ -101,6 +102,7 @@ def card(self):
vuetify.VTextField(
v_model=("npart",),
label="Number of Particles",
id="npart",
error_messages=("npart_validation",),
change=(
ctrl.on_input_change,
Expand All @@ -114,6 +116,7 @@ def card(self):
vuetify.VTextField(
v_model=("kin_energy",),
label="Kinetic Energy",
id="kin_energy",
error_messages=("kin_energy_validation",),
change=(
ctrl.on_input_change,
Expand All @@ -127,6 +130,7 @@ def card(self):
vuetify.VSelect(
v_model=("kin_energy_unit",),
label="Unit",
id="kin_energy_unit",
items=(["meV", "eV", "keV", "MeV", "GeV", "TeV"],),
change=(ctrl.kin_energy_unit_change, "[$event]"),
dense=True,
Expand All @@ -135,6 +139,7 @@ def card(self):
with vuetify.VCol(cols=8, classes="py-0"):
vuetify.VTextField(
label="Bunch Charge",
id="bunch_charge_C",
v_model=("bunch_charge_C",),
error_messages=("bunch_charge_C_validation",),
change=(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ def on_add_lattice_element_click():
def on_lattice_element_parameter_change(
index, parameter_name, parameter_value, parameter_type
):
parameter_value, input_type = generalFunctions.determine_input_type(parameter_value)
error_message = generalFunctions.validate_against(parameter_value, parameter_type)

update_latticeElement_parameters(
Expand Down Expand Up @@ -253,6 +252,7 @@ def card():
with vuetify.VCol(cols=8):
vuetify.VCombobox(
label="Select Accelerator Lattice",
id="selected_lattice",
v_model=("selectedLattice", None),
items=("listOfLatticeElements",),
error_messages=("isSelectedLatticeListEmpty",),
Expand All @@ -262,6 +262,7 @@ def card():
with vuetify.VCol(cols="auto"):
vuetify.VBtn(
"ADD",
id="add_button",
color="primary",
dense=True,
classes="mr-2",
Expand All @@ -270,6 +271,7 @@ def card():
with vuetify.VCol(cols="auto"):
vuetify.VBtn(
"CLEAR",
id="clear_button",
color="secondary",
dense=True,
classes="mr-2",
Expand All @@ -279,6 +281,7 @@ def card():
vuetify.VIcon(
"mdi-cog",
click="showDialog_settings = true",
id="lattice_settings_icon",
)
with vuetify.VRow():
with vuetify.VCol():
Expand Down Expand Up @@ -337,6 +340,7 @@ def card():
):
vuetify.VTextField(
label=("parameter.parameter_name",),
id=("parameter.parameter_name + index",),
v_model=(
"parameter.parameter_default_value",
),
Expand Down Expand Up @@ -420,6 +424,7 @@ def dialog_lattice_settings():
with vuetify.VCol(no_gutters=True):
vuetify.VTextField(
v_model=("nsliceDefaultValue",),
id="nslice_default_value",
change=(
ctrl.nsliceDefaultChange,
"['nslice', $event]",
Expand All @@ -431,3 +436,13 @@ def dialog_lattice_settings():
style="max-width: 75px",
classes="ma-0 pa-0",
)
vuetify.VDivider()
with vuetify.VCardActions():
vuetify.VSpacer()
vuetify.VBtn(
"Close",
id="lattice_settings_close",
color="primary",
text=True,
click="showDialog_settings = false",
)
2 changes: 1 addition & 1 deletion src/python/impactx/dashboard/Input/trameFunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ def create_route(route_title, mdi_icon):
with vuetify.VListItemIcon():
vuetify.VIcon(mdi_icon)
with vuetify.VListItemContent():
vuetify.VListItemTitle(route_title)
vuetify.VListItemTitle(route_title, id=f"{route_title}_route")
14 changes: 14 additions & 0 deletions src/python/impactx/dashboard/Toolbar/toolbarMain.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def plot_options():
v_model=("active_plot", "1D plots over s"),
items=("plot_options",),
label="Select plot to view",
id="select_plot",
hide_details=True,
dense=True,
style="max-width: 250px",
Expand All @@ -39,11 +40,23 @@ def plot_options():
def run_simulation_button():
vuetify.VBtn(
"Run Simulation",
id="run_simulation_button",
style="background-color: #00313C; color: white; margin: 0 20px;",
click=ctrl.run_simulation,
disabled=("disableRunSimulationButton", True),
)

@staticmethod
def show_simulation_complete():
vuetify.VAlert(
"Simulation Complete",
v_model=("simulation_complete", False),
id="simulation_complete",
type="success",
dense=True,
classes="mt-4",
)


# -----------------------------------------------------------------------------
# Content
Expand All @@ -62,6 +75,7 @@ def run_toolbar():
"""

vuetify.VSpacer(),
ToolbarElements.show_simulation_complete(),
ToolbarElements.run_simulation_button(),

@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion src/python/impactx/dashboard/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# GUI
# -----------------------------------------------------------------------------
def init_terminal():
with xterm.XTerm(v_if="$route.path == '/Run'") as term:
with xterm.XTerm(v_show="$route.path == '/Run'", id="xterm_component") as term:
ctrl.terminal_print = term.writeln


Expand Down
88 changes: 88 additions & 0 deletions tests/python/dashboard/test_dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import importlib

import pytest
from util import (
check_until_visible,
set_input_value,
start_dashboard,
wait_for_dashboard_ready,
wait_for_ready,
)

TIMEOUT = 60


@pytest.mark.skipif(
importlib.util.find_spec("seleniumbase") is None,
reason="seleniumbase is not available",
)
def test_dashboard():
"""
This test runs the FODO example on the dashboard and verifies
that the simulation has ran successfully.
"""
from seleniumbase import SB

app_process = None

try:
with SB(headless=True) as sb:
app_process = start_dashboard()
wait_for_dashboard_ready(app_process, timeout=TIMEOUT)

url = "http://localhost:8080/index.html#/Input"
sb.open(url)

wait_for_ready(sb, ".trame__loader", TIMEOUT)

# Adjust beam properties
sb.click("#particle_shape")
sb.click("div.v-list-item:nth-of-type(2)")
set_input_value(sb, "npart", 10000)
set_input_value(sb, "kin_energy", 2.0e3)
set_input_value(sb, "bunch_charge_C", 1.0e-9)

# Adjust beam distribution
set_input_value(sb, "selected_distribution", "Waterbag")
set_input_value(sb, "lambdaX", 3.9984884770e-5)
set_input_value(sb, "lambdaY", 3.9984884770e-5)
set_input_value(sb, "lambdaT", 1.0e-3)
set_input_value(sb, "lambdaPx", 2.6623538760e-5)
set_input_value(sb, "lambdaPy", 2.6623538760e-5)
set_input_value(sb, "lambdaPt", 2.0e-3)
set_input_value(sb, "muxpx", -0.846574929020762)
set_input_value(sb, "muypy", 0.846574929020762)
set_input_value(sb, "mutpt", 0.0)

# Adjust lattice configuration
sb.click("#lattice_settings_icon")
set_input_value(sb, "nslice_default_value", 25)
sb.click("#lattice_settings_close")
sb.click("#clear_button")
set_input_value(sb, "selected_lattice", "Drift")
sb.click("#add_button")
set_input_value(sb, "ds0", 0.25)
set_input_value(sb, "selected_lattice", "Quad")
sb.click("#add_button")
set_input_value(sb, "ds1", 1.0)
set_input_value(sb, "k1", 1.0)
set_input_value(sb, "selected_lattice", "Drift")
sb.click("#add_button")
set_input_value(sb, "ds2", 0.5)
set_input_value(sb, "selected_lattice", "Quad")
sb.click("#add_button")
set_input_value(sb, "ds3", 1.0)
set_input_value(sb, "k3", -1.0)
set_input_value(sb, "selected_lattice", "Drift")
sb.click("#add_button")
set_input_value(sb, "ds4", 0.25)

# Run simulation
sb.click("#Run_route")
sb.click("#run_simulation_button")

assert check_until_visible(sb, "#simulation_complete"), "Simulation did not complete successfully."

finally:
if app_process is not None:
app_process.terminate()
Loading