Rewire hover as a flow trigger
Add "survol"/"fin_survol" trigger events (mouseenter/mouseleave, same anti-doublon pattern as bindClicks()) so hovering an element can run flow nodes, instead of the old static hover-text-only control removed from the properties panel. Also add "Contenu" as a settable "Modifier un élément" property so an action can display a defined text on another element on hover — the concrete use case that motivated this. Verified live with Playwright: a "Au survol" trigger on one element correctly updates another element's text via the action, and text stays put with no "Fin du survol" wired (explicit, no implicit revert, consistent with "Au clic").
This commit is contained in:
+61
-3
@@ -22,9 +22,10 @@ def test_hover_text_control_removed_from_properties_panel(client, game):
|
||||
"""Le réglage "Survol" a été retiré du panneau de propriétés (voir
|
||||
universal_controls.py) : survoler un élément est conceptuellement un
|
||||
déclencheur de la Logique de la scène, pas une propriété statique —
|
||||
il sera réintroduit là-bas. Poster ctrl_survol_texte ne doit donc plus
|
||||
avoir d'effet (le mécanisme data-hover-text/bindHoverTexts sous-jacent
|
||||
reste en place pour un usage futur, voir les tests ci-dessous)."""
|
||||
reconstruit là-bas avec les déclencheurs "survol"/"fin_survol" (voir
|
||||
plus bas). Poster ctrl_survol_texte ne doit donc plus avoir d'effet (le
|
||||
mécanisme data-hover-text/bindHoverTexts sous-jacent reste en place, il
|
||||
n'est simplement plus réglable depuis ce panneau)."""
|
||||
screen_id = _create_screen(client, game)
|
||||
el_id = _add_element(client, game, screen_id, "titre")
|
||||
client.post(f"/game/{game}/elements/{el_id}/save", data={
|
||||
@@ -54,6 +55,63 @@ def test_play_page_exposes_hover_binding_runtime(client, game):
|
||||
assert "bindHoverTexts" in html
|
||||
|
||||
|
||||
def test_survol_trigger_node_persists(client, game):
|
||||
screen_id = _create_screen(client, game)
|
||||
el_id = _add_element(client, game, screen_id, "titre")
|
||||
resp = client.post(
|
||||
f"/game/{game}/screens/{screen_id}/flow/nodes/add",
|
||||
data=json.dumps({"node_type": "trigger", "trigger_element_id": el_id, "trigger_event": "survol"}),
|
||||
content_type="application/json",
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
node = resp.get_json()
|
||||
assert node["trigger_event"] == "survol"
|
||||
assert node["trigger_element_id"] == el_id
|
||||
|
||||
|
||||
def test_play_page_exposes_hover_trigger_runtime(client, game):
|
||||
"""bindHoverTriggers() (mouseenter/mouseleave -> runFlowFrom) doit être
|
||||
exposé et appelé, exactement comme bindClicks() pour "Au clic"."""
|
||||
resp = client.get(f"/game/{game}/play")
|
||||
html = resp.data.decode()
|
||||
assert "bindHoverTriggers" in html
|
||||
assert "'survol'" in html
|
||||
assert "'fin_survol'" in html
|
||||
|
||||
|
||||
def test_modifier_element_contenu_action_persists(client, game):
|
||||
""""Modifier un élément → Contenu" : c'est ce qui permet de reconstruire
|
||||
l'ancien "texte affiché au survol" (et bien d'autres usages) à la main
|
||||
dans la Logique de la scène, en le combinant avec un déclencheur
|
||||
"Au survol" posé sur un AUTRE élément."""
|
||||
screen_id = _create_screen(client, game)
|
||||
source_id = _add_element(client, game, screen_id, "titre")
|
||||
target_id = _add_element(client, game, screen_id, "texte")
|
||||
resp = client.post(
|
||||
f"/game/{game}/screens/{screen_id}/flow/nodes/add",
|
||||
data=json.dumps({
|
||||
"node_type": "action", "action_type": "modifier_element",
|
||||
"target_element_id": target_id, "element_property": "contenu", "element_value": "Survol actif !",
|
||||
}),
|
||||
content_type="application/json",
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
node = resp.get_json()
|
||||
assert node["element_property"] == "contenu"
|
||||
assert node["element_value"] == "Survol actif !"
|
||||
assert node["target_element_id"] == target_id
|
||||
# source_id n'est utilisé que pour documenter le scénario (le
|
||||
# déclencheur "Au survol" se poserait dessus) — non exercé ici, déjà
|
||||
# couvert par test_survol_trigger_node_persists.
|
||||
assert source_id != target_id
|
||||
|
||||
|
||||
def test_play_page_exposes_contenu_property_runtime(client, game):
|
||||
resp = client.get(f"/game/{game}/play")
|
||||
html = resp.data.decode()
|
||||
assert "'contenu'" in html
|
||||
|
||||
|
||||
# ---------- 3.2 — Séquences temporisées ----------
|
||||
|
||||
def test_attendre_action_node_persists_delay(client, game):
|
||||
|
||||
Reference in New Issue
Block a user