"""Playwright E2E: drag-transfer рейса между периодами.""" from __future__ import annotations import pytest from tests.e2e.conftest import ( E2E_DISP_ID, E2E_DISP_RECIPE_1, E2E_DISP_RECIPE_2, E2E_PERIOD_A, E2E_PERIOD_B, ) from tests.e2e.recipes_e2e_helpers import ( LONG_HOVER_MS, drag_reorder_recipe, drag_transfer_to_period, list_dom_recipe_ids, period_recipe_ids, ) pytestmark = pytest.mark.e2e SCENARIO_E2E_TRANSFER_ESCAPE = "E2E_TRANSFER_ESCAPE" SCENARIO_E2E_TRANSFER_REPEAT = "E2E_TRANSFER_REPEAT" SCENARIO_E2E_REORDER_THEN_TRANSFER = "E2E_REORDER_THEN_TRANSFER" SCENARIO_E2E_TRANSFER_THEN_REORDER = "E2E_TRANSFER_THEN_REORDER" def _open_period_a(page, recipe_id: str = E2E_DISP_RECIPE_1) -> None: page.locator(f'[data-action="select-dispenser"][data-dispenser-id="{E2E_DISP_ID}"]').click() page.locator(f'[data-action="select-period"][data-period-id="{E2E_PERIOD_A}"]').click() page.wait_for_selector( f'[data-action="select-recipe"][data-recipe-id="{recipe_id}"]', timeout=10000 ) def test_transfer_escape_cancels_without_api_call(authenticated_page) -> None: SCENARIO_E2E_TRANSFER_ESCAPE # noqa: F841 page = authenticated_page page.set_viewport_size({"width": 1280, "height": 800}) _open_period_a(page) handle = page.locator( f'#recipesList .list-item[data-recipe-id="{E2E_DISP_RECIPE_1}"] [data-action="recipe-drag-handle"]' ).first box = handle.bounding_box() assert box page.mouse.move(box["x"] + 5, box["y"] + 5) page.mouse.down() page.mouse.move(box["x"] + 200, box["y"] + 200, steps=8) page.keyboard.press("Escape") page.mouse.up() assert page.locator("button.recipe-transfer-slot").count() == 0 def test_transfer_drag_to_other_period_inserts_recipe(authenticated_page, live_server_url) -> None: page = authenticated_page page.set_viewport_size({"width": 1280, "height": 800}) _open_period_a(page) handle = page.locator( f'#recipesList .list-item[data-recipe-id="{E2E_DISP_RECIPE_1}"] [data-action="recipe-drag-handle"]' ).first period_b = page.locator(f'[data-action="select-period"][data-period-id="{E2E_PERIOD_B}"]') handle_box = handle.bounding_box() period_box = period_b.bounding_box() assert handle_box and period_box page.mouse.move(handle_box["x"] + handle_box["width"] / 2, handle_box["y"] + 5) page.mouse.down() page.mouse.move(period_box["x"] + period_box["width"] / 2, period_box["y"] + 10, steps=12) page.wait_for_timeout(LONG_HOVER_MS) page.mouse.up() slot = page.locator("button.recipe-transfer-slot") page.wait_for_selector("button.recipe-transfer-slot", timeout=10000) with page.expect_response( lambda r: "/transfer" in r.url and r.request.method == "POST", timeout=15000, ): slot.first.click() page.wait_for_timeout(500) listed = page.request.get(f"{live_server_url}/api/periods/{E2E_PERIOD_B}/recipes") assert listed.ok ids = [r["id"] for r in listed.json()] assert E2E_DISP_RECIPE_1 in ids def test_transfer_repeat_a_b_a(authenticated_page, live_server_url) -> None: SCENARIO_E2E_TRANSFER_REPEAT # noqa: F841 page = authenticated_page page.set_viewport_size({"width": 1280, "height": 800}) _open_period_a(page) drag_transfer_to_period(page, E2E_DISP_RECIPE_1, E2E_PERIOD_B) assert period_recipe_ids(page, live_server_url, E2E_PERIOD_A) == [E2E_DISP_RECIPE_2] assert period_recipe_ids(page, live_server_url, E2E_PERIOD_B) == [E2E_DISP_RECIPE_1] page.locator(f'[data-action="select-period"][data-period-id="{E2E_PERIOD_B}"]').click() page.wait_for_selector( f'[data-action="select-recipe"][data-recipe-id="{E2E_DISP_RECIPE_1}"]', timeout=10000 ) drag_transfer_to_period(page, E2E_DISP_RECIPE_1, E2E_PERIOD_A, slot_index=1) assert period_recipe_ids(page, live_server_url, E2E_PERIOD_A) == [ E2E_DISP_RECIPE_2, E2E_DISP_RECIPE_1, ] assert period_recipe_ids(page, live_server_url, E2E_PERIOD_B) == [] def test_transfer_slot_index_one_when_target_has_recipe( authenticated_page, live_server_url ) -> None: page = authenticated_page page.set_viewport_size({"width": 1280, "height": 800}) _open_period_a(page) drag_transfer_to_period(page, E2E_DISP_RECIPE_2, E2E_PERIOD_B) assert period_recipe_ids(page, live_server_url, E2E_PERIOD_B) == [E2E_DISP_RECIPE_2] _open_period_a(page, E2E_DISP_RECIPE_1) drag_transfer_to_period(page, E2E_DISP_RECIPE_1, E2E_PERIOD_B, slot_index=0) assert period_recipe_ids(page, live_server_url, E2E_PERIOD_B) == [ E2E_DISP_RECIPE_1, E2E_DISP_RECIPE_2, ] def test_reorder_then_transfer_still_moves_recipe(authenticated_page, live_server_url) -> None: SCENARIO_E2E_REORDER_THEN_TRANSFER # noqa: F841 page = authenticated_page page.set_viewport_size({"width": 1280, "height": 800}) _open_period_a(page) assert list_dom_recipe_ids(page) == [E2E_DISP_RECIPE_1, E2E_DISP_RECIPE_2] with page.expect_response( lambda r: r.request.method == "PUT" and "/move" in r.url, timeout=15000, ): drag_reorder_recipe(page, E2E_DISP_RECIPE_1, direction="down") page.wait_for_timeout(500) assert list_dom_recipe_ids(page) == [E2E_DISP_RECIPE_2, E2E_DISP_RECIPE_1] drag_transfer_to_period(page, E2E_DISP_RECIPE_1, E2E_PERIOD_B) assert period_recipe_ids(page, live_server_url, E2E_PERIOD_A) == [E2E_DISP_RECIPE_2] assert period_recipe_ids(page, live_server_url, E2E_PERIOD_B) == [E2E_DISP_RECIPE_1] def test_transfer_then_reorder_on_target_period(authenticated_page, live_server_url) -> None: SCENARIO_E2E_TRANSFER_THEN_REORDER # noqa: F841 page = authenticated_page page.set_viewport_size({"width": 1280, "height": 800}) _open_period_a(page) drag_transfer_to_period(page, E2E_DISP_RECIPE_1, E2E_PERIOD_B) _open_period_a(page, E2E_DISP_RECIPE_2) drag_transfer_to_period(page, E2E_DISP_RECIPE_2, E2E_PERIOD_B, slot_index=1) page.locator(f'[data-action="select-period"][data-period-id="{E2E_PERIOD_B}"]').click() page.wait_for_selector( f'#recipesList .list-item[data-recipe-id="{E2E_DISP_RECIPE_2}"]', timeout=10000 ) assert list_dom_recipe_ids(page) == [E2E_DISP_RECIPE_1, E2E_DISP_RECIPE_2] drag_reorder_recipe(page, E2E_DISP_RECIPE_2, direction="up", expect_move_response=False) page.wait_for_timeout(500) assert list_dom_recipe_ids(page) == [E2E_DISP_RECIPE_2, E2E_DISP_RECIPE_1] assert period_recipe_ids(page, live_server_url, E2E_PERIOD_B) == [ E2E_DISP_RECIPE_2, E2E_DISP_RECIPE_1, ]