diff --git a/e2e_tests/conftest.py b/e2e_tests/conftest.py index b9b8e36f..8d8eac3b 100644 --- a/e2e_tests/conftest.py +++ b/e2e_tests/conftest.py @@ -1,3 +1,4 @@ +import socket import threading from wsgiref.simple_server import make_server @@ -211,6 +212,14 @@ def make_dummy_storage(study_name: str) -> optuna.storages.InMemoryStorage: return storage +def get_free_port() -> int: + tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + tcp.bind(("", 0)) + _, port = tcp.getsockname() + tcp.close() + return port + + @pytest.fixture(scope="session", params=study_names) def storage(request: pytest.FixtureRequest) -> optuna.storages.InMemoryStorage: study_name = request.param @@ -221,7 +230,7 @@ def storage(request: pytest.FixtureRequest) -> optuna.storages.InMemoryStorage: @pytest.fixture(scope="session") def server_url(request: pytest.FixtureRequest, storage: optuna.storages.InMemoryStorage) -> str: addr = "127.0.0.1" - port = 38080 + port = get_free_port() app = wsgi(storage) httpd = make_server(addr, port, app) thread = threading.Thread(target=httpd.serve_forever) @@ -234,4 +243,15 @@ def server_url(request: pytest.FixtureRequest, storage: optuna.storages.InMemory request.addfinalizer(stop_server) - return f"http://{addr}:{port}/dashboard/" + return f"http://{addr}:{port}/dashboard" + + +@pytest.fixture(scope="session") +def browser_context_args(browser_context_args: dict) -> dict: + return { + **browser_context_args, + "viewport": { + "width": 1000, + "height": 3000, + }, + } diff --git a/e2e_tests/visual_regression_test.py b/e2e_tests/visual_regression_test.py index 42b2190c..706ec2f3 100644 --- a/e2e_tests/visual_regression_test.py +++ b/e2e_tests/visual_regression_test.py @@ -7,8 +7,6 @@ def test_study_list( storage: optuna.storages.InMemoryStorage, server_url: str, ) -> None: - page.set_viewport_size({"width": 1000, "height": 3000}) - summaries = optuna.get_all_study_summaries(storage) study_id = summaries[0]._study_id study_name = summaries[0].study_name @@ -22,3 +20,87 @@ def test_study_list( title = element.text_content() assert title is not None assert study_name in title + + +def test_study_analytics( + page: Page, + storage: optuna.storages.InMemoryStorage, + server_url: str, +) -> None: + summaries = optuna.get_all_study_summaries(storage) + study_id = summaries[0]._study_id + study_name = summaries[0].study_name + url = f"{server_url}/studies/{study_id}" + + page.goto(url) + page.click(f"a[href='/dashboard/studies/{study_id}/analytics']") + + element = page.query_selector(".MuiTypography-body1") + assert element is not None + + title = element.text_content() + assert title is not None + assert study_name in title + + +def test_trial_list( + page: Page, + storage: optuna.storages.InMemoryStorage, + server_url: str, +) -> None: + summaries = optuna.get_all_study_summaries(storage) + study_id = summaries[0]._study_id + study_name = summaries[0].study_name + url = f"{server_url}/studies/{study_id}" + + page.goto(url) + page.click(f"a[href='/dashboard/studies/{study_id}/trials']") + + element = page.query_selector(".MuiTypography-body1") + assert element is not None + + title = element.text_content() + assert title is not None + assert study_name in title + + +def test_trial_table( + page: Page, + storage: optuna.storages.InMemoryStorage, + server_url: str, +) -> None: + summaries = optuna.get_all_study_summaries(storage) + study_id = summaries[0]._study_id + study_name = summaries[0].study_name + url = f"{server_url}/studies/{study_id}" + + page.goto(url) + page.click(f"a[href='/dashboard/studies/{study_id}/trialTable']") + + element = page.query_selector(".MuiTypography-body1") + assert element is not None + + title = element.text_content() + assert title is not None + assert study_name in title + + +def test_trial_note( + page: Page, + storage: optuna.storages.InMemoryStorage, + server_url: str, +) -> None: + summaries = optuna.get_all_study_summaries(storage) + study_id = summaries[0]._study_id + study_name = summaries[0].study_name + url = f"{server_url}/studies/{study_id}" + + page.goto(url) + page.click(f"a[href='/dashboard/studies/{study_id}/note']") + + element = page.query_selector(".MuiTypography-body1") + assert element is not None + + title = element.text_content() + assert title is not None + assert study_name in title diff --git a/optuna_dashboard/ts/searchSpace.ts b/optuna_dashboard/ts/searchSpace.ts index 729f1f51..f0bd4006 100644 --- a/optuna_dashboard/ts/searchSpace.ts +++ b/optuna_dashboard/ts/searchSpace.ts @@ -3,9 +3,9 @@ import { useMemo } from "react" export const mergeUnionSearchSpace = ( unionSearchSpace: SearchSpaceItem[] ): SearchSpaceItem[] => { - const knownElements = new Map() + let knownElements = new Map() unionSearchSpace.forEach((s) => { - const d = knownElements.get(s.name) + let d = knownElements.get(s.name) if (d === undefined) { knownElements.set(s.name, s.distribution) return @@ -17,9 +17,12 @@ export const mergeUnionSearchSpace = ( // CategoricalDistribution.choices will never be changed return } - d.low = Math.min(d.low, s.distribution.low) - d.high = Math.max(d.low, s.distribution.high) - knownElements.set(s.name, d) + const updated: Distribution = { + ...d, + low: Math.min(d.low, s.distribution.low), + high: Math.max(d.high, s.distribution.high), + } + knownElements.set(s.name, updated) }) return Array.from(knownElements.keys()) .sort((a, b) => (a > b ? 1 : a < b ? -1 : 0))