@@ -0,0 +1,159 @@
|
||||
"""E2E: два терминала — DnD/sync (баготест #4)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.e2e.recipes_e2e_helpers import (
|
||||
drag_reorder_recipe,
|
||||
list_dom_recipe_ids,
|
||||
period_recipe_ids,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.e2e
|
||||
|
||||
SCENARIO_DUAL_E2E_DND_SYNC = "DUAL_E2E_DND_SYNC"
|
||||
SCENARIO_DUAL_E2E_TRANSFER_REORDER = "DUAL_E2E_TRANSFER_REORDER"
|
||||
|
||||
|
||||
def test_dual_reorder_visible_on_both_terminals(
|
||||
page_a, page_b, dual_harness, live_server_a_url, live_server_b_url
|
||||
) -> None:
|
||||
SCENARIO_DUAL_E2E_DND_SYNC # noqa: F841
|
||||
disp_id = dual_harness._e2e_disp_id # type: ignore[attr-defined]
|
||||
period_a = dual_harness._e2e_period_a # type: ignore[attr-defined]
|
||||
r1 = dual_harness._e2e_r1 # type: ignore[attr-defined]
|
||||
r2 = dual_harness._e2e_r2 # type: ignore[attr-defined]
|
||||
|
||||
for page, url in ((page_a, live_server_a_url), (page_b, live_server_b_url)):
|
||||
page.locator(f'[data-action="select-dispenser"][data-dispenser-id="{disp_id}"]').click()
|
||||
page.locator(f'[data-action="select-period"][data-period-id="{period_a}"]').click()
|
||||
page.wait_for_selector("#recipesList .list-item", timeout=10000)
|
||||
|
||||
assert list_dom_recipe_ids(page_a) == [r1, r2]
|
||||
assert list_dom_recipe_ids(page_b) == [r1, r2]
|
||||
|
||||
drag_reorder_recipe(page_a, r1, direction="down")
|
||||
page_a.wait_for_timeout(600)
|
||||
from tests.e2e.dual_terminal_conftest import sync_both
|
||||
|
||||
sync_both(dual_harness)
|
||||
page_b.reload()
|
||||
page_b.wait_for_selector("#recipesDashboard", timeout=15000)
|
||||
page_b.locator(f'[data-action="select-dispenser"][data-dispenser-id="{disp_id}"]').click()
|
||||
page_b.locator(f'[data-action="select-period"][data-period-id="{period_a}"]').click()
|
||||
page_b.wait_for_timeout(500)
|
||||
|
||||
assert period_recipe_ids(page_a, live_server_a_url, period_a) == [r2, r1]
|
||||
assert period_recipe_ids(page_b, live_server_b_url, period_a) == [r2, r1]
|
||||
|
||||
|
||||
def test_dual_edit_recipe_name_both_see(
|
||||
page_a, page_b, dual_harness, live_server_a_url, live_server_b_url
|
||||
) -> None:
|
||||
r1 = dual_harness._e2e_r1 # type: ignore[attr-defined]
|
||||
current = page_a.request.get(f"{live_server_a_url}/api/recipes/{r1}")
|
||||
assert current.ok
|
||||
payload = current.json()
|
||||
payload["name"] = "Dual renamed"
|
||||
payload["ingredients"] = payload.get("ingredients") or []
|
||||
payload["unloading_groups"] = payload.get("unloading_groups") or []
|
||||
|
||||
put = page_a.request.put(f"{live_server_a_url}/api/recipes/{r1}", data=payload)
|
||||
assert put.ok, put.text()
|
||||
|
||||
dual_harness.push_from_terminal("a")
|
||||
with dual_harness.server_ctx():
|
||||
from app import db
|
||||
from app.models import Recipe
|
||||
from app.services.sync_manager import enqueue_sync_queue_task
|
||||
|
||||
row = db.session.get(Recipe, r1)
|
||||
if row is not None:
|
||||
row.name = "Dual renamed"
|
||||
db.session.commit()
|
||||
enqueue_sync_queue_task("recipe", r1, "update", priority=2)
|
||||
db.session.commit()
|
||||
|
||||
from tests.e2e.dual_terminal_conftest import sync_both
|
||||
|
||||
sync_both(dual_harness)
|
||||
|
||||
for page, url in ((page_a, live_server_a_url), (page_b, live_server_b_url)):
|
||||
resp = page.request.get(f"{url}/api/recipes/{r1}")
|
||||
assert resp.ok
|
||||
assert resp.json().get("name") == "Dual renamed"
|
||||
|
||||
|
||||
def test_dual_copy_paste_unloading_groups(
|
||||
page_a, dual_harness, live_server_a_url, live_server_b_url, page_b
|
||||
) -> None:
|
||||
"""После paste на A sync — B видит рецепт в period B (API)."""
|
||||
period_b = dual_harness._e2e_period_b # type: ignore[attr-defined]
|
||||
r1 = dual_harness._e2e_r1 # type: ignore[attr-defined]
|
||||
|
||||
src = page_a.request.get(f"{live_server_a_url}/api/recipes/{r1}")
|
||||
assert src.ok
|
||||
body = src.json()
|
||||
body["name"] = f"{body.get('name', 'R')} (копия)"
|
||||
body["ingredients"] = body.get("ingredients") or []
|
||||
body["unloading_groups"] = body.get("unloading_groups") or [
|
||||
{"name": "G1", "distribution_type": "percent", "value": 100, "order": 1}
|
||||
]
|
||||
create = page_a.request.post(
|
||||
f"{live_server_a_url}/api/periods/{period_b}/recipes",
|
||||
data=body,
|
||||
)
|
||||
assert create.ok or create.status in (200, 201), create.text()
|
||||
new_id = create.json().get("id") if create.ok else None
|
||||
|
||||
dual_harness.push_from_terminal("a")
|
||||
if new_id:
|
||||
with dual_harness.server_ctx():
|
||||
from app.services.sync_manager import enqueue_sync_queue_task
|
||||
|
||||
enqueue_sync_queue_task("recipe", new_id, "create", priority=2)
|
||||
enqueue_sync_queue_task(
|
||||
"period_recipes", f"{period_b}:{new_id}", "create", priority=2
|
||||
)
|
||||
from app import db
|
||||
|
||||
db.session.commit()
|
||||
|
||||
from tests.e2e.dual_terminal_conftest import sync_both
|
||||
|
||||
sync_both(dual_harness)
|
||||
|
||||
listed = page_b.request.get(f"{live_server_b_url}/api/periods/{period_b}/recipes")
|
||||
assert listed.ok
|
||||
assert len(listed.json()) >= 1
|
||||
rid = new_id or listed.json()[0]["id"]
|
||||
detail = page_b.request.get(f"{live_server_b_url}/api/recipes/{rid}")
|
||||
assert detail.ok
|
||||
groups = detail.json().get("unloading_groups") or []
|
||||
assert groups
|
||||
|
||||
|
||||
def test_dual_transfer_then_reorder_on_b(
|
||||
page_a, page_b, dual_harness, live_server_a_url, live_server_b_url
|
||||
) -> None:
|
||||
SCENARIO_DUAL_E2E_TRANSFER_REORDER # noqa: F841
|
||||
disp_id = dual_harness._e2e_disp_id # type: ignore[attr-defined]
|
||||
period_a = dual_harness._e2e_period_a # type: ignore[attr-defined]
|
||||
period_b = dual_harness._e2e_period_b # type: ignore[attr-defined]
|
||||
r2 = dual_harness._e2e_r2 # type: ignore[attr-defined]
|
||||
|
||||
from tests.e2e.recipes_e2e_helpers import drag_transfer_to_period
|
||||
|
||||
page_a.locator(f'[data-action="select-dispenser"][data-dispenser-id="{disp_id}"]').click()
|
||||
page_a.locator(f'[data-action="select-period"][data-period-id="{period_a}"]').click()
|
||||
drag_transfer_to_period(page_a, r2, period_b)
|
||||
|
||||
from tests.e2e.dual_terminal_conftest import sync_both
|
||||
|
||||
sync_both(dual_harness)
|
||||
|
||||
page_b.locator(f'[data-action="select-dispenser"][data-dispenser-id="{disp_id}"]').click()
|
||||
page_b.locator(f'[data-action="select-period"][data-period-id="{period_b}"]').click()
|
||||
ids_b = period_recipe_ids(page_b, live_server_b_url, period_b)
|
||||
assert r2 in ids_b
|
||||
Reference in New Issue
Block a user