diff --git a/static/js/screen_edit/animation-timeline.js b/static/js/screen_edit/animation-timeline.js
new file mode 100644
index 00000000..0d383370
--- /dev/null
+++ b/static/js/screen_edit/animation-timeline.js
@@ -0,0 +1,316 @@
+// ---------- Timeline d'animation : piste par élément, clips Animate.css ou
+// personnalisés (images-clés), glissés/redimensionnés à la souris sur un
+// axe du temps en secondes depuis l'affichage de l'écran. Même principe de
+// panneau rétractable/redimensionnable que "Logique de la scène"
+// ci-dessus, positionné juste en dessous. ----------
+
+// ANIM_CLIPS/ANIMATE_CSS_LABELS/GAME_SLUG : voir le petit
+
+
+
+
+
+
{% endblock %}
diff --git a/tests/conftest.py b/tests/conftest.py
index 310c3cdc..bb350fdc 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -87,7 +87,19 @@ def game(client):
shutil.rmtree(game_dir)
-_PLAY_JS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "static", "js", "play")
+_STATIC_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "static", "js")
+_PLAY_JS_DIR = os.path.join(_STATIC_DIR, "play")
+_SCREEN_EDIT_JS_DIR = os.path.join(_STATIC_DIR, "screen_edit")
+
+
+def _js_bundle(directory):
+ parts = []
+ for name in sorted(os.listdir(directory)):
+ path = os.path.join(directory, name)
+ if os.path.isfile(path) and name.endswith(".js"):
+ with open(path, encoding="utf-8") as f:
+ parts.append(f.read())
+ return "\n".join(parts)
def play_js_bundle():
@@ -98,13 +110,13 @@ def play_js_bundle():
telle chaîne, sans dépendre d'un navigateur — avant le découpage, ça
revenait à chercher dans le HTML de /game//play (tout était
inline) ; maintenant la logique vit dans ces fichiers statiques."""
- parts = []
- for name in sorted(os.listdir(_PLAY_JS_DIR)):
- path = os.path.join(_PLAY_JS_DIR, name)
- if os.path.isfile(path) and name.endswith(".js"):
- with open(path, encoding="utf-8") as f:
- parts.append(f.read())
- return "\n".join(parts)
+ return _js_bundle(_PLAY_JS_DIR)
+
+
+def screen_edit_js_bundle():
+ """Même principe que play_js_bundle(), pour l'éditeur (static/js/
+ screen_edit/, extrait de templates/screen_edit.html)."""
+ return _js_bundle(_SCREEN_EDIT_JS_DIR)
@pytest.fixture
diff --git a/tests/test_condition_variable.py b/tests/test_condition_variable.py
index 3705b1e4..3b2fff28 100644
--- a/tests/test_condition_variable.py
+++ b/tests/test_condition_variable.py
@@ -13,6 +13,8 @@ passent."""
import json
import re
+from conftest import screen_edit_js_bundle
+
def _create_screen(client, slug, name="Accueil"):
resp = client.post(f"/game/{slug}/screens/new", data={"name": name}, follow_redirects=False)
@@ -88,7 +90,7 @@ def test_screen_edit_panel_exposes_variable_source_condition_ui(client, game):
assert 'id="nf-cond-source"' in html
assert 'id="nf-cond-variable-fields"' in html
assert "onFlowConditionSourceChange" in html
- assert "onFlowClauseSourceChange" in html
+ assert "onFlowClauseSourceChange" in screen_edit_js_bundle()
def test_condition_builder_still_available_without_any_object_defined(client, game):
diff --git a/tests/test_flow_clicked_row.py b/tests/test_flow_clicked_row.py
index 6c40c56b..c31ea1b9 100644
--- a/tests/test_flow_clicked_row.py
+++ b/tests/test_flow_clicked_row.py
@@ -10,6 +10,8 @@ import re
import db
import screens
+from conftest import screen_edit_js_bundle
+
def _create_screen(client, slug, name="Accueil"):
resp = client.post(f"/game/{slug}/screens/new", data={"name": name}, follow_redirects=False)
@@ -105,6 +107,8 @@ def test_ordinary_fixed_row_target_is_unaffected(client, game):
def test_clicked_row_option_appears_in_the_flow_node_editor(client, game):
_create_email_object(client, game)
screen_id = _create_screen(client, game)
- html = client.get(f"/game/{game}/screens/{screen_id}/edit").data.decode()
- assert "FLOW_CLICKED_ROW_ID" in html
- assert "Ligne cliquée" in html
+ resp = client.get(f"/game/{game}/screens/{screen_id}/edit")
+ assert resp.status_code == 200
+ js = screen_edit_js_bundle()
+ assert "FLOW_CLICKED_ROW_ID" in js
+ assert "Ligne cliquée" in js